} while (0)
static SV **registry;
-static I32 regsize;
+static I32 registry_size;
#define REGHASH(sv,size) ((((U32)(sv)) >> 2) % (size))
#define REG_REPLACE(sv,a,b) \
do { \
void* p = sv->sv_any; \
- I32 h = REGHASH(sv, regsize); \
+ I32 h = REGHASH(sv, registry_size); \
I32 i = h; \
while (registry[i] != (a)) { \
- if (++i >= regsize) \
+ if (++i >= registry_size) \
i = 0; \
if (i == h) \
die("SV registry bug"); \
reg_add(sv)
SV* sv;
{
- if (sv_count >= (regsize >> 1))
+ if (sv_count >= (registry_size >> 1))
{
SV **oldreg = registry;
- I32 oldsize = regsize;
+ I32 oldsize = registry_size;
- regsize = regsize ? ((regsize << 2) + 1) : 2037;
- Newz(707, registry, regsize, SV*);
+ registry_size = registry_size ? ((registry_size << 2) + 1) : 2037;
+ Newz(707, registry, registry_size, SV*);
if (oldreg) {
I32 i;
{
I32 i;
- for (i = 0; i < regsize; ++i) {
+ for (i = 0; i < registry_size; ++i) {
SV* sv = registry[i];
- if (sv)
+ if (sv && SvTYPE(sv) != SVTYPEMASK)
(*f)(sv);
}
}
DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning named glob object:\n "), sv_dump(sv));)
SvREFCNT_dec(sv);
}
- else if (GvSV(sv))
- do_clean_objs(GvSV(sv));
}
}
#endif
sv_clean_objs(void)
{
in_clean_objs = TRUE;
+ visit(FUNC_NAME_TO_PTR(do_clean_objs));
#ifndef DISABLE_DESTRUCTOR_KLUDGE
+ /* some barnacles may yet remain, clinging to typeglobs */
visit(FUNC_NAME_TO_PTR(do_clean_named_objs));
#endif
- visit(FUNC_NAME_TO_PTR(do_clean_objs));
in_clean_objs = FALSE;
}
STATIC void
do_clean_all(SV *sv)
{
- DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning loops:\n "), sv_dump(sv));)
+ DEBUG_D((PerlIO_printf(Perl_debug_log, "Cleaning loops: SV at 0x%lx\n", sv) );)
SvFLAGS(sv) |= SVf_BREAK;
SvREFCNT_dec(sv);
}
STATIC XPVIV*
new_xiv(void)
{
- IV** xiv;
+ IV* xiv;
if (xiv_root) {
xiv = xiv_root;
/*
* See comment in more_xiv() -- RAM.
*/
- xiv_root = (IV**)*xiv;
- return (XPVIV*)((char*)xiv - sizeof(XPV));
+ xiv_root = *(IV**)xiv;
+ return (XPVIV*)((char*)xiv - STRUCT_OFFSET(XPVIV, xiv_iv));
}
return more_xiv();
}
STATIC void
del_xiv(XPVIV *p)
{
- IV** xiv = (IV**)((char*)(p) + sizeof(XPV));
- *xiv = (IV *)xiv_root;
+ IV* xiv = (IV*)((char*)(p) + STRUCT_OFFSET(XPVIV, xiv_iv));
+ *(IV**)xiv = xiv_root;
xiv_root = xiv;
}
STATIC XPVIV*
more_xiv(void)
{
- register IV** xiv;
- register IV** xivend;
+ register IV* xiv;
+ register IV* xivend;
XPV* ptr;
New(705, ptr, 1008/sizeof(XPV), XPV);
ptr->xpv_pv = (char*)xiv_arenaroot; /* linked list of xiv arenas */
xiv_arenaroot = ptr; /* to keep Purify happy */
- xiv = (IV**) ptr;
- xivend = &xiv[1008 / sizeof(IV *) - 1];
- xiv += (sizeof(XPV) - 1) / sizeof(IV *) + 1; /* fudge by size of XPV */
+ xiv = (IV*) ptr;
+ xivend = &xiv[1008 / sizeof(IV) - 1];
+ xiv += (sizeof(XPV) - 1) / sizeof(IV) + 1; /* fudge by size of XPV */
xiv_root = xiv;
while (xiv < xivend) {
- *xiv = (IV *)(xiv + 1);
+ *(IV**)xiv = (IV *)(xiv + 1);
xiv++;
}
- *xiv = 0;
+ *(IV**)xiv = 0;
return new_xiv();
}
if (xnv_root) {
xnv = xnv_root;
xnv_root = *(double**)xnv;
- return (XPVNV*)((char*)xnv - sizeof(XPVIV));
+ return (XPVNV*)((char*)xnv - STRUCT_OFFSET(XPVNV, xnv_nv));
}
return more_xnv();
}
STATIC void
del_xnv(XPVNV *p)
{
- double* xnv = (double*)((char*)(p) + sizeof(XPVIV));
+ double* xnv = (double*)((char*)(p) + STRUCT_OFFSET(XPVNV, xnv_nv));
*(double**)xnv = xnv_root;
xnv_root = xnv;
}
else
s = SvPVX(sv);
if (newlen > SvLEN(sv)) { /* need more room? */
- if (SvLEN(sv) && s)
+ if (SvLEN(sv) && s) {
+#if defined(MYMALLOC) && !defined(PURIFY)
+ STRLEN l = malloced_size((void*)SvPVX(sv));
+ if (newlen <= l) {
+ SvLEN_set(sv, l);
+ return s;
+ } else
+#endif
Renew(s,newlen,char);
+ }
else
New(703,s,newlen,char);
SvPV_set(sv, s);
case SVt_PV:
case SVt_PVIV:
sv_upgrade(sv, SVt_PVNV);
- /* FALL THROUGH */
- case SVt_PVNV:
- case SVt_PVMG:
- case SVt_PVBM:
- case SVt_PVLV:
- if (SvOOK(sv))
- (void)SvOOK_off(sv);
break;
+
case SVt_PVGV:
if (SvFAKE(sv)) {
sv_unglob(sv);
if (!sv)
s = "NULLREF";
else {
+ MAGIC *mg;
+
switch (SvTYPE(sv)) {
+ case SVt_PVMG:
+ if ( ((SvFLAGS(sv) &
+ (SVs_OBJECT|SVf_OK|SVs_GMG|SVs_SMG|SVs_RMG))
+ == (SVs_OBJECT|SVs_RMG))
+ && strEQ(s=HvNAME(SvSTASH(sv)), "Regexp")
+ && (mg = mg_find(sv, 'r'))) {
+ dTHR;
+ regexp *re = (regexp *)mg->mg_obj;
+
+ if (!mg->mg_ptr) {
+ char *fptr = "msix";
+ char reflags[6];
+ char ch;
+ int left = 0;
+ int right = 4;
+ U16 reganch = (re->reganch & PMf_COMPILETIME) >> 12;
+
+ while(ch = *fptr++) {
+ if(reganch & 1) {
+ reflags[left++] = ch;
+ }
+ else {
+ reflags[right--] = ch;
+ }
+ reganch >>= 1;
+ }
+ if(left != 4) {
+ reflags[left] = '-';
+ left = 5;
+ }
+
+ mg->mg_len = re->prelen + 4 + left;
+ New(616, mg->mg_ptr, mg->mg_len + 1 + left, char);
+ Copy("(?", mg->mg_ptr, 2, char);
+ Copy(reflags, mg->mg_ptr+2, left, char);
+ Copy(":", mg->mg_ptr+left+2, 1, char);
+ Copy(re->precomp, mg->mg_ptr+3+left, re->prelen, char);
+ mg->mg_ptr[mg->mg_len - 1] = ')';
+ mg->mg_ptr[mg->mg_len] = 0;
+ }
+ reginterp_cnt += re->program[0].next_off;
+ *lp = mg->mg_len;
+ return mg->mg_ptr;
+ }
+ /* Fall through */
case SVt_NULL:
case SVt_IV:
case SVt_NV:
case SVt_PV:
case SVt_PVIV:
case SVt_PVNV:
- case SVt_PVBM:
- case SVt_PVMG: s = "SCALAR"; break;
+ case SVt_PVBM: s = "SCALAR"; break;
case SVt_PVLV: s = "LVALUE"; break;
case SVt_PVAV: s = "ARRAY"; break;
case SVt_PVHV: s = "HASH"; break;
switch (stype) {
case SVt_NULL:
+ undef_sstr:
if (dtype != SVt_PVGV) {
(void)SvOK_off(dstr);
return;
}
break;
case SVt_IV:
- if (dtype != SVt_IV && dtype < SVt_PVIV) {
- if (dtype < SVt_IV)
+ if (SvIOK(sstr)) {
+ switch (dtype) {
+ case SVt_NULL:
sv_upgrade(dstr, SVt_IV);
- else if (dtype == SVt_NV)
+ break;
+ case SVt_NV:
sv_upgrade(dstr, SVt_PVNV);
- else
+ break;
+ case SVt_RV:
+ case SVt_PV:
sv_upgrade(dstr, SVt_PVIV);
+ break;
+ }
+ (void)SvIOK_only(dstr);
+ SvIVX(dstr) = SvIVX(sstr);
+ SvTAINT(dstr);
+ return;
}
- break;
+ goto undef_sstr;
+
case SVt_NV:
- if (dtype != SVt_NV && dtype < SVt_PVNV) {
- if (dtype < SVt_NV)
+ if (SvNOK(sstr)) {
+ switch (dtype) {
+ case SVt_NULL:
+ case SVt_IV:
sv_upgrade(dstr, SVt_NV);
- else
+ break;
+ case SVt_RV:
+ case SVt_PV:
+ case SVt_PVIV:
sv_upgrade(dstr, SVt_PVNV);
+ break;
+ }
+ SvNVX(dstr) = SvNVX(sstr);
+ (void)SvNOK_only(dstr);
+ SvTAINT(dstr);
+ return;
}
- break;
+ goto undef_sstr;
+
case SVt_RV:
if (dtype < SVt_RV)
sv_upgrade(dstr, SVt_RV);
SvFAKE_on(dstr); /* can coerce to non-glob */
}
/* ahem, death to those who redefine active sort subs */
- else if (curstackinfo->si_type == SI_SORT
+ else if (curstackinfo->si_type == PERLSI_SORT
&& GvCV(dstr) && sortcop == CvSTART(GvCV(dstr)))
croak("Can't redefine active sort subroutine %s",
GvNAME(dstr));
Nullcv));
/* ahem, death to those who redefine
* active sort subs */
- if (curstackinfo->si_type == SI_SORT &&
+ if (curstackinfo->si_type == PERLSI_SORT &&
sortcop == CvSTART(cv))
croak(
"Can't redefine active sort subroutine %s",
destructor = gv_fetchmethod(SvSTASH(sv), "DESTROY");
if (destructor) {
ENTER;
- PUSHSTACK(SI_DESTROY);
+ PUSHSTACKi(PERLSI_DESTROY);
SvRV(&tmpref) = SvREFCNT_inc(sv);
EXTEND(SP, 2);
PUSHMARK(SP);
perl_call_sv((SV*)GvCV(destructor),
G_DISCARD|G_EVAL|G_KEEPERR);
SvREFCNT(sv)--;
- POPSTACK();
+ POPSTACK;
LEAVE;
}
} while (SvOBJECT(sv) && SvSTASH(sv) != stash);
case SVt_PVAV:
av_undef((AV*)sv);
break;
+ case SVt_PVLV:
+ SvREFCNT_dec(LvTARG(sv));
+ goto freescalar;
case SVt_PVGV:
gp_free((GV*)sv);
Safefree(GvNAME(sv));
-- JohnPC, 27 Mar 1998 */
stash = GvSTASH(sv);
/* FALL THROUGH */
- case SVt_PVLV:
case SVt_PVMG:
case SVt_PVNV:
case SVt_PVIV:
if (!sv)
return;
- if (SvREADONLY(sv)) {
- if (sv == &sv_undef || sv == &sv_yes || sv == &sv_no)
- return;
- }
if (SvREFCNT(sv) == 0) {
if (SvFLAGS(sv) & SVf_BREAK)
return;
if (in_clean_all) /* All is fair */
return;
+ if (SvREADONLY(sv) && SvIMMORTAL(sv)) {
+ /* make sure SvREFCNT(sv)==0 happens very seldom */
+ SvREFCNT(sv) = (~(U32)0)/2;
+ return;
+ }
warn("Attempt to free unreferenced scalar");
return;
}
return;
#ifdef DEBUGGING
if (SvTEMP(sv)) {
- warn("Attempt to free temp prematurely: %s", SvPEEK(sv));
+ warn("Attempt to free temp prematurely: SV 0x%lx", (unsigned long)sv);
return;
}
#endif
+ if (SvREADONLY(sv) && SvIMMORTAL(sv)) {
+ /* make sure SvREFCNT(sv)==0 happens very seldom */
+ SvREFCNT(sv) = (~(U32)0)/2;
+ return;
+ }
sv_clear(sv);
if (! SvREFCNT(sv))
del_SV(sv);
rsptr = NULL;
rslen = 0;
}
+ else if (RsRECORD(rs)) {
+ I32 recsize, bytesread;
+ char *buffer;
+
+ /* Grab the size of the record we're getting */
+ recsize = SvIV(SvRV(rs));
+ (void)SvPOK_only(sv); /* Validate pointer */
+ buffer = SvGROW(sv, recsize + 1);
+ /* Go yank in */
+#ifdef VMS
+ /* VMS wants read instead of fread, because fread doesn't respect */
+ /* RMS record boundaries. This is not necessarily a good thing to be */
+ /* doing, but we've got no other real choice */
+ bytesread = PerlLIO_read(PerlIO_fileno(fp), buffer, recsize);
+#else
+ bytesread = PerlIO_read(fp, buffer, recsize);
+#endif
+ SvCUR_set(sv, bytesread);
+ buffer[bytesread] = '\0';
+ return(SvCUR(sv) ? SvPVX(sv) : Nullch);
+ }
else if (RsPARA(rs)) {
rsptr = "\n\n";
rslen = 2;
croak(no_modify);
}
if (SvROK(sv)) {
+ IV i;
#ifdef OVERLOAD
- if (SvAMAGIC(sv) && AMG_CALLun(sv,inc)) return;
+ if (SvAMAGIC(sv) && AMG_CALLun(sv,inc)) return;
#endif /* OVERLOAD */
- sv_unref(sv);
+ i = (IV)SvRV(sv);
+ sv_unref(sv);
+ sv_setiv(sv, i);
}
}
if (SvGMAGICAL(sv))
croak(no_modify);
}
if (SvROK(sv)) {
+ IV i;
#ifdef OVERLOAD
- if (SvAMAGIC(sv) && AMG_CALLun(sv,dec)) return;
+ if (SvAMAGIC(sv) && AMG_CALLun(sv,dec)) return;
#endif /* OVERLOAD */
- sv_unref(sv);
+ i = (IV)SvRV(sv);
+ sv_unref(sv);
+ sv_setiv(sv, i);
}
}
if (SvGMAGICAL(sv))
dTHR;
if (!sv)
return sv;
- if (SvREADONLY(sv) && curcop != &compiling)
- croak(no_modify);
+ if (SvREADONLY(sv) && SvIMMORTAL(sv))
+ return sv;
if (++tmps_ix >= tmps_max)
sv_mortalgrow();
tmps_stack[tmps_ix] = sv;
}
SV *
-newRV(SV *tmpRef)
+newRV_noinc(SV *tmpRef)
{
dTHR;
register SV *sv;
SvFLAGS(sv) = 0;
sv_upgrade(sv, SVt_RV);
SvTEMP_off(tmpRef);
- SvRV(sv) = SvREFCNT_inc(tmpRef);
+ SvRV(sv) = tmpRef;
SvROK_on(sv);
return sv;
}
-
-
SV *
-Perl_newRV_noinc(SV *tmpRef)
+newRV(SV *tmpRef)
{
- register SV *sv;
-
- sv = newRV(tmpRef);
- SvREFCNT_dec(tmpRef);
- return sv;
+ return newRV_noinc(SvREFCNT_inc(tmpRef));
}
/* make an exact duplicate of old */