register const SV * const svend = &sva[SvREFCNT(sva)];
register SV* sv;
for (sv = sva + 1; sv < svend; ++sv) {
- if (SvTYPE(sv) != SVTYPEMASK
+ if (SvTYPE(sv) != (svtype)SVTYPEMASK
&& (sv->sv_flags & mask) == flags
&& SvREFCNT(sv))
{
static void
do_report_used(pTHX_ SV *const sv)
{
- if (SvTYPE(sv) != SVTYPEMASK) {
+ if (SvTYPE(sv) != (svtype)SVTYPEMASK) {
PerlIO_printf(Perl_debug_log, "****\n");
sv_dump(sv);
}
NOARENA /* IVS don't need an arena */, 0
},
- /* 8 bytes on most ILP32 with IEEE doubles */
{ sizeof(NV), sizeof(NV),
STRUCT_OFFSET(XPVNV, xnv_u),
SVt_NV, FALSE, HADNV, HASARENA, FIT_ARENA(0, sizeof(NV)) },
- /* 8 bytes on most ILP32 with IEEE doubles */
{ sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur),
copy_length(XPV, xpv_len) - STRUCT_OFFSET(XPV, xpv_cur),
+ STRUCT_OFFSET(XPV, xpv_cur),
SVt_PV, FALSE, NONV, HASARENA,
FIT_ARENA(0, sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur)) },
- /* 12 */
{ sizeof(XPVIV) - STRUCT_OFFSET(XPV, xpv_cur),
copy_length(XPVIV, xiv_u) - STRUCT_OFFSET(XPV, xpv_cur),
+ STRUCT_OFFSET(XPV, xpv_cur),
SVt_PVIV, FALSE, NONV, HASARENA,
FIT_ARENA(0, sizeof(XPVIV) - STRUCT_OFFSET(XPV, xpv_cur)) },
- /* 20 */
{ sizeof(XPVNV) - STRUCT_OFFSET(XPV, xpv_cur),
copy_length(XPVNV, xnv_u) - STRUCT_OFFSET(XPV, xpv_cur),
+ STRUCT_OFFSET(XPV, xpv_cur),
SVt_PVNV, FALSE, HADNV, HASARENA,
FIT_ARENA(0, sizeof(XPVNV) - STRUCT_OFFSET(XPV, xpv_cur)) },
- /* 28 */
{ sizeof(XPVMG), copy_length(XPVMG, xnv_u), 0, SVt_PVMG, FALSE, HADNV,
HASARENA, FIT_ARENA(0, sizeof(XPVMG)) },
- /* something big */
{ sizeof(regexp),
sizeof(regexp),
0,
FIT_ARENA(0, sizeof(regexp))
},
- /* 48 */
{ sizeof(XPVGV), sizeof(XPVGV), 0, SVt_PVGV, TRUE, HADNV,
HASARENA, FIT_ARENA(0, sizeof(XPVGV)) },
- /* 64 */
{ sizeof(XPVLV), sizeof(XPVLV), 0, SVt_PVLV, TRUE, HADNV,
HASARENA, FIT_ARENA(0, sizeof(XPVLV)) },
SVt_PVHV, TRUE, NONV, HASARENA,
FIT_ARENA(0, sizeof(XPVHV)) },
- /* 56 */
{ sizeof(XPVCV),
sizeof(XPVCV),
0,
SVt_PVFM, TRUE, NONV, NOARENA,
FIT_ARENA(20, sizeof(XPVFM)) },
- /* XPVIO is 84 bytes, fits 48x */
{ sizeof(XPVIO),
sizeof(XPVIO),
0,
dVAR;
if (!sv)
return 0;
- if (SvGMAGICAL(sv) || (SvTYPE(sv) == SVt_PVGV && SvVALID(sv))) {
+ if (SvGMAGICAL(sv) || SvVALID(sv)) {
/* FBMs use the space for SvIVX and SvNVX for other purposes, and use
the same flag bit as SVf_IVisUV, so must not let them cache IVs.
In practice they are extremely unlikely to actually get anywhere
dVAR;
if (!sv)
return 0;
- if (SvGMAGICAL(sv) || (SvTYPE(sv) == SVt_PVGV && SvVALID(sv))) {
+ if (SvGMAGICAL(sv) || SvVALID(sv)) {
/* FBMs use the space for SvIVX and SvNVX for other purposes, and use
the same flag bit as SVf_IVisUV, so must not let them cache IVs. */
if (flags & SV_GMAGIC)
dVAR;
if (!sv)
return 0.0;
- if (SvGMAGICAL(sv) || (SvTYPE(sv) == SVt_PVGV && SvVALID(sv))) {
+ if (SvGMAGICAL(sv) || SvVALID(sv)) {
/* FBMs use the space for SvIVX and SvNVX for other purposes, and use
the same flag bit as SVf_IVisUV, so must not let them cache NVs. */
if (flags & SV_GMAGIC)
if (lp) {
*lp = SvCUR(buffer);
}
+ if ( SvUTF8(buffer) ) SvUTF8_on(sv);
return SvPVX(buffer);
}
else {
/* case SVt_BIND: */
case SVt_PVLV:
case SVt_PVGV:
- /* SvVALID means that this PVGV is playing at being an FBM. */
-
case SVt_PVMG:
if (SvGMAGICAL(sstr) && (flags & SV_GMAGIC)) {
mg_get(sstr);
"Undefined value assigned to typeglob");
}
else {
- GV *gv = gv_fetchsv(sstr, GV_ADD, SVt_PVGV);
+ GV *gv = gv_fetchsv_nomg(sstr, GV_ADD, SVt_PVGV);
if (dstr != (const SV *)gv) {
const char * const name = GvNAME((const GV *)dstr);
const STRLEN len = GvNAMELEN(dstr);
}
#else
if (SvREADONLY(sv)) {
- if (SvFAKE(sv)) {
+ if (SvFAKE(sv) && !isGV_with_GP(sv)) {
const char * const pvx = SvPVX_const(sv);
const STRLEN len = SvCUR(sv);
SvFAKE_off(sv);
In 5.9.3, newSV() replaces the older NEWSV() API, and drops the first
parameter, I<x>, a debug aid which allowed callers to identify themselves.
This aid has been superseded by a new build option, PERL_MEM_LOG (see
-L<perlhack/PERL_MEM_LOG>). The older API is still there for use in XS
+L<perlhacktips/PERL_MEM_LOG>). The older API is still there for use in XS
modules supporting older perls.
=cut
dVAR;
const MGVTBL *vtable;
MAGIC* mg;
+ unsigned int flags;
+ unsigned int vtable_index;
PERL_ARGS_ASSERT_SV_MAGIC;
+ if (how < 0 || (unsigned)how > C_ARRAY_LENGTH(PL_magic_data)
+ || ((flags = PL_magic_data[how]),
+ (vtable_index = flags & PERL_MAGIC_VTABLE_MASK)
+ > magic_vtable_max))
+ Perl_croak(aTHX_ "Don't know how to handle magic of type \\%o", how);
+
+ /* PERL_MAGIC_ext is reserved for use by extensions not perl internals.
+ Useful for attaching extension internal data to perl vars.
+ Note that multiple extensions may clash if magical scalars
+ etc holding private data from one are passed to another. */
+
+ vtable = (vtable_index == magic_vtable_max)
+ ? NULL : PL_magic_vtables + vtable_index;
+
#ifdef PERL_OLD_COPY_ON_WRITE
if (SvIsCOW(sv))
sv_force_normal_flags(sv, 0);
!(SvFAKE(sv) && SvTYPE(sv) < SVt_PVMG)
&& IN_PERL_RUNTIME
- && how != PERL_MAGIC_regex_global
- && how != PERL_MAGIC_bm
- && how != PERL_MAGIC_fm
- && how != PERL_MAGIC_sv
- && how != PERL_MAGIC_backref
+ && !PERL_MAGIC_TYPE_READONLY_ACCEPTABLE(how)
)
{
Perl_croak_no_modify(aTHX);
}
}
- switch (how) {
- case PERL_MAGIC_sv:
- vtable = &PL_vtbl_sv;
- break;
- case PERL_MAGIC_overload:
- vtable = &PL_vtbl_amagic;
- break;
- case PERL_MAGIC_overload_elem:
- vtable = &PL_vtbl_amagicelem;
- break;
- case PERL_MAGIC_overload_table:
- vtable = &PL_vtbl_ovrld;
- break;
- case PERL_MAGIC_bm:
- vtable = &PL_vtbl_bm;
- break;
- case PERL_MAGIC_regdata:
- vtable = &PL_vtbl_regdata;
- break;
- case PERL_MAGIC_regdatum:
- vtable = &PL_vtbl_regdatum;
- break;
- case PERL_MAGIC_env:
- vtable = &PL_vtbl_env;
- break;
- case PERL_MAGIC_fm:
- vtable = &PL_vtbl_fm;
- break;
- case PERL_MAGIC_envelem:
- vtable = &PL_vtbl_envelem;
- break;
- case PERL_MAGIC_regex_global:
- vtable = &PL_vtbl_mglob;
- break;
- case PERL_MAGIC_isa:
- vtable = &PL_vtbl_isa;
- break;
- case PERL_MAGIC_isaelem:
- vtable = &PL_vtbl_isaelem;
- break;
- case PERL_MAGIC_nkeys:
- vtable = &PL_vtbl_nkeys;
- break;
- case PERL_MAGIC_dbfile:
- vtable = NULL;
- break;
- case PERL_MAGIC_dbline:
- vtable = &PL_vtbl_dbline;
- break;
-#ifdef USE_LOCALE_COLLATE
- case PERL_MAGIC_collxfrm:
- vtable = &PL_vtbl_collxfrm;
- break;
-#endif /* USE_LOCALE_COLLATE */
- case PERL_MAGIC_tied:
- vtable = &PL_vtbl_pack;
- break;
- case PERL_MAGIC_tiedelem:
- case PERL_MAGIC_tiedscalar:
- vtable = &PL_vtbl_packelem;
- break;
- case PERL_MAGIC_qr:
- vtable = &PL_vtbl_regexp;
- break;
- case PERL_MAGIC_sig:
- vtable = &PL_vtbl_sig;
- break;
- case PERL_MAGIC_sigelem:
- vtable = &PL_vtbl_sigelem;
- break;
- case PERL_MAGIC_taint:
- vtable = &PL_vtbl_taint;
- break;
- case PERL_MAGIC_uvar:
- vtable = &PL_vtbl_uvar;
- break;
- case PERL_MAGIC_vec:
- vtable = &PL_vtbl_vec;
- break;
- case PERL_MAGIC_arylen_p:
- case PERL_MAGIC_rhash:
- case PERL_MAGIC_symtab:
- case PERL_MAGIC_vstring:
- case PERL_MAGIC_checkcall:
- vtable = NULL;
- break;
- case PERL_MAGIC_utf8:
- vtable = &PL_vtbl_utf8;
- break;
- case PERL_MAGIC_substr:
- vtable = &PL_vtbl_substr;
- break;
- case PERL_MAGIC_defelem:
- vtable = &PL_vtbl_defelem;
- break;
- case PERL_MAGIC_arylen:
- vtable = &PL_vtbl_arylen;
- break;
- case PERL_MAGIC_pos:
- vtable = &PL_vtbl_pos;
- break;
- case PERL_MAGIC_backref:
- vtable = &PL_vtbl_backref;
- 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. */
- /* Note that multiple extensions may clash if magical scalars */
- /* etc holding private data from one are passed to another. */
- vtable = NULL;
- break;
- default:
- Perl_croak(aTHX_ "Don't know how to handle magic of type \\%o", how);
- }
-
/* Rest of work is done else where */
mg = sv_magicext(sv,obj,how,vtable,name,namlen);
Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "Reference is already weak");
return sv;
}
+ else if (SvREADONLY(sv)) croak_no_modify();
tsv = SvRV(sv);
Perl_sv_add_backref(aTHX_ tsv, sv);
SvWEAKREF_on(sv);
type = SvTYPE(sv);
assert(SvREFCNT(sv) == 0);
- assert(SvTYPE(sv) != SVTYPEMASK);
+ assert(SvTYPE(sv) != (svtype)SVTYPEMASK);
if (type <= SVt_IV) {
/* See the comment in sv.h about the collusion between this
}
} else if (SvTYPE(iter_sv) == SVt_PVHV) {
sv = Perl_hfree_next_entry(aTHX_ (HV*)iter_sv, &hash_index);
- if (!sv) { /* no more elements of current HV to free */
+ if (!sv && !HvTOTALKEYS((HV *)iter_sv)) {
+ /* no more elements of current HV to free */
sv = iter_sv;
type = SvTYPE(sv);
/* Restore previous value of iter_sv, squirrelled away */
if (!sv)
return;
if (SvTHINKFIRST(sv)) {
- if (SvIsCOW(sv))
+ if (SvIsCOW(sv) || isGV_with_GP(sv))
sv_force_normal_flags(sv, 0);
if (SvREADONLY(sv)) {
if (IN_PERL_RUNTIME)
if (!sv)
return;
if (SvTHINKFIRST(sv)) {
- if (SvIsCOW(sv))
+ if (SvIsCOW(sv) || isGV_with_GP(sv))
sv_force_normal_flags(sv, 0);
if (SvREADONLY(sv)) {
if (IN_PERL_RUNTIME)
into an hv routine with a regular hash.
Similarly, a hash that isn't using shared hash keys has to have
the flag in every key so that we know not to try to call
- share_hek_kek on it. */
+ share_hek_hek on it. */
SV * const sv = newSVpvn (HEK_KEY(hek), HEK_LEN(hek));
if (HEK_UTF8(hek))
if (!old)
return NULL;
- if (SvTYPE(old) == SVTYPEMASK) {
+ if (SvTYPE(old) == (svtype)SVTYPEMASK) {
Perl_ck_warner_d(aTHX_ packWARN(WARN_INTERNAL), "semi-panic: attempt to dup freed string");
return NULL;
}
*st = NULL;
*gvp = NULL;
return NULL;
- case SVt_PVGV:
- if (isGV_with_GP(sv)) {
- gv = MUTABLE_GV(sv);
- *gvp = gv;
- *st = GvESTASH(gv);
- goto fix_gv;
- }
- /* FALL THROUGH */
-
default:
+ SvGETMAGIC(sv);
if (SvROK(sv)) {
- SvGETMAGIC(sv);
if (SvAMAGIC(sv))
sv = amagic_deref_call(sv, to_cv_amg);
/* At this point I'd like to do SPAGAIN, but really I need to
Perl_croak(aTHX_ "Not a subroutine reference");
}
else if (isGV_with_GP(sv)) {
- SvGETMAGIC(sv);
gv = MUTABLE_GV(sv);
}
- else
- gv = gv_fetchsv(sv, lref, SVt_PVCV); /* Calls get magic */
+ else {
+ gv = gv_fetchsv_nomg(sv, lref, SVt_PVCV);
+ }
*gvp = gv;
if (!gv) {
*st = NULL;
return NULL;
}
*st = GvESTASH(gv);
- fix_gv:
- if (lref && !GvCVu(gv)) {
+ if (lref & ~GV_ADDMG && !GvCVu(gv)) {
SV *tmpsv;
ENTER;
tmpsv = newSV(0);
=for apidoc sv_untaint
Untaint an SV. Use C<SvTAINTED_off> instead.
+
=cut
*/
=for apidoc sv_tainted
Test an SV for taintedness. Use C<SvTAINTED> instead.
+
=cut
*/
PERL_ARGS_ASSERT_SV_DUP_COMMON;
- if (SvTYPE(sstr) == SVTYPEMASK) {
+ if (SvTYPE(sstr) == (svtype)SVTYPEMASK) {
#ifdef DEBUG_LEAKING_SCALARS_ABORT
abort();
#endif
OP_REFCNT_LOCK;
CvROOT(dstr) = OpREFCNT_inc(CvROOT(dstr));
OP_REFCNT_UNLOCK;
- CvFILE(dstr) = SAVEPV(CvFILE(dstr));
} else if (CvCONST(dstr)) {
CvXSUBANY(dstr).any_ptr =
sv_dup_inc((const SV *)CvXSUBANY(dstr).any_ptr, param);
}
+ if (CvDYNFILE(dstr)) CvFILE(dstr) = SAVEPV(CvFILE(dstr));
/* don't dup if copying back - CvGV isn't refcounted, so the
* duped GV may never be freed. A bit of a hack! DAPM */
SvANY(MUTABLE_CV(dstr))->xcv_gv =
TOPLONG(nss,ix) = longval;
break;
case SAVEt_I32: /* I32 reference */
- case SAVEt_COP_ARYBASE: /* call CopARYBASE_set */
ptr = POPPTR(ss,ix);
TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
i = POPINT(ss,ix);
PoisonNew(my_perl, 1, PerlInterpreter);
PL_op = NULL;
PL_curcop = NULL;
+ PL_defstash = NULL; /* may be used by perl malloc() */
PL_markstack = 0;
PL_scopestack = 0;
PL_scopestack_name = 0;
PL_hash_seed = proto_perl->Ihash_seed;
PL_rehash_seed = proto_perl->Irehash_seed;
-#ifdef USE_REENTRANT_API
- /* XXX: things like -Dm will segfault here in perlio, but doing
- * PERL_SET_CONTEXT(proto_perl);
- * breaks too many other things
- */
- Perl_reentrant_init(aTHX);
-#endif
-
- /* create SV map for pointer relocation */
- PL_ptr_table = ptr_table_new();
-
- /* initialize these special pointers as early as possible */
SvANY(&PL_sv_undef) = NULL;
SvREFCNT(&PL_sv_undef) = (~(U32)0)/2;
SvFLAGS(&PL_sv_undef) = SVf_READONLY|SVt_NULL;
- ptr_table_store(PL_ptr_table, &proto_perl->Isv_undef, &PL_sv_undef);
-
- SvANY(&PL_sv_no) = new_XPVNV();
SvREFCNT(&PL_sv_no) = (~(U32)0)/2;
SvFLAGS(&PL_sv_no) = SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK
|SVp_POK|SVf_POK|SVf_READONLY|SVt_PVNV;
- SvPV_set(&PL_sv_no, savepvn(PL_No, 0));
- SvCUR_set(&PL_sv_no, 0);
- SvLEN_set(&PL_sv_no, 1);
- SvIV_set(&PL_sv_no, 0);
- SvNV_set(&PL_sv_no, 0);
- ptr_table_store(PL_ptr_table, &proto_perl->Isv_no, &PL_sv_no);
SvANY(&PL_sv_yes) = new_XPVNV();
SvREFCNT(&PL_sv_yes) = (~(U32)0)/2;
SvFLAGS(&PL_sv_yes) = SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK
|SVp_POK|SVf_POK|SVf_READONLY|SVt_PVNV;
- SvPV_set(&PL_sv_yes, savepvn(PL_Yes, 1));
- SvCUR_set(&PL_sv_yes, 1);
- SvLEN_set(&PL_sv_yes, 2);
- SvIV_set(&PL_sv_yes, 1);
- SvNV_set(&PL_sv_yes, 1);
- ptr_table_store(PL_ptr_table, &proto_perl->Isv_yes, &PL_sv_yes);
/* dbargs array probably holds garbage */
PL_dbargs = NULL;
- /* create (a non-shared!) shared string table */
- PL_strtab = newHV();
- HvSHAREKEYS_off(PL_strtab);
- hv_ksplit(PL_strtab, HvTOTALKEYS(proto_perl->Istrtab));
- ptr_table_store(PL_ptr_table, proto_perl->Istrtab, PL_strtab);
-
PL_compiling = proto_perl->Icompiling;
- /* These two PVs will be free'd special way so must set them same way op.c does */
- PL_compiling.cop_stashpv = savesharedpv(PL_compiling.cop_stashpv);
- ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_stashpv, PL_compiling.cop_stashpv);
-
- PL_compiling.cop_file = savesharedpv(PL_compiling.cop_file);
- ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_file, PL_compiling.cop_file);
-
- ptr_table_store(PL_ptr_table, &proto_perl->Icompiling, &PL_compiling);
- PL_compiling.cop_warnings = DUP_WARNINGS(PL_compiling.cop_warnings);
- CopHINTHASH_set(&PL_compiling, cophh_copy(CopHINTHASH_get(&PL_compiling)));
- PL_curcop = (COP*)any_dup(proto_perl->Icurcop, proto_perl);
#ifdef PERL_DEBUG_READONLY_OPS
PL_slabs = NULL;
PL_slab_count = 0;
PL_origargc = proto_perl->Iorigargc;
PL_origargv = proto_perl->Iorigargv;
- param->stashes = newAV(); /* Setup array of objects to call clone on */
- /* This makes no difference to the implementation, as it always pushes
- and shifts pointers to other SVs without changing their reference
- count, with the array becoming empty before it is freed. However, it
- makes it conceptually clear what is going on, and will avoid some
- work inside av.c, filling slots between AvFILL() and AvMAX() with
- &PL_sv_undef, and SvREFCNT_dec()ing those. */
- AvREAL_off(param->stashes);
-
- if (!(flags & CLONEf_COPY_STACKS)) {
- param->unreferenced = newAV();
- }
-
/* Set tainting stuff before PerlIO_debug can possibly get called */
PL_tainting = proto_perl->Itainting;
PL_taint_warn = proto_perl->Itaint_warn;
-#ifdef PERLIO_LAYERS
- /* Clone PerlIO tables as soon as we can handle general xx_dup() */
- PerlIO_clone(aTHX_ proto_perl, param);
-#endif
-
- PL_envgv = gv_dup(proto_perl->Ienvgv, param);
- PL_incgv = gv_dup(proto_perl->Iincgv, param);
- PL_hintgv = gv_dup(proto_perl->Ihintgv, param);
- PL_origfilename = SAVEPV(proto_perl->Iorigfilename);
- PL_diehook = sv_dup_inc(proto_perl->Idiehook, param);
- PL_warnhook = sv_dup_inc(proto_perl->Iwarnhook, param);
-
- /* switches */
PL_minus_c = proto_perl->Iminus_c;
- PL_patchlevel = sv_dup_inc(proto_perl->Ipatchlevel, param);
- PL_apiversion = sv_dup_inc(proto_perl->Iapiversion, param);
+
PL_localpatches = proto_perl->Ilocalpatches;
PL_splitstr = proto_perl->Isplitstr;
PL_minus_n = proto_perl->Iminus_n;
PL_dowarn = proto_perl->Idowarn;
PL_sawampersand = proto_perl->Isawampersand;
PL_unsafe = proto_perl->Iunsafe;
- PL_inplace = SAVEPV(proto_perl->Iinplace);
- PL_e_script = sv_dup_inc(proto_perl->Ie_script, param);
PL_perldb = proto_perl->Iperldb;
PL_perl_destruct_level = proto_perl->Iperl_destruct_level;
PL_exit_flags = proto_perl->Iexit_flags;
- /* magical thingies */
/* XXX time(&PL_basetime) when asked for? */
PL_basetime = proto_perl->Ibasetime;
- PL_formfeed = sv_dup(proto_perl->Iformfeed, param);
PL_maxsysfd = proto_perl->Imaxsysfd;
PL_statusvalue = proto_perl->Istatusvalue;
#else
PL_statusvalue_posix = proto_perl->Istatusvalue_posix;
#endif
- PL_encoding = sv_dup(proto_perl->Iencoding, param);
- sv_setpvs(PERL_DEBUG_PAD(0), ""); /* For regex debugging. */
- sv_setpvs(PERL_DEBUG_PAD(1), ""); /* ext/re needs these */
- sv_setpvs(PERL_DEBUG_PAD(2), ""); /* even without DEBUGGING. */
-
-
/* RE engine related */
Zero(&PL_reg_state, 1, struct re_save_state);
PL_reginterp_cnt = 0;
PL_regmatch_slab = NULL;
-
- /* Clone the regex array */
- /* ORANGE FIXME for plugins, probably in the SV dup code.
- newSViv(PTR2IV(CALLREGDUPE(
- INT2PTR(REGEXP *, SvIVX(regex)), param))))
- */
- PL_regex_padav = av_dup_inc(proto_perl->Iregex_padav, param);
- PL_regex_pad = AvARRAY(PL_regex_padav);
-
- /* shortcuts to various I/O objects */
- PL_ofsgv = gv_dup_inc(proto_perl->Iofsgv, param);
- PL_stdingv = gv_dup(proto_perl->Istdingv, param);
- PL_stderrgv = gv_dup(proto_perl->Istderrgv, param);
- PL_defgv = gv_dup(proto_perl->Idefgv, param);
- PL_argvgv = gv_dup(proto_perl->Iargvgv, param);
- PL_argvoutgv = gv_dup(proto_perl->Iargvoutgv, param);
- PL_argvout_stack = av_dup_inc(proto_perl->Iargvout_stack, param);
-
- /* shortcuts to regexp stuff */
- PL_replgv = gv_dup(proto_perl->Ireplgv, param);
-
- /* shortcuts to misc objects */
- PL_errgv = gv_dup(proto_perl->Ierrgv, param);
-
- /* shortcuts to debugging objects */
- PL_DBgv = gv_dup(proto_perl->IDBgv, param);
- PL_DBline = gv_dup(proto_perl->IDBline, param);
- PL_DBsub = gv_dup(proto_perl->IDBsub, param);
- PL_DBsingle = sv_dup(proto_perl->IDBsingle, param);
- PL_DBtrace = sv_dup(proto_perl->IDBtrace, param);
- PL_DBsignal = sv_dup(proto_perl->IDBsignal, param);
-
- /* symbol tables */
- PL_defstash = hv_dup_inc(proto_perl->Idefstash, param);
- PL_curstash = hv_dup(proto_perl->Icurstash, param);
- PL_debstash = hv_dup(proto_perl->Idebstash, param);
- PL_globalstash = hv_dup(proto_perl->Iglobalstash, param);
- PL_curstname = sv_dup_inc(proto_perl->Icurstname, param);
-
- PL_beginav = av_dup_inc(proto_perl->Ibeginav, param);
- PL_beginav_save = av_dup_inc(proto_perl->Ibeginav_save, param);
- PL_checkav_save = av_dup_inc(proto_perl->Icheckav_save, param);
- PL_unitcheckav = av_dup_inc(proto_perl->Iunitcheckav, param);
- PL_unitcheckav_save = av_dup_inc(proto_perl->Iunitcheckav_save, param);
- PL_endav = av_dup_inc(proto_perl->Iendav, param);
- PL_checkav = av_dup_inc(proto_perl->Icheckav, param);
- PL_initav = av_dup_inc(proto_perl->Iinitav, param);
PL_sub_generation = proto_perl->Isub_generation;
- PL_isarev = hv_dup_inc(proto_perl->Iisarev, param);
/* funky return mechanisms */
PL_forkprocess = proto_perl->Iforkprocess;
- /* subprocess state */
- PL_fdpid = av_dup_inc(proto_perl->Ifdpid, param);
-
/* internal state */
PL_maxo = proto_perl->Imaxo;
- if (proto_perl->Iop_mask)
- PL_op_mask = SAVEPVN(proto_perl->Iop_mask, PL_maxo);
- else
- PL_op_mask = NULL;
- /* PL_asserting = proto_perl->Iasserting; */
- /* current interpreter roots */
- PL_main_cv = cv_dup_inc(proto_perl->Imain_cv, param);
- OP_REFCNT_LOCK;
- PL_main_root = OpREFCNT_inc(proto_perl->Imain_root);
- OP_REFCNT_UNLOCK;
PL_main_start = proto_perl->Imain_start;
PL_eval_root = proto_perl->Ieval_root;
PL_eval_start = proto_perl->Ieval_start;
- /* runtime control stuff */
- PL_curcopdb = (COP*)any_dup(proto_perl->Icurcopdb, proto_perl);
-
PL_filemode = proto_perl->Ifilemode;
PL_lastfd = proto_perl->Ilastfd;
PL_oldname = proto_perl->Ioldname; /* XXX not quite right */
PL_Argv = NULL;
PL_Cmd = NULL;
PL_gensym = proto_perl->Igensym;
- PL_preambleav = av_dup_inc(proto_perl->Ipreambleav, param);
+
PL_laststatval = proto_perl->Ilaststatval;
PL_laststype = proto_perl->Ilaststype;
PL_mess_sv = NULL;
- PL_ors_sv = sv_dup_inc(proto_perl->Iors_sv, param);
-
- /* interpreter atexit processing */
- PL_exitlistlen = proto_perl->Iexitlistlen;
- if (PL_exitlistlen) {
- Newx(PL_exitlist, PL_exitlistlen, PerlExitListEntry);
- Copy(proto_perl->Iexitlist, PL_exitlist, PL_exitlistlen, PerlExitListEntry);
- }
- else
- PL_exitlist = (PerlExitListEntry*)NULL;
-
- PL_my_cxt_size = proto_perl->Imy_cxt_size;
- if (PL_my_cxt_size) {
- Newx(PL_my_cxt_list, PL_my_cxt_size, void *);
- Copy(proto_perl->Imy_cxt_list, PL_my_cxt_list, PL_my_cxt_size, void *);
-#ifdef PERL_GLOBAL_STRUCT_PRIVATE
- Newx(PL_my_cxt_keys, PL_my_cxt_size, const char *);
- Copy(proto_perl->Imy_cxt_keys, PL_my_cxt_keys, PL_my_cxt_size, char *);
-#endif
- }
- else {
- PL_my_cxt_list = (void**)NULL;
-#ifdef PERL_GLOBAL_STRUCT_PRIVATE
- PL_my_cxt_keys = (const char**)NULL;
-#endif
- }
- PL_modglobal = hv_dup_inc(proto_perl->Imodglobal, param);
- PL_custom_op_names = hv_dup_inc(proto_perl->Icustom_op_names,param);
- PL_custom_op_descs = hv_dup_inc(proto_perl->Icustom_op_descs,param);
- PL_custom_ops = hv_dup_inc(proto_perl->Icustom_ops, param);
-
PL_profiledata = NULL;
- PL_compcv = cv_dup(proto_perl->Icompcv, param);
-
- PAD_CLONE_VARS(proto_perl, param);
-
-#ifdef HAVE_INTERP_INTERN
- sys_intern_dup(&proto_perl->Isys_intern, &PL_sys_intern);
-#endif
-
- /* more statics moved here */
PL_generation = proto_perl->Igeneration;
- PL_DBcv = cv_dup(proto_perl->IDBcv, param);
PL_in_clean_objs = proto_perl->Iin_clean_objs;
PL_in_clean_all = proto_perl->Iin_clean_all;
PL_evalseq = proto_perl->Ievalseq;
PL_origenviron = proto_perl->Iorigenviron; /* XXX not quite right */
PL_origalen = proto_perl->Iorigalen;
-#ifdef PERL_USES_PL_PIDSTATUS
- PL_pidstatus = newHV(); /* XXX flag for cloning? */
-#endif
- PL_osname = SAVEPV(proto_perl->Iosname);
+
PL_sighandlerp = proto_perl->Isighandlerp;
PL_runops = proto_perl->Irunops;
- PL_parser = parser_dup(proto_perl->Iparser, param);
-
- /* XXX this only works if the saved cop has already been cloned */
- if (proto_perl->Iparser) {
- PL_parser->saved_curcop = (COP*)any_dup(
- proto_perl->Iparser->saved_curcop,
- proto_perl);
- }
-
- PL_subline = proto_perl->Isubline;
- PL_subname = sv_dup_inc(proto_perl->Isubname, param);
+ PL_subline = proto_perl->Isubline;
#ifdef FCRYPT
PL_cryptseen = proto_perl->Icryptseen;
#ifdef USE_LOCALE_COLLATE
PL_collation_ix = proto_perl->Icollation_ix;
- PL_collation_name = SAVEPV(proto_perl->Icollation_name);
PL_collation_standard = proto_perl->Icollation_standard;
PL_collxfrm_base = proto_perl->Icollxfrm_base;
PL_collxfrm_mult = proto_perl->Icollxfrm_mult;
#endif /* USE_LOCALE_COLLATE */
#ifdef USE_LOCALE_NUMERIC
- PL_numeric_name = SAVEPV(proto_perl->Inumeric_name);
PL_numeric_standard = proto_perl->Inumeric_standard;
PL_numeric_local = proto_perl->Inumeric_local;
- PL_numeric_radix_sv = sv_dup_inc(proto_perl->Inumeric_radix_sv, param);
#endif /* !USE_LOCALE_NUMERIC */
- /* utf8 character classes */
- PL_utf8_alnum = sv_dup_inc(proto_perl->Iutf8_alnum, param);
- PL_utf8_ascii = sv_dup_inc(proto_perl->Iutf8_ascii, param);
- PL_utf8_alpha = sv_dup_inc(proto_perl->Iutf8_alpha, param);
- PL_utf8_space = sv_dup_inc(proto_perl->Iutf8_space, param);
- PL_utf8_cntrl = sv_dup_inc(proto_perl->Iutf8_cntrl, param);
- PL_utf8_graph = sv_dup_inc(proto_perl->Iutf8_graph, param);
- PL_utf8_digit = sv_dup_inc(proto_perl->Iutf8_digit, param);
- PL_utf8_upper = sv_dup_inc(proto_perl->Iutf8_upper, param);
- PL_utf8_lower = sv_dup_inc(proto_perl->Iutf8_lower, param);
- PL_utf8_print = sv_dup_inc(proto_perl->Iutf8_print, param);
- PL_utf8_punct = sv_dup_inc(proto_perl->Iutf8_punct, param);
- PL_utf8_xdigit = sv_dup_inc(proto_perl->Iutf8_xdigit, param);
- PL_utf8_mark = sv_dup_inc(proto_perl->Iutf8_mark, param);
- PL_utf8_X_begin = sv_dup_inc(proto_perl->Iutf8_X_begin, param);
- PL_utf8_X_extend = sv_dup_inc(proto_perl->Iutf8_X_extend, param);
- PL_utf8_X_prepend = sv_dup_inc(proto_perl->Iutf8_X_prepend, param);
- PL_utf8_X_non_hangul = sv_dup_inc(proto_perl->Iutf8_X_non_hangul, param);
- PL_utf8_X_L = sv_dup_inc(proto_perl->Iutf8_X_L, param);
- PL_utf8_X_LV = sv_dup_inc(proto_perl->Iutf8_X_LV, param);
- PL_utf8_X_LVT = sv_dup_inc(proto_perl->Iutf8_X_LVT, param);
- PL_utf8_X_T = sv_dup_inc(proto_perl->Iutf8_X_T, param);
- PL_utf8_X_V = sv_dup_inc(proto_perl->Iutf8_X_V, param);
- PL_utf8_X_LV_LVT_V = sv_dup_inc(proto_perl->Iutf8_X_LV_LVT_V, param);
- PL_utf8_toupper = sv_dup_inc(proto_perl->Iutf8_toupper, param);
- PL_utf8_totitle = sv_dup_inc(proto_perl->Iutf8_totitle, param);
- PL_utf8_tolower = sv_dup_inc(proto_perl->Iutf8_tolower, param);
- PL_utf8_tofold = sv_dup_inc(proto_perl->Iutf8_tofold, param);
- PL_utf8_idstart = sv_dup_inc(proto_perl->Iutf8_idstart, param);
- PL_utf8_xidstart = sv_dup_inc(proto_perl->Iutf8_xidstart, param);
- PL_utf8_idcont = sv_dup_inc(proto_perl->Iutf8_idcont, param);
- PL_utf8_xidcont = sv_dup_inc(proto_perl->Iutf8_xidcont, param);
- PL_utf8_foldable = hv_dup_inc(proto_perl->Iutf8_foldable, param);
-
/* Did the locale setup indicate UTF-8? */
PL_utf8locale = proto_perl->Iutf8locale;
/* Unicode features (see perlrun/-C) */
PL_glob_index = proto_perl->Iglob_index;
PL_srand_called = proto_perl->Isrand_called;
+ if (flags & CLONEf_COPY_STACKS) {
+ /* next allocation will be PL_tmps_stack[PL_tmps_ix+1] */
+ PL_tmps_ix = proto_perl->Itmps_ix;
+ PL_tmps_max = proto_perl->Itmps_max;
+ PL_tmps_floor = proto_perl->Itmps_floor;
+
+ /* next push_scope()/ENTER sets PL_scopestack[PL_scopestack_ix]
+ * NOTE: unlike the others! */
+ PL_scopestack_ix = proto_perl->Iscopestack_ix;
+ PL_scopestack_max = proto_perl->Iscopestack_max;
+
+ /* next SSPUSHFOO() sets PL_savestack[PL_savestack_ix]
+ * NOTE: unlike the others! */
+ PL_savestack_ix = proto_perl->Isavestack_ix;
+ PL_savestack_max = proto_perl->Isavestack_max;
+ }
+
+ PL_start_env = proto_perl->Istart_env; /* XXXXXX */
+ PL_top_env = &PL_start_env;
+
+ PL_op = proto_perl->Iop;
+
+ PL_Sv = NULL;
+ PL_Xpv = (XPV*)NULL;
+ my_perl->Ina = proto_perl->Ina;
+
+ PL_statbuf = proto_perl->Istatbuf;
+ PL_statcache = proto_perl->Istatcache;
+
+#ifdef HAS_TIMES
+ PL_timesbuf = proto_perl->Itimesbuf;
+#endif
+
+ PL_tainted = proto_perl->Itainted;
+ PL_curpm = proto_perl->Icurpm; /* XXX No PMOP ref count */
+
+ PL_chopset = proto_perl->Ichopset; /* XXX never deallocated */
+
+ PL_restartjmpenv = proto_perl->Irestartjmpenv;
+ PL_restartop = proto_perl->Irestartop;
+ PL_in_eval = proto_perl->Iin_eval;
+ PL_delaymagic = proto_perl->Idelaymagic;
+ PL_phase = proto_perl->Iphase;
+ PL_localizing = proto_perl->Ilocalizing;
+
+ PL_hv_fetch_ent_mh = NULL;
+ PL_modcount = proto_perl->Imodcount;
+ PL_lastgotoprobe = NULL;
+ PL_dumpindent = proto_perl->Idumpindent;
+
+ PL_efloatbuf = NULL; /* reinits on demand */
+ PL_efloatsize = 0; /* reinits on demand */
+
+ /* regex stuff */
+
+ PL_regdummy = proto_perl->Iregdummy;
+ PL_colorset = 0; /* reinits PL_colors[] */
+ /*PL_colors[6] = {0,0,0,0,0,0};*/
+
+ /* Pluggable optimizer */
+ PL_peepp = proto_perl->Ipeepp;
+ PL_rpeepp = proto_perl->Irpeepp;
+ /* op_free() hook */
+ PL_opfreehook = proto_perl->Iopfreehook;
+
+#ifdef USE_REENTRANT_API
+ /* XXX: things like -Dm will segfault here in perlio, but doing
+ * PERL_SET_CONTEXT(proto_perl);
+ * breaks too many other things
+ */
+ Perl_reentrant_init(aTHX);
+#endif
+
+ /* create SV map for pointer relocation */
+ PL_ptr_table = ptr_table_new();
+
+ /* initialize these special pointers as early as possible */
+ ptr_table_store(PL_ptr_table, &proto_perl->Isv_undef, &PL_sv_undef);
+
+ SvANY(&PL_sv_no) = new_XPVNV();
+ SvPV_set(&PL_sv_no, savepvn(PL_No, 0));
+ SvCUR_set(&PL_sv_no, 0);
+ SvLEN_set(&PL_sv_no, 1);
+ SvIV_set(&PL_sv_no, 0);
+ SvNV_set(&PL_sv_no, 0);
+ ptr_table_store(PL_ptr_table, &proto_perl->Isv_no, &PL_sv_no);
+
+ SvPV_set(&PL_sv_yes, savepvn(PL_Yes, 1));
+ SvCUR_set(&PL_sv_yes, 1);
+ SvLEN_set(&PL_sv_yes, 2);
+ SvIV_set(&PL_sv_yes, 1);
+ SvNV_set(&PL_sv_yes, 1);
+ ptr_table_store(PL_ptr_table, &proto_perl->Isv_yes, &PL_sv_yes);
+
+ /* create (a non-shared!) shared string table */
+ PL_strtab = newHV();
+ HvSHAREKEYS_off(PL_strtab);
+ hv_ksplit(PL_strtab, HvTOTALKEYS(proto_perl->Istrtab));
+ ptr_table_store(PL_ptr_table, proto_perl->Istrtab, PL_strtab);
+
+ /* These two PVs will be free'd special way so must set them same way op.c does */
+ PL_compiling.cop_stashpv = savesharedpv(PL_compiling.cop_stashpv);
+ ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_stashpv, PL_compiling.cop_stashpv);
+
+ PL_compiling.cop_file = savesharedpv(PL_compiling.cop_file);
+ ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_file, PL_compiling.cop_file);
+
+ ptr_table_store(PL_ptr_table, &proto_perl->Icompiling, &PL_compiling);
+ PL_compiling.cop_warnings = DUP_WARNINGS(PL_compiling.cop_warnings);
+ CopHINTHASH_set(&PL_compiling, cophh_copy(CopHINTHASH_get(&PL_compiling)));
+ PL_curcop = (COP*)any_dup(proto_perl->Icurcop, proto_perl);
+
+ param->stashes = newAV(); /* Setup array of objects to call clone on */
+ /* This makes no difference to the implementation, as it always pushes
+ and shifts pointers to other SVs without changing their reference
+ count, with the array becoming empty before it is freed. However, it
+ makes it conceptually clear what is going on, and will avoid some
+ work inside av.c, filling slots between AvFILL() and AvMAX() with
+ &PL_sv_undef, and SvREFCNT_dec()ing those. */
+ AvREAL_off(param->stashes);
+
+ if (!(flags & CLONEf_COPY_STACKS)) {
+ param->unreferenced = newAV();
+ }
+
+#ifdef PERLIO_LAYERS
+ /* Clone PerlIO tables as soon as we can handle general xx_dup() */
+ PerlIO_clone(aTHX_ proto_perl, param);
+#endif
+
+ PL_envgv = gv_dup(proto_perl->Ienvgv, param);
+ PL_incgv = gv_dup(proto_perl->Iincgv, param);
+ PL_hintgv = gv_dup(proto_perl->Ihintgv, param);
+ PL_origfilename = SAVEPV(proto_perl->Iorigfilename);
+ PL_diehook = sv_dup_inc(proto_perl->Idiehook, param);
+ PL_warnhook = sv_dup_inc(proto_perl->Iwarnhook, param);
+
+ /* switches */
+ PL_patchlevel = sv_dup_inc(proto_perl->Ipatchlevel, param);
+ PL_apiversion = sv_dup_inc(proto_perl->Iapiversion, param);
+ PL_inplace = SAVEPV(proto_perl->Iinplace);
+ PL_e_script = sv_dup_inc(proto_perl->Ie_script, param);
+
+ /* magical thingies */
+ PL_formfeed = sv_dup(proto_perl->Iformfeed, param);
+
+ PL_encoding = sv_dup(proto_perl->Iencoding, param);
+
+ sv_setpvs(PERL_DEBUG_PAD(0), ""); /* For regex debugging. */
+ sv_setpvs(PERL_DEBUG_PAD(1), ""); /* ext/re needs these */
+ sv_setpvs(PERL_DEBUG_PAD(2), ""); /* even without DEBUGGING. */
+
+
+ /* Clone the regex array */
+ /* ORANGE FIXME for plugins, probably in the SV dup code.
+ newSViv(PTR2IV(CALLREGDUPE(
+ INT2PTR(REGEXP *, SvIVX(regex)), param))))
+ */
+ PL_regex_padav = av_dup_inc(proto_perl->Iregex_padav, param);
+ PL_regex_pad = AvARRAY(PL_regex_padav);
+
+ /* shortcuts to various I/O objects */
+ PL_ofsgv = gv_dup_inc(proto_perl->Iofsgv, param);
+ PL_stdingv = gv_dup(proto_perl->Istdingv, param);
+ PL_stderrgv = gv_dup(proto_perl->Istderrgv, param);
+ PL_defgv = gv_dup(proto_perl->Idefgv, param);
+ PL_argvgv = gv_dup(proto_perl->Iargvgv, param);
+ PL_argvoutgv = gv_dup(proto_perl->Iargvoutgv, param);
+ PL_argvout_stack = av_dup_inc(proto_perl->Iargvout_stack, param);
+
+ /* shortcuts to regexp stuff */
+ PL_replgv = gv_dup(proto_perl->Ireplgv, param);
+
+ /* shortcuts to misc objects */
+ PL_errgv = gv_dup(proto_perl->Ierrgv, param);
+
+ /* shortcuts to debugging objects */
+ PL_DBgv = gv_dup(proto_perl->IDBgv, param);
+ PL_DBline = gv_dup(proto_perl->IDBline, param);
+ PL_DBsub = gv_dup(proto_perl->IDBsub, param);
+ PL_DBsingle = sv_dup(proto_perl->IDBsingle, param);
+ PL_DBtrace = sv_dup(proto_perl->IDBtrace, param);
+ PL_DBsignal = sv_dup(proto_perl->IDBsignal, param);
+
+ /* symbol tables */
+ PL_defstash = hv_dup_inc(proto_perl->Idefstash, param);
+ PL_curstash = hv_dup(proto_perl->Icurstash, param);
+ PL_debstash = hv_dup(proto_perl->Idebstash, param);
+ PL_globalstash = hv_dup(proto_perl->Iglobalstash, param);
+ PL_curstname = sv_dup_inc(proto_perl->Icurstname, param);
+
+ PL_beginav = av_dup_inc(proto_perl->Ibeginav, param);
+ PL_beginav_save = av_dup_inc(proto_perl->Ibeginav_save, param);
+ PL_checkav_save = av_dup_inc(proto_perl->Icheckav_save, param);
+ PL_unitcheckav = av_dup_inc(proto_perl->Iunitcheckav, param);
+ PL_unitcheckav_save = av_dup_inc(proto_perl->Iunitcheckav_save, param);
+ PL_endav = av_dup_inc(proto_perl->Iendav, param);
+ PL_checkav = av_dup_inc(proto_perl->Icheckav, param);
+ PL_initav = av_dup_inc(proto_perl->Iinitav, param);
+
+ PL_isarev = hv_dup_inc(proto_perl->Iisarev, param);
+
+ /* subprocess state */
+ PL_fdpid = av_dup_inc(proto_perl->Ifdpid, param);
+
+ if (proto_perl->Iop_mask)
+ PL_op_mask = SAVEPVN(proto_perl->Iop_mask, PL_maxo);
+ else
+ PL_op_mask = NULL;
+ /* PL_asserting = proto_perl->Iasserting; */
+
+ /* current interpreter roots */
+ PL_main_cv = cv_dup_inc(proto_perl->Imain_cv, param);
+ OP_REFCNT_LOCK;
+ PL_main_root = OpREFCNT_inc(proto_perl->Imain_root);
+ OP_REFCNT_UNLOCK;
+
+ /* runtime control stuff */
+ PL_curcopdb = (COP*)any_dup(proto_perl->Icurcopdb, proto_perl);
+
+ PL_preambleav = av_dup_inc(proto_perl->Ipreambleav, param);
+
+ PL_ors_sv = sv_dup_inc(proto_perl->Iors_sv, param);
+
+ /* interpreter atexit processing */
+ PL_exitlistlen = proto_perl->Iexitlistlen;
+ if (PL_exitlistlen) {
+ Newx(PL_exitlist, PL_exitlistlen, PerlExitListEntry);
+ Copy(proto_perl->Iexitlist, PL_exitlist, PL_exitlistlen, PerlExitListEntry);
+ }
+ else
+ PL_exitlist = (PerlExitListEntry*)NULL;
+
+ PL_my_cxt_size = proto_perl->Imy_cxt_size;
+ if (PL_my_cxt_size) {
+ Newx(PL_my_cxt_list, PL_my_cxt_size, void *);
+ Copy(proto_perl->Imy_cxt_list, PL_my_cxt_list, PL_my_cxt_size, void *);
+#ifdef PERL_GLOBAL_STRUCT_PRIVATE
+ Newx(PL_my_cxt_keys, PL_my_cxt_size, const char *);
+ Copy(proto_perl->Imy_cxt_keys, PL_my_cxt_keys, PL_my_cxt_size, char *);
+#endif
+ }
+ else {
+ PL_my_cxt_list = (void**)NULL;
+#ifdef PERL_GLOBAL_STRUCT_PRIVATE
+ PL_my_cxt_keys = (const char**)NULL;
+#endif
+ }
+ PL_modglobal = hv_dup_inc(proto_perl->Imodglobal, param);
+ PL_custom_op_names = hv_dup_inc(proto_perl->Icustom_op_names,param);
+ PL_custom_op_descs = hv_dup_inc(proto_perl->Icustom_op_descs,param);
+ PL_custom_ops = hv_dup_inc(proto_perl->Icustom_ops, param);
+
+ PL_compcv = cv_dup(proto_perl->Icompcv, param);
+
+ PAD_CLONE_VARS(proto_perl, param);
+
+#ifdef HAVE_INTERP_INTERN
+ sys_intern_dup(&proto_perl->Isys_intern, &PL_sys_intern);
+#endif
+
+ PL_DBcv = cv_dup(proto_perl->IDBcv, param);
+
+#ifdef PERL_USES_PL_PIDSTATUS
+ PL_pidstatus = newHV(); /* XXX flag for cloning? */
+#endif
+ PL_osname = SAVEPV(proto_perl->Iosname);
+ PL_parser = parser_dup(proto_perl->Iparser, param);
+
+ /* XXX this only works if the saved cop has already been cloned */
+ if (proto_perl->Iparser) {
+ PL_parser->saved_curcop = (COP*)any_dup(
+ proto_perl->Iparser->saved_curcop,
+ proto_perl);
+ }
+
+ PL_subname = sv_dup_inc(proto_perl->Isubname, param);
+
+#ifdef USE_LOCALE_COLLATE
+ PL_collation_name = SAVEPV(proto_perl->Icollation_name);
+#endif /* USE_LOCALE_COLLATE */
+
+#ifdef USE_LOCALE_NUMERIC
+ PL_numeric_name = SAVEPV(proto_perl->Inumeric_name);
+ PL_numeric_radix_sv = sv_dup_inc(proto_perl->Inumeric_radix_sv, param);
+#endif /* !USE_LOCALE_NUMERIC */
+
+ /* utf8 character classes */
+ PL_utf8_alnum = sv_dup_inc(proto_perl->Iutf8_alnum, param);
+ PL_utf8_alpha = sv_dup_inc(proto_perl->Iutf8_alpha, param);
+ PL_utf8_space = sv_dup_inc(proto_perl->Iutf8_space, param);
+ PL_utf8_graph = sv_dup_inc(proto_perl->Iutf8_graph, param);
+ PL_utf8_digit = sv_dup_inc(proto_perl->Iutf8_digit, param);
+ PL_utf8_upper = sv_dup_inc(proto_perl->Iutf8_upper, param);
+ PL_utf8_lower = sv_dup_inc(proto_perl->Iutf8_lower, param);
+ PL_utf8_print = sv_dup_inc(proto_perl->Iutf8_print, param);
+ PL_utf8_punct = sv_dup_inc(proto_perl->Iutf8_punct, param);
+ PL_utf8_xdigit = sv_dup_inc(proto_perl->Iutf8_xdigit, param);
+ PL_utf8_mark = sv_dup_inc(proto_perl->Iutf8_mark, param);
+ PL_utf8_X_begin = sv_dup_inc(proto_perl->Iutf8_X_begin, param);
+ PL_utf8_X_extend = sv_dup_inc(proto_perl->Iutf8_X_extend, param);
+ PL_utf8_X_prepend = sv_dup_inc(proto_perl->Iutf8_X_prepend, param);
+ PL_utf8_X_non_hangul = sv_dup_inc(proto_perl->Iutf8_X_non_hangul, param);
+ PL_utf8_X_L = sv_dup_inc(proto_perl->Iutf8_X_L, param);
+ PL_utf8_X_LV = sv_dup_inc(proto_perl->Iutf8_X_LV, param);
+ PL_utf8_X_LVT = sv_dup_inc(proto_perl->Iutf8_X_LVT, param);
+ PL_utf8_X_T = sv_dup_inc(proto_perl->Iutf8_X_T, param);
+ PL_utf8_X_V = sv_dup_inc(proto_perl->Iutf8_X_V, param);
+ PL_utf8_X_LV_LVT_V = sv_dup_inc(proto_perl->Iutf8_X_LV_LVT_V, param);
+ PL_utf8_toupper = sv_dup_inc(proto_perl->Iutf8_toupper, param);
+ PL_utf8_totitle = sv_dup_inc(proto_perl->Iutf8_totitle, param);
+ PL_utf8_tolower = sv_dup_inc(proto_perl->Iutf8_tolower, param);
+ PL_utf8_tofold = sv_dup_inc(proto_perl->Iutf8_tofold, param);
+ PL_utf8_idstart = sv_dup_inc(proto_perl->Iutf8_idstart, param);
+ PL_utf8_xidstart = sv_dup_inc(proto_perl->Iutf8_xidstart, param);
+ PL_utf8_perl_idstart = sv_dup_inc(proto_perl->Iutf8_perl_idstart, param);
+ PL_utf8_idcont = sv_dup_inc(proto_perl->Iutf8_idcont, param);
+ PL_utf8_xidcont = sv_dup_inc(proto_perl->Iutf8_xidcont, param);
+ PL_utf8_foldable = sv_dup_inc(proto_perl->Iutf8_foldable, param);
+
+
if (proto_perl->Ipsig_pend) {
Newxz(PL_psig_pend, SIG_SIZE, int);
}
PL_psig_name = (SV**)NULL;
}
- /* intrpvar.h stuff */
-
if (flags & CLONEf_COPY_STACKS) {
- /* next allocation will be PL_tmps_stack[PL_tmps_ix+1] */
- PL_tmps_ix = proto_perl->Itmps_ix;
- PL_tmps_max = proto_perl->Itmps_max;
- PL_tmps_floor = proto_perl->Itmps_floor;
Newx(PL_tmps_stack, PL_tmps_max, SV*);
sv_dup_inc_multiple(proto_perl->Itmps_stack, PL_tmps_stack,
PL_tmps_ix+1, param);
/* next push_scope()/ENTER sets PL_scopestack[PL_scopestack_ix]
* NOTE: unlike the others! */
- PL_scopestack_ix = proto_perl->Iscopestack_ix;
- PL_scopestack_max = proto_perl->Iscopestack_max;
Newxz(PL_scopestack, PL_scopestack_max, I32);
Copy(proto_perl->Iscopestack, PL_scopestack, PL_scopestack_ix, I32);
- proto_perl->Istack_base);
PL_stack_max = PL_stack_base + AvMAX(PL_curstack);
- /* next SSPUSHFOO() sets PL_savestack[PL_savestack_ix]
- * NOTE: unlike the others! */
- PL_savestack_ix = proto_perl->Isavestack_ix;
- PL_savestack_max = proto_perl->Isavestack_max;
/*Newxz(PL_savestack, PL_savestack_max, ANY);*/
PL_savestack = ss_dup(proto_perl, param);
}
ENTER; /* perl_destruct() wants to LEAVE; */
}
- PL_start_env = proto_perl->Istart_env; /* XXXXXX */
- PL_top_env = &PL_start_env;
-
- PL_op = proto_perl->Iop;
-
- PL_Sv = NULL;
- PL_Xpv = (XPV*)NULL;
- my_perl->Ina = proto_perl->Ina;
-
- PL_statbuf = proto_perl->Istatbuf;
- PL_statcache = proto_perl->Istatcache;
PL_statgv = gv_dup(proto_perl->Istatgv, param);
PL_statname = sv_dup_inc(proto_perl->Istatname, param);
-#ifdef HAS_TIMES
- PL_timesbuf = proto_perl->Itimesbuf;
-#endif
- PL_tainted = proto_perl->Itainted;
- PL_curpm = proto_perl->Icurpm; /* XXX No PMOP ref count */
PL_rs = sv_dup_inc(proto_perl->Irs, param);
PL_last_in_gv = gv_dup(proto_perl->Ilast_in_gv, param);
PL_defoutgv = gv_dup_inc(proto_perl->Idefoutgv, param);
- PL_chopset = proto_perl->Ichopset; /* XXX never deallocated */
PL_toptarget = sv_dup_inc(proto_perl->Itoptarget, param);
PL_bodytarget = sv_dup_inc(proto_perl->Ibodytarget, param);
PL_formtarget = sv_dup(proto_perl->Iformtarget, param);
- PL_restartjmpenv = proto_perl->Irestartjmpenv;
- PL_restartop = proto_perl->Irestartop;
- PL_in_eval = proto_perl->Iin_eval;
- PL_delaymagic = proto_perl->Idelaymagic;
- PL_phase = proto_perl->Iphase;
- PL_localizing = proto_perl->Ilocalizing;
-
PL_errors = sv_dup_inc(proto_perl->Ierrors, param);
- PL_hv_fetch_ent_mh = NULL;
- PL_modcount = proto_perl->Imodcount;
- PL_lastgotoprobe = NULL;
- PL_dumpindent = proto_perl->Idumpindent;
PL_sortcop = (OP*)any_dup(proto_perl->Isortcop, proto_perl);
PL_sortstash = hv_dup(proto_perl->Isortstash, param);
PL_firstgv = gv_dup(proto_perl->Ifirstgv, param);
PL_secondgv = gv_dup(proto_perl->Isecondgv, param);
- PL_efloatbuf = NULL; /* reinits on demand */
- PL_efloatsize = 0; /* reinits on demand */
-
- /* regex stuff */
-
- PL_screamfirst = NULL;
- PL_screamnext = NULL;
- PL_maxscream = -1; /* reinits on demand */
- PL_lastscream = NULL;
-
-
- PL_regdummy = proto_perl->Iregdummy;
- PL_colorset = 0; /* reinits PL_colors[] */
- /*PL_colors[6] = {0,0,0,0,0,0};*/
-
-
-
- /* Pluggable optimizer */
- PL_peepp = proto_perl->Ipeepp;
- PL_rpeepp = proto_perl->Irpeepp;
- /* op_free() hook */
- PL_opfreehook = proto_perl->Iopfreehook;
PL_stashcache = newHV();
keysv, index, subscript_type);
}
+ case OP_RV2SV:
+ if (cUNOPx(obase)->op_first->op_type == OP_GV) {
+ /* $global */
+ gv = cGVOPx_gv(cUNOPx(obase)->op_first);
+ if (!gv || !GvSTASH(gv))
+ break;
+ if (match && (GvSV(gv) != uninit_sv))
+ break;
+ return varname(gv, '$', 0, NULL, 0, FUV_SUBSCRIPT_NONE);
+ }
+ /* ${expr} */
+ return find_uninit_var(cUNOPx(obase)->op_first, uninit_sv, 1);
+
case OP_PADSV:
if (match && PAD_SVl(obase->op_targ) != uninit_sv)
break;
break;
return varname(gv, '$', 0, NULL, 0, FUV_SUBSCRIPT_NONE);
- case OP_AELEMFAST:
- if (obase->op_flags & OPf_SPECIAL) { /* lexical array */
- if (match) {
- SV **svp;
- AV *av = MUTABLE_AV(PAD_SV(obase->op_targ));
- if (!av || SvRMAGICAL(av))
- break;
- svp = av_fetch(av, (I32)obase->op_private, FALSE);
- if (!svp || *svp != uninit_sv)
- break;
- }
- return varname(NULL, '$', obase->op_targ,
- NULL, (I32)obase->op_private, FUV_SUBSCRIPT_ARRAY);
+ case OP_AELEMFAST_LEX:
+ if (match) {
+ SV **svp;
+ AV *av = MUTABLE_AV(PAD_SV(obase->op_targ));
+ if (!av || SvRMAGICAL(av))
+ break;
+ svp = av_fetch(av, (I32)obase->op_private, FALSE);
+ if (!svp || *svp != uninit_sv)
+ break;
}
- else {
+ return varname(NULL, '$', obase->op_targ,
+ NULL, (I32)obase->op_private, FUV_SUBSCRIPT_ARRAY);
+ case OP_AELEMFAST:
+ {
gv = cGVOPx_gv(obase);
if (!gv)
break;
case OP_AELEM:
case OP_HELEM:
+ {
+ bool negate = FALSE;
+
if (PL_op == obase)
/* $a[uninit_expr] or $h{uninit_expr} */
return find_uninit_var(cBINOPx(obase)->op_last, uninit_sv, match);
if (!sv)
break;
+ if (kid && kid->op_type == OP_NEGATE) {
+ negate = TRUE;
+ kid = cUNOPx(kid)->op_first;
+ }
+
if (kid && kid->op_type == OP_CONST && SvOK(cSVOPx_sv(kid))) {
/* index is constant */
+ SV* kidsv;
+ if (negate) {
+ kidsv = sv_2mortal(newSVpvs("-"));
+ sv_catsv(kidsv, cSVOPx_sv(kid));
+ }
+ else
+ kidsv = cSVOPx_sv(kid);
if (match) {
if (SvMAGICAL(sv))
break;
if (obase->op_type == OP_HELEM) {
- HE* he = hv_fetch_ent(MUTABLE_HV(sv), cSVOPx_sv(kid), 0, 0);
+ HE* he = hv_fetch_ent(MUTABLE_HV(sv), kidsv, 0, 0);
if (!he || HeVAL(he) != uninit_sv)
break;
}
else {
- SV * const * const svp = av_fetch(MUTABLE_AV(sv), SvIV(cSVOPx_sv(kid)), FALSE);
+ SV * const * const svp = av_fetch(MUTABLE_AV(sv),
+ negate ? - SvIV(cSVOPx_sv(kid)) : SvIV(cSVOPx_sv(kid)),
+ FALSE);
if (!svp || *svp != uninit_sv)
break;
}
}
if (obase->op_type == OP_HELEM)
return varname(gv, '%', o->op_targ,
- cSVOPx_sv(kid), 0, FUV_SUBSCRIPT_HASH);
+ kidsv, 0, FUV_SUBSCRIPT_HASH);
else
return varname(gv, '@', o->op_targ, NULL,
- SvIV(cSVOPx_sv(kid)), FUV_SUBSCRIPT_ARRAY);
+ negate ? - SvIV(cSVOPx_sv(kid)) : SvIV(cSVOPx_sv(kid)),
+ FUV_SUBSCRIPT_ARRAY);
}
else {
/* index is an expression;
o->op_targ, NULL, 0, FUV_SUBSCRIPT_WITHIN);
}
break;
+ }
case OP_AASSIGN:
/* only examine RHS */
case OP_ENTEREVAL: /* could be eval $undef or $x='$undef'; eval $x */
- case OP_RV2SV:
case OP_CUSTOM: /* XS or custom code could trigger random warnings */
/* the following ops are capable of returning PL_sv_undef even for