X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=Types.xs;h=69b92e20137ff84771019adbdb5b862ca676e6fd;hb=b5122742fcc1f1f4c219d40894c9821a2debaafa;hp=518fd8f1122c37f5d51966b6270c17f02c156f3e;hpb=9cc3a83c895e5be1ac696757e27acfc6b4cecb03;p=perl%2Fmodules%2FLexical-Types.git diff --git a/Types.xs b/Types.xs index 518fd8f..69b92e2 100644 --- a/Types.xs +++ b/Types.xs @@ -411,8 +411,6 @@ STATIC SV *lt_hint(pTHX) { #define ptable_map_store(T, K, V) ptable_map_store(aPTBLMS_ (T), (K), (V)) #define ptable_map_delete(T, K) ptable_map_delete(aPTBLMS_ (T), (K)) -STATIC ptable *lt_op_map = NULL; - #ifdef USE_ITHREADS STATIC perl_mutex lt_op_map_mutex; @@ -427,7 +425,10 @@ STATIC perl_mutex lt_op_map_mutex; #endif /* !USE_ITHREADS */ +STATIC ptable *lt_op_padxv_map = NULL; + typedef struct { + OP *(*old_pp)(pTHX); #ifdef MULTIPLICITY STRLEN buf_size, orig_pkg_len, type_pkg_len, type_meth_len; char *buf; @@ -436,18 +437,72 @@ typedef struct { SV *type_pkg; SV *type_meth; #endif /* !MULTIPLICITY */ - OP *(*old_pp_padsv)(pTHX); -} lt_op_info; +} lt_op_padxv_info; + +STATIC void lt_op_padxv_info_call(pTHX_ const lt_op_padxv_info *oi, SV *sv) { +#define lt_op_padxv_info_call(O, S) lt_op_padxv_info_call(aTHX_ (O), (S)) + SV *orig_pkg, *type_pkg, *type_meth; + int items; + dSP; + + ENTER; + SAVETMPS; + +#ifdef 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 /* MULTIPLICITY */ + orig_pkg = oi->orig_pkg; + type_pkg = oi->type_pkg; + type_meth = oi->type_meth; +#endif /* !MULTIPLICITY */ + + PUSHMARK(SP); + EXTEND(SP, 3); + PUSHs(type_pkg); + PUSHs(sv); + PUSHs(orig_pkg); + PUTBACK; -STATIC void lt_map_store(pTHX_ const OP *o, SV *orig_pkg, SV *type_pkg, SV *type_meth, OP *(*old_pp_padsv)(pTHX)) { -#define lt_map_store(O, OP, TP, TM, PP) lt_map_store(aTHX_ (O), (OP), (TP), (TM), (PP)) - lt_op_info *oi; + items = call_sv(type_meth, G_ARRAY | G_METHOD); + + SPAGAIN; + switch (items) { + case 0: + break; + case 1: + sv_setsv(sv, POPs); + break; + default: + croak("Typed scalar initializer method should return zero or one scalar, but got %d", items); + } + PUTBACK; + + FREETMPS; + LEAVE; + + return; +} + +STATIC void lt_padxv_map_store(pTHX_ const OP *o, SV *orig_pkg, SV *type_pkg, SV *type_meth, OP *(*old_pp)(pTHX)) { +#define lt_padxv_map_store(O, OP, TP, TM, PP) lt_padxv_map_store(aTHX_ (O), (OP), (TP), (TM), (PP)) + lt_op_padxv_info *oi; LT_LOCK(<_op_map_mutex); - if (!(oi = ptable_fetch(lt_op_map, o))) { + if (!(oi = ptable_fetch(lt_op_padxv_map, o))) { oi = PerlMemShared_malloc(sizeof *oi); - ptable_map_store(lt_op_map, o, oi); + ptable_map_store(lt_op_padxv_map, o, oi); #ifdef MULTIPLICITY oi->buf = NULL; oi->buf_size = 0; @@ -490,17 +545,17 @@ STATIC void lt_map_store(pTHX_ const OP *o, SV *orig_pkg, SV *type_pkg, SV *type oi->type_meth = type_meth; #endif /* !MULTIPLICITY */ - oi->old_pp_padsv = old_pp_padsv; + oi->old_pp = old_pp; LT_UNLOCK(<_op_map_mutex); } -STATIC const lt_op_info *lt_map_fetch(const OP *o, lt_op_info *oi) { - const lt_op_info *val; +STATIC const lt_op_padxv_info *lt_padxv_map_fetch(const OP *o, lt_op_padxv_info *oi) { + const lt_op_padxv_info *val; LT_LOCK(<_op_map_mutex); - val = ptable_fetch(lt_op_map, o); + val = ptable_fetch(lt_op_padxv_map, o); if (val) { *oi = *val; val = oi; @@ -515,7 +570,7 @@ STATIC void lt_map_delete(pTHX_ const OP *o) { #define lt_map_delete(O) lt_map_delete(aTHX_ (O)) LT_LOCK(<_op_map_mutex); - ptable_map_delete(lt_op_map, o); + ptable_map_delete(lt_op_padxv_map, o); LT_UNLOCK(<_op_map_mutex); } @@ -525,61 +580,12 @@ STATIC void lt_map_delete(pTHX_ const OP *o) { /* ... Our pp_padsv ........................................................ */ STATIC OP *lt_pp_padsv(pTHX) { - lt_op_info oi; + lt_op_padxv_info oi; - if (lt_map_fetch(PL_op, &oi)) { - SV *orig_pkg, *type_pkg, *type_meth; - int items; - dSP; + if (lt_padxv_map_fetch(PL_op, &oi)) { dTARGET; - - ENTER; - SAVETMPS; - -#ifdef 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 /* MULTIPLICITY */ - orig_pkg = oi.orig_pkg; - type_pkg = oi.type_pkg; - type_meth = oi.type_meth; -#endif /* !MULTIPLICITY */ - - PUSHMARK(SP); - EXTEND(SP, 3); - PUSHs(type_pkg); - PUSHTARG; - PUSHs(orig_pkg); - PUTBACK; - - items = call_sv(type_meth, G_ARRAY | G_METHOD); - - SPAGAIN; - switch (items) { - case 0: - break; - case 1: - sv_setsv(TARG, POPs); - break; - default: - croak("Typed scalar initializer method should return zero or one scalar, but got %d", items); - } - PUTBACK; - - FREETMPS; - LEAVE; - - return oi.old_pp_padsv(aTHX); + lt_op_padxv_info_call(&oi, TARG); + return oi.old_pp(aTHX); } return PL_op->op_ppaddr(aTHX); @@ -662,7 +668,7 @@ STATIC OP *lt_ck_padany(pTHX_ OP *o) { SvREFCNT_inc_simple_void_NN(orig_meth); } - lt_map_store(o, orig_pkg, type_pkg, type_meth, o->op_ppaddr); + lt_padxv_map_store(o, orig_pkg, type_pkg, type_meth, o->op_ppaddr); } else { skip: lt_map_delete(o); @@ -686,8 +692,6 @@ STATIC peep_t lt_old_peep = 0; /* This is actually the rpeep past 5.13.5 */ STATIC void lt_peep_rec(pTHX_ OP *o, ptable *seen) { #define lt_peep_rec(O) lt_peep_rec(aTHX_ (O), seen) for (; o; o = o->op_next) { - lt_op_info *oi = NULL; - if (ptable_fetch(seen, o)) break; ptable_seen_store(seen, o, o); @@ -695,11 +699,12 @@ STATIC void lt_peep_rec(pTHX_ OP *o, ptable *seen) { switch (o->op_type) { case OP_PADSV: if (o->op_ppaddr != lt_pp_padsv && o->op_private & OPpLVAL_INTRO) { + lt_op_padxv_info *oi; LT_LOCK(<_op_map_mutex); - oi = ptable_fetch(lt_op_map, o); + oi = ptable_fetch(lt_op_padxv_map, o); if (oi) { - oi->old_pp_padsv = o->op_ppaddr; - o->op_ppaddr = lt_pp_padsv; + oi->old_pp = o->op_ppaddr; + o->op_ppaddr = lt_pp_padsv; } LT_UNLOCK(<_op_map_mutex); } @@ -840,7 +845,7 @@ BOOT: if (!lt_booted++) { HV *stash; - lt_op_map = ptable_new(); + lt_op_padxv_map = ptable_new(); #ifdef USE_ITHREADS MUTEX_INIT(<_op_map_mutex); #endif