This fixes [perl #68590] : %^H not lexical enough.
t/comp/colon.t See if colons are parsed correctly
t/comp/decl.t See if declarations work
t/comp/fold.t See if constant folding works
+t/comp/hints.aux Auxillary file for %^H test
t/comp/hints.t See if %^H works
t/comp/multiline.t See if multiline strings work
t/comp/opsubs.t See if q() etc. are not parsed as functions
#define CopARYBASE_set(c, b) STMT_START { \
if (b || ((c)->cop_hints & HINT_ARYBASE)) { \
(c)->cop_hints |= HINT_ARYBASE; \
- if ((c) == &PL_compiling) \
- PL_hints |= HINT_LOCALIZE_HH | HINT_ARYBASE; \
- (c)->cop_hints_hash \
- = Perl_refcounted_he_new(aTHX_ (c)->cop_hints_hash, \
+ if ((c) == &PL_compiling) { \
+ SV *val = newSViv(b); \
+ (void)hv_stores(GvHV(PL_hintgv), "$[", val); \
+ mg_set(val); \
+ PL_hints |= HINT_ARYBASE; \
+ } else { \
+ (c)->cop_hints_hash \
+ = Perl_refcounted_he_new(aTHX_ (c)->cop_hints_hash, \
newSVpvs_flags("$[", SVs_TEMP), \
sv_2mortal(newSViv(b))); \
+ } \
} \
} STMT_END
else if (v == &PL_vtbl_utf8) s = "utf8";
else if (v == &PL_vtbl_arylen_p) s = "arylen_p";
else if (v == &PL_vtbl_hintselem) s = "hintselem";
+ else if (v == &PL_vtbl_hints) s = "hints";
else s = NULL;
if (s)
Perl_dump_indent(aTHX_ level, file, " MG_VIRTUAL = &PL_vtbl_%s\n", s);
p |int |magic_clearenv |NN SV* sv|NN MAGIC* mg
p |int |magic_clear_all_env|NN SV* sv|NN MAGIC* mg
dp |int |magic_clearhint|NN SV* sv|NN MAGIC* mg
+dp |int |magic_clearhints|NN SV* sv|NN MAGIC* mg
p |int |magic_clearisa |NULLOK SV* sv|NN MAGIC* mg
p |int |magic_clearpack|NN SV* sv|NN MAGIC* mg
p |int |magic_clearsig |NN SV* sv|NN MAGIC* mg
#define magic_clearenv Perl_magic_clearenv
#define magic_clear_all_env Perl_magic_clear_all_env
#define magic_clearhint Perl_magic_clearhint
+#define magic_clearhints Perl_magic_clearhints
#define magic_clearisa Perl_magic_clearisa
#define magic_clearpack Perl_magic_clearpack
#define magic_clearsig Perl_magic_clearsig
#define magic_clearenv(a,b) Perl_magic_clearenv(aTHX_ a,b)
#define magic_clear_all_env(a,b) Perl_magic_clear_all_env(aTHX_ a,b)
#define magic_clearhint(a,b) Perl_magic_clearhint(aTHX_ a,b)
+#define magic_clearhints(a,b) Perl_magic_clearhints(aTHX_ a,b)
#define magic_clearisa(a,b) Perl_magic_clearisa(aTHX_ a,b)
#define magic_clearpack(a,b) Perl_magic_clearpack(aTHX_ a,b)
#define magic_clearsig(a,b) Perl_magic_clearsig(aTHX_ a,b)
const char *const start = SvPV(sv, len);
const char *out = (const char*)memchr(start, '\0', len);
SV *tmp;
- struct refcounted_he *tmp_he;
PL_compiling.cop_hints |= HINT_LEXICAL_IO_IN | HINT_LEXICAL_IO_OUT;
- PL_hints
- |= HINT_LOCALIZE_HH | HINT_LEXICAL_IO_IN | HINT_LEXICAL_IO_OUT;
+ PL_hints |= HINT_LEXICAL_IO_IN | HINT_LEXICAL_IO_OUT;
/* Opening for input is more common than opening for output, so
ensure that hints for input are sooner on linked list. */
tmp = out ? newSVpvn_flags(out + 1, start + len - out - 1,
- SVs_TEMP | SvUTF8(sv))
- : newSVpvs_flags("", SVs_TEMP | SvUTF8(sv));
+ SvUTF8(sv))
+ : newSVpvs_flags("", SvUTF8(sv));
+ (void)hv_stores(GvHV(PL_hintgv), "open>", tmp);
+ mg_set(tmp);
- tmp_he
- = Perl_refcounted_he_new(aTHX_ PL_compiling.cop_hints_hash,
- newSVpvs_flags("open>", SVs_TEMP),
- tmp);
-
- /* The UTF-8 setting is carried over */
- sv_setpvn(tmp, start, out ? (STRLEN)(out - start) : len);
-
- PL_compiling.cop_hints_hash
- = Perl_refcounted_he_new(aTHX_ tmp_he,
- newSVpvs_flags("open<", SVs_TEMP),
- tmp);
+ tmp = newSVpvn_flags(start, out ? (STRLEN)(out - start) : len,
+ SvUTF8(sv));
+ (void)hv_stores(GvHV(PL_hintgv), "open<", tmp);
+ mg_set(tmp);
}
break;
case '\020': /* ^P */
}
/*
+=for apidoc magic_clearhints
+
+Triggered by clearing %^H, resets C<PL_compiling.cop_hints_hash>.
+
+=cut
+*/
+int
+Perl_magic_clearhints(pTHX_ SV *sv, MAGIC *mg)
+{
+ PERL_ARGS_ASSERT_MAGIC_CLEARHINTS;
+ PERL_UNUSED_ARG(sv);
+ PERL_UNUSED_ARG(mg);
+ if (PL_compiling.cop_hints_hash) {
+ Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints_hash);
+ PL_compiling.cop_hints_hash = NULL;
+ }
+ return 0;
+}
+
+/*
* Local variables:
* c-indentation-style: bsd
* c-basic-offset: 4
want_vtbl_utf8,
want_vtbl_symtab,
want_vtbl_arylen_p,
- want_vtbl_hintselem
+ want_vtbl_hintselem,
+ want_vtbl_hints
};
0
);
-/* For now, hints magic will also use vtbl_sig, because it is all 0 */
MGVTBL_SET(
PL_vtbl_sig,
0,
0
);
+MGVTBL_SET(
+ PL_vtbl_hints,
+ 0,
+ 0,
+ 0,
+ MEMBER_TO_FPTR(Perl_magic_clearhints),
+ 0,
+ 0,
+ 0,
+ 0
+);
+
#include "overload.h"
END_EXTERN_C
e PERL_MAGIC_envelem vtbl_envelem %ENV hash element
f PERL_MAGIC_fm vtbl_fm Formline ('compiled' format)
g PERL_MAGIC_regex_global vtbl_mglob m//g target / study()ed string
- H PERL_MAGIC_hints vtbl_sig %^H hash
+ H PERL_MAGIC_hints vtbl_hints %^H hash
h PERL_MAGIC_hintselem vtbl_hintselem %^H hash element
I PERL_MAGIC_isa vtbl_isa @ISA array
i PERL_MAGIC_isaelem vtbl_isaelem @ISA array element
SAVEHINTS();
PL_hints = 0;
- if (PL_compiling.cop_hints_hash) {
- Perl_refcounted_he_free(aTHX_ PL_compiling.cop_hints_hash);
- PL_compiling.cop_hints_hash = NULL;
- }
+ hv_clear(GvHV(PL_hintgv));
SAVECOMPILEWARNINGS();
if (PL_dowarn & G_WARN_ALL_ON)
#define PERL_ARGS_ASSERT_MAGIC_CLEARHINT \
assert(sv); assert(mg)
+PERL_CALLCONV int Perl_magic_clearhints(pTHX_ SV* sv, MAGIC* mg)
+ __attribute__nonnull__(pTHX_1)
+ __attribute__nonnull__(pTHX_2);
+#define PERL_ARGS_ASSERT_MAGIC_CLEARHINTS \
+ assert(sv); assert(mg)
+
PERL_CALLCONV int Perl_magic_clearisa(pTHX_ SV* sv, MAGIC* mg)
__attribute__nonnull__(pTHX_2);
#define PERL_ARGS_ASSERT_MAGIC_CLEARISA \
case PERL_MAGIC_qr:
vtable = &PL_vtbl_regexp;
break;
- case PERL_MAGIC_hints:
- /* As this vtable is all NULL, we can reuse it. */
case PERL_MAGIC_sig:
vtable = &PL_vtbl_sig;
break;
case PERL_MAGIC_hintselem:
vtable = &PL_vtbl_hintselem;
break;
+ case PERL_MAGIC_hints:
+ vtable = &PL_vtbl_hints;
+ break;
case PERL_MAGIC_ext:
/* Reserved for use by extensions not perl internals. */
/* Useful for attaching extension internal data to perl vars. */
--- /dev/null
+our($ra1, $ri1, $rf1, $rfe1);
+$ra1 = $[;
+BEGIN { $ri1 = $^H; $rf1 = $^H{foo}; $rfe1 = exists($^H{foo}); }
+
+1;
}
-BEGIN { print "1..17\n"; }
+BEGIN { print "1..32\n"; }
BEGIN {
print "not " if exists $^H{foo};
print "ok 1 - \$^H{foo} doesn't exist initially\n";
}
BEGIN {
print "not " if $^H{foo} ne "a";
- print "ok 6 - \$H^{foo} restored to 'a'\n";
+ print "ok 6 - \$^H{foo} restored to 'a'\n";
}
# The pragma settings disappear after compilation
# (test at CHECK-time and at run-time)
{
BEGIN{$^H{x}=1};
- for(1..2) {
+ for my $tno (16..17) {
eval q(
- print $^H{x}==1 && !$^H{y} ? "ok\n" : "not ok\n";
+ print $^H{x}==1 && !$^H{y} ? "ok $tno\n" : "not ok $tno\n";
$^H{y} = 1;
);
if ($@) {
(my $str = $@)=~s/^/# /gm;
- print "not ok\n$str\n";
+ print "not ok $tno\n$str\n";
}
}
}
+
+{
+ $[ = 11;
+ print +($[ == 11 ? "" : "not "), "ok 18 - setting \$[ affects \$[\n";
+ our $t11; BEGIN { $t11 = $^H{'$['} }
+ print +($t11 == 11 ? "" : "not "), "ok 19 - setting \$[ affects \$^H{'\$['}\n";
+
+ BEGIN { $^H{'$['} = 22 }
+ print +($[ == 22 ? "" : "not "), "ok 20 - setting \$^H{'\$['} affects \$[\n";
+ our $t22; BEGIN { $t22 = $^H{'$['} }
+ print +($t22 == 22 ? "" : "not "), "ok 21 - setting \$^H{'\$['} affects \$^H{'\$['}\n";
+
+ BEGIN { %^H = () }
+ print +($[ == 0 ? "" : "not "), "ok 22 - clearing \%^H affects \$[\n";
+ our $t0; BEGIN { $t0 = $^H{'$['} }
+ print +($t0 == 0 ? "" : "not "), "ok 23 - clearing \%^H affects \$^H{'\$['}\n";
+}
+
+{
+ $[ = 13;
+ BEGIN { $^H |= 0x04000000; $^H{foo} = "z"; }
+
+ our($ri0, $rf0); BEGIN { $ri0 = $^H; $rf0 = $^H{foo}; }
+ print +($[ == 13 ? "" : "not "), "ok 24 - \$[ correct before require\n";
+ print +($ri0 & 0x04000000 ? "" : "not "), "ok 25 - \$^H correct before require\n";
+ print +($rf0 eq "z" ? "" : "not "), "ok 26 - \$^H{foo} correct before require\n";
+
+ our($ra1, $ri1, $rf1, $rfe1);
+ BEGIN { require "comp/hints.aux"; }
+ print +($ra1 == 0 ? "" : "not "), "ok 27 - \$[ cleared for require\n";
+ print +(!($ri1 & 0x04000000) ? "" : "not "), "ok 28 - \$^H cleared for require\n";
+ print +(!defined($rf1) && !$rfe1 ? "" : "not "), "ok 29 - \$^H{foo} cleared for require\n";
+
+ our($ri2, $rf2); BEGIN { $ri2 = $^H; $rf2 = $^H{foo}; }
+ print +($[ == 13 ? "" : "not "), "ok 30 - \$[ correct after require\n";
+ print +($ri2 & 0x04000000 ? "" : "not "), "ok 31 - \$^H correct after require\n";
+ print +($rf2 eq "z" ? "" : "not "), "ok 32 - \$^H{foo} correct after require\n";
+}