X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Magic.xs;h=65858173557c76dd7977609b65b4dc462af8df5c;hb=e8fc00c8574346d926269a64ac51d5da2ad2019e;hp=dfce918d55c300915f07bcf212a47e538912462d;hpb=8bbf0ce9dd377b7b16d442d8b6a51769bf78416c;p=perl%2Fmodules%2FVariable-Magic.git diff --git a/Magic.xs b/Magic.xs index dfce918..6585817 100644 --- a/Magic.xs +++ b/Magic.xs @@ -546,13 +546,10 @@ STATIC int vmg_svt_set(pTHX_ SV *sv, MAGIC *mg) { STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { SV *svr; - I32 len, has_array; - U32 ret; + U32 len, ret; + svtype t = SvTYPE(sv); dSP; - int count; - - has_array = SvTYPE(sv) == SVt_PVAV; ENTER; SAVETMPS; @@ -561,16 +558,24 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { EXTEND(SP, 3); PUSHs(sv_2mortal(newRV_inc(sv))); PUSHs(mg->mg_obj ? mg->mg_obj : &PL_sv_undef); - if (has_array) { + if (t < SVt_PVAV) { + STRLEN l; + U8 *s = (U8 *) SvPV_const(sv, l); + if (DO_UTF8(sv)) + len = utf8_length(s, s + l); + else + len = l; + mPUSHu(len); + } else if (t == SVt_PVAV) { len = av_len((AV *) sv) + 1; - mPUSHi(len); + mPUSHu(len); } else { len = 0; PUSHs(&PL_sv_undef); } PUTBACK; - count = call_sv(SV2MGWIZ(mg->mg_ptr)->cb_len, G_SCALAR); + call_sv(SV2MGWIZ(mg->mg_ptr)->cb_len, G_SCALAR); SPAGAIN; svr = POPs; @@ -580,7 +585,7 @@ STATIC U32 vmg_svt_len(pTHX_ SV *sv, MAGIC *mg) { FREETMPS; LEAVE; - return has_array ? ret - 1 : ret; + return t == SVt_PVAV ? ret - 1 : ret; } STATIC int vmg_svt_clear(pTHX_ SV *sv, MAGIC *mg) { @@ -595,7 +600,7 @@ STATIC int vmg_svt_free(pTHX_ SV *sv, MAGIC *mg) { if (SvTYPE(wiz) == SVTYPEMASK) return 0; - /* So that it can survive tmp cleanup in vmg_cb_call */ + /* So that it survives the temp cleanup in vmg_cb_call */ SvREFCNT_inc(sv); #if !VMG_HAS_PERL_MAINT(5, 11, 0, 32686) @@ -605,14 +610,14 @@ STATIC int vmg_svt_free(pTHX_ SV *sv, MAGIC *mg) { SvMAGIC_set(sv, mg); #endif - /* Perl_mg_free will get rid of the magic and decrement mg->mg_obj and - * mg->mg_ptr reference count */ ret = vmg_cb_call1e(SV2MGWIZ(wiz)->cb_free, sv, mg->mg_obj); /* Calling SvREFCNT_dec() will trigger destructors in an infinite loop, so * we have to rely on SvREFCNT() being a lvalue. Heck, even the core does it */ --SvREFCNT(sv); + /* Perl_mg_free will get rid of the magic and decrement mg->mg_obj and + * mg->mg_ptr reference count */ return ret; } @@ -695,7 +700,7 @@ STATIC I32 vmg_svt_val(pTHX_ IV action, SV *sv) { continue; case 2: if (!newkey) - newkey = key = umg->mg_obj = sv_2mortal(newSVsv(umg->mg_obj)); + newkey = key = umg->mg_obj = sv_mortalcopy(umg->mg_obj); } switch (action) { case 0: @@ -972,13 +977,14 @@ BOOT: newCONSTSUB(stash, "VMG_THREADSAFE", newSVuv(VMG_THREADSAFE)); } +#if VMG_THREADSAFE + void CLONE(...) PROTOTYPE: DISABLE PREINIT: HV *hv; CODE: -#if VMG_THREADSAFE { HE *key; dMY_CXT; @@ -1001,6 +1007,7 @@ CODE: MY_CXT_CLONE; MY_CXT = hv; } + #endif /* VMG_THREADSAFE */ SV *_wizard(...)