STATIC void
S_more_xpviv(pTHX)
{
- XPVIV* xpviv;
- XPVIV* xpvivend;
- New(714, xpviv, PERL_ARENA_SIZE/sizeof(XPVIV), XPVIV);
- *((XPVIV**)xpviv) = PL_xpviv_arenaroot;
+ xpviv_allocated* xpviv;
+ xpviv_allocated* xpvivend;
+ New(713, xpviv, PERL_ARENA_SIZE/sizeof(xpviv_allocated), xpviv_allocated);
+ *((xpviv_allocated**)xpviv) = PL_xpviv_arenaroot;
PL_xpviv_arenaroot = xpviv;
- xpvivend = &xpviv[PERL_ARENA_SIZE / sizeof(XPVIV) - 1];
+ xpvivend = &xpviv[PERL_ARENA_SIZE / sizeof(xpviv_allocated) - 1];
PL_xpviv_root = ++xpviv;
while (xpviv < xpvivend) {
- *((XPVIV**)xpviv) = xpviv + 1;
+ *((xpviv_allocated**)xpviv) = xpviv + 1;
xpviv++;
}
- *((XPVIV**)xpviv) = 0;
+ *((xpviv_allocated**)xpviv) = 0;
}
/* allocate another arena's worth of struct xpvnv */
STATIC XPVIV*
S_new_xpviv(pTHX)
{
- XPVIV* xpviv;
+ xpviv_allocated* xpviv;
LOCK_SV_MUTEX;
if (!PL_xpviv_root)
S_more_xpviv(aTHX);
xpviv = PL_xpviv_root;
- PL_xpviv_root = *(XPVIV**)xpviv;
+ PL_xpviv_root = *(xpviv_allocated**)xpviv;
UNLOCK_SV_MUTEX;
- return xpviv;
+ /* If xpviv_allocated is the same structure as XPVIV then the two OFFSETs
+ sum to zero, and the pointer is unchanged. If the allocated structure
+ is smaller (no initial IV actually allocated) then the net effect is
+ to subtract the size of the IV from the pointer, to return a new pointer
+ as if an initial IV were actually allocated. */
+ return (XPVIV*)((char*)xpviv - STRUCT_OFFSET(XPVIV, xpv_cur)
+ + STRUCT_OFFSET(xpviv_allocated, xpv_cur));
}
/* return a struct xpviv to the free list */
STATIC void
S_del_xpviv(pTHX_ XPVIV *p)
{
+ xpviv_allocated* xpviv
+ = (xpviv_allocated*)((char*)(p) + STRUCT_OFFSET(XPVIV, xpv_cur)
+ - STRUCT_OFFSET(xpviv_allocated, xpv_cur));
LOCK_SV_MUTEX;
- *(XPVIV**)p = PL_xpviv_root;
- PL_xpviv_root = p;
+ *(xpviv_allocated**)xpviv = PL_xpviv_root;
+ PL_xpviv_root = xpviv;
UNLOCK_SV_MUTEX;
}
case SVt_NULL:
Perl_croak(aTHX_ "Can't upgrade to undef");
case SVt_IV:
- SvANY(sv) = (XPVIV*)((char*)&(sv->sv_u.sv_iv) - STRUCT_OFFSET(XPVIV, xiv_iv));
+ SvANY(sv) = (XPVIV*)((char*)&(sv->sv_u.svu_iv) - STRUCT_OFFSET(XPVIV, xiv_iv));
SvIV_set(sv, iv);
break;
case SVt_NV:
SvNV_set(sv, nv);
break;
case SVt_RV:
- SvANY(sv) = &sv->sv_u.sv_rv;
+ SvANY(sv) = &sv->sv_u.svu_rv;
SvRV_set(sv, (SV*)pv);
break;
case SVt_PVHV:
if (SvPOKp(sv)) {
register XPV* Xpvtmp;
if ((Xpvtmp = (XPV*)SvANY(sv)) &&
- (*sv->sv_u.sv_pv > '0' ||
+ (*sv->sv_u.svu_pv > '0' ||
Xpvtmp->xpv_cur > 1 ||
- (Xpvtmp->xpv_cur && *sv->sv_u.sv_pv != '0')))
+ (Xpvtmp->xpv_cur && *sv->sv_u.svu_pv != '0')))
return 1;
else
return 0;
it would be unclear. */
if(SvTYPE(sv) == SVt_IV)
SvANY(sv)
- = (XPVIV*)((char*)&(sv->sv_u.sv_iv) - STRUCT_OFFSET(XPVIV, xiv_iv));
+ = (XPVIV*)((char*)&(sv->sv_u.svu_iv) - STRUCT_OFFSET(XPVIV, xiv_iv));
else if (SvTYPE(sv) == SVt_RV) {
- SvANY(sv) = &sv->sv_u.sv_rv;
+ SvANY(sv) = &sv->sv_u.svu_rv;
}
const register XPV* tXpv;
if ((tXpv = (XPV*)SvANY(sv)) &&
(tXpv->xpv_cur > 1 ||
- (tXpv->xpv_cur && *sv->sv_u.sv_pv != '0')))
+ (tXpv->xpv_cur && *sv->sv_u.svu_pv != '0')))
return 1;
else
return 0;
SvANY(dstr) = NULL;
break;
case SVt_IV:
- SvANY(dstr) = (XPVIV*)((char*)&(dstr->sv_u.sv_iv) - STRUCT_OFFSET(XPVIV, xiv_iv));
+ SvANY(dstr) = (XPVIV*)((char*)&(dstr->sv_u.svu_iv) - STRUCT_OFFSET(XPVIV, xiv_iv));
SvIV_set(dstr, SvIVX(sstr));
break;
case SVt_NV:
SvNV_set(dstr, SvNVX(sstr));
break;
case SVt_RV:
- SvANY(dstr) = &(dstr->sv_u.sv_rv);
+ SvANY(dstr) = &(dstr->sv_u.svu_rv);
Perl_rvpv_dup(aTHX_ dstr, sstr, param);
break;
case SVt_PV:
SvMAGIC_set(dstr, mg_dup(SvMAGIC(sstr), param));
SvSTASH_set(dstr, hv_dup_inc(SvSTASH(sstr), param));
{
- const char *hvname = HvNAME_get((HV*)sstr);
struct xpvhv_aux *aux = ((XPVHV *)SvANY(sstr))->xhv_aux;
+ HEK *hvname = 0;
- ((XPVHV *)SvANY(dstr))->xhv_aux = 0;
if (aux) {
- HvRITER_set((HV*)dstr, HvRITER_get((HV*)sstr));
- /* FIXME strlen HvNAME */
- Perl_hv_name_set(aTHX_ (HV*) dstr, hvname,
- hvname ? strlen(hvname) : 0,
- 0);
+ I32 riter = aux->xhv_riter;
+
+ hvname = aux->xhv_name;
+ if (hvname || riter != -1) {
+ struct xpvhv_aux *d_aux;
+
+ New(0, d_aux, 1, struct xpvhv_aux);
+
+ d_aux->xhv_riter = riter;
+ d_aux->xhv_eiter = 0;
+ d_aux->xhv_name = hvname ? hek_dup(hvname, param) : hvname;
+
+ ((XPVHV *)SvANY(dstr))->xhv_aux = d_aux;
+ } else {
+ ((XPVHV *)SvANY(dstr))->xhv_aux = 0;
+ }
+ }
+ else {
+ ((XPVHV *)SvANY(dstr))->xhv_aux = 0;
}
if (HvARRAY((HV*)sstr)) {
STRLEN i = 0;
const char *hvname = HvNAME_get((HV*)sv);
if (hvname) {
GV* cloner = gv_fetchmethod_autoload((HV*)sv, "CLONE_SKIP", 0);
+ STRLEN len = HvNAMELEN_get((HV*)sv);
SvFLAGS(sv) |= SVphv_CLONEABLE; /* clone objects by default */
if (cloner && GvCV(cloner)) {
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
- XPUSHs(sv_2mortal(newSVpv(hvname, 0)));
+ XPUSHs(sv_2mortal(newSVpvn(hvname, len)));
PUTBACK;
call_sv((SV*)GvCV(cloner), G_SCALAR);
SPAGAIN;
/* create (a non-shared!) shared string table */
PL_strtab = newHV();
HvSHAREKEYS_off(PL_strtab);
- hv_ksplit(PL_strtab, 512);
+ hv_ksplit(PL_strtab, HvTOTALKEYS(proto_perl->Istrtab));
ptr_table_store(PL_ptr_table, proto_perl->Istrtab, PL_strtab);
PL_compiling = proto_perl->Icompiling;
ENTER;
SAVETMPS;
PUSHMARK(SP);
- XPUSHs(sv_2mortal(newSVpv(HvNAME_get(stash), 0)));
+ XPUSHs(sv_2mortal(newSVpvn(HvNAME_get(stash), HvNAMELEN_get(stash))));
PUTBACK;
call_sv((SV*)GvCV(cloner), G_DISCARD);
FREETMPS;