summaryrefslogtreecommitdiff
path: root/pad.c
Commit message (Collapse)AuthorAgeFilesLines
* Unused dVARs found by g++ -DPERL_GLOBAL_STRUCT_PRIVATE.Jarkko Hietaniemi2014-07-241-4/+0
|
* Remove or downgrade unnecessary dVAR.Jarkko Hietaniemi2014-06-251-23/+2
| | | | | | | | You need to configure with g++ *and* -Accflags=-DPERL_GLOBAL_STRUCT or -Accflags=-DPERL_GLOBAL_STRUCT_PRIVATE to see any difference. (g++ does not do the "post-annotation" form of "unused".) The version code has some of these issues, reported upstream.
* fix multi-evals problems in pad name list apiDaniel Dragan2014-06-241-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | The PAD_COMPNAME api, created in dd2155a49b , originally had alot of, multi-eval problems, since av_fetch would be repeatedly called in macro expansions. Later in commit b21dc0313d , an incomplete attempt at removing multi-eval was done. Also in commit 035dab7448 added more multi-eval problems. Prior to commit dd2155a49b , the code used a seemingly random mix of av_fetch and AvARRAY, so both are ok. To fix this, replace av_fetch with func-free AvARRAY. Since existing code has lval 0 to av_fetch and unconditional deref on ret, a segv is fine to detect breakage. A #define PAD_COMPNAME_SV(po) \ ((assert(!SvMAGICAL(PL_comppad_name))),(AvARRAY(PL_comppad_name)[(po)])) shows the AV is ! magical/tied during smoke. The assert was not added for perf reasons on debugging builds. Inline funcs were not used for better compiler optimizing if PAD_COMPNAME_FLAGS_isOUR is immediatly followed by PAD_COMPNAME_OURSTASH (2 statements), as in scan_inputsymbol. Inlines are not guaranteed to be inlined all the time on all compilers in all situations, Visual C especially. Also inline is more likely to cause readding of multi-eval problems than the macro if future changes to the API put the inline func in a multi-eval macro. On VC 2003 32bit .text section of perl521.dll dropped from 0xC296F to 0xC281F bytes of machine code with this patch.
* Remove MAD.Jarkko Hietaniemi2014-06-131-22/+0
| | | | | | MAD = Misc Attribute Decoration; unmaintained attempt at preserving the Perl parse tree more faithfully so that automatic conversion to Perl 6 would have been easier.
* Cast %p arguments to (void*)Brian Fraser2014-06-131-2/+2
| | | | | These were all part of debugging statements; the commit silences a chunk of warnings under -Wformat
* Adding missing SVfARG() invocationsBrian Fraser2014-06-131-5/+5
| | | | This silences a chunk of warnings under -Wformat
* Revert "[perl #79908] Stop sub inlining from breaking closures"Ævar Arnfjörð Bjarmason2014-05-121-0/+19
| | | | | | | | | | | | | | | | | | | | | | | | This reverts commit 137da2b05b4b7628115049f343163bdaf2c30dbb. See the "How about having a recommended way to add constant subs dynamically?" thread on perl5-porters, specifically while it sucks that we have this bug, it's been documented to work this way since 5.003 in "Constant Functions" in perlsub: If the result after optimization and constant folding is either a constant or a lexically-scoped scalar which has no other references, then it will be used in place of function calls made without C<&> -- http://perldoc.perl.org/perlsub.html#Constant-Functions Since we've had this documented bug for a long time we should introduce this fix in a deprecation cycle rather than silently slowing down code that assumes it's going to be optimized by constant folding. I didn't revert the tests it t/op/sub.t, but turned them into TODO tests instead. Conflicts: t/op/sub.t
* perlapi: Consistent spaces after dotsFather Chrysostomos2013-12-291-8/+9
| | | | plus some typo fixes. I probably changed some things in perlintern, too.
* Don’t give unavailability warnings about our varsFather Chrysostomos2013-08-241-0/+5
| | | | | | | | | | | | | | | | Commit ce0d59fdd1c started using NULL to indicate nonexistent array elements. Since pads are AVs, they are filled with NULLs initially, rather than &PL_sv_undef. For ‘our’ vars, the pad entry is never actually touched. Only one piece of code was inspecting it, namely S_cv_clone_pad. &PL_sv_undef just happens to pass the checks that make sure the var is not stale. However, we really should not be checking that at all if this is an ‘our’ var. Even if we change ‘our’ vars back to having a &PL_sv_undef pad entry, this fix should stay, as it makes the code clearer and makes S_cv_clone_pad more robust.
* [perl #7508] Use NULL for nonexistent array elemsFather Chrysostomos2013-08-201-10/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | This commit fixes bug #7508 and provides the groundwork for fixing several other bugs. Elements of @_ are aliased to the arguments, so that \$_[0] within sub foo will reference the same scalar as \$x if the sub is called as foo($x). &PL_sv_undef (the global read-only undef scalar returned by the ‘undef’ operator itself) was being used to represent nonexistent array elements. So the pattern would be broken for foo(undef), where \$_[0] would vivify a new $_[0] element, treating it as having been nonexistent. This also causes other problems with constants under ithreads (#105906) and causes a pending fix for another bug (#118691) to trig- ger this bug. This commit changes the internals to use a null pointer to represent a nonexistent element. This requires that Storable be changed to account for it. Also, IPC::Open3 was relying on the bug. So this commit patches both modules.
* Fix skip logic in pad_tidy and cv_cloneFather Chrysostomos2013-08-201-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit 325e1816dc changed the logic for determining whether a pad entry is to be treated like a constant; i.e., shared between recursion levels and sub clones. According the old logic, a pad entry must be shared if it is marked READONLY or is a shared hash key scalar. According to the new logic, the entry must be shared if the pad name has a zero-length PV (i.e., &PL_sv_no). Two pieces of code were still following the old logic. Changing them fixes this old bug: my $close_over_me; sub { () = $close_over_me; open my $fh, "/dev/null"; print "$$fh\n" }->(); __END__ Output: *main:: The name attached to the implicit rv2gv op in open() was not being copied by sub clones. The previous commit is also part of the fix. In the tests, I tested the combination of sub cloning and recursion, since it seemed like a good idea (and also as a result of copying and pasting :-). S_pmtrans was still relying on the old logic, so it gets changed, too.
* Skip trailing constants when searching padsFather Chrysostomos2013-07-301-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Under ithreads, constants and GVs are stored in the pad. When names are looked up up in a pad, the search begins at the end and works its way toward the beginning, so that an $x declared later masks one declared earlier. If there are many constants at the end of the pad, which can happen for generated code such as lib/unicore/TestProp.pl (which has about 100,000 lines and over 500,000 pad entries for constants at the end of the file scope’s pad), it can take a long time to search through them all. Before commit 325e1816, constants used &PL_sv_undef ‘names’. Since that is the default value for array elements (when viewed directly through AvARRAY, rather than av_fetch), the pad allocation code did not even bother storing the ‘name’ for these. So the name pad (aka padnamelist) was not extended, leaving just 10 entries or so in the case of lib/unicore/TestProp.pl. Commit 325e1816 make pad constants have &PL_sv_no names, so the name pad would be implicitly extended as a result of storing &PL_sv_no, causing a huge slowdown in t/re/uniprops.t (which runs lib/unicore/TestProp.pl) under threaded builds. Now, normally the name pad *does* get extended to match the pad, in pad_tidy, but that is skipped for string eval (and required file scope, of course). Hence, wrapping the contents of lib/unicore/TestProp.pl in a sub or adding ‘my $x’ to end of it will cause the same slowdown before 325e1816. lib/unicore/TestProp.pl just happened to be written (ok, generated) in such a way that it ended up with a small name pad. This commit fixes things to make them as fast as before by recording the index of the last named variable in the pad. Anything following that is disregarded in pad lookup and search begins with the last named variable. (This actually does make things faster before for subs with many trailing constants in the pad.) This is not a complete fix. Adding ‘my $x’ to the end of a large file like lib/unicore/TestProp.pl will make it just as slow again. Ultimately we need another algorithm, such as a binary search.
* pad.c apidocs: Clarify use of &PL_sv_noFather Chrysostomos2013-07-251-1/+2
| | | | specifically with regard to possible future changes.
* Stop op freeing from interfering with sub(){42} mutabilityFather Chrysostomos2013-07-251-2/+0
| | | | | | | The problem is that when an OP_CONST is freed, it calls pad_swipe, which clears the PADTMP flag when removing the SV from the pad. Since PADTMP no longer necessarily means ‘in a pad’, we shouldn’t turn this flag off.
* Don’t check IS_PADCONST in pad.c:pad_allocFather Chrysostomos2013-07-251-1/+1
| | | | | | Since recent commits have given constants &PL_sv_no names, this check is redundant, since any slots for constants will have been skipped over by the sv != &PL_sv_undef check just above.
* pad.c: Don’t copy shared hash key targets when cloningFather Chrysostomos2013-07-251-1/+1
| | | | | | | | | When creating a new thread, don’t treat shared hash key targets as constants. (See the previous commit for explanation.) This should cause no change in behaviour, because the new target will not be in use, and its next use will immediately overwrite its value. It just saves having to copy a string that will be overwritten.
* Stop shared hash key TARGs from being sharedFather Chrysostomos2013-07-251-1/+1
| | | | | | | | | | | | | | | | | | | | A CV has a list of pads containing a different pad for each recursion level. pad_push, which adds a new pad to the list, copies some items from pad no. 1 but not others. In particular op targets¹ are created anew, but, under ithreads, constants² are not. Historically, these were distinguished from each other by flags on the value. Any read- only or shared hash key scalar was considered to be a constant, and hence shared between pads. The target returned by ref() is a shared hash key scalar, so it was being shared between recursion levels. Recent commits have made it possible to distinguish between constants and targets based on the name. Formerly, both were nameless pad entries. Now constants have zero-length names (PadnamePV(name) && !PadnameLEN(name)). So we can use that to fix this bug. ¹ Many operators return the same scalar each time, for efficiency. This is stored in the pad, and is known as the target, or TARG. ² Constanst are stored in the pad under ithreads, instead of being attached directly to ops, as they are under non-threaded builds.
* [perl #79908] Stop sub inlining from breaking closuresFather Chrysostomos2013-07-251-19/+0
| | | | | | | | | | | | | | | | | | | | | | | | When a closure closes over a variable, it references the variable itself, as opposed to taking a snapshot of its value. This was broken by the constant optimisation added for constant.pm’s sake: { my $x; sub () { $x }; # takes a snapshot of the current value of $x } constant.pm no longer uses that mechanism, except on older perls, so we can remove this hack, causing code like this this to start work- ing again: BEGIN{ my $x = 5; *foo = sub(){$x}; $x = 6 } print foo; # now prints 6, not 5
* pad.c: cast before comparing signed with unsignedFather Chrysostomos2013-07-251-1/+1
|
* op.c: Stop copying constants under ithreadsFather Chrysostomos2013-07-251-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This fixes bugs #21979, #89188, #109746, #114838 and #115388 and mostly fixes #109744 and #105906 (other issues still remain in those two tickets). Because the PADTMP flag was doing double duty, indicating that a pad slot was in use in addition to indicating a target, constants could not be shared between pad slots, as freeing one const op (and turning of its PADTMP flag in pad_free) would mark some other pad slot as free. I believe this may have been fixed already by change 3b1c21fabed, which made const ops use pad_swipe (which removes the SV from the pad) instead of pad_free (which marks it as available for reuse). But the copying still happens. In any case, as of the previous commit, whether a pad slot for a con- stant is in use is now stored in the pad name. Slots in use for const ops now have &PL_sv_no names. So there is no longer any reason to copy the constants. The difference can be observed thus: Before: $ ./perl -lIlib -MDevel::Peek -e 'sub foo(){42} Dump foo; Dump foo' SV = IV(0x7f94ea02ef10) at 0x7f94ea02ef20 REFCNT = 2 FLAGS = (PADTMP,IOK,READONLY,pIOK) IV = 42 SV = IV(0x7f94ea02eeb0) at 0x7f94ea02eec0 REFCNT = 1 FLAGS = (PADTMP,IOK,READONLY,pIOK) IV = 42 After: $ ./perl -lIlib -MDevel::Peek -e 'sub foo(){42} Dump foo; Dump foo' SV = IV(0x7f894882ef10) at 0x7f894882ef20 REFCNT = 3 FLAGS = (IOK,READONLY,pIOK) IV = 42 SV = IV(0x7f894882ef10) at 0x7f894882ef20 REFCNT = 3 FLAGS = (IOK,READONLY,pIOK) IV = 42 Notice the different addresses. There are still special cases for copying &PL_sv_undef, which I need to tackle. Since most constants created by ‘use constant’ have the PADMY flag on (since they reside in lexical variables inside constant.pm) and PADMY and PADTMP are exclusive, I have stop turning on PADTMP for constants. It is no longer necessary now, since before its purpose was to mark pad entries as being in use. That means many to-do tests pass.
* pad.c: Expand pad_push SVf_READONLY explanationFather Chrysostomos2013-07-251-1/+4
|
* pad.c: Use &PL_sv_no for const pad namesFather Chrysostomos2013-07-251-15/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently &PL_sv_undef as a pad name can indicate either a free slot available for use by pad_alloc or a slot used by an op target (or, under ithreads, a constant or GV). Currently pad_alloc distinguishes between free slots and unnamed slots based on whether the value in the pad has PADMY or PADTMP set. If neither is set, then the slot is free. If either is set, the slot is in use. This makes it rather difficult to distinguish between constants stored in the pad (under ithreads) and targets. The latter need to be copied when referenced, to give the impression that a new scalar is being returned by an operator each time. (So \"$a" has to return a refer- ence to a new scalar each time, but \1 should return the same one.) Also, constants are shared between recursion levels. Currently, if the value is marked READONLY or is a shared hash key scalar, it is shared. But targets can also me shared hash keys, resulting in bugs. It also makes it impossible for the same constant to be shared by mul- tiple pad slots, as freeing one const op will turn off the PADTMP flag while the other slot still uses it, making the latter appear to be free. Hence a lot of copying occurs under ithreads. (Actually, that may not be true any more since 3b1c21fabed, as freed const ops swipe their constants from the pad. But right now, a lot of copying does still happen.) Also, XS modules may want to create const ops that return the same mutable SV each time. That is currently not possible without various workarounds including custom ops and references. (See <https://rt.perl.org/rt3/Ticket/Display.html?id=105906#txn-1075354>.) This commit changes pad_alloc and pad_free to use &PL_sv_no for con- stants and updates other code to keep all tests passing. Subsequent commits will actually use that information to fix bugs. This will probably break PadWalker, but I think it is an acceptable trade-off. The alternative would be to make PadnamePV forever more complex than necessary, by giving it a special case for &PL_sv_no and having it return NULL. I gave PadnameLEN a special case for &PL_sv_undef, so it may appear that I have simply shifted the complexity around. But if pad names stop being SVs, then this exception will simply disappear, since the global &PL_padname_undef will have 0 in its length field.
* Re(mov|writ)e two comments from pad.c:pad_allocFather Chrysostomos2013-07-251-3/+3
| | | | | | | | | | | | | | | | The thing about "foreach" index vars was added in bbce6d697 (insepar- able changes from patch from perl5.003_08 to perl5.003_09, presuma- bly the ‘Lexical scoping cleanup’ part). It is not valid, because ‘foreach’ doesn’t aliases a pad entry to a non-pad (not marked PADMY or PADTMP) value until run time, and pad_alloc happens at compile time. The real reason we need this loop is that entries that close over unavailable variables are not marked PADMY. That may have been a mistake, but it works because of this loop. The reason for the loop also may have changed over time. The comment about copying to sv is not valid, because it is used later on in the same condition when compared to &PL_sv_undef. It was added in commit dd2155a49b.
* pad.c, S_cv_clone: Maintain the utf8-ness of the cloned cvBrian Fraser2013-06-281-1/+4
| | | | | | | | | | | Because of a missing SvUTF8_on() in cv_clone(), these two were different: use utf8; eval " sub foo ($;\x{30cd});" eval "my sub foo ($;\x{30cd});" Because the lexical version would lose the UTF8 flag in the prototype.
* pad.c: Correct comment added by dd2155a49bFather Chrysostomos2013-06-141-1/+1
|
* expand comment in Perl_pad_tidyDavid Mitchell2013-01-111-7/+15
| | | | | make it clear that /$var/ is only eval-able in the presence of 'use re eval'; then generally tidy and reformat the comment.
* Convert some SvREFCNT_dec's to SvREFCNT_dec_NN's for efficiencySteffen Mueller2012-12-091-5/+5
|
* Stop format closure fatal warnings from leakingFather Chrysostomos2012-11-301-2/+5
|
* Stop duplicate lex vars from leaking under fatal warningsFather Chrysostomos2012-11-301-0/+4
|
* Remove "register" declarationsKarl Williamson2012-11-241-1/+1
| | | | | | | This finishes the removal of register declarations started by eb578fdb5569b91c28466a4d1939e381ff6ceaf4. It neglected the ones in function parameter declarations, and didn't include things in dist, ext, and lib, which this does include
* Stop eval "END OF TERMS" from leakingFather Chrysostomos2012-11-141-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I found this memory leak by evaluating lines of the Copying file as Perl code. :-) The parser requires yylex to return exactly one token with each call. Sometimes yylex needs to record a few tokens ahead of time, so its puts them in its forced token stack. The next call to yylex then pops the pending token off that stack. Ops belong to their subroutines. If the subroutine is freed before its root is attached, all the ops created when PL_compcv pointed to that sub are freed as well. To avoid crashes, the ops on the savestack and the forced token stack are specially marked so they are not freed when the sub is freed. When it comes to evaluating "END OF TERMS AND CONDITIONS", the END token causes a subroutine to be created and placed in PL_compcv. The OF token is treated by the lexer as a method call on the TERMS pack- age. The TERMS token is placed in the forced token stack as an sv in an op for a WORD token, and a METHOD token for OF is returned. As soon as the parser sees the OF, it generates an error, which results in LEAVE_SCOPE being called, which frees the subroutine for END while TERMS is still on the forced token stack. So the subroutine’s op cleanup skips that op. Then the parser calls back into the lexer, which returns the TERMS token from the forced token stack. Since there has been an error, the parser discards that token, so the op is never freed. The forced token stack cleanup that happens in parser_free does not catch this, as the token is no longer on that stack. Earlier, to solve the problem of yylex returning freed ops to the parser, resulting in crashes, I set the op_savefree flag on ops on the forced token stack. But that resulted in a leak. So now I am using a different approach: When the sub is freed and frees all its ops, have it also look in the parser’s forced token stack, freeing any ops that belong to it, and setting the point- ers to null.
* Silence two build warnings on systems where ivsize > ptrsize.Eric Brine\" (via RT)2012-11-131-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | # New Ticket Created by "Eric Brine" # Please include the string: [perl #115710] # in the subject line of all future correspondence about this issue. # <URL: https://rt.perl.org:443/rt3/Ticket/Display.html?id=115710 > This is a bug report for perl from ikegami@adaelis.com, generated with the help of perlbug 1.39 running under perl 5.14.2. ----------------------------------------------------------------- [Please describe your issue here] Attached patch silences two build warnings on systems where ivsize > ptrsize. They are safe to ignore, a side-effect of a function with a polymorphic interface. cv = find_runcv_where(FIND_RUNCV_level_eq, iv, NULL); cv = find_runcv_where(FIND_RUNCV_padid_eq, PTR2IV(p), NULL); // p is a PADNAMELIST* [Please do not change anything below this line] -----------------------------------------------------------------
* pad_free(): don't clear SVs_PADSTALEDavid Mitchell2012-11-101-3/+6
| | | | | | | | | pad_free() clears the SVs_PADTMP bit. Since that bit is now shared with SVs_PADSTALE, that gets cleared on state vars. It didn't matter up till now, but the next commit will start optimising away pad ops, and op_null() will call pad_free() which would clear the SVs_PADSTALE bit. So only clear SVs_PADTMP/SVs_PADSTALE for non-lexical var ops.
* Add C define to remove taint support from perlSteffen Mueller2012-11-051-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | By defining NO_TAINT_SUPPORT, all the various checks that perl does for tainting become no-ops. It's not an entirely complete change: it doesn't attempt to remove the taint-related interpreter variables, but instead virtually eliminates access to it. Why, you ask? Because it appears to speed up perl's run-time significantly by avoiding various "are we running under taint" checks and the like. This change is not in a state to go into blead yet. The actual way I implemented it might raise some (valid) objections. Basically, I replaced all uses of the global taint variables (but not PL_taint_warn!) with an extra layer of get/set macros (TAINT_get/TAINTING_get). Furthermore, the change is not complete: - PL_taint_warn would likely deserve the same treatment. - Obviously, tests fail. We have tests for -t/-T - Right now, I added a Perl warn() on startup when -t/-T are detected but the perl was not compiled support it. It might be argued that it should be silently ignored! Needs some thinking. - Code quality concerns - needs review. - Configure support required. - Needs thinking: How does this tie in with CPAN XS modules that use PL_taint and friends? It's easy to backport the new macros via PPPort, but that doesn't magically change all code out there. Might be harmless, though, because whenever you're running under NO_TAINT_SUPPORT, any check of PL_taint/etc is going to come up false. Thus, the only CPAN code that SHOULD be adversely affected is code that changes taint state.
* Used pad name lists for pad idsFather Chrysostomos2012-10-161-4/+4
| | | | | | | | | | | | | | | | | I added pad IDs so that a pad could record which pad it closes over, to avoid problems with closures closing over the wrong pad, resulting in crashes or bizarre copies. These pad IDs were shared between clones of the same pad. In commit 9ef8d56, for efficiency I made clones of the same closure share the same pad name list. It has just occurred to be that each padlist containing the same pad name list also has the same pad ID, so we can just use the pad name list itself as the ID. This makes padlists 32 bits smaller and eliminates PL_pad_generation from the interpreter struct.
* fix -DPERL_GLOBAL_STRUCT build failure introduced in 97b03d64 and e10681aaTony Cook2012-09-281-0/+2
|
* Move my sub prototype CVs to the pad namesFather Chrysostomos2012-09-151-21/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | my subs are cloned on scope entry. To make closures work, a stub stored in the pad (and closed over elsewhere) is cloned into. But we need somewhere to store the prototype from which the clone is made. I was attaching the prototype via magic to the stub in the pad, since the pad is available at run time, but not the pad names. That leads to lots of little games all over the place to make sure the prototype isn’t lost when the pad is swiped on scope exit (SAVEt_CLEARSV in scope.c). We also run the risk of losing it if an XS module replaces the sub with another. Instead, we should be storing it with the pad name. The previous com- mit made the pad names available at run time, so we can move it there (still stuffed inside a magic box) and delete much code. This does mean that newMYSUB cannot rely on the behaviour of non-clon- able subs that close over variables (or subs) immediately. Previ- ously, we would dig through outer scopes to find the stub in cases like this: sub y { my sub foo; sub x { sub { sub foo { ... } } } } We would stop at x, which happens to have y’s stub in its pad, so that’s no problem. If we attach it to the pad name, we definitely have to dig past x to get to the pad name in y’s pad. Usually, immediate closures do not store the parent pad index, since it will never be used. But now we do need to use it, so we modify the code in pad.c:S_pad_findlex to set it always for my/state.
* pad.c: Put unavailability warning in one spotFather Chrysostomos2012-09-151-19/+14
|
* Use the same outside logic for mysubs and formatsFather Chrysostomos2012-09-151-11/+1
| | | | | | | | | | | | | | | | | | | | | | | | | By using find_runcv_where both for formats and my subs nested in inner clonable subs, we can simplify the code. It happens to make this work ($x is visible): use 5.01; sub not_lexical8 { my sub foo; foo(); sub not_lexical9 { my sub bar { my $x = 'khaki car keys for the khaki car'; not_lexical8(); sub foo { warn $x } } bar() } } not_lexical9(); This is definitely iffy code, but if making it work makes the imple- mentation simpler, so why not?
* Fix subroutine unavailability during cloningFather Chrysostomos2012-09-151-2/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | sub foo { my $x; format = @ $x||'#' . } write; __END__ Variable "$x" is not available at - line 9. That one’s OK. sub foo { my sub x {}; format = @ &x . } write; __END__ Variable "&x" is not available at - line 9. Assertion failed: (SvTYPE(_svmagic) >= SVt_PVMG), function S_mg_findext_flags, file mg.c, line 404. Abort trap That should say ‘Subroutine’. And it shouldn’t crash. The my-sub-cloning code was not taking this case into account. The value in the proto pad is an undef scalar.
* ‘Subroutine "&x" is not available’ during compilationFather Chrysostomos2012-09-151-2/+10
| | | | | | | | | | | | | | | | | | | | sub { my $x; sub { eval '$x' } }->()() __END__ Variable "$x" is not available at (eval 1) line 2. That one’s OK (though I wonder about the line number). sub { my sub x {}; sub { eval '\&x' } }->()() __END__ Variable "&x" is not available at (eval 1) line 1. That should say ‘Subroutine’.
* In cv_clone, use pad ID to identify mysub outsideFather Chrysostomos2012-09-151-4/+8
| | | | | | | | | | | | | | | | | | | | This code prints ARRAY(0x802e10), whereas it should print SCALAR(0xfedbee): undef &bar; eval 'sub bar { my @x }'; { my sub foo; foo(); sub bar { CORE::state $x; sub foo { warn \$x } } } The foo sub has a strong CvOUTSIDE pointer, but what it points to can still be undefined and redefined. So we need to identify it by its pad.
* CvOUTSIDE should be strong for lexsub declared in inner pack subFather Chrysostomos2012-09-151-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | PadnameOUTER (SvFAKE) entries in pads of clonable subs contain the offset in the parent pad where the closed-over entry is to be found. The pad itself does not reference the outer lexical until the sub is cloned at run time. newMYSUB had to account for that by following CvOUTSIDE for PadnameOUTER entries, to account for cases like this: my sub foo; my sub bar { sub foo {} } The sub foo{} definition would have to find the my sub foo declaration from outside and store the sub there. That code was not accounting for named package subs, which close over variables at compile time, so they don’t need (and don’t) store a par- ent offset. So outcv would point to bar in this case: my sub foo; sub bar { sub foo {} } If outcv matched CvOUTSIDE(foo), then CvOUTSIDE was made weak. That does not help in cases like this: undef *bar; { my sub foo; sub bar { sub foo {} } } If foo has a weak CvOUTSIDE pointer, then it will still point to bar after bar is freed, which does not help when the sub is cloned and tries to look at CvROOT(CvOUTSIDE). If the pad name is marked PadnameOUTER, even if it has no parent pad index, newMYSUB needs to leave the CvOUTSIDE pointer strongc. Also, pad_fixup_inner_anons did not account for subs with strong CvOUTSIDE pointers whose CvOUTSIDE point to the sub whose pad is being iterated through.
* Use the right outside for my subs defined in inner subsFather Chrysostomos2012-09-151-7/+6
| | | | | | | | | | | | | | | | | | | | | In this example, { my sub foo; sub bar { sub foo { } } } the foo sub is cloned when the scope containing the ‘my sub’ declara- tion is entered, but foo’s CvOUTSIDE pointer points to something other than the active sub. cv_clone assumes that the currently-running sub is the right sub to close over (at least for subs; formats are another matter). That was true in the absence of my subs. This commit changes it to account. I had to tweak the test, which was wrong, because sub foo was closing over a stale var.
* Preserve outside pointers of my subs with string evalFather Chrysostomos2012-09-151-1/+1
| | | | | | | | | | | The CvHASEVAL flag lets cv_clone know that the clone needs to have its CvOUTSIDE pointer set, for the sake of string evals’ being able to look up variables. It was only being set on anonymous subs. It should be set for all clonable subs. It doesn’t actually hurt to set it on all types of subs, whether clonable or not, since it has no effect on non-clon- able subs.
* Fix up outside pointers for my subsFather Chrysostomos2012-09-151-4/+9
| | | | | | | | | | | | | | I had not yet fixed Perl_pad_fixup_inner_anons to account for the fact that my sub prototype CVs are stored in magic attached to the SV slot in the pad, rather than directly in the pad. It also did not like & entries that close over subs defined in outer or inner subs (‘my sub foo; sub bar; sub bar { &foo } }’ and ‘sub bar; sub bar { my sub foo; sub { sub foo { } } }’ respectively). This was resulting in assertion failures, unsurprisingly. Some of the tests I added, which were causing assertion failures, are now failing for other reasons, and are marked as to-do.
* CvNAME_HEK_setFather Chrysostomos2012-09-151-9/+4
|
* Clone my subs on scope entryFather Chrysostomos2012-09-151-6/+54
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The pad slot for a my sub now holds a stub with a prototype CV attached to it by proto magic. The prototype is cloned on scope entry. The stub in the pad is used when cloning, so any code that references the sub before scope entry will be able to see that stub become defined, making these behave similarly: our $x; BEGIN { $x = \&foo } sub foo { } our $x; my sub foo { } BEGIN { $x = \&foo } Constants are currently not cloned, but that may cause bugs in pad_push. I’ll have to look into that. On scope exit, lexical CVs go through leave_scope’s SAVEt_CLEARSV sec- tion, like lexical variables. If the sub is referenced elsewhere, it is abandoned, and its proto magic is stolen and attached to a new stub stored in the pad. If the sub is not referenced elsewhere, it is undefined via cv_undef. To clone my subs on scope entry, we create a sequence of introcv and clonecv ops. See the huge comment in block_end that explains why we need two separate ops for each CV. To allow my subs to be defined in inner subs (my sub foo; sub { sub foo {} }), pad_add_name_pvn and S_pad_findlex now upgrade the entry for a my sub to a CV to begin with, so that fake entries added to pads (fake entries are those that reference outer pads) can share the same CV. Otherwise newMYSUB would have to add the CV to every pad that closes over the ‘my sub’ declaration. newMYSUB no longer throws away the initial value replacing it with a new one. Prototypes are not currently visible to sub calls at compile time, because the lexer sees the empty stub. A future commit will solve that. When I added name heks to CV’s I made mistakes in a few places, by not turning on the CVf_NAMED flag, or by not clearing the field when free- ing the hek. Those code paths were not exercised enough by state subs, so the problems did not show up till now. So this commit fixes those, too. One of the tests in lexsub.t, involving foreach loops, was incorrect, and has been fixed. Another test has been added to the end for a par- ticular case of state subs closing over my subs that I broke when ini- tially trying to get sibling my subs to close over each other, before I had separate introcv and clonecv ops.
* cv_clone: panic for no padFather Chrysostomos2012-09-151-0/+1
| | | | | | | | cv_clone has serendipitously gained the ability to clone CVs without pads. It is not clear that we want to add this ability to this API function, because we would be stuck supporting it, even if we came up with a better interface. It used to crash or fail an assertion if there was no pad.
* pad.c: Let S_cv_clone clone stubsFather Chrysostomos2012-09-151-27/+43
| | | | | | | | | This will be used by cv_clone_into (which does not exist yet) in a later commit. pp_clonecv will use cv_clone_into. Teasing out the pad-related and non-pad-related parts of cv_clone was the easiest way to do this. Now the pad stuff is in a separate function.