diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-09-06 00:17:05 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-09-06 06:18:08 -0700 |
commit | dd2a7f9048da2c440a4dfed5122c0bfd98f079d3 (patch) | |
tree | c901bb9cb11796df795d97b5cf5c1914a2781aec /pp_hot.c | |
parent | 956f23f034b0a3aa7c521134b47f388252b9f843 (diff) | |
download | perl-dd2a7f9048da2c440a4dfed5122c0bfd98f079d3.tar.gz |
Use defelems for (goto) &xsub calls
Before ce0d59f:
$ perl -e '++$#_; &utf8::encode'
Modification of a read-only value attempted at -e line 1.
As of ce0d59f:
$ ./perl -Ilib -e '++$#_; &utf8::encode'
Assertion failed: (sv), function Perl_sv_utf8_encode, file sv.c, line 3581.
Abort trap: 6
Calling sub { utf8::encode($_[0]) } should be more or less equivalent
to calling utf8::encode, but it is not in this case:
$ ./perl -Ilib -we '++$#_; &{sub { utf8::encode($_[0]) }}'
Use of uninitialized value in subroutine entry at -e line 1.
In the first two examples above, an implementation detail is leaking
through. What you are seeing is not the array element, but a place-
holder that indicates an element that has not been assigned to yet.
We should use defelem magic so that what the XSUB assigns to will cre-
ate an array element (as happens with utf8::encode($_[0])).
All of the above applies to goto &xsub as well.
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 13 |
1 files changed, 12 insertions, 1 deletions
@@ -2728,9 +2728,20 @@ try_autoload: const I32 items = AvFILLp(av) + 1; /* @_ is not tieable */ if (items) { + SSize_t i = 0; /* Mark is at the end of the stack. */ EXTEND(SP, items); - Copy(AvARRAY(av), SP + 1, items, SV*); + for (; i < items; ++i) + if (AvARRAY(av)[i]) SP[i+1] = AvARRAY(av)[i]; + else { + SV * const lv = sv_2mortal(newSV_type(SVt_PVLV)); + SP[i+1] = lv; + LvTYPE(lv) = 'y'; + sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0); + LvTARG(lv) = SvREFCNT_inc_simple_NN(av); + LvSTARGOFF(lv) = i; + LvTARGLEN(lv) = 1; + } SP += items; PUTBACK ; } |