From: Gurusamy Sarathy Date: Mon, 8 Nov 1999 18:50:40 +0000 (+0000) Subject: preliminary support for GVOP indirection via pad X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=350de78d9c02710bb008e9ca922c78ba251ec366;p=p5sagit%2Fp5-mst-13.2.git preliminary support for GVOP indirection via pad p4raw-id: //depot/perl@4539 --- diff --git a/doio.c b/doio.c index 16cff29..02d74b9 100644 --- a/doio.c +++ b/doio.c @@ -1064,7 +1064,7 @@ Perl_my_stat(pTHX) if (PL_op->op_flags & OPf_REF) { EXTEND(SP,1); - tmpgv = (GV*)cSVOP->op_sv; + tmpgv = cGVOP; do_fstat: io = GvIO(tmpgv); if (io && IoIFP(io)) { @@ -1117,7 +1117,7 @@ Perl_my_lstat(pTHX) STRLEN n_a; if (PL_op->op_flags & OPf_REF) { EXTEND(SP,1); - if ((GV*)cSVOP->op_sv == PL_defgv) { + if (cGVOP == PL_defgv) { if (PL_laststype != OP_LSTAT) Perl_croak(aTHX_ "The stat preceding -l _ wasn't an lstat"); return PL_laststatval; diff --git a/dump.c b/dump.c index 3881003..076811d 100644 --- a/dump.c +++ b/dump.c @@ -512,11 +512,11 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, OP *o) switch (o->op_type) { case OP_GVSV: case OP_GV: - if (cSVOPo->op_sv) { + if (cGVOPo) { SV *tmpsv = NEWSV(0,0); ENTER; SAVEFREESV(tmpsv); - gv_fullname3(tmpsv, (GV*)cSVOPo->op_sv, Nullch); + gv_fullname3(tmpsv, (GV*)cGVOPo, Nullch); Perl_dump_indent(aTHX_ level, file, "GV = %s\n", SvPV(tmpsv, n_a)); LEAVE; } diff --git a/embed.h b/embed.h index 781a539..3307585 100644 --- a/embed.h +++ b/embed.h @@ -437,6 +437,7 @@ #define newHVhv Perl_newHVhv #define newIO Perl_newIO #define newLISTOP Perl_newLISTOP +#define newPADOP Perl_newPADOP #define newPMOP Perl_newPMOP #define newPVOP Perl_newPVOP #define newRV Perl_newRV @@ -1813,6 +1814,7 @@ #define newHVhv(a) Perl_newHVhv(aTHX_ a) #define newIO() Perl_newIO(aTHX) #define newLISTOP(a,b,c,d) Perl_newLISTOP(aTHX_ a,b,c,d) +#define newPADOP(a,b,c) Perl_newPADOP(aTHX_ a,b,c) #define newPMOP(a,b) Perl_newPMOP(aTHX_ a,b) #define newPVOP(a,b,c) Perl_newPVOP(aTHX_ a,b,c) #define newRV(a) Perl_newRV(aTHX_ a) @@ -3552,6 +3554,8 @@ #define newIO Perl_newIO #define Perl_newLISTOP CPerlObj::Perl_newLISTOP #define newLISTOP Perl_newLISTOP +#define Perl_newPADOP CPerlObj::Perl_newPADOP +#define newPADOP Perl_newPADOP #define Perl_newPMOP CPerlObj::Perl_newPMOP #define newPMOP Perl_newPMOP #define Perl_newPVOP CPerlObj::Perl_newPVOP diff --git a/embed.pl b/embed.pl index 514ba82..07bed66 100755 --- a/embed.pl +++ b/embed.pl @@ -1404,6 +1404,7 @@ p |HV* |newHV p |HV* |newHVhv |HV* hv p |IO* |newIO p |OP* |newLISTOP |I32 type|I32 flags|OP* first|OP* last +p |OP* |newPADOP |I32 type|I32 flags|SV* sv p |OP* |newPMOP |I32 type|I32 flags p |OP* |newPVOP |I32 type|I32 flags|char* pv p |SV* |newRV |SV* pref diff --git a/global.sym b/global.sym index add1fe9..b6596b6 100644 --- a/global.sym +++ b/global.sym @@ -358,6 +358,7 @@ Perl_newHV Perl_newHVhv Perl_newIO Perl_newLISTOP +Perl_newPADOP Perl_newPMOP Perl_newPVOP Perl_newRV diff --git a/objXSUB.h b/objXSUB.h index 168f547..c90b984 100644 --- a/objXSUB.h +++ b/objXSUB.h @@ -2263,6 +2263,10 @@ #define Perl_newLISTOP pPerl->Perl_newLISTOP #undef newLISTOP #define newLISTOP Perl_newLISTOP +#undef Perl_newPADOP +#define Perl_newPADOP pPerl->Perl_newPADOP +#undef newPADOP +#define newPADOP Perl_newPADOP #undef Perl_newPMOP #define Perl_newPMOP pPerl->Perl_newPMOP #undef newPMOP diff --git a/op.c b/op.c index 6fd669a..fadd4b3 100644 --- a/op.c +++ b/op.c @@ -717,8 +717,13 @@ S_op_clear(pTHX_ OP *o) case OP_GVSV: case OP_GV: case OP_AELEMFAST: - SvREFCNT_dec(cSVOPo->op_sv); + SvREFCNT_dec(cGVOPo); +#ifdef USE_ITHREADS + pad_free(cPADOPo->op_padix); + cPADOPo->op_padix = 0; +#else cSVOPo->op_sv = Nullsv; +#endif break; case OP_CONST: SvREFCNT_dec(cSVOPo->op_sv); @@ -1357,7 +1362,7 @@ Perl_mod(pTHX_ OP *o, I32 type) break; } - cv = GvCV((GV*)kSVOP->op_sv); + cv = GvCV(kGVOP); if (!cv) goto restore_2cv; if (CvLVALUE(cv)) @@ -2815,7 +2820,7 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl) } #else if (curop->op_type == OP_GV) { - GV *gv = (GV*)((SVOP*)curop)->op_sv; + GV *gv = cGVOPx(curop); repl_has_vars = 1; if (strchr("&`'123456789+", *GvENAME(gv))) break; @@ -2896,10 +2901,32 @@ Perl_newSVOP(pTHX_ I32 type, I32 flags, SV *sv) } OP * +Perl_newPADOP(pTHX_ I32 type, I32 flags, SV *sv) +{ + PADOP *padop; + NewOp(1101, padop, 1, PADOP); + padop->op_type = type; + padop->op_ppaddr = PL_ppaddr[type]; + padop->op_padix = pad_alloc(type, SVs_PADTMP); + PL_curpad[padop->op_padix] = sv; + padop->op_next = (OP*)padop; + padop->op_flags = flags; + if (PL_opargs[type] & OA_RETSCALAR) + scalar((OP*)padop); + if (PL_opargs[type] & OA_TARGET) + padop->op_targ = pad_alloc(type, SVs_PADTMP); + return CHECKOP(type, padop); +} + +OP * Perl_newGVOP(pTHX_ I32 type, I32 flags, GV *gv) { dTHR; +#ifdef USE_ITHREADS + return newPADOP(type, flags, SvREFCNT_inc(gv)); +#else return newSVOP(type, flags, SvREFCNT_inc(gv)); +#endif } OP * @@ -3138,7 +3165,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) for (curop = LINKLIST(o); curop != o; curop = LINKLIST(curop)) { if (PL_opargs[curop->op_type] & OA_DANGEROUS) { if (curop->op_type == OP_GV) { - GV *gv = (GV*)((SVOP*)curop)->op_sv; + GV *gv = cGVOPx(curop); if (gv == PL_defgv || SvCUR(gv) == PL_generation) break; SvCUR(gv) = PL_generation; @@ -3190,7 +3217,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) { tmpop = ((UNOP*)left)->op_first; if (tmpop->op_type == OP_GV && !pm->op_pmreplroot) { - pm->op_pmreplroot = (OP*)((SVOP*)tmpop)->op_sv; + pm->op_pmreplroot = (OP*)((SVOP*)tmpop)->op_sv; /* XXXXXX */ pm->op_pmflags |= PMf_ONCE; tmpop = cUNOPo->op_first; /* to list (nulled) */ tmpop = ((UNOP*)tmpop)->op_first; /* to pushmark */ @@ -5004,7 +5031,13 @@ Perl_ck_rvconst(pTHX_ register OP *o) if (gv) { kid->op_type = OP_GV; SvREFCNT_dec(kid->op_sv); +#ifdef USE_ITHREADS + /* XXXXXX hack: dependence on sizeof(PADOP) <= sizeof(SVOP) */ + kPADOP->op_padix = pad_alloc(OP_GV, SVs_PADTMP); + PL_curpad[kPADOP->op_padix] = SvREFCNT_inc(gv); +#else kid->op_sv = SvREFCNT_inc(gv); +#endif kid->op_ppaddr = PL_ppaddr[OP_GV]; } } @@ -5678,6 +5711,7 @@ S_simplify_sort(pTHX_ OP *o) register OP *kid = cLISTOPo->op_first->op_sibling; /* get past pushmark */ OP *k; int reversed; + GV *gv; if (!(o->op_flags & OPf_STACKED)) return; GvMULTI_on(gv_fetchpv("a", TRUE, SVt_PV)); @@ -5701,11 +5735,12 @@ S_simplify_sort(pTHX_ OP *o) if (kUNOP->op_first->op_type != OP_GV) return; kid = kUNOP->op_first; /* get past rv2sv */ - if (GvSTASH((GV*)kSVOP->op_sv) != PL_curstash) + gv = kGVOP; + if (GvSTASH(gv) != PL_curstash) return; - if (strEQ(GvNAME((GV*)kSVOP->op_sv), "a")) + if (strEQ(GvNAME(gv), "a")) reversed = 0; - else if(strEQ(GvNAME((GV*)kSVOP->op_sv), "b")) + else if(strEQ(GvNAME(gv), "b")) reversed = 1; else return; @@ -5716,10 +5751,11 @@ S_simplify_sort(pTHX_ OP *o) if (kUNOP->op_first->op_type != OP_GV) return; kid = kUNOP->op_first; /* get past rv2sv */ - if (GvSTASH((GV*)kSVOP->op_sv) != PL_curstash + gv = kGVOP; + if (GvSTASH(gv) != PL_curstash || ( reversed - ? strNE(GvNAME((GV*)kSVOP->op_sv), "a") - : strNE(GvNAME((GV*)kSVOP->op_sv), "b"))) + ? strNE(GvNAME(gv), "a") + : strNE(GvNAME(gv), "b"))) return; o->op_flags &= ~(OPf_STACKED | OPf_SPECIAL); if (reversed) @@ -5825,11 +5861,12 @@ Perl_ck_subr(pTHX_ OP *o) null(cvop); /* disable rv2cv */ tmpop = (SVOP*)((UNOP*)cvop)->op_first; if (tmpop->op_type == OP_GV && !(o->op_private & OPpENTERSUB_AMPER)) { - cv = GvCVu(tmpop->op_sv); + GV *gv = cGVOPx(tmpop); + cv = GvCVu(gv); if (!cv) tmpop->op_private |= OPpEARLY_CV; else if (SvPOK(cv)) { - namegv = CvANON(cv) ? (GV*)tmpop->op_sv : CvGV(cv); + namegv = CvANON(cv) ? gv : CvGV(cv); proto = SvPV((SV*)cv, n_a); } } @@ -5892,7 +5929,7 @@ Perl_ck_subr(pTHX_ OP *o) (gvop = ((UNOP*)gvop)->op_first) && gvop->op_type == OP_GV) { - GV *gv = (GV*)((SVOP*)gvop)->op_sv; + GV *gv = cGVOPx(gvop); OP *sibling = o2->op_sibling; SV *n = newSVpvn("",0); op_free(o2); @@ -6110,6 +6147,7 @@ Perl_peep(pTHX_ register OP *o) <= 255 && i >= 0) { + GV *gv; null(o->op_next); null(pop->op_next); null(pop); @@ -6118,11 +6156,12 @@ Perl_peep(pTHX_ register OP *o) o->op_type = OP_AELEMFAST; o->op_ppaddr = PL_ppaddr[OP_AELEMFAST]; o->op_private = (U8)i; - GvAVn((GV*)((SVOP*)o)->op_sv); + gv = cGVOPo; + GvAVn(gv); } } else if ((o->op_private & OPpEARLY_CV) && ckWARN(WARN_UNSAFE)) { - GV *gv = (GV*)cSVOPo->op_sv; + GV *gv = cGVOPo; if (SvTYPE(gv) == SVt_PVGV && GvCV(gv) && SvPVX(GvCV(gv))) { /* XXX could check prototype here instead of just carping */ SV *sv = sv_newmortal(); diff --git a/op.h b/op.h index d34435b..2129572 100644 --- a/op.h +++ b/op.h @@ -258,39 +258,68 @@ struct loop { OP * op_lastop; }; -#define cUNOP ((UNOP*)PL_op) -#define cBINOP ((BINOP*)PL_op) -#define cLISTOP ((LISTOP*)PL_op) -#define cLOGOP ((LOGOP*)PL_op) -#define cPMOP ((PMOP*)PL_op) -#define cSVOP ((SVOP*)PL_op) -#define cPADOP ((PADOP*)PL_op) -#define cPVOP ((PVOP*)PL_op) -#define cCOP ((COP*)PL_op) -#define cLOOP ((LOOP*)PL_op) - -#define cUNOPo ((UNOP*)o) -#define cBINOPo ((BINOP*)o) -#define cLISTOPo ((LISTOP*)o) -#define cLOGOPo ((LOGOP*)o) -#define cPMOPo ((PMOP*)o) -#define cSVOPo ((SVOP*)o) -#define cPADOPo ((PADOP*)o) -#define cPVOPo ((PVOP*)o) -#define cCVOPo ((CVOP*)o) -#define cCOPo ((COP*)o) -#define cLOOPo ((LOOP*)o) - -#define kUNOP ((UNOP*)kid) -#define kBINOP ((BINOP*)kid) -#define kLISTOP ((LISTOP*)kid) -#define kLOGOP ((LOGOP*)kid) -#define kPMOP ((PMOP*)kid) -#define kSVOP ((SVOP*)kid) -#define kPADOP ((PADOP*)kid) -#define kPVOP ((PVOP*)kid) -#define kCOP ((COP*)kid) -#define kLOOP ((LOOP*)kid) +#define cUNOPx(o) ((UNOP*)o) +#define cBINOPx(o) ((BINOP*)o) +#define cLISTOPx(o) ((LISTOP*)o) +#define cLOGOPx(o) ((LOGOP*)o) +#define cPMOPx(o) ((PMOP*)o) +#define cSVOPx(o) ((SVOP*)o) +#define cPADOPx(o) ((PADOP*)o) +#define cPVOPx(o) ((PVOP*)o) +#define cCOPx(o) ((COP*)o) +#define cLOOPx(o) ((LOOP*)o) + +#define cUNOP cUNOPx(PL_op) +#define cBINOP cBINOPx(PL_op) +#define cLISTOP cLISTOPx(PL_op) +#define cLOGOP cLOGOPx(PL_op) +#define cPMOP cPMOPx(PL_op) +#define cSVOP cSVOPx(PL_op) +#define cPADOP cPADOPx(PL_op) +#define cPVOP cPVOPx(PL_op) +#define cCOP cCOPx(PL_op) +#define cLOOP cLOOPx(PL_op) + +#define cUNOPo cUNOPx(o) +#define cBINOPo cBINOPx(o) +#define cLISTOPo cLISTOPx(o) +#define cLOGOPo cLOGOPx(o) +#define cPMOPo cPMOPx(o) +#define cSVOPo cSVOPx(o) +#define cPADOPo cPADOPx(o) +#define cPVOPo cPVOPx(o) +#define cCOPo cCOPx(o) +#define cLOOPo cLOOPx(o) + +#define kUNOP cUNOPx(kid) +#define kBINOP cBINOPx(kid) +#define kLISTOP cLISTOPx(kid) +#define kLOGOP cLOGOPx(kid) +#define kPMOP cPMOPx(kid) +#define kSVOP cSVOPx(kid) +#define kPADOP cPADOPx(kid) +#define kPVOP cPVOPx(kid) +#define kCOP cCOPx(kid) +#define kLOOP cLOOPx(kid) + + +#ifdef USE_ITHREADS +# define cGVOPx(o) ((GV*)PAD_SV(cPADOPx(o)->op_padix)) +# define cGVOP ((GV*)PAD_SV(cPADOP->op_padix)) +# define cGVOPo ((GV*)PAD_SV(cPADOPo->op_padix)) +# define kGVOP ((GV*)PAD_SV(kPADOP->op_padix)) +# define cGVOP_set(v) (PL_curpad[cPADOP->op_padix] = (SV*)(v)) +# define cGVOPo_set(v) (PL_curpad[cPADOPo->op_padix] = (SV*)(v)) +# define kGVOP_set(v) (PL_curpad[kPADOP->op_padix] = (SV*)(v)) +#else +# define cGVOPx(o) ((GV*)cSVOPx(o)->op_sv) +# define cGVOP ((GV*)cSVOP->op_sv) +# define cGVOPo ((GV*)cSVOPo->op_sv) +# define kGVOP ((GV*)kSVOP->op_sv) +# define cGVOP_set(v) (cPADOP->op_sv = (SV*)(v)) +# define cGVOPo_set(v) (cPADOPo->op_sv = (SV*)(v)) +# define kGVOP_set(v) (kPADOP->op_sv = (SV*)(v)) +#endif #define Nullop Null(OP*) diff --git a/opcode.pl b/opcode.pl index c9174f2..3dfca9e 100755 --- a/opcode.pl +++ b/opcode.pl @@ -183,7 +183,7 @@ END '|', 3, # logop '@', 4, # listop '/', 5, # pmop - '$', 6, # svop + '$', 6, # svop_or_padop '#', 7, # padop '"', 8, # pvop_or_svop '{', 9, # loop diff --git a/perlapi.c b/perlapi.c index cdea984..6ea713c 100644 --- a/perlapi.c +++ b/perlapi.c @@ -2636,6 +2636,13 @@ Perl_newLISTOP(pTHXo_ I32 type, I32 flags, OP* first, OP* last) return ((CPerlObj*)pPerl)->Perl_newLISTOP(type, flags, first, last); } +#undef Perl_newPADOP +OP* +Perl_newPADOP(pTHXo_ I32 type, I32 flags, SV* sv) +{ + return ((CPerlObj*)pPerl)->Perl_newPADOP(type, flags, sv); +} + #undef Perl_newPMOP OP* Perl_newPMOP(pTHXo_ I32 type, I32 flags) diff --git a/pp_hot.c b/pp_hot.c index ecaed7b..0c5fd16 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -58,9 +58,9 @@ PP(pp_gvsv) djSP; EXTEND(SP,1); if (PL_op->op_private & OPpLVAL_INTRO) - PUSHs(save_scalar((GV*)cSVOP->op_sv)); + PUSHs(save_scalar(cGVOP)); else - PUSHs(GvSV((GV*)cSVOP->op_sv)); + PUSHs(GvSV(cGVOP)); RETURN; } @@ -95,7 +95,7 @@ PP(pp_stringify) PP(pp_gv) { djSP; - XPUSHs(cSVOP->op_sv); + XPUSHs((SV*)cGVOP); RETURN; } @@ -271,7 +271,7 @@ PP(pp_add) PP(pp_aelemfast) { djSP; - AV *av = GvAV((GV*)cSVOP->op_sv); + AV *av = GvAV(cGVOP); U32 lval = PL_op->op_flags & OPf_MOD; SV** svp = av_fetch(av, PL_op->op_private, lval); SV *sv = (svp ? *svp : &PL_sv_undef); diff --git a/pp_sys.c b/pp_sys.c index 8222f18..f25e151 100644 --- a/pp_sys.c +++ b/pp_sys.c @@ -411,7 +411,7 @@ PP(pp_indread) PP(pp_rcatline) { - PL_last_in_gv = (GV*)cSVOP->op_sv; + PL_last_in_gv = cGVOP; return do_readline(); } @@ -2412,7 +2412,7 @@ PP(pp_stat) STRLEN n_a; if (PL_op->op_flags & OPf_REF) { - tmpgv = (GV*)cSVOP->op_sv; + tmpgv = cGVOP; do_fstat: if (tmpgv != PL_defgv) { PL_laststype = OP_STAT; @@ -2857,7 +2857,7 @@ PP(pp_fttty) STRLEN n_a; if (PL_op->op_flags & OPf_REF) - gv = (GV*)cSVOP->op_sv; + gv = cGVOP; else if (isGV(TOPs)) gv = (GV*)POPs; else if (SvROK(TOPs) && isGV(SvRV(TOPs))) @@ -2898,7 +2898,7 @@ PP(pp_fttext) STRLEN n_a; if (PL_op->op_flags & OPf_REF) - gv = (GV*)cSVOP->op_sv; + gv = cGVOP; else if (isGV(TOPs)) gv = (GV*)POPs; else if (SvROK(TOPs) && isGV(SvRV(TOPs))) @@ -2949,7 +2949,7 @@ PP(pp_fttext) else { if (ckWARN(WARN_UNOPENED)) Perl_warner(aTHX_ WARN_UNOPENED, "Test on unopened file <%s>", - GvENAME((GV*)cSVOP->op_sv)); + GvENAME(cGVOP)); SETERRNO(EBADF,RMS$_IFI); RETPUSHUNDEF; } diff --git a/proto.h b/proto.h index 7956898..5daeb90 100644 --- a/proto.h +++ b/proto.h @@ -397,6 +397,7 @@ PERL_CALLCONV HV* Perl_newHV(pTHX); PERL_CALLCONV HV* Perl_newHVhv(pTHX_ HV* hv); PERL_CALLCONV IO* Perl_newIO(pTHX); PERL_CALLCONV OP* Perl_newLISTOP(pTHX_ I32 type, I32 flags, OP* first, OP* last); +PERL_CALLCONV OP* Perl_newPADOP(pTHX_ I32 type, I32 flags, SV* sv); PERL_CALLCONV OP* Perl_newPMOP(pTHX_ I32 type, I32 flags); PERL_CALLCONV OP* Perl_newPVOP(pTHX_ I32 type, I32 flags, char* pv); PERL_CALLCONV SV* Perl_newRV(pTHX_ SV* pref); diff --git a/run.c b/run.c index a6391e9..8feba18 100644 --- a/run.c +++ b/run.c @@ -71,9 +71,9 @@ Perl_debop(pTHX_ OP *o) break; case OP_GVSV: case OP_GV: - if (cSVOPo->op_sv) { + if (cGVOPo) { sv = NEWSV(0,0); - gv_fullname3(sv, (GV*)cSVOPo->op_sv, Nullch); + gv_fullname3(sv, cGVOPo, Nullch); PerlIO_printf(Perl_debug_log, "(%s)", SvPV(sv, n_a)); SvREFCNT_dec(sv); }