X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_hot.c;h=bf33ab872a68bbf78b4bcb79a23e9331a462a298;hb=f6aff53ad72449dfefc5f6d9d303886bbb4ae545;hp=63362c45c0d9dc8ba542a59e4757c4a417d275fe;hpb=a5f75d667838e8e7bb037880391f5c44476d33b4;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_hot.c b/pp_hot.c index 63362c4..bf33ab8 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -252,8 +252,13 @@ PP(pp_preinc) { dSP; if (SvIOK(TOPs)) { - ++SvIVX(TOPs); - SvFLAGS(TOPs) &= ~(SVf_NOK|SVf_POK|SVp_NOK|SVp_POK); + if (SvIVX(TOPs) == IV_MAX) { + sv_setnv(TOPs, (double)(SvIVX(TOPs)) + 1.0 ); + } + else { + ++SvIVX(TOPs); + SvFLAGS(TOPs) &= ~(SVf_NOK|SVf_POK|SVp_NOK|SVp_POK); + } } else sv_inc(TOPs); @@ -315,16 +320,31 @@ PP(pp_print) dSP; dMARK; dORIGMARK; GV *gv; IO *io; - register FILE *fp; + register PerlIO *fp; + MAGIC *mg; if (op->op_flags & OPf_STACKED) gv = (GV*)*++MARK; else gv = defoutgv; + if (SvMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) { + SV *sv; + + PUSHMARK(MARK-1); + *MARK = mg->mg_obj; + ENTER; + perl_call_method("PRINT", G_SCALAR); + LEAVE; + SPAGAIN; + sv = POPs; + SP = ORIGMARK; + PUSHs(sv); + RETURN; + } if (!(io = GvIO(gv))) { if (dowarn) { SV* sv = sv_newmortal(); - gv_fullname(sv,gv); + gv_fullname(sv, gv, Nullch); warn("Filehandle %s never opened", SvPV(sv,na)); } @@ -334,7 +354,7 @@ PP(pp_print) else if (!(fp = IoOFP(io))) { if (dowarn) { SV* sv = sv_newmortal(); - gv_fullname(sv,gv); + gv_fullname(sv, gv, Nullch); if (IoIFP(io)) warn("Filehandle %s opened only for input", SvPV(sv,na)); else @@ -351,7 +371,7 @@ PP(pp_print) break; MARK++; if (MARK <= SP) { - if (fwrite1(ofs, 1, ofslen, fp) == 0 || ferror(fp)) { + if (PerlIO_write(fp, ofs, ofslen) == 0 || PerlIO_error(fp)) { MARK--; break; } @@ -369,11 +389,11 @@ PP(pp_print) goto just_say_no; else { if (orslen) - if (fwrite1(ors, 1, orslen, fp) == 0 || ferror(fp)) + if (PerlIO_write(fp, ors, orslen) == 0 || PerlIO_error(fp)) goto just_say_no; if (IoFLAGS(io) & IOf_FLUSH) - if (Fflush(fp) == EOF) + if (PerlIO_flush(fp) == EOF) goto just_say_no; } } @@ -414,6 +434,8 @@ PP(pp_rv2av) } } else { + GV *gv; + if (SvTYPE(sv) != SVt_PVGV) { char *sym; @@ -433,11 +455,13 @@ PP(pp_rv2av) sym = SvPV(sv,na); if (op->op_private & HINT_STRICT_REFS) DIE(no_symref, sym, "an ARRAY"); - sv = (SV*)gv_fetchpv(sym, TRUE, SVt_PVAV); + gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVAV); + } else { + gv = (GV*)sv; } - av = GvAVn(sv); + av = GvAVn(gv); if (op->op_private & OPpLVAL_INTRO) - av = save_ary(sv); + av = save_ary(gv); if (op->op_flags & OPf_REF) { PUSHs((SV*)av); RETURN; @@ -487,6 +511,8 @@ PP(pp_rv2hv) } } else { + GV *gv; + if (SvTYPE(sv) != SVt_PVGV) { char *sym; @@ -508,11 +534,13 @@ PP(pp_rv2hv) sym = SvPV(sv,na); if (op->op_private & HINT_STRICT_REFS) DIE(no_symref, sym, "a HASH"); - sv = (SV*)gv_fetchpv(sym, TRUE, SVt_PVHV); + gv = (GV*)gv_fetchpv(sym, TRUE, SVt_PVHV); + } else { + gv = (GV*)sv; } - hv = GvHVn(sv); + hv = GvHVn(gv); if (op->op_private & OPpLVAL_INTRO) - hv = save_hash(sv); + hv = save_hash(gv); if (op->op_flags & OPf_REF) { SETs((SV*)hv); RETURN; @@ -595,7 +623,6 @@ PP(pp_aassign) } break; case SVt_PVHV: { - char *tmps; SV *tmpstr; hash = (HV*)sv; @@ -608,16 +635,17 @@ PP(pp_aassign) sv = *(relem++); else sv = &sv_no, relem++; - tmps = SvPV(sv, len); tmpstr = NEWSV(29,0); if (*relem) sv_setsv(tmpstr,*relem); /* value */ *(relem++) = tmpstr; - (void)hv_store(hash,tmps,len,tmpstr,0); + (void)hv_store_ent(hash,sv,tmpstr,0); if (magic) mg_set(tmpstr); tainted = 0; } + if (relem == lastrelem) + warn("Odd number of elements in hash list"); } break; default: @@ -809,7 +837,7 @@ play_it_again: } else if (!multiline) { if (*SvPVX(pm->op_pmshort) != *s || - bcmp(SvPVX(pm->op_pmshort), s, pm->op_pmslen) ) { + memcmp(SvPVX(pm->op_pmshort), s, pm->op_pmslen) ) { if (pm->op_pmflags & PMf_FOLD) { if (ibcmp((U8*)SvPVX(pm->op_pmshort), (U8*)s, pm->op_pmslen) ) goto nope; @@ -936,10 +964,22 @@ do_readline() register SV *sv; STRLEN tmplen = 0; STRLEN offset; - FILE *fp; + PerlIO *fp; register IO *io = GvIO(last_in_gv); register I32 type = op->op_type; + MAGIC *mg; + if (SvMAGICAL(last_in_gv) && (mg = mg_find((SV*)last_in_gv, 'q'))) { + PUSHMARK(SP); + XPUSHs(mg->mg_obj); + PUTBACK; + ENTER; + perl_call_method("READLINE", GIMME); + LEAVE; + SPAGAIN; + if (GIMME == G_SCALAR) sv_setsv(TARG, TOPs); + RETURN; + } fp = Nullfp; if (io) { fp = IoIFP(io); @@ -976,7 +1016,7 @@ do_readline() char *rstr = rslt + sizeof(unsigned short int), *begin, *end, *cp; char tmpfnam[L_tmpnam] = "SYS$SCRATCH:"; $DESCRIPTOR(dfltdsc,"SYS$DISK:[]*.*;"); - FILE *tmpfp; + PerlIO *tmpfp; STRLEN i; struct dsc$descriptor_s wilddsc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0}; @@ -1006,7 +1046,7 @@ do_readline() break; } } - if ((tmpfp = fopen(tmpfnam,"w+","fop=dlt")) != NULL) { + if ((tmpfp = PerlIO_open(tmpfnam,"w+","fop=dlt")) != NULL) { ok = ((wilddsc.dsc$a_pointer = tovmsspec(SvPVX(tmpglob),vmsspec)) != NULL); if (ok) wilddsc.dsc$w_length = (unsigned short int) strlen(wilddsc.dsc$a_pointer); while (ok && ((sts = lib$find_file(&wilddsc,&rsdsc,&cxt, @@ -1016,7 +1056,7 @@ do_readline() *(end++) = '\n'; *end = '\0'; for (cp = rstr; *cp; cp++) *cp = _tolower(*cp); if (hasdir) { - if (isunix) trim_unixpath(SvPVX(tmpglob),rstr); + if (isunix) trim_unixpath(rstr,SvPVX(tmpglob)); begin = rstr; } else { @@ -1024,7 +1064,7 @@ do_readline() while (*(--begin) != ']' && *begin != '>') ; ++begin; } - ok = (fputs(begin,tmpfp) != EOF); + ok = (PerlIO_puts(tmpfp,begin) != EOF); } if (cxt) (void)lib$find_file_end(&cxt); if (ok && sts != RMS$_NMF && @@ -1033,11 +1073,11 @@ do_readline() if (!(sts & 1)) { SETERRNO((sts == RMS$_SYN ? EINVAL : EVMSERR),sts); } - fclose(tmpfp); + PerlIO_close(tmpfp); fp = NULL; } else { - rewind(tmpfp); + PerlIO_rewind(tmpfp); IoTYPE(io) = '<'; IoIFP(io) = fp = tmpfp; } @@ -1045,11 +1085,17 @@ do_readline() } #else /* !VMS */ #ifdef DOSISH +#ifdef OS2 + sv_setpv(tmpcmd, "for a in "); + sv_catsv(tmpcmd, tmpglob); + sv_catpv(tmpcmd, "; do echo \"$a\\0\\c\"; done |"); +#else sv_setpv(tmpcmd, "perlglob "); sv_catsv(tmpcmd, tmpglob); sv_catpv(tmpcmd, " |"); -#else -#ifdef CSH +#endif /* !OS2 */ +#else /* !DOSISH */ +#if defined(CSH) sv_setpvn(tmpcmd, cshname, cshlen); sv_catpv(tmpcmd, " -cf 'set nonomatch; glob "); sv_catsv(tmpcmd, tmpglob); @@ -1063,7 +1109,7 @@ do_readline() sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\n\\n\\n\\n'|"); #endif #endif /* !CSH */ -#endif /* !MSDOS */ +#endif /* !DOSISH */ (void)do_open(last_in_gv, SvPVX(tmpcmd), SvCUR(tmpcmd), FALSE, 0, 0, Nullfp); fp = IoIFP(io); @@ -1100,7 +1146,7 @@ do_readline() } for (;;) { if (!sv_gets(sv, fp, offset)) { - clearerr(fp); + PerlIO_clearerr(fp); if (IoFLAGS(io) & IOf_ARGV) { fp = nextargv(last_in_gv); if (fp) @@ -1191,25 +1237,23 @@ PP(pp_enter) PP(pp_helem) { dSP; - SV** svp; + HE* he; SV *keysv = POPs; - STRLEN keylen; - char *key = SvPV(keysv, keylen); HV *hv = (HV*)POPs; I32 lval = op->op_flags & OPf_MOD; if (SvTYPE(hv) != SVt_PVHV) RETPUSHUNDEF; - svp = hv_fetch(hv, key, keylen, lval); + he = hv_fetch_ent(hv, keysv, lval, 0); if (lval) { - if (!svp || *svp == &sv_undef) - DIE(no_helem, key); + if (!he || HeVAL(he) == &sv_undef) + DIE(no_helem, SvPV(keysv, na)); if (op->op_private & OPpLVAL_INTRO) - save_svref(svp); + save_svref(&HeVAL(he)); else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV)) - provide_ref(op, *svp); + provide_ref(op, HeVAL(he)); } - PUSHs(svp ? *svp : &sv_undef); + PUSHs(he ? HeVAL(he) : &sv_undef); RETURN; } @@ -1278,7 +1322,7 @@ PP(pp_iter) if (cx->cx_type != CXt_LOOP) DIE("panic: pp_iter"); av = cx->blk_loop.iterary; - if (av == stack && cx->blk_loop.iterix >= cx->blk_oldsp) + if (av == curstack && cx->blk_loop.iterix >= cx->blk_oldsp) RETPUSHNO; if (cx->blk_loop.iterix >= AvFILL(av)) @@ -1368,7 +1412,7 @@ PP(pp_subst) } else if (!multiline) { if (*SvPVX(pm->op_pmshort) != *s || - bcmp(SvPVX(pm->op_pmshort), s, pm->op_pmslen) ) { + memcmp(SvPVX(pm->op_pmshort), s, pm->op_pmslen) ) { if (pm->op_pmflags & PMf_FOLD) { if (ibcmp((U8*)SvPVX(pm->op_pmshort), (U8*)s, pm->op_pmslen) ) goto nope; @@ -1647,6 +1691,7 @@ PP(pp_entersub) register CV *cv; register CONTEXT *cx; I32 gimme; + I32 hasargs = (op->op_flags & OPf_STACKED) != 0; if (!sv) DIE("Not a CODE reference"); @@ -1701,7 +1746,7 @@ PP(pp_entersub) goto retry; } tmpstr = sv_newmortal(); - gv_efullname(tmpstr, gv); + gv_efullname(tmpstr, gv, Nullch); ngv = gv_fetchmethod(GvESTASH(gv), "AUTOLOAD"); if (ngv && ngv != gv && (cv = GvCV(ngv))) { /* One more chance... */ gv = ngv; @@ -1717,18 +1762,20 @@ PP(pp_entersub) } gimme = GIMME; - if ((op->op_private & OPpENTERSUB_DB) && !CvXSUB(cv)) { + if ((op->op_private & OPpENTERSUB_DB)) { sv = GvSV(DBsub); save_item(sv); - if (CvFLAGS(cv) & (CVf_ANON | CVf_CLONED)) { + gv = CvGV(cv); + if ( CvFLAGS(cv) & (CVf_ANON | CVf_CLONED) + || strEQ(GvNAME(gv), "END") ) { /* GV is potentially non-unique */ sv_setsv(sv, newRV((SV*)cv)); } else { - gv = CvGV(cv); - gv_efullname(sv,gv); + gv_efullname(sv, gv, Nullch); } cv = GvCV(DBsub); + if (CvXSUB(cv)) curcopdb = curcop; if (!cv) DIE("No DBsub routine"); } @@ -1738,6 +1785,7 @@ PP(pp_entersub) I32 (*fp3)_((int,int,int)); dMARK; register I32 items = SP - MARK; + /* We dont worry to copy from @_. */ while (sp > mark) { sp[1] = sp[0]; sp--; @@ -1753,6 +1801,30 @@ PP(pp_entersub) I32 markix = TOPMARK; PUTBACK; + + if (!hasargs) { + /* Need to copy @_ to stack. Alternative may be to + * switch stack to @_, and copy return values + * back. This would allow popping @_ in XSUB, e.g.. XXXX */ + AV* av = GvAV(defgv); + I32 items = AvFILL(av) + 1; + + if (items) { + /* Mark is at the end of the stack. */ + EXTEND(sp, items); + Copy(AvARRAY(av), sp + 1, items, SV*); + sp += items; + PUTBACK ; + } + } + if (curcopdb) { /* We assume that the first + XSUB in &DB::sub is the + called one. */ + SAVESPTR(curcop); + curcop = curcopdb; + curcopdb = NULL; + } + /* Do we need to open block here? XXXX */ (void)(*CvXSUB(cv))(cv); /* Enforce some sanity in scalar context. */ @@ -1770,7 +1842,6 @@ PP(pp_entersub) else { dMARK; register I32 items = SP - MARK; - I32 hasargs = (op->op_flags & OPf_STACKED) != 0; AV* padlist = CvPADLIST(cv); SV** svp = AvARRAY(padlist); push_return(op->op_next); @@ -1922,9 +1993,10 @@ PP(pp_method) else { GV* iogv; char* packname = 0; + STRLEN packlen; if (!SvOK(sv) || - !(packname = SvPV(sv, na)) || + !(packname = SvPV(sv, packlen)) || !(iogv = gv_fetchpv(packname, FALSE, SVt_PVIO)) || !(ob=(SV*)GvIO(iogv))) { @@ -1932,9 +2004,9 @@ PP(pp_method) HV *stash; if (!packname || !isALPHA(*packname)) DIE("Can't call method \"%s\" without a package or object reference", name); - if (!(stash = gv_stashpv(packname, FALSE))) { - if (gv_stashpv("UNIVERSAL", FALSE)) - stash = gv_stashpv(packname, TRUE); + if (!(stash = gv_stashpvn(packname, packlen, FALSE))) { + if (gv_stashpvn("UNIVERSAL", 9, FALSE)) + stash = gv_stashpvn(packname, packlen, TRUE); else DIE("Can't call method \"%s\" in empty package \"%s\"", name, packname); @@ -1943,10 +2015,10 @@ DIE("Can't call method \"%s\" without a package or object reference", name); if (!gv) DIE("Can't locate object method \"%s\" via package \"%s\"", name, packname); - SETs(gv); + SETs((SV*)gv); RETURN; } - *(stack_base + TOPMARK + 1) = sv_2mortal(newRV(iogv)); + *(stack_base + TOPMARK + 1) = sv_2mortal(newRV((SV*)iogv)); } if (!ob || !SvOBJECT(ob)) { @@ -1962,7 +2034,7 @@ DIE("Can't call method \"%s\" without a package or object reference", name); name, HvNAME(SvSTASH(ob))); } - SETs(gv); + SETs((SV*)gv); RETURN; }