X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;ds=sidebyside;f=Types.xs;h=a01cc1525e7208324f0eb6ab243d6b5118124bf6;hb=fbe95a2d759869fa1c790eb26d9dab02a27c8651;hp=f3ce903ecbdbc9fc6953312c8cbc465b3b48f957;hpb=1a89808e0eb3e27e0d2b61d0bfa84fa8ab94b9cb;p=perl%2Fmodules%2FLexical-Types.git diff --git a/Types.xs b/Types.xs index f3ce903..a01cc15 100644 --- a/Types.xs +++ b/Types.xs @@ -319,9 +319,14 @@ STATIC perl_mutex lt_op_map_mutex; #endif typedef struct { +#if LT_MULTIPLICITY + STRLEN buf_size, orig_pkg_len, type_pkg_len, type_meth_len; + char *buf; +#else /* LT_MULTIPLICITY */ SV *orig_pkg; SV *type_pkg; SV *type_meth; +#endif /* !LT_MULTIPLICITY */ OP *(*pp_padsv)(pTHX); } lt_op_info; @@ -336,11 +341,45 @@ STATIC void lt_map_store(pPTBLMS_ const OP *o, SV *orig_pkg, SV *type_pkg, SV *t if (!(oi = ptable_fetch(lt_op_map, o))) { oi = PerlMemShared_malloc(sizeof *oi); ptable_map_store(lt_op_map, o, oi); +#if LT_MULTIPLICITY + oi->buf = NULL; + oi->buf_size = 0; +#else /* LT_MULTIPLICITY */ + } else { + SvREFCNT_dec(oi->orig_pkg); + SvREFCNT_dec(oi->type_pkg); + SvREFCNT_dec(oi->type_meth); +#endif /* !LT_MULTIPLICITY */ } +#if LT_MULTIPLICITY + { + STRLEN op_len = SvCUR(orig_pkg); + STRLEN tp_len = SvCUR(type_pkg); + STRLEN tm_len = SvCUR(type_meth); + STRLEN new_buf_size = op_len + tp_len + tm_len; + char *buf; + if (new_buf_size > oi->buf_size) { + PerlMemShared_free(oi->buf); + oi->buf = PerlMemShared_malloc(new_buf_size); + oi->buf_size = new_buf_size; + } + buf = oi->buf; + Copy(SvPVX(orig_pkg), buf, op_len, char); + buf += op_len; + Copy(SvPVX(type_pkg), buf, tp_len, char); + buf += tp_len; + Copy(SvPVX(type_meth), buf, tm_len, char); + oi->orig_pkg_len = op_len; + oi->type_pkg_len = tp_len; + oi->type_meth_len = tm_len; + } +#else /* LT_MULTIPLICITY */ oi->orig_pkg = orig_pkg; oi->type_pkg = type_pkg; oi->type_meth = type_meth; +#endif /* !LT_MULTIPLICITY */ + oi->pp_padsv = pp_padsv; #ifdef USE_ITHREADS @@ -393,20 +432,40 @@ STATIC OP *lt_pp_padsv(pTHX) { SV *sv = PAD_SVl(targ); if (sv) { + SV *orig_pkg, *type_pkg, *type_meth; int items; dSP; ENTER; SAVETMPS; +#if LT_MULTIPLICITY + { + STRLEN op_len = oi.orig_pkg_len, tp_len = oi.type_pkg_len; + char *buf = oi.buf; + orig_pkg = sv_2mortal(newSVpvn(buf, op_len)); + SvREADONLY_on(orig_pkg); + buf += op_len; + type_pkg = sv_2mortal(newSVpvn(buf, tp_len)); + SvREADONLY_on(type_pkg); + buf += tp_len; + type_meth = sv_2mortal(newSVpvn(buf, oi.type_meth_len)); + SvREADONLY_on(type_meth); + } +#else /* LT_MULTIPLICITY */ + orig_pkg = oi.orig_pkg; + type_pkg = oi.type_pkg; + type_meth = oi.type_meth; +#endif /* !LT_MULTIPLICITY */ + PUSHMARK(SP); EXTEND(SP, 3); - PUSHs(oi.type_pkg); + PUSHs(type_pkg); PUSHs(sv); - PUSHs(oi.orig_pkg); + PUSHs(orig_pkg); PUTBACK; - items = call_sv(oi.type_meth, G_ARRAY | G_METHOD); + items = call_sv(type_meth, G_ARRAY | G_METHOD); SPAGAIN; switch (items) {