RETURN;
}
+PP(pp_gelem)
+{
+ GV *gv;
+ SV *sv;
+ SV *ref;
+ char *elem;
+ dSP;
+
+ sv = POPs;
+ elem = SvPV(sv, na);
+ gv = (GV*)POPs;
+ ref = Nullsv;
+ sv = Nullsv;
+ switch (elem ? *elem : '\0')
+ {
+ case 'A':
+ if (strEQ(elem, "ARRAY"))
+ ref = (SV*)GvAV(gv);
+ break;
+ case 'C':
+ if (strEQ(elem, "CODE"))
+ ref = (SV*)GvCV(gv);
+ break;
+ case 'F':
+ if (strEQ(elem, "FILEHANDLE"))
+ ref = (SV*)GvIOp(gv);
+ break;
+ case 'G':
+ if (strEQ(elem, "GLOB"))
+ ref = (SV*)gv;
+ break;
+ case 'H':
+ if (strEQ(elem, "HASH"))
+ ref = (SV*)GvHV(gv);
+ break;
+ case 'N':
+ if (strEQ(elem, "NAME"))
+ sv = newSVpv(GvNAME(gv), GvNAMELEN(gv));
+ break;
+ case 'P':
+ if (strEQ(elem, "PACKAGE"))
+ sv = newSVpv(HvNAME(GvSTASH(gv)), 0);
+ break;
+ case 'S':
+ if (strEQ(elem, "SCALAR"))
+ ref = GvSV(gv);
+ break;
+ }
+ if (ref)
+ sv = newRV(ref);
+ if (sv)
+ sv_2mortal(sv);
+ else
+ sv = &sv_undef;
+ XPUSHs(sv);
+ RETURN;
+}
+
PP(pp_and)
{
dSP;
s = SvPV(left,len);
sv_setpvn(TARG,s,len);
}
- else if (!SvOK(TARG))
+ else if (SvGMAGICAL(TARG))
+ mg_get(TARG);
+ else if (!SvOK(TARG)) {
+ s = SvPV_force(TARG, len);
sv_setpv(TARG, ""); /* Suppress warning. */
+ }
s = SvPV(right,len);
sv_catpvn(TARG,s,len);
SETTARG;
{
dSP; dTARGET;
XPUSHs(TARG);
- if (op->op_private & OPpLVAL_INTRO)
- SAVECLEARSV(curpad[op->op_targ]);
+ if (op->op_flags & OPf_MOD) {
+ if (op->op_private & OPpLVAL_INTRO)
+ SAVECLEARSV(curpad[op->op_targ]);
+ else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV))
+ provide_ref(op, curpad[op->op_targ]);
+ }
RETURN;
}
{
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);
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));
}
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
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;
}
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;
}
}
}
}
else {
+ GV *gv;
+
if (SvTYPE(sv) != SVt_PVGV) {
char *sym;
if (op->op_flags & OPf_REF ||
op->op_private & HINT_STRICT_REFS)
DIE(no_usym, "an ARRAY");
+ if (GIMME == G_ARRAY)
+ RETURN;
RETPUSHUNDEF;
}
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;
}
}
else {
+ GV *gv;
+
if (SvTYPE(sv) != SVt_PVGV) {
char *sym;
if (op->op_flags & OPf_REF ||
op->op_private & HINT_STRICT_REFS)
DIE(no_usym, "a HASH");
+ if (GIMME == G_ARRAY) {
+ SP--;
+ RETURN;
+ }
RETSETUNDEF;
}
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;
ary = Null(AV*);
hash = Null(HV*);
while (lelem <= lastlelem) {
+ tainted = 0; /* Each item stands on its own, taintwise. */
sv = *lelem++;
switch (SvTYPE(sv)) {
case SVt_PVAV:
(void)av_store(ary,i++,sv);
if (magic)
mg_set(sv);
+ tainted = 0;
}
break;
case SVt_PVHV: {
- char *tmps;
SV *tmpstr;
hash = (HV*)sv;
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:
gid = (int)getgid();
egid = (int)getegid();
}
- tainting |= (euid != uid || egid != gid);
+ tainting |= (uid && (euid != uid || egid != gid));
}
delaymagic = 0;
if (GIMME == G_ARRAY) {
RETURN;
}
else {
+ dTARGET;
SP = firstrelem;
- for (relem = firstrelem; relem <= lastrelem; ++relem) {
- if (SvOK(*relem)) {
- dTARGET;
- SETi(lastrelem - firstrelem + 1);
- RETURN;
- }
- }
- RETSETUNDEF;
+ SETi(lastrelem - firstrelem + 1);
+ RETURN;
}
}
I32 gimme = GIMME;
STRLEN len;
I32 minmatch = 0;
+ I32 oldsave = savestack_ix;
if (op->op_flags & OPf_STACKED)
TARG = POPs;
}
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;
pm->op_pmshort = Nullsv; /* opt is being useless */
}
}
- if (regexec(rx, s, strend, truebase, minmatch,
+ if (pregexec(rx, s, strend, truebase, minmatch,
SvSCREAM(TARG) ? TARG : Nullsv,
safebase)) {
curpm = pm;
++rx->endp[0];
goto play_it_again;
}
+ LEAVE_SCOPE(oldsave);
RETURN;
}
else {
else
mg->mg_len = -1;
}
+ LEAVE_SCOPE(oldsave);
RETPUSHYES;
}
tmps = rx->startp[0] = tmps + (s - t);
rx->endp[0] = tmps + SvCUR(pm->op_pmshort);
}
+ LEAVE_SCOPE(oldsave);
RETPUSHYES;
nope:
mg->mg_len = -1;
}
}
+ LEAVE_SCOPE(oldsave);
if (gimme == G_ARRAY)
RETURN;
RETPUSHNO;
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);
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};
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,
*(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 {
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 &&
sts != RMS$_DNF && sts != RMS$_FNF) ok = 0;
if (!ok) {
+ if (!(sts & 1)) {
+ SETERRNO((sts == RMS$_SYN ? EINVAL : EVMSERR),sts);
+ }
+ PerlIO_close(tmpfp);
fp = NULL;
}
else {
- rewind(tmpfp);
+ PerlIO_rewind(tmpfp);
IoTYPE(io) = '<';
IoIFP(io) = fp = tmpfp;
}
}
#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);
- sv_catpv(tmpcmd, "'|");
+ sv_catpv(tmpcmd, "' 2>/dev/null |");
#else
sv_setpv(tmpcmd, "echo ");
sv_catsv(tmpcmd, tmpglob);
sv_catpv(tmpcmd, "|tr -s ' \t\f\r' '\\n\\n\\n\\n'|");
#endif
#endif /* !CSH */
-#endif /* !MSDOS */
- (void)do_open(last_in_gv, SvPVX(tmpcmd), SvCUR(tmpcmd),Nullfp);
+#endif /* !DOSISH */
+ (void)do_open(last_in_gv, SvPVX(tmpcmd), SvCUR(tmpcmd),
+ FALSE, 0, 0, Nullfp);
fp = IoIFP(io);
#endif /* !VMS */
LEAVE;
SP--;
}
if (!fp) {
- if (dowarn && !(IoFLAGS(io) & IOf_START))
+ if (dowarn && io && !(IoFLAGS(io) & IOf_START))
warn("Read on closed filehandle <%s>", GvENAME(last_in_gv));
if (GIMME == G_SCALAR) {
(void)SvOK_off(TARG);
}
for (;;) {
if (!sv_gets(sv, fp, offset)) {
- clearerr(fp);
+ PerlIO_clearerr(fp);
if (IoFLAGS(io) & IOf_ARGV) {
fp = nextargv(last_in_gv);
if (fp)
if (type == OP_GLOB) {
char *tmps;
- if (SvCUR(sv) > 0)
- SvCUR(sv)--;
- if (*SvEND(sv) == rschar)
- *SvEND(sv) = '\0';
- else
- SvCUR(sv)++;
+ if (SvCUR(sv) > 0 && SvCUR(rs) > 0) {
+ tmps = SvEND(sv) - 1;
+ if (*tmps == *SvPVX(rs)) {
+ *tmps = '\0';
+ SvCUR(sv)--;
+ }
+ }
for (tmps = SvPVX(sv); *tmps; tmps++)
if (!isALPHA(*tmps) && !isDIGIT(*tmps) &&
strchr("$&*(){}[]'\";\\|?<>~`", *tmps))
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);
- else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV)) {
- SV* sv = *svp;
- if (SvGMAGICAL(sv))
- mg_get(sv);
- if (!SvOK(sv)) {
- (void)SvUPGRADE(sv, SVt_RV);
- SvRV(sv) = (op->op_private & OPpDEREF_HV ?
- (SV*)newHV() : (SV*)newAV());
- SvROK_on(sv);
- SvSETMAGIC(sv);
- }
- }
+ save_svref(&HeVAL(he));
+ else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV))
+ provide_ref(op, HeVAL(he));
}
- PUSHs(svp ? *svp : &sv_undef);
+ PUSHs(he ? HeVAL(he) : &sv_undef);
RETURN;
}
dSP;
register CONTEXT *cx;
SV *sv;
+ AV* av;
EXTEND(sp, 1);
cx = &cxstack[cxstack_ix];
if (cx->cx_type != CXt_LOOP)
DIE("panic: pp_iter");
+ av = cx->blk_loop.iterary;
+ if (av == curstack && cx->blk_loop.iterix >= cx->blk_oldsp)
+ RETPUSHNO;
- if (cx->blk_loop.iterix >= cx->blk_oldsp)
+ if (cx->blk_loop.iterix >= AvFILL(av))
RETPUSHNO;
- if (sv = AvARRAY(cx->blk_loop.iterary)[++cx->blk_loop.iterix]) {
+ if (sv = AvARRAY(av)[++cx->blk_loop.iterix]) {
SvTEMP_off(sv);
*cx->blk_loop.itervar = sv;
}
register REGEXP *rx = pm->op_pmregexp;
STRLEN len;
int force_on_match = 0;
+ I32 oldsave = savestack_ix;
if (pm->op_pmflags & PMf_CONST) /* known replacement string? */
dstr = POPs;
EXTEND(SP,1);
}
s = SvPV(TARG, len);
- if (!SvPOKp(TARG) || SvREADONLY(TARG))
+ if (!SvPOKp(TARG) || SvREADONLY(TARG) || (SvTYPE(TARG) == SVt_PVGV))
force_on_match = 1;
force_it:
}
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;
c = SvPV(dstr, clen);
if (clen <= rx->minlen) {
/* can do inplace substitution */
- if (regexec(rx, s, strend, orig, 0,
+ if (pregexec(rx, s, strend, orig, 0,
SvSCREAM(TARG) ? TARG : Nullsv, safebase)) {
if (force_on_match) {
force_on_match = 0;
(void)SvPOK_only(TARG);
SvSETMAGIC(TARG);
PUSHs(&sv_yes);
+ LEAVE_SCOPE(oldsave);
RETURN;
}
/*SUPPRESS 560*/
(void)SvPOK_only(TARG);
SvSETMAGIC(TARG);
PUSHs(&sv_yes);
+ LEAVE_SCOPE(oldsave);
RETURN;
}
else if (clen) {
(void)SvPOK_only(TARG);
SvSETMAGIC(TARG);
PUSHs(&sv_yes);
+ LEAVE_SCOPE(oldsave);
RETURN;
}
else {
(void)SvPOK_only(TARG);
SvSETMAGIC(TARG);
PUSHs(&sv_yes);
+ LEAVE_SCOPE(oldsave);
RETURN;
}
/* NOTREACHED */
d += clen;
}
s = rx->endp[0];
- } while (regexec(rx, s, strend, orig, s == m,
+ } while (pregexec(rx, s, strend, orig, s == m,
Nullsv, TRUE)); /* (don't match same null twice) */
if (s != d) {
i = strend - s;
(void)SvPOK_only(TARG);
SvSETMAGIC(TARG);
PUSHs(sv_2mortal(newSViv((I32)iters)));
+ LEAVE_SCOPE(oldsave);
RETURN;
}
PUSHs(&sv_no);
+ LEAVE_SCOPE(oldsave);
RETURN;
}
}
else
c = Nullch;
- if (regexec(rx, s, strend, orig, 0,
+ if (pregexec(rx, s, strend, orig, 0,
SvSCREAM(TARG) ? TARG : Nullsv, safebase)) {
long_way:
if (force_on_match) {
sv_catpvn(dstr, c, clen);
if (once)
break;
- } while (regexec(rx, s, strend, orig, s == m, Nullsv,
+ } while (pregexec(rx, s, strend, orig, s == m, Nullsv,
safebase));
sv_catpvn(dstr, s, strend - s);
+ (void)SvOOK_off(TARG);
Safefree(SvPVX(TARG));
SvPVX(TARG) = SvPVX(dstr);
SvCUR_set(TARG, SvCUR(dstr));
(void)SvPOK_only(TARG);
SvSETMAGIC(TARG);
PUSHs(sv_2mortal(newSViv((I32)iters)));
+ LEAVE_SCOPE(oldsave);
RETURN;
}
PUSHs(&sv_no);
+ LEAVE_SCOPE(oldsave);
RETURN;
nope:
++BmUSEFUL(pm->op_pmshort);
PUSHs(&sv_no);
+ LEAVE_SCOPE(oldsave);
RETURN;
}
register CV *cv;
register CONTEXT *cx;
I32 gimme;
+ I32 hasargs = (op->op_flags & OPf_STACKED) != 0;
if (!sv)
DIE("Not a CODE reference");
if (!CvROOT(cv) && !CvXSUB(cv)) {
if (gv = CvGV(cv)) {
- SV *tmpstr = sv_newmortal();
+ SV *tmpstr;
GV *ngv;
- gv_efullname(tmpstr, gv);
+ if (SvFAKE(cv) && GvCV(gv) != cv) { /* autoloaded stub? */
+ cv = GvCV(gv);
+ if (SvTYPE(sv) == SVt_PVGV) {
+ SvREFCNT_dec(GvCV((GV*)sv));
+ GvCV((GV*)sv) = (CV*)SvREFCNT_inc((SV*)cv);
+ }
+ goto retry;
+ }
+ tmpstr = sv_newmortal();
+ gv_efullname(tmpstr, gv, Nullch);
ngv = gv_fetchmethod(GvESTASH(gv), "AUTOLOAD");
if (ngv && ngv != gv && (cv = GvCV(ngv))) { /* One more chance... */
gv = ngv;
sv_setsv(GvSV(CvGV(cv)), tmpstr); /* Set CV's $AUTOLOAD */
+ if (tainting)
+ sv_unmagic(GvSV(CvGV(cv)), 't');
goto retry;
}
else
DIE("Undefined subroutine called");
}
- if ((op->op_private & OPpDEREF_DB) && !CvXSUB(cv)) {
+ gimme = GIMME;
+ if ((op->op_private & OPpENTERSUB_DB)) {
sv = GvSV(DBsub);
save_item(sv);
- if (SvFLAGS(cv) & SVpcv_ANON) /* Is GV potentially non-unique? */
+ 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");
}
- gimme = GIMME;
-
if (CvXSUB(cv)) {
if (CvOLDSTYLE(cv)) {
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--;
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. */
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);
if (CvDEPTH(cv) > AvFILL(padlist)) {
AV *av;
AV *newpad = newAV();
- AV *oldpad = (AV*)AvARRAY(svp[CvDEPTH(cv)-1]);
+ SV **oldpad = AvARRAY(svp[CvDEPTH(cv)-1]);
I32 ix = AvFILL((AV*)svp[1]);
svp = AvARRAY(svp[0]);
for ( ;ix > 0; ix--) {
char *name = SvPVX(svp[ix]);
if (SvFLAGS(svp[ix]) & SVf_FAKE) { /* outer lexical? */
av_store(newpad, ix,
- SvREFCNT_inc(AvARRAY(oldpad)[ix]) );
+ SvREFCNT_inc(oldpad[ix]) );
}
else { /* our own lexical */
if (*name == '@')
DIE(no_aelem, elem);
if (op->op_private & OPpLVAL_INTRO)
save_svref(svp);
- else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV)) {
- SV* sv = *svp;
- if (SvGMAGICAL(sv))
- mg_get(sv);
- if (!SvOK(sv)) {
- (void)SvUPGRADE(sv, SVt_RV);
- SvRV(sv) = (op->op_private & OPpDEREF_HV ?
- (SV*)newHV() : (SV*)newAV());
- SvROK_on(sv);
- SvSETMAGIC(sv);
- }
- }
+ else if (op->op_private & (OPpDEREF_HV|OPpDEREF_AV))
+ provide_ref(op, *svp);
}
PUSHs(svp ? *svp : &sv_undef);
RETURN;
}
+void
+provide_ref(op, sv)
+OP* op;
+SV* sv;
+{
+ if (SvGMAGICAL(sv))
+ mg_get(sv);
+ if (!SvOK(sv)) {
+ if (SvREADONLY(sv))
+ croak(no_modify);
+ (void)SvUPGRADE(sv, SVt_RV);
+ SvRV(sv) = (op->op_private & OPpDEREF_HV ?
+ (SV*)newHV() : (SV*)newAV());
+ SvROK_on(sv);
+ SvSETMAGIC(sv);
+ }
+}
+
PP(pp_method)
{
dSP;
sv = *(stack_base + TOPMARK + 1);
gv = 0;
+ if (SvGMAGICAL(sv))
+ mg_get(sv);
if (SvROK(sv))
- ob = SvRV(sv);
+ ob = (SV*)SvRV(sv);
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)))
{
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);
if (!gv)
DIE("Can't locate object method \"%s\" via package \"%s\"",
name, packname);
- SETs(gv);
+ SETs((SV*)gv);
RETURN;
}
- *(stack_base + TOPMARK + 1) = iogv;
+ *(stack_base + TOPMARK + 1) = sv_2mortal(newRV((SV*)iogv));
}
if (!ob || !SvOBJECT(ob)) {
name, HvNAME(SvSTASH(ob)));
}
- SETs(gv);
+ SETs((SV*)gv);
RETURN;
}