summaryrefslogtreecommitdiff
path: root/scope.h
Commit message (Collapse)AuthorAgeFilesLines
* Expose a public SAVESTRLEN() macroPaul "LeoNerd" Evans2021-10-051-22/+24
| | | | | | | This seems to have been forgotten in the public API, perhaps because it was added later. Fixes #19165
* use CLANG_DIAG_IGNORE_STMT instead of GCC_DIAG_IGNORE_STMTTony Cook2021-08-031-2/+2
| | | | | | | | | | It turns out gcc wasn't warning on this code, but older gcc (as included in debian buster) *does* warn on the switch which it doesn't recognise. Newer gcc does recognise the -Wstring-compare switch, but it controls warning on a different construct, so there's no reason to present it to gcc.
* Eliminate '-Wstring-compare' build-time warning in re_comp.c.James E Keenan2021-07-051-0/+2
| | | | | | | | | Per discussion with TonyC, use of the 'GCC' versions of two macros here is appropriate because that version is documented to handle CLANG as well. Using these macros preserves an optimization added in d0f83c3 in 2009. PR GH 18948 for issue GH 17015.
* style: Detabify indentation of the C code maintained by the core.Michael G. Schwern2021-01-171-24/+24
| | | | | | | | | | | This just detabifies to get rid of the mixed tab/space indentation. Applying consistent indentation and dealing with other tabs are another issue. Done with `expand -i`. * vutil.* left alone, it's part of version. * Left regen managed files alone for now.
* Implement SAVEt_STRLEN_SMALLPaul "LeoNerd" Evans2020-12-091-32/+33
| | | | | | | Most uses of SAVEt_STRLEN actually store small values; often zero. Rather than using an entire U64-sized element for these values, it saves space to use the same "SMALL" mechanism as other numerical values, like SAVEt_INT_SMALL.
* autodoc.pl: Enhance apidoc_section featureKarl Williamson2020-11-061-1/+1
| | | | | | | | | | | This feature allows documentation destined for perlapi or perlintern to be split into sections of related functions, no matter where the documentation source is. Prior to this commit the line had to contain the exact text of the title of the section. Now it can be a $variable name that autodoc.pl expands to the title. It still has to be an exact match for the variable in autodoc, but now, the expanded text can be changed in autodoc alone, without other files needing to be updated at the same time.
* Change some =head1 to apidoc_section linesKarl Williamson2020-09-041-1/+1
| | | | | apidoc_section is slightly favored over head1, as it is known only to autodoc, and can't be confused with real pod.
* Define a new SAVEt_HINT_HH typePaul "LeoNerd" Evans2020-07-301-0/+1
| | | | | | | | | | | Rather than possibly push an extra HV* to the save stack if the right bit is set in the (saved) hints flags, better just to define a different SAVEt type. Having done this, the stack layout is now constant per type value. This fixes https://github.com/Perl/perl5/issues/17895
* Change pod for macros that require "literal strings"Karl Williamson2019-09-021-2/+2
| | | | | Now that Devel::PPPort has the ability to handle these, we can loosen the syntax for clarity.
* autodoc.pl: Make 's' flag independent of 'n'Karl Williamson2019-05-301-2/+2
| | | | | | | | | | | | The 's' flag is used by autodoc.pl to add a semi-colon to the end of a usage example. This commit allows that to happen even if the macro has parameters. This allows two macros in scope.c to be properly documented. Previously they weren't, and caused warnings in Devel::PPPort as a result. This commit adds documentation to embed.fnc for the 's' flag, which has long existed, undocumented.
* Add 'n' flag to various =for apidoc linesKarl Williamson2019-05-301-4/+4
| | | | | | This indicates to not output the macro with parentheses for parameters. Currently that doesn't happen anyway, but a future commit will change things so this is required (so that a bug can be fixed)
* better document macros taking literal stringsZefram2017-11-121-1/+1
| | | | | | | | | | When giving a function-style prototype for a macro taking a literal string parameter, put a string literal in place of a type for that parameter. This goofy appearance makes it obvious that this isn't really a function, and clues the reader in that the parameter can't actually be an arbitrary expression of the right type. Also change the nonsensical "NUL-terminated literal string" to "literal string" to describe these parameters. Fixes [perl #116286].
* perlapi: Fix docs for 2 scope related macrosKarl Williamson2016-10-121-8/+4
| | | | | | These 2 macros were using =item instead of =for apidoc, so they silently were not included in perlapi. This commit also changes their references to links.
* leave_scope(): pop args in each branchDavid Mitchell2016-08-111-7/+1
| | | | | | | | | | | | | About 4 years ago I heavily refactored Perl_leave_scope(). One of the things I did was to pop the args for each action once at the top of the loop. This involved a number of nested condtionals. This commit makes each action (i.e. each switch branch) responsible for copying its own args off the save stack, while the top of loop is still responsible for decrementing PL_savestack_ix. The gain is marginal, but it makes the code cleaner and the object code smaller.
* minor comment improvements in hv.h and scope.hDaniel Dragan2016-02-161-1/+1
| | | | | -perl doesn't use malloc, it uses Newx (per interp memory) -say what the return type is of SSNEW
* perlapi: Clarify that a literal string must end in a NULKarl Williamson2016-02-031-1/+1
| | | | Some entries already had this. For those, it standardizes the text.
* offset PL_savestack_max by SS_MAXPUSHDavid Mitchell2016-02-031-6/+8
| | | | | | | | | | | | | | | | The newer SS_ADD macros expect there to always be SS_MAXPUSH slots free on the savestack; so they can push multiple items, then only check once at the end whether stack needs expanding. This commit makes savestack_grow() set PL_savestack_max to SS_MAXPUSH short of what has actually been allocated. This makes the tests to see whether the stack needs growing slightly simpler, i.e. PL_savestack_ix > PL_savestack_max rather than PL_savestack_ix + SS_MAXPUSH > PL_savestack_max
* add SAVEt_TMPSFLOOR save type and Perl_savetmps()David Mitchell2016-02-031-3/+3
| | | | | | | | By making SAVETMPS have its own dedicated save type, it avoids having to push the address of PL_tmps_floor onto the save stack each time. By also giving it a dedicated save function, the function can do the PL_tmpsfloor = PL_tmps_ix step too, making the binary slightly more compact.
* perlapi, perlintern: Add L<> links to podKarl Williamson2015-09-031-4/+4
|
* Eliminate PL_sawalias, GPf_ALIASED_SVDavid Mitchell2015-08-171-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | These two commits: v5.21.3-759-gff2a62e "Skip no-common-vars optimisation for aliases" v5.21.4-210-gc997e36 "Make list assignment respect foreach aliasing" added a run-time mechanism to detect aliased package variables, by either "*pkg = ...," or "for $pkg (...)", and used that information to enable the OPpASSIGN_COMMON mechanism at runtime for detecting common elements in a list assign, e.g. for $alias ($a, ...) { ($a,$b) = (1,$alias); } The previous commit but one changed the OPpASSIGN_COMMON mechanism such that it no longer uses PL_sawalias. So this var and the mechanism for setting it can now be removed. This commit removes: * the PL_sawalias variable * the GPf_ALIASED_SV GP flag * the SAVEt_GP_ALIASED_SV and save_aliased_sv() save type.
* Replace common Emacs file-local variables with dir-localsDagfinn Ilmari Mannsåker2015-03-221-6/+0
| | | | | | | | | | | | | | | | An empty cpan/.dir-locals.el stops Emacs using the core defaults for code imported from CPAN. Committer's work: To keep t/porting/cmp_version.t and t/porting/utils.t happy, $VERSION needed to be incremented in many files, including throughout dist/PathTools. perldelta entry for module updates. Add two Emacs control files to MANIFEST; re-sort MANIFEST. For: RT #124119.
* [perl #123223] Make PADNAME a separate typeFather Chrysostomos2014-11-301-4/+7
| | | | | | | | | | | distinct from SV. This should fix the CPAN modules that were failing when the PadnameLVALUE flag was added, because it shared the same bit as SVs_OBJECT and pad names were going through code paths not designed to handle pad names. Unfortunately, it will probably break other CPAN modules, but I think this change is for the better, as it makes both pad names and SVs sim- pler and makes pad names take less memory.
* Skip no-common-vars optimisation for aliasesFather Chrysostomos2014-09-181-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | The ‘no common vars’ optimisation allows perl to copy the values straight from the rhs to the lhs in a list assignment. In ($a,$b) = ($c,$d), that means $c gets assigned to $a, then $d to $b. If the same variable occurs on both sides of the expression (($a,$b)=($b,$a)), then it is necessary to make temporary copies of the variables on the rhs, before assigning them to the left. If some variables have been aliased to others, then the common vars detection can be fooled: *x = *y; $x = 3; ($x, $z) = (1, $y); That assigns 1 to $x, and then goes to assign $y to $z, but $y is the same as $x, which has just been clobbered. So 1 gets assigned instead of 3. This commit solves this by recording in each typeglob whether the sca- lar is an alias of a scalar from elsewhere. If such a glob is encountered, then the entire expression is ‘tainted’ such that list assignments will assume there might be common vars.
* sprinkle LIKELY() on pp_hot.c scope.c and some *.hDavid Mitchell2014-03-121-3/+3
| | | | | | | | I've gone through pp_hot.c and scope.c and added LIKELY() or UNLIKELY() to all conditionals where I understand the code well enough to know that a particular branch is or isn't likely to be taken very often. I also processed some of the .h files which contain commonly used macros.
* Use SSize_t for arraysFather Chrysostomos2013-08-251-2/+2
| | | | | | | | | | Make the array interface 64-bit safe by using SSize_t instead of I32 for array indices. This is based on a patch by Chip Salzenberg. This completes what the previous commit began when it changed av_extend.
* Use SSize_t for tmps stack offsetsFather Chrysostomos2013-08-251-2/+3
| | | | | | | | | | | | | | | This is a partial fix for #119161. On 64-bit platforms, I32 is too small to hold offsets into a stack that can grow larger than I32_MAX. What happens is the offsets can wrap so we end up referencing and modifying elements with negative indices, corrupting memory, and causing crashes. With this commit, ()=1..1000000000000 stops crashing immediately. Instead, it gobbles up all your memory first, and then, if your com- puter still survives, crashes. The second crash happesn bcause of a similar bug with the argument stack, which the next commit will take care of.
* Revert "[perl #117855] Store CopFILEGV in a pad under ithreads"Father Chrysostomos2013-08-091-12/+6
| | | | | | | | | | | | This reverts commit c82ecf346. It turn out to be faulty, because a location shared betweens threads (the cop) was holding a reference count on a pad entry in a particu- lar thread. So when you free the cop, how do you know where to do SvREFCNT_dec? In reverting c82ecf346, this commit still preserves the bug fix from 1311cfc0a7b, but shifts it around.
* Remove SAVEt_STACK_CXPOSFather Chrysostomos2013-08-051-10/+1
| | | | 81ed78b25c4b removed the only use of this.
* [perl #117855] Store CopFILEGV in a pad under ithreadsFather Chrysostomos2013-08-051-6/+12
| | | | | | | | | | | | | | | | This saves having to allocate a separate string buffer for every cop (control op; every statement has one). Under non-threaded builds, every cop has a pointer to the GV for that source file, namely *{"_<filename"}. Under threaded builds, the name of the GV used to be stored instead. Now we store an offset into the per-interpreter PL_filegvpad, which points to the GV. This makes no significant speed difference, but it reduces mem- ory usage.
* In-place sort should not leave array read-onlyFather Chrysostomos2013-06-261-4/+5
| | | | | | | | | $ ./perl -Ilib -e '@a=1..2; eval { @a=sort{die} @a }; warn "ok so far\n"; @a = 1' ok so far Modification of a read-only value attempted at -e line 1. If something goes wrong inside the sort block and it dies, we still need to make sure we turn off the read-only flag on that array.
* eliminate PL_reg_stateDavid Mitchell2013-06-021-1/+1
| | | | | | | | | | This is a struct that holds all the global state of the current regex match. The previous set of commits have gradually removed all the fields of this struct (by making things local rather than global state). Since the struct is now empty, the PL_reg_state var can be removed, along with the SAVEt_RE_STATE save type which was used to save and restore those fields on recursive re-entry to the regex engine.
* refactor Perl_leave_scopeDavid Mitchell2012-12-041-52/+71
| | | | | | | | | | | | | | | | | | | This is a large and hot function. The main problem with it is that there is code to pop a few args repeated in just about every branch. Also, there are a whole bunch of local vars (sv, av, hv, gv etc) that are never all used simultaneously, but are really just there for casting convenience. Together, they defeat the compiler's register allocation algorithms (well, they did for gcc anyway). We fix this by just declaring three general vars, arg0,1,2 of type ANY, and move the popping code to above the switch(). We sort the SAVEt_* indices in order of number of args, so it's quick to determine how many args we need to pop for a particular type. Together with the previous commits which added the SS_ADD_* macros, this reduces the size of scope.o (-O2, gcc x86_64) by about 9% (threaded) or 17% (unthreaded), and seems to speed up simple loops / function calls by around 5%.
* Add SS_ADD_* macros and replace most SSPUSH* usesDavid Mitchell2012-12-041-11/+52
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The current idiom for adding an entry to the savestack is SSCHECK(3); SSPUSHINT(...); SSPUSHPTR(...); SSPUSHUV(SAVEt_...); Replace this with a new idiom: { dSS_ADD; SS_ADD_INT(...); SS_ADD_PTR(...); SS_ADD_UV(SAVEt_...); SS_ADD_END(3); } This is designed to be more efficient. First, it defines some local vars, and defers updating PL_savestack_ix to the end. Second, it performs the 'is there space on the stack' check *after* pushing. Doing the check last means that values in registers will have been pushed and no longer needed, so don't need saving around the call to grow. Also, tail-call elimination of the grow() can be done. These changes reduce the code of something like save_pushptrptr() to half its former size. Of course, doing the size check *after* pushing means we must always ensure there are SS_MAXPUSH free slots on the savestack */
* Clear method caches when unwinding local *foo=sub{}Father Chrysostomos2012-11-291-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | local *foo=sub{} is done in two stages: • First the local *foo localises the GP (the glob pointer, or list of slots), setting a flag on the GV. • Then scalar assignment sees the flag on the GV on the LHS and loca- lises a single slot. The slot localisation only stores on the savestack a pointer into the GP struct and the old value. There is no reference to the GV. To restore a method properly, we have to have a reference to the GV when the slot localisation is undone. So in this commit I have added a new save type, SAVEt_GVSLOT. It is like SAVEt_GENERIC_SV, except it pushes the GV as well. Currently it is used only for CVs, but I will need it for HVs and maybe AVs as well. It is possible for the unwinding of the slot localisation to affect only a GV other than the one that is pushed, if glob assignments have taken place since the local *foo. So we have to check whether the pointer is inside the GP and use PL_sub_generation++ if it is not.
* save_freeop is not an expression, remove PL_XpvDaniel Dragan2012-11-151-12/+3
| | | | | | save_freeop and SAVEFREEOP are never used in expressions only statements. Using PL_Xpv is never ideal. For me .text section dropped from 0xC1DFF to 0xC1DBF after applying this.
* add SAVEt_CLEARPADRANGEDavid Mitchell2012-11-101-0/+1
| | | | | Add a new save type that does the equivalent of multiple SAVEt_CLEARSV's for a given target range. This makes the new padange op more efficient.
* Restore special blocks to working orderFather Chrysostomos2012-09-261-1/+3
| | | | | | | | | | | | | | | | | | I accidentally broke these in commit 85ffec3682, yet everything passed for me under threads+mad. PL_compcv is usually restored to its previous value at the end of newATTRSUB when LEAVE_SCOPE is called. But BEGIN blocks are called before that. I needed PL_compcv to be restored to its previ- ous value before it was called, so I added LEAVE_SCOPE before process_special_blocks. But that caused the name to be freed before S_process_special_blocks got a chance to look at it. So I have now added a new parameter to S_process_special_blocks to allow *it* to call LEAVE_SCOPE after it determines that it is a BEGIN block, but before it calls it.
* Revert "Set PL_comppad_name on sub entry"Father Chrysostomos2012-09-171-2/+1
| | | | This reverts commit d2c8bf052f5a8bb99050f6d2418d77151eb4b468.
* Set PL_comppad_name on sub entryFather Chrysostomos2012-09-151-1/+2
|
* Prevent double frees/crashes with format syntax errsFather Chrysostomos2012-08-081-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This was brought up in ticket #43425. The new slab allocator for ops (8be227ab5e) makes a CV responsible for cleaning up its ops if it is freed prematurely (before the root is attached). Certain syntax errors involving formats can cause the parser to free the CV owning an op when that op is on the PL_nextval stack. This happens in these cases: format = @ use; format strict . format = @ ;use strict . format foo require bar In the first two cases it is the line containing ‘strict’ that is being interpreted as a format picture line and being fed through force_next by S_scan_formline. Then the error condition kicks in after the force, causing a LEAVE_SCOPE in the parser (perly.c) which frees the sub owning the const op for the format picture. Then a token with a freed op is fed to the parser. To make this clearer, when the second case above is parsed, the tokens produced are as follows: format = [;] [formline] "@\n" [,] ; use [<word>] [;] [formline] <freed> [;] . Notice how there is an implicit semicolon before each (implicit) formline. Notice also how there is an implicit semicolon before the final dot. The <freed> thing represents the "strict\n" constant after it has been freed. (-DT displays it as THING(opval=op_freed).) When the implicit semicolon is emitted before a formline, the next two tokens (formline and the string constant for this format picture line) are put on to the PL_nextval stack via force_next. It is when the implicit semicolon before "strict\n" is emitted that the parser sees the error (there is only one path through the gram- mar that uses the USE token, and it must have two WORDs following it; therefore a semicolon after one WORD is an immediate error), calling LEAVE_SCOPE, which frees the sub created by ‘use’, which owns the const op on the PL_nextval stack containing the word "strict" and con- sequently frees it. I thought I could fix this by putting an implicit do { ... } around the argument line. (This would fix another bug, whereby the argument line in a format can ‘leak out’ of the formline(...).) But this does not solve anything, as we end up with four tokens ( } ; formline const ) on the PL_nextval stack when we emit the implicit semicolon after ‘use’, instead of two. format= @ ;use strict . will turn into format = [;] [formline] "@\n" [,] [do] [{] ; use [<word>] [;] [}] [;] [formline] "strict\n"/<freed> [;] . It is when the lexer reaches "strict" that it will emit the semicolon after the use. So we will be in the same situation as before. So fixing the fact that the argument line can ‘leak out’ of the formline and start a new statement won’t solve this particu- lar problem. I tried eliminating the LEAVE_SCOPE. (See <https://rt.perl.org/rt3/Ticket/Display.html?id=43425#txn-273447> where Dave Mitchell explains that the LEAVE_SCOPE is not strictly nec- essary, but it is ‘still good to ensure that the savestack gets cor- rectly popped during error recovery’.) That does not help, because the lexer itself does ENTER/LEAVE to make sure form_lex_state and lex_formbrack get restored properly after the lexer exits the format (see 583c9d5cccf and 64a408986cf). So when the final dot is reached, the ‘use’ CV is freed. Then an op tree that includes the now-freed "strict\n" const op is passed to newFORM, which tries to do op_free(block) (as of 3 commits ago; before that the errors were more catastrophic), and ends up freeing an op belonging to a freed slab. Removing LEAVE_SCOPE did actually fix ‘format foo require bar’, because there is no ENTER/LEAVE involved there, as the = (ENTER) has not been reached yet. It was failing because ‘require bar’ would call force_next for "bar", and then feed a REQUIRE token to the parser, which would immediately see the error and call LEAVE_SCOPE (free- ing the format), with the "bar" (belonging to the format’s slab) still pending. The final solution I came up with was to reuse an mechanism I came up with earlier. Since the savestack may cause ops to outlive their CVs due to SAVEFREEOP, opslab_force_free (called when an incomplete CV is freed prematurely) will skip any op with o->op_savestack set. The nextval stack can use the same flag. To make sure nothing goes awry (we don’t want the same op on the nextval stack and the savestack at the same time), I added a few assertions.
* Flag ops that are on the savestackFather Chrysostomos2012-06-291-1/+15
| | | | | | | | | This is to allow future commits to free dangling ops after errors. If an op is on the savestack, then it is going to be freed by scope.c, and op_free must not be called on it by anyone else. So we flag such ops new.
* Say goodbye to SAVECOPSTASHFather Chrysostomos2012-06-041-3/+2
| | | | This is undocumented and unused.
* [perl #78742] Store CopSTASH in a pad under threadsFather Chrysostomos2012-06-041-4/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Before this commit, a pointer to the cop’s stash was stored in cop->cop_stash under non-threaded perls, and the name and name length were stored in cop->cop_stashpv and cop->cop_stashlen under ithreads. Consequently, eval "__PACKAGE__" would end up returning the wrong package name under threads if the current package had been assigned over. This commit changes the way cops store their stash under threads. Now it is an offset (cop->cop_stashoff) into the new PL_stashpad array (just a mallocked block), which holds pointers to all stashes that have code compiled in them. I didn’t use the lexical pads, because CopSTASH(cop) won’t work unless PL_curpad is holding the right pad. And things start to get very hairy in pp_caller, since the correct pad isn’t anywhere easily accessible on the context stack (oldcomppad actually referring to the current comppad). The approach I’ve followed uses far less code, too. In addition to fixing the bug, this also saves memory. Instead of allocating a separate PV for every single statement (to hold the stash name), now all lines of code in a package can share the same stashpad slot. So, on a 32-bit OS X, that’s 16 bytes less memory per COP for short package names. Since stashoff is the same size as stashpv, there is no difference there. Each package now needs just 4 bytes in the stashpad for storing a pointer. For speed’s sake PL_stashpadix stores the index of the last-used stashpad offset. So only when switching packages is there a linear search through the stashpad.
* update the editor hints for spaces, not tabsRicardo Signes2012-05-291-2/+2
| | | | | This updates the editor hints in our files for Emacs and vim to request that tabs be inserted as spaces.
* [perl #113060] Save cop_stashlen threaded even with shared cop pvReini Urban2012-05-291-1/+2
| | | | | | | | | Perl_sv_compile_2op_is_broken() does at line 3354 a LEAVE_with_name("eval"), a SSPOPSTR via SAVEt_SHARED_PVREF for the localized cop_stashpv, but not for the cop_stashlen. The cop in question is PL_compiling, which was "AutoSplit" before with len=9 and restores it back to "main" but keeps len 9. Thus leading to a heap-overflow in gv_stashpvn.
* [perl #112316] Make strict vars respect assignment from null pkgFather Chrysostomos2012-04-191-1/+2
| | | | | | Under threads, strict vars was not respecting glob assignment from a package with a null in its name if the name of the package assigned to was equal to the prefix of the current package up to the null.
* remove index offsetting ($[)Zefram2011-09-091-3/+0
| | | | | | $[ remains as a variable. It no longer has compile-time magic. At runtime, it always reads as zero, accepts a write of zero, but dies on writing any other value.
* Fix typos (spelling errors) in Perl sources.Peter J. Acklam) (via RT2011-01-071-1/+1
| | | | | | | | | # New Ticket Created by (Peter J. Acklam) # Please include the string: [perl #81904] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=81904 > Signed-off-by: Abigail <abigail@abigail.be>
* add SAVEFREECOPHH()Zefram2010-10-281-0/+2
| | | | | Add the facility for the save stack to free (decrement the refcount of) a COPHH*.
* bad things happened with for $x (...) { *x = *y }David Mitchell2010-09-081-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | fix for [perl #21469]: since the GP may be pulled from under us and freed, coredumps and strange things can happen. Fix this by storing a pointer to the GV in the loop block, rather than a pointer to the GvSV slot. The ITHREADS variant already stores GV rather than than &GvSV; extend this to non-threaded builds too. Also, for both threaded and non-threaded, it used to push &GvSV on the save stack. Fix this by introducing a new save type, SAVEt_GVSV. This behaves similarly to SAVEt_SV, but without magic get/set. This means that for $package_var (...) is now close in behaviour to local $package_var = ... (except for the magic bit).