summaryrefslogtreecommitdiff
path: root/mg.c
Commit message (Collapse)AuthorAgeFilesLines
* Remove get-magic from $/Father Chrysostomos2015-08-101-2/+1
| | | | | | | | | | | | | | | | | and use a different approach to prevent $/ from being set to a bad value. This should fix ticket #123739. Commit v5.21.8-197-g5fe499a made $/’s get-magic read PL_rs, so that the croak when setting $/ to a bad value would not leave $/ with that bad value, in order to fix bug #123218. Some CPAN modules do not like $/ reading PL_rs that way. So we have to change this back. I am not actually removing the get- magic, but just making it a no-op, as it was before. The set- magic now sets $/ back to its previous value before croaking. (cherry picked from commit ddce084af02764d4f30ef6089ae67a7983fcc690)
* [perl #123218] "preserve" $/ if set to a bad valueTony Cook2015-08-101-0/+1
| | | | | | and base/rs.t tests $/ not $! (cherry picked from commit 5fe499a8e26270679c0c6d48431f3a328a8ffeba)
* [perl #122669] Don’t taint at compile timeFather Chrysostomos2014-12-271-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #!perl -T # tainted constant use constant K=>$^X; # Just reading the constant for the sake of folding can enabled # taintedness at compile time. 0 if K; # Taintedness is still on when the ‘strict.pm’ SV is created, so # require croaks on it (‘Insecure dependency’). use strict; The fix is simply not to propagate taintedness at compile time. Hence, the value of K will still be tainted at run time (require(K) croaks), but just reading the value of K at compile time won’t taint subsequent string literals (or barewords treated as strings). ‘Compile time’ here is relative: Taintedness still wafts about as usual when BEGIN blocks are executed, because code is actually run- ning. It’s when code is being parsed that propagation is disabled. The reason taint propagation could span across statements at compile time was that *execution* of a new statement resets taintedness, whereas parsing is oblivious to it. (cherry picked from commit 64ff300be0f7714585466af5bb87b2e37db5082a)
* Use PERL_UNUSED_RESULT.Jarkko Hietaniemi2014-07-281-30/+22
| | | | | | | | | (1) Enhance its description. (2) Simplify it: define only if has warn_unused_result. (3) Make it use STMT_START { ... } STMT_END to be less GNU-extensiony. (4) Redo 04783dc7 ("fix 'ignoring return value' compiler warnings") with it. (cherry picked from commit b469f1e0fc5f0ac882161e627a1255ee11e67c37)
* PATCH: [perl #119499] "$!" with UTF-8 flagKarl Williamson2014-04-011-0/+6
| | | | | | | | This disables the code that sets the UTF-8 flag when "$!" is UTF-8. This is being done to get v5.20 out the door, with changes to follow in v5.21. See towards the end of the discussion of this ticket. Unfortunately this change will cause #112208 to no longer be fixed.
* mg.c: Fix comment typoKarl Williamson2014-04-011-1/+1
|
* Restore proper functioning of -MdiagnosticsKarl Williamson2014-02-201-1/+1
| | | | | | | | Commit 1c604e7c7f fixed some pod errors, but broke ./perl -Ilib -Mdiagnostics -e '$/=[]' This fixes that.
* Fix pod errorsKarl Williamson2014-02-181-1/+1
|
* Use ‘an’ for $/=[] error messageFather Chrysostomos2014-02-091-1/+3
| | | | | | | | | | | | | | This says ‘an ARRAY’: $ perl -Mstrict -e '@{"a"}' Can't use string ("a") as an ARRAY ref while "strict refs" in use at -e line 1. This says ‘a ARRAY’: $ ./miniperl -e '$/=[]' Setting $/ to a ARRAY reference is forbidden at -e line 1. It ought to say ‘an’.
* Add tests and fix new fatal errors related to $/Yves Orton2014-02-041-12/+24
| | | | | | | | | | | In b3a2acfa0c0e4f8e48e1f6eb4d6fd143f293d2c6 I added new exceptions, but forgot to test them properly. In the process I managed to partially break the functionality, and since it was not tested I did not notice. Ilmari on #p5p pointed out I forgot the test, and in the end I had to completely rewrite the original patch. Now tested as fully as I could. Thanks Ilmari.
* deal with assignment to $/ better, deprecate edge cases, and forbid othersYves Orton2014-02-031-2/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The actual behavior of $/ under various settings and how it is documented varies quite a bit. Clarify the documentation, and add various checks that are validated when setting $/. The gist of the problem was that the way that weirdo ref assignments were handled was mostly broken: * setting to a reference to an array, hash, or other higher level construct would behave similarly to setting it to a reference to a an integer, by numifying the ref and using it as an integer. This behavior was entirely undocumented. * setting to a reference to 0 or to -1 was *documented* in triggering "slurp" behavior, but actually did not. Instead it would set the separator to the stringified form of the ref, which would *appear* as slurp behavior due to the unlikelihood of a file actually containing a string which matched, however was less efficient, and if someone's luck were *terrible* might actually behave as a split. In the future we wish to support more sophisticated ways of setting the input record separator, possibly supporting things like: $/= [ "foo", "bar" ]; $/= qr/foo|bar/; Accordingly this patch *forbids* the use of a non scalar ref, and raises a fatal exception when one does so. Additionally it treats non-positive refs *exactly* the same as assigning undef, *including* ignoring the original value and setting $/ to undef. The means the implementation now matches the documentation. However since this might involve some crazy script changing in behavior (as one can't fetch back the original ref from $/) I have added a warning in category "deprecated" advising the user what has happened and recommending setting to "undef" explicitly. As far as I can tell this will only *break* code doing extremely dodgy things with $/. While putting together this patch I encountered numerous problems with porting tests. First off was porting/podcheck.t, which failed test without saying why or what to do, even under TEST_VERBOSE=1. Then when I did a regen to update the exceptions database and then used that information to try to fix the reported problems it seems that it does not work properly anyway. Specifically you aren't allowed to have a / in the interesting parts of a L<> reference. If you replace the / with an E<0x2f> then the link is valid POD, but podcheck.t then considers it a broken link. If you then replace the / in perdiag with E<0x2f> as well then porting/diag.t complains that you have an undocumented diagnostic! Accordingly I used the --regen option of podcheck.t to add exceptions to the exception database. I have no idea if the pod is correctly formatted or not.
* Consistent spaces after dots in perlintern.podFather Chrysostomos2013-12-291-4/+5
|
* perlapi: Consistent spaces after dotsFather Chrysostomos2013-12-291-1/+1
| | | | plus some typo fixes. I probably changed some things in perlintern, too.
* Revert "[perl #119801] Stop @DB::dbline modifications from crashing"Father Chrysostomos2013-12-251-6/+11
| | | | | | This reverts commit c1cec775e9019cc8ae244d4db239a7ea5c0b343e. See ticket #120864.
* [perl #119801] Stop @DB::dbline modifications from crashingFather Chrysostomos2013-12-211-11/+6
| | | | | | | | | | | | | | | | | | | | | The cop address for each breakable line was being stored in the IVX slot of ${"_<$file"}[$line]. This value itself, writable from Perl space, was being used as the address of the op to be flagged, whenever a breakpoint was set. This meant writing to ${"_<$file"}[$line] and assigning a number (like 42) would cause perl to use 42 as an op address, and crash when trying to flag the op. Furthermore, since the array holding the lines could outlive the ops, setting a breakpoint on the op could write to freed memory or to an unrelated op (even a different type), potentially changing the beha- viour of unrelated code. This commit solves those pitfalls by moving breakpoints into a global breakpoint bitfield. Dbstate ops now have an extra field on the end holding a sequence number, representing which bit holds the breakpoint for that op.
* mg.c: White-space onlyKarl Williamson2013-12-171-18/+17
| | | | Indent code that's in a block added in the previous commit.
* Fix HP-UX $! failureKarl Williamson2013-12-171-1/+6
| | | | | | | HP-UX strerror() returns an empty string for an unknown error code. This caused an assertion to fail under DEBUGGING builds. This patch removes the assertion and changes the return into a non-empty string indicating the errno is for an unknown error.
* mg.c: White-space onlyKarl Williamson2013-12-171-18/+18
| | | | Properly indent code that is interior to a block
* Revert part of 2efab60d9Father Chrysostomos2013-11-281-1/+1
| | | | | | As Karl Williamson pointed out in <5296C04E.10103@khwilliamson.com>, sv_setpv will do SvOK_off if Strerror returns null, so this SvOK check is not redundant.
* mg.c: Remove redundant SvOK checksFather Chrysostomos2013-11-271-4/+2
|
* Respect 'use bytes' in returning $! and $^EKarl Williamson2013-11-261-1/+2
| | | | | | | | | This addresses some of the field problems caused by commit 1500bd919ffeae0f3252f8d1bb28b03b043d328e, but by no means all. If the stringification of $^E or $! is done in the scope of 'use bytes', the UTF-8 flag on the result is now never set. In such scope, the behavior is then the same as it was prior to that commit. The actual behavior will change before v5.20 ships.
* $^E should have same handling as $! for Win32 and OS/2Karl Williamson2013-11-261-0/+6
| | | | | | | | | | | | | | | | Commit 1500bd919ffeae0f3252f8d1bb28b03b043d328e changed the handling of $! to look for UTF-8 messages. This issue is also present in Win32 for $^E. The two should have uniform treatment, so this commit causes the actual same code to be executed for both. OS/2 is also subject to locale issues, and so it also is changed here to use the same code, so that future changes will apply to it automatically. VMS doesn't use locales, so it retains its current behavior. Note that 1500bd919 has created some field problems, so that the changes it introduced will be further changed or reverted. The current commit just makes sure that whatever those further changes are will be automatically propagated to all necessary platforms.
* mg.c: Extract code into a function.Karl Williamson2013-11-261-18/+32
| | | | | This is in preparation for the same code to be used in additional places. There should be no logic changes.
* mg.c: White-space onlyKarl Williamson2013-11-261-34/+34
| | | | Outdent this code as a result of removing outer blocks
* mg.c: Use $! code for $^E on platforms where are sameKarl Williamson2013-11-261-12/+10
| | | | | | | Only a few platforms have $^E distinguished from $!. On all others they should behave identically. Previous commits, have caused these to get out-of-sync. This causes them to share their code on platforms where they mean the same thing, so this won't happen again.
* mg.c: Reorder if else clausesKarl Williamson2013-11-261-3/+5
| | | | | This is to allow two cases in the switch statement to be combined in the next commit. There should be no effective logic change
* mg.c: Reorder cases in a switch()Karl Williamson2013-11-261-49/+50
| | | | | This is just cut and paste with no other changes; it is in preparation for combining two cases in a future commit
* fix 'ignoring return value' compiler warningsDavid Mitchell2013-11-241-18/+30
| | | | | | | | | | | Various system functions like write() are marked with the __warn_unused_result__ attribute, which causes an 'ignoring return value' warning to be emitted, even if the function call result is cast to (void). The generic solution seems to be int rc = write(...); PERL_UNUSED_VAR(rc);
* fix a few warnings (format strings, unused variable)Lukas Mai2013-11-201-1/+1
| | | | | | | | | | | | | | During compilation gcc complains about the following: perl.c:4970: warning: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'U32' [-Wformat=] perl.c:5075: warning: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'I32' [-Wformat=] mg.c:1972: warning: format '%ld' expects argument of type 'long int', but argument 2 has type 'ssize_t' [-Wformat=] pp_ctl.c:2610: warning: unused variable 'mark' [-Wunused-variable] regexec.c:2275: warning: format '%ld' expects argument of type 'long int', but argument 3 has type 'int' [-Wformat=] This patch fixes all of them. Tony: warning: unused variable 'mark' was fixed in 481c819b
* mg.c: Fix misuse of AvARRAY in defelem_targetFather Chrysostomos2013-11-041-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | defelem magic does not usually apply to tied arrays, but an array can be tied after a defelem has been created and points to it. The code for handling deferred elements was never updated for tied arrays when those were added, so it still does AvFILL and AvARRAY. AvFILL works on tied arrays, and calls FETCHSIZE. But AvARRAY accesses the AV’s internal structure. So AvFILL might suggest that the index is within the array, whereas it is actually past the end of AvARRAY. By tying the array after a deferred element with a high index has been created and then extending the tied array (so AvFILL returns a big number), we can make AvARRAY[big number] crash. This script: use Tie::Array; sub { tie @a, "Tie::StdArray"; $#a = 20000; warn pre; "$_[0]"; warn post }->($a[10000]); gives this output: pre at -e line 5. Segmentation fault: 11 For tied arrays, we need to use av_fetch, rather than AvARRAY.
* [perl #119799] Set breakpoints without *DB::dblineFather Chrysostomos2013-10-281-1/+2
| | | | | | | | | | | | | | | | | | | The elements of the %{"_<..."} hashes (where ‘...’ is the filename), whose keys are line numbers, are used to set breakpoints on the given lines. The corresponding @{"_<..."} array contains the actual lines of source code. %{"_<..."} actually acts on the array of lines that @DB::dbline is aliased to. The assumption is that *DB::dbline = *{"_<..."} will have taken place first. Hence, all %{"_<..."} hashes are the same, when it comes to writing to keys. It is more useful for each %{"_<..."} hash to set breakpoints on its corresponding file’s lines regardless of whether @DB::dbline has been aliased, so that is what this commit does. Each hash’s mg_obj pointer in its dbfile magic now points to the array, and magic_setdbline uses it instead of PL_DBline.
* WinCE Makefile and make_ext.pl general and XS fixesDaniel Dragan2013-10-211-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | On a WinCE build. On the 2nd nmake run, using Makefile.ce, eventually calls the Extensions target which calls make_ext.pl. What happens is nmake for CE for each module is called on the Desktop per module makefile from the earlier Desktop build. Since the Desktop Perl already was built sucessfully, all rules/deps are met in the Desktop per module makefile, and nothing happens during the module building phase for a CE build. Previously I used external file management tools to delete the per module Makefiles before running Makefile.ce. *make_ext.pl - implement deleting and rebuilding the per module makefile on a Cross build - use constants for constant folding, there are opportunities for other variables to be converted to constants in the future - fix a bug from commit baff067e71 where unlink() on a file with an open handle ($mfh) didn't delete the file from disk and a new per module makefile would be not be built by make_ext.pl later since the per module makefile was still on disk. This was observed on Win32. Also harden the unlink code with a new _unlink sub that is fatal if the file is still on disk after unlink supposedly deleted it. - var $header and the quotemeta is because of an issue in Perl #119793 *Makefile.ce - bring the debugging symbol generation flags and optimization flags to be closer to a Dekstop VC Perl build - ICWD is obsolete as of commit f6b3c354c9 , remove it - MINIMOD is obsolete as of commit 7b4d95f74b , remove it - make a poisoned config.h so if there is a XS building mixup between a desktop and CE perl, the poisoned config.h for CE will stop the build gracefully - $(MINIPERL) has never been defined in Makefile.ce from day 1 (10 years) replace with $(HPERL) everywhere, this was causing things to not run silently since $(MINIPERL) was empty string. Use HPERL instead of MINIPERL to allow flexibility to use the full perl binary if necessery one day - better cleaning on root makefile clean target *win32/win32.h *win32/win32iop.h - silence alot of redefinition warnings which gave pages of warnings on each WinCE compliand *mg.c - win32_get_errno is only on WIN32 build not WINCE a "nmake -f Makefile.ce all" will now build the CE interp and all modules in 1 shot with no user intervention
* Intercept assignment to $! to translate WSAExxx values to Exxx values on WindowsSteve Hay2013-09-161-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | Since perl previously assigned WSAExxx values to $! on Windows it is quite possible that (Perl-level) user code may also manually make similar assignments, which will now cause breakage if the value put in $! is subsequently compared to Errno/POSIX constants because the latter are now the corresponding Exxx values where possible. An example of this is in Net::Ping::tcp_connect(), which does the following to fetch a socket-level error code: unpack("i", getsockopt($self->{"fh"}, SOL_SOCKET, SO_ERROR)) and assigns the result (a WSAExxx value such as 10061) to $! and then goes wrong in the subsequent test (in ping_tcp()) for $! == ECONNREFUSED (which is now 107 rather than 10061 if perl is built with VC10 or higher). To avoid this we now intercept assignment to $! and convert any WSAExxx values to Exxx values first. This causes a minor oddity in that this: perl -le "$! = 10061; print 0+$!" will now output 107 (for VC10+ perls) but this is surely preferable to the alternative breakage described above.
* Simplify some code in Perl_magic_get() and Perl_magic_set().Nicholas Clark2013-09-021-9/+3
| | | | | | | | | | | Remove the checks that avoided confusing $^P, ${^PREMATCH} and ${^POSTMATCH} now that the latter two do not take that code path. Remove a similar check for $^S added by commit 4ffa73a366885f68 (Feb 2003). (This commit did not add any other variable starting with a control-S.) This eliminates all uses of the variable remaining. Move the goto target do_numbuf_fetch inside the checks for PL_curpm, as both its comefroms have already made the same check.
* Remove now unused $` $' ${^MATCH} ${^PREMATCH} ${^POSTMATCH} code.Nicholas Clark2013-09-021-36/+0
| | | | | The previous commit's changes to Perl_gv_fetchpvn_flags() rendered this code in Perl_magic_get() and Perl_magic_set() unreachable.
* Store all other match vars in mg_len instead of mg_ptr/mg_len.Nicholas Clark2013-09-021-2/+1
| | | | | | | Perl_gv_fetchpvn_flags() now stores the appropriate RX_BUFF_IDX_* constant in mg_len for $` $' ${^MATCH} ${^PREMATCH} and ${^POSTMATCH} This makes some code in mg.c unreachable and hence unnecessary; the next commit will remove it.
* Store the match vars in mg_len instead of calling atoi() on mg_ptr.Nicholas Clark2013-09-021-38/+35
| | | | | | | | | | | | | | The match variables $1, $2 etc, along with many other special scalars, have magic type PERL_MAGIC_sv, with the variable's name stored in mg_ptr. The look up in mg.c involved calling atoi() on the string in mg_ptr to get the capture buffer as an integer, which is passed to the regex API. To avoid this repeated use of atoi() at runtime, change the storage in the MAGIC structure for $1, $2 etc and $&. Set mg_ptr to NULL, and store the capture buffer in mg_len. Other code which manipulates magic ignores mg_len if mg_ptr is NULL, so this representation does not require changes outside of the routines which set up, read and write these variables. (Perl_gv_fetchpvn_flags(), Perl_magic_get() and Perl_magic_set())
* In Perl_magic_setdbline, replace the use of atoi() with sv_2iv().Nicholas Clark2013-08-291-5/+12
| | | | | The value on which atoi() is called is actually always the buffer of an SV. Hence we can use sv_2iv() instead.
* Make vivify_defelem allow &PL_sv_undef array entriesFather Chrysostomos2013-08-281-1/+1
| | | | | | | This is something I failed to change in commit ce0d59f. I don’t know of a way to trigger this in pure-Perl code, hence the use of XS in the test. It did show up in pure-Perl code due to a bug fixed by the previous commit.
* Fix assert fail when fetching pos clobbers ref with undefFather Chrysostomos2013-08-251-1/+1
| | | | | | | | | | | pos($x) returns a special magical scalar that sets the match position on $x. Calling pos($x) twice will provide two such scalars. If we set one of them to a reference, set the other to undef, and then read the first, all hail breaks loose, because of the use of SvOK_off. SvOK_off is not sufficient if arbitrary values can be assigned by Perl code. Globs, refs and regexps (among others) need special handling, which sv_setsv knows how to do.
* Stop values from ‘sticking’ to @- and @+ elemsFather Chrysostomos2013-08-251-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | These arrays are very similar to tied arrays, in that the elements are created on the fly when looked up. So push @_, \$+[0], \$+[0], will push references to two different scalars on to @_. That they are created on the fly prevents this bug from showing up in most code: If you reference the element you can observe that, on FETCH, it gets set to the corresponding offset *if* the last match has a set of capturing parentheses with the right number. Otherwise, the value in the element is left as-is. So, doing another pattern match with, say, 5 captures and then another with fewer will leave $+[5] and $-[5] holding values from the first match, if there is a FETCH in between the two matches: $ perl -le '" "=~/()()()()(..)/; $_ = \$+[5]; print $$_; ""=~ /()/; print $$_;' 2 2 And attempts at assignment will succeed, even though they croak: $ perl -le 'for ($-[0]) { eval { $_ = *foo }; print $_ }' *main::foo The solution here is to make the magic ‘get’ handler set the SV no matter what, instead of just setting it when it refers to a valid offset.
* Make @- and @+ return correct offsets beyond 2**31Father Chrysostomos2013-08-251-5/+5
|
* Stop pos() from being confused by changing utf8nessFather Chrysostomos2013-08-251-6/+2
| | | | | | | | | | | | | | | | | | | | | | | The value of pos() is stored as a byte offset. If it is stored on a tied variable or a reference (or glob), then the stringification could change, resulting in pos() now pointing to a different character off- set or pointing to the middle of a character: $ ./perl -Ilib -le '$x = bless [], chr 256; pos $x=1; bless $x, a; print pos $x' 2 $ ./perl -Ilib -le '$x = bless [], chr 256; pos $x=1; bless $x, "\x{1000}"; print pos $x' Malformed UTF-8 character (unexpected end of string) in match position at -e line 1. 0 So pos() should be stored as a character offset. The regular expression engine expects byte offsets always, so allow it to store bytes when possible (a pure non-magical string) but use char- acters otherwise. This does result in more complexity than I should like, but the alter- native (always storing a character offset) would slow down regular expressions, which is a big no-no.
* Remove null check from mg.c:magic_getvecFather Chrysostomos2013-08-221-4/+1
| | | | | lsv can never be null here. This null check has been here since vec’s get-magic was added in ae389c8a or 6ff81951f7.
* Fix assertion failure with $#a=\1Father Chrysostomos2013-08-221-1/+1
| | | | | | | | | If the array has been freed and a reference is then assigned to the arylen scalar and then get-magic is called on that scalar, Perl_magic_getarylen misbehaves. SvOK_off is not sufficient if arbitrary values can be assigned by Perl code. Globs, refs and regexps (among others) need special handling, which sv_setsv knows how to do.
* [perl #118691] Allow defelem magic with neg indicesFather Chrysostomos2013-08-211-6/+8
| | | | | | | | | | | | | | | | | | | | | | When a nonexistent array element is passed to a subroutine, a special ‘deferred element’ scalar (implemented using something called defelem magic) is passed to the subroutine instead, which delegates to the array element. This allows some_benign_function($array[$nonexistent]) to avoid autovivifying unnecessarily. Whether this magic would be triggered was based on whether the element was within the range 0..$#array. Since arrays can contain nonexistent elements before $#array, this logic is incorrect. It also makes sense to allow $array[$neg] where the negative number points before the beginning of the array to create a deferred element and only croak if it is assigned to. This commit fixes the logic for when deferred elements are created and implements these deferred negative elements. Since we have to be able to store negative values in xlv_targoff, it is convenient to make it a union (with two types--signed and unsigned) and use LvSTARGOFF for defelem array indices.
* mg.c: Fix U32-to-bool assignmentFather Chrysostomos2013-08-121-1/+1
| | | | | | | This was caused by 3805b5fb04. This commit restores the !=0 that was there before 2fd13eccf0. Thanks to Steve Hay for helping to track down the smoke failures.
* Make PL_hints an alias for PL_compiling.cop_hintsFather Chrysostomos2013-08-111-1/+0
| | | | | | | | | | | | | | | | | | | PL_hints stores the hints at compile time that get copied into the cop_hints field of each COP (in newSTATEOP). Since perl-5.8.0-8053-gd5ec298, COPs have stored all the hints. Before that, COPs used to store only some of the hints. The hints were copied here and there into PL_compiling, a static COP-shaped buf- fer used during compilation, so that things like constant folding would see the correct hints. a0ed51b3 back in 1998 did that. Now that COPs can store all the hints, we can just use PL_compiling.cop_hints to avoid having to copy them from PL_hints from time to time. This simplifies the code and avoids creating bugs like those that a547fd219 and 1c75beb82 fixed.
* Modifying ${^OPEN} changes the value of $^H:Father Chrysostomos2013-08-111-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | $ ./perl -le 'BEGIN { print $^H; ${^OPEN} = "a\0b"; print $^H}' 256 917760 So changing $^H back should change the value of ${^OPEN} back to undef, right? $ ./perl -le 'BEGIN { ${^OPEN} = "a\0b"; $^H=256; print ${^OPEN}//"undef"}' ab $ ./perl -le 'BEGIN { ${^OPEN} = "a\0b"; $^H=256;}BEGIN{ print ${^OPEN}//"undef"}' undef Apparently you have to hop from one BEGIN block to another to see the changes. This happens because compile-time hints are stored in PL_hints (which $^H sets) but ${^OPEN} looks in PL_compiling.cop_hints. Setting ${^OPEN} sets both. The contents of PL_hints are assigned to PL_compiling.cop_hints at certain points (the start of a BEGIN block sees the right value because newSTATEOP sets it), but the two are not always kept in synch. The smallest fix here is to have $^H set PL_compiling.cop_hints as well as PL_hints, but the ultimate fix--to come later--is to merge the two and stop storing hints in two different places.
* Remove SvIsCOW checks from mg.c:mg_localizeFather Chrysostomos2013-08-111-1/+1
| | | | | | | | | | | | | | | | It no longer needs to worry about SvIsCOW. This logic is left over from when READONLY+FAKE was used for COWs. Since it is possible for COWs to be read-only now, this logic is actu- ally faulty, as it doesn’t temporarily stop read-only COWs from being read-only, as it does for other read-only values. This actually causes discrepancies with scalar-tied locked hash keys, which differ in readonliness when localised depending on whether the previous value used copy-on-write. Whether such scalars should be read-only after localisation is open to debate, but it should not differ based on the means of storing the previous value.