diff options
author | Nicholas Clark <nick@ccl4.org> | 2006-04-01 14:31:37 +0000 |
---|---|---|
committer | Nicholas Clark <nick@ccl4.org> | 2006-04-01 14:31:37 +0000 |
commit | a24d89c9b4c1e58840711d560a34763a7ca91051 (patch) | |
tree | d13f807afb7745e725f87a7d9fb37f52313ab56e /hv.c | |
parent | 9b2c10f1c598e1e6a0db9d0b301c9559b079b129 (diff) | |
download | perl-a24d89c9b4c1e58840711d560a34763a7ca91051.tar.gz |
Propagate cop_hints inside string evals. For the unthreaded case this
is easy. For the threaded case it's not, because the current OP may
be shared with another thread, so solve this by copying the hints
chain.
p4raw-id: //depot/perl@27659
Diffstat (limited to 'hv.c')
-rw-r--r-- | hv.c | 33 |
1 files changed, 33 insertions, 0 deletions
@@ -2695,6 +2695,39 @@ Perl_refcounted_he_dup(pTHX_ const struct refcounted_he *const he, 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 /* |