Ap |void |hv_ksplit |NN HV* hv|IV newmax
Apdbm |void |hv_magic |NN HV* hv|NULLOK GV* gv|int how
#ifdef USE_ITHREADS
+dpoM|struct refcounted_he *|refcounted_he_copy \
+ |NULLOK const struct refcounted_he *he
dpoM|struct refcounted_he *|refcounted_he_dup \
|NULLOK const struct refcounted_he *const he \
|NN CLONE_PARAMS* param
copy->refcounted_he_refcnt = he->refcounted_he_refcnt;
return copy;
}
+
+/*
+=for apidoc refcounted_he_copy
+
+Copies a chain of C<struct refcounted_he *>. Used by C<pp_entereval>.
+
+=cut
+*/
+
+struct refcounted_he *
+Perl_refcounted_he_copy(pTHX_ const struct refcounted_he * he)
+{
+ struct refcounted_he *copy;
+ HEK *hek;
+ /* This is much easier to express recursively than iteratively. */
+ if (!he)
+ return NULL;
+
+ Newx(copy, 1, struct refcounted_he);
+ copy->refcounted_he_he.hent_next
+ = (HE *)Perl_refcounted_he_copy(aTHX_
+ (struct refcounted_he *)
+ he->refcounted_he_he.hent_next);
+ copy->refcounted_he_he.he_valu.hent_val
+ = newSVsv(he->refcounted_he_he.he_valu.hent_val);
+ hek = he->refcounted_he_he.hent_hek;
+ copy->refcounted_he_he.hent_hek
+ = share_hek(HEK_KEY(hek),
+ HEK_UTF8(hek) ? -(I32)HEK_LEN(hek) : HEK_LEN(hek),
+ HEK_HASH(hek));
+ copy->refcounted_he_refcnt = 1;
+ return copy;
+}
#endif
/*
=for hackers
Found in file hv.c
+=item refcounted_he_copy
+X<refcounted_he_copy>
+
+Copies a chain of C<struct refcounted_he *>. Used by C<pp_entereval>.
+
+ struct refcounted_he * refcounted_he_copy(const struct refcounted_he *he)
+
+=for hackers
+Found in file hv.c
+
=item refcounted_he_dup
X<refcounted_he_dup>
the property of the caller. The C<struct refcounted_he> is returned with a
reference count of 1.
- struct refcounted_he * refcounted_he_new(struct refcounted_he *parent, SV *key, SV *value)
+ struct refcounted_he * refcounted_he_new(struct refcounted_he *const parent, SV *key, SV *value)
=for hackers
Found in file hv.c
PL_compiling.cop_io = newSVsv(PL_curcop->cop_io);
SAVEFREESV(PL_compiling.cop_io);
}
+ if (PL_compiling.cop_hints) {
+ PL_compiling.cop_hints->refcounted_he_refcnt--;
+ }
+ PL_compiling.cop_hints = PL_curcop->cop_hints;
+ if (PL_compiling.cop_hints) {
+#ifdef USE_ITHREADS
+ /* PL_curcop could be pointing to an optree owned by another /.*parent/
+ thread. We can't manipulate the reference count of the refcounted he
+ there (race condition) so we have to do something less than
+ pleasant to keep it read only. The simplest solution seems to be to
+ copy their chain. We might want to cache this.
+ Alternatively we could add a flag to the refcounted he *we* point to
+ here saying "I don't own a reference count on the thing I point to",
+ and arrange for Perl_refcounted_he_free() to spot that. If so, we'd
+ still need to copy the topmost refcounted he so that we could change
+ its flag. So still not trivial. (Flag bits could be hung from the
+ shared HEK) */
+ PL_compiling.cop_hints
+ = Perl_refcounted_he_copy(aTHX_ PL_compiling.cop_hints);
+#else
+ PL_compiling.cop_hints->refcounted_he_refcnt++;
+#endif
+ }
/* special case: an eval '' executed within the DB package gets lexically
* placed in the first non-DB CV rather than the current CV - this
* allows the debugger to execute code, find lexicals etc, in the
__attribute__nonnull__(pTHX_1); */
#ifdef USE_ITHREADS
+PERL_CALLCONV struct refcounted_he * Perl_refcounted_he_copy(pTHX_ const struct refcounted_he *he);
PERL_CALLCONV struct refcounted_he * Perl_refcounted_he_dup(pTHX_ const struct refcounted_he *const he, CLONE_PARAMS* param)
__attribute__nonnull__(pTHX_2);
chdir 't' if -d 't';
@INC = '../lib';
require './test.pl';
- plan( tests => 56 );
+ plan( tests => 64 );
}
my @c;
is(get_dooot(), 6 * 7);
is(get_thikoosh(), "SKREECH");
}
+
+print "# which now works inside evals\n";
+
+{
+ BEGIN {
+ $^H{dooot} = 42;
+ }
+ is(get_dooot(), 6 * 7);
+
+ eval "is(get_dooot(), 6 * 7); 1" or die $@;
+
+ eval <<'EOE' or die $@;
+ is(get_dooot(), 6 * 7);
+ eval "is(get_dooot(), 6 * 7); 1" or die $@;
+ BEGIN {
+ $^H{dooot} = 54;
+ }
+ is(get_dooot(), 54);
+ eval "is(get_dooot(), 54); 1" or die $@;
+ eval 'BEGIN { $^H{dooot} = -1; }; 1' or die $@;
+ is(get_dooot(), 54);
+ eval "is(get_dooot(), 54); 1" or die $@;
+EOE
+}