diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-07-15 18:57:01 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-07-15 19:14:23 -0700 |
commit | 96c2a8ff507ccc5e4a6d00051b23e7a73d844322 (patch) | |
tree | 21a226d6eb96eaca777384ff09bc5e466807608d /mg.c | |
parent | d30fb84472a75fa446629f16d12e1ced09787ce4 (diff) | |
download | perl-96c2a8ff507ccc5e4a6d00051b23e7a73d844322.tar.gz |
[perl #77814] Make defelems propagate pos
When elements of @_ refer to nonexistent hash or array elements, then
the magic scalar in $_[0] delegates all set/get actions to the element
in represents, vivifying it if needed.
pos($_[0]), however, was not delegating the value to the element, but
storing it on the magical ‘deferred element’ scalar.
Diffstat (limited to 'mg.c')
-rw-r--r-- | mg.c | 33 |
1 files changed, 19 insertions, 14 deletions
@@ -436,6 +436,21 @@ Perl_mg_findext(pTHX_ const SV *sv, int type, const MGVTBL *vtbl) return S_mg_findext_flags(aTHX_ sv, type, vtbl, 1); } +MAGIC * +Perl_mg_find_mglob(pTHX_ SV *sv) +{ + PERL_ARGS_ASSERT_MG_FIND_MGLOB; + if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'y') { + /* This sv is only a delegate. //g magic must be attached to + its target. */ + vivify_defelem(sv); + sv = LvTARG(sv); + } + if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) + return S_mg_findext_flags(aTHX_ sv, PERL_MAGIC_regex_global, 0, 0); + return NULL; +} + /* =for apidoc mg_copy @@ -2076,19 +2091,17 @@ Perl_magic_getpos(pTHX_ SV *sv, MAGIC *mg) { dVAR; SV* const lsv = LvTARG(sv); + MAGIC * const found = mg_find_mglob(lsv); PERL_ARGS_ASSERT_MAGIC_GETPOS; PERL_UNUSED_ARG(mg); - if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) { - MAGIC * const found = mg_find(lsv, PERL_MAGIC_regex_global); - if (found && found->mg_len >= 0) { + if (found && found->mg_len >= 0) { I32 i = found->mg_len; if (DO_UTF8(lsv)) sv_pos_b2u(lsv, &i); sv_setiv(sv, i); return 0; - } } SvOK_off(sv); return 0; @@ -2108,19 +2121,11 @@ Perl_magic_setpos(pTHX_ SV *sv, MAGIC *mg) PERL_ARGS_ASSERT_MAGIC_SETPOS; PERL_UNUSED_ARG(mg); - if (SvTYPE(lsv) >= SVt_PVMG && SvMAGIC(lsv)) - found = mg_find(lsv, PERL_MAGIC_regex_global); - else - found = NULL; + found = mg_find_mglob(lsv); if (!found) { if (!SvOK(sv)) return 0; -#ifdef PERL_OLD_COPY_ON_WRITE - if (SvIsCOW(lsv)) - sv_force_normal_flags(lsv, 0); -#endif - found = sv_magicext(lsv, NULL, PERL_MAGIC_regex_global, &PL_vtbl_mglob, - NULL, 0); + found = sv_magicext_mglob(lsv); } else if (!SvOK(sv)) { found->mg_len = -1; |