/* pp_ctl.c
*
- * Copyright (c) 1991-2002, Larry Wall
+ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ * 2000, 2001, 2002, 2003, by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
#include "perl.h"
#ifndef WORD_ALIGN
-#define WORD_ALIGN sizeof(U16)
+#define WORD_ALIGN sizeof(U32)
#endif
#define DOCATCH(o) ((CATCH_GET == TRUE) ? docatch(o) : (o))
memNE(PM_GETRE(pm)->precomp, t, len))
{
if (PM_GETRE(pm)) {
- ReREFCNT_dec(PM_GETRE(pm));
+ ReREFCNT_dec(PM_GETRE(pm));
PM_SETRE(pm, Null(REGEXP*)); /* crucial if regcomp aborts */
}
if (PL_op->op_flags & OPf_SPECIAL)
register char *m = cx->sb_m;
char *orig = cx->sb_orig;
register REGEXP *rx = cx->sb_rx;
+ SV *nsv = Nullsv;
+
+ {
+ REGEXP *old = PM_GETRE(pm);
+ if(old != rx) {
+ if(old)
+ ReREFCNT_dec(old);
+ PM_SETRE(pm,rx);
+ }
+ }
rxres_restore(&cx->sb_rxres, rx);
- PL_reg_match_utf8 = SvUTF8(cx->sb_targ) ? 1 : 0;
+ RX_MATCH_UTF8_set(rx, SvUTF8(cx->sb_targ));
if (cx->sb_iters++) {
I32 saviters = cx->sb_iters;
{
SV *targ = cx->sb_targ;
- sv_catpvn(dstr, s, cx->sb_strend - s);
+ if (DO_UTF8(dstr) && !SvUTF8(targ))
+ sv_catpvn_utf8_upgrade(dstr, s, cx->sb_strend - s, nsv);
+ else
+ sv_catpvn(dstr, s, cx->sb_strend - s);
cx->sb_rxtainted |= RX_MATCH_TAINTED(rx);
- (void)SvOOK_off(targ);
- Safefree(SvPVX(targ));
+#ifdef PERL_COPY_ON_WRITE
+ if (SvIsCOW(targ)) {
+ sv_force_normal_flags(targ, SV_COW_DROP_PV);
+ } else
+#endif
+ {
+ (void)SvOOK_off(targ);
+ if (SvLEN(targ))
+ Safefree(SvPVX(targ));
+ }
SvPVX(targ) = SvPVX(dstr);
SvCUR_set(targ, SvCUR(dstr));
SvLEN_set(targ, SvLEN(dstr));
sv_free(dstr);
TAINT_IF(cx->sb_rxtainted & 1);
- PUSHs(sv_2mortal(newSViv((I32)cx->sb_iters - 1)));
+ PUSHs(sv_2mortal(newSViv(saviters - 1)));
(void)SvPOK_only_UTF8(targ);
TAINT_IF(cx->sb_rxtainted);
SvTAINT(targ);
LEAVE_SCOPE(cx->sb_oldsave);
+ ReREFCNT_dec(rx);
POPSUBST(cx);
RETURNOP(pm->op_next);
}
cx->sb_strend = s + (cx->sb_strend - m);
}
cx->sb_m = m = rx->startp[0] + orig;
- if (m > s)
- sv_catpvn(dstr, s, m-s);
+ if (m > s) {
+ if (DO_UTF8(dstr) && !SvUTF8(cx->sb_targ))
+ sv_catpvn_utf8_upgrade(dstr, s, m - s, nsv);
+ else
+ sv_catpvn(dstr, s, m-s);
+ }
cx->sb_s = rx->endp[0] + orig;
{ /* Update the pos() information. */
SV *sv = cx->sb_targ;
sv_pos_b2u(sv, &i);
mg->mg_len = i;
}
+ ReREFCNT_inc(rx);
cx->sb_rxtainted |= RX_MATCH_TAINTED(rx);
rxres_save(&cx->sb_rxres, rx);
RETURNOP(pm->op_pmreplstart);
U32 i;
if (!p || p[1] < rx->nparens) {
+#ifdef PERL_COPY_ON_WRITE
+ i = 7 + rx->nparens * 2;
+#else
i = 6 + rx->nparens * 2;
+#endif
if (!p)
New(501, p, i, UV);
else
*p++ = PTR2UV(RX_MATCH_COPIED(rx) ? rx->subbeg : Nullch);
RX_MATCH_COPIED_off(rx);
+#ifdef PERL_COPY_ON_WRITE
+ *p++ = PTR2UV(rx->saved_copy);
+ rx->saved_copy = Nullsv;
+#endif
+
*p++ = rx->nparens;
*p++ = PTR2UV(rx->subbeg);
UV *p = (UV*)*rsp;
U32 i;
- if (RX_MATCH_COPIED(rx))
- Safefree(rx->subbeg);
+ RX_MATCH_COPY_FREE(rx);
RX_MATCH_COPIED_set(rx, *p);
*p++ = 0;
+#ifdef PERL_COPY_ON_WRITE
+ if (rx->saved_copy)
+ SvREFCNT_dec (rx->saved_copy);
+ rx->saved_copy = INT2PTR(SV*,*p);
+ *p++ = 0;
+#endif
+
rx->nparens = *p++;
rx->subbeg = INT2PTR(char*,*p++);
if (p) {
Safefree(INT2PTR(char*,*p));
+#ifdef PERL_COPY_ON_WRITE
+ if (p[1]) {
+ SvREFCNT_dec (INT2PTR(SV*,p[1]));
+ }
+#endif
Safefree(p);
*rsp = Null(void*);
}
{
dSP; dMARK; dORIGMARK;
register SV *tmpForm = *++MARK;
- register U16 *fpc;
+ register U32 *fpc;
register char *t;
register char *f;
register char *s;
bool gotsome = FALSE;
STRLEN len;
STRLEN fudge = SvCUR(tmpForm) * (IN_BYTES ? 1 : 3) + 1;
- bool item_is_utf = FALSE;
+ bool item_is_utf8 = FALSE;
+ bool targ_is_utf8 = FALSE;
+ SV * nsv = Nullsv;
if (!SvMAGICAL(tmpForm) || !SvCOMPILED(tmpForm)) {
if (SvREADONLY(tmpForm)) {
else
doparseform(tmpForm);
}
-
SvPV_force(PL_formtarget, len);
+ if (DO_UTF8(PL_formtarget))
+ targ_is_utf8 = TRUE;
t = SvGROW(PL_formtarget, len + fudge + 1); /* XXX SvCUR bad */
t += len;
f = SvPV(tmpForm, len);
/* need to jump to the next word */
s = f + len + WORD_ALIGN - SvCUR(tmpForm) % WORD_ALIGN;
- fpc = (U16*)s;
+ fpc = (U32*)s;
for (;;) {
DEBUG_f( {
case FF_LITERAL:
arg = *fpc++;
+ if (targ_is_utf8 && !SvUTF8(tmpForm)) {
+ SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
+ *t = '\0';
+ sv_catpvn_utf8_upgrade(PL_formtarget, f, arg, nsv);
+ t = SvEND(PL_formtarget);
+ break;
+ }
+ if (!targ_is_utf8 && DO_UTF8(tmpForm)) {
+ SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
+ *t = '\0';
+ sv_utf8_upgrade(PL_formtarget);
+ SvGROW(PL_formtarget, SvCUR(PL_formtarget) + fudge + 1);
+ t = SvEND(PL_formtarget);
+ targ_is_utf8 = TRUE;
+ }
while (arg--)
*t++ = *f++;
break;
break;
s++;
}
- item_is_utf = TRUE;
+ item_is_utf8 = TRUE;
itemsize = s - item;
sv_pos_b2u(sv, &itemsize);
break;
}
}
- item_is_utf = FALSE;
+ item_is_utf8 = FALSE;
if (itemsize > fieldsize)
itemsize = fieldsize;
send = chophere = s + itemsize;
itemsize = chophere - item;
sv_pos_b2u(sv, &itemsize);
}
- item_is_utf = TRUE;
+ item_is_utf8 = TRUE;
break;
}
}
- item_is_utf = FALSE;
+ item_is_utf8 = FALSE;
if (itemsize <= fieldsize) {
send = chophere = s + itemsize;
while (s < send) {
case FF_ITEM:
arg = itemsize;
s = item;
- if (item_is_utf) {
+ if (item_is_utf8) {
+ if (!targ_is_utf8) {
+ SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
+ *t = '\0';
+ sv_utf8_upgrade(PL_formtarget);
+ SvGROW(PL_formtarget, SvCUR(PL_formtarget) + fudge + 1);
+ t = SvEND(PL_formtarget);
+ targ_is_utf8 = TRUE;
+ }
while (arg--) {
if (UTF8_IS_CONTINUED(*s)) {
STRLEN skip = UTF8SKIP(s);
}
break;
}
+ if (targ_is_utf8 && !item_is_utf8) {
+ SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
+ *t = '\0';
+ sv_catpvn_utf8_upgrade(PL_formtarget, s, arg, nsv);
+ for (; t < SvEND(PL_formtarget); t++) {
+#ifdef EBCDIC
+ int ch = *t++ = *s++;
+ if (iscntrl(ch))
+#else
+ if (!(*t & ~31))
+#endif
+ *t = ' ';
+ }
+ break;
+ }
while (arg--) {
#ifdef EBCDIC
int ch = *t++ = *s++;
s++;
}
sv_chop(sv,s);
+ SvSETMAGIC(sv);
break;
case FF_LINEGLOB:
item = s = SvPV(sv, len);
itemsize = len;
- item_is_utf = FALSE; /* XXX is this correct? */
+ if ((item_is_utf8 = DO_UTF8(sv)))
+ itemsize = sv_len_utf8(sv);
if (itemsize) {
+ bool chopped = FALSE;
gotsome = TRUE;
- send = s + itemsize;
+ send = s + len;
while (s < send) {
if (*s++ == '\n') {
- if (s == send)
+ if (s == send) {
itemsize--;
+ chopped = TRUE;
+ }
else
lines++;
}
}
SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
- sv_catpvn(PL_formtarget, item, itemsize);
+ if (targ_is_utf8)
+ SvUTF8_on(PL_formtarget);
+ sv_catsv(PL_formtarget, sv);
+ if (chopped)
+ SvCUR_set(PL_formtarget, SvCUR(PL_formtarget) - 1);
SvGROW(PL_formtarget, SvCUR(PL_formtarget) + fudge + 1);
t = SvPVX(PL_formtarget) + SvCUR(PL_formtarget);
+ if (item_is_utf8)
+ targ_is_utf8 = TRUE;
}
break;
if (strnEQ(linemark, linemark - arg, arg))
DIE(aTHX_ "Runaway format");
}
+ if (targ_is_utf8)
+ SvUTF8_on(PL_formtarget);
FmLINES(PL_formtarget) = lines;
SP = ORIGMARK;
RETURNOP(cLISTOP->op_first);
case FF_END:
*t = '\0';
SvCUR_set(PL_formtarget, t - SvPVX(PL_formtarget));
+ if (targ_is_utf8)
+ SvUTF8_on(PL_formtarget);
FmLINES(PL_formtarget) += lines;
SP = ORIGMARK;
RETPUSHYES;
if (SvGMAGICAL(right))
mg_get(right);
+ /* This code tries to decide if "$left .. $right" should use the
+ magical string increment, or if the range is numeric (we make
+ an exception for .."0" [#18165]). AMS 20021031. */
+
if (SvNIOKp(left) || !SvPOKp(left) ||
SvNIOKp(right) || !SvPOKp(right) ||
(looks_like_number(left) && *SvPVX(left) != '0' &&
- looks_like_number(right) && *SvPVX(right) != '0'))
+ looks_like_number(right)))
{
if (SvNV(left) < IV_MIN || SvNV(right) > IV_MAX)
DIE(aTHX_ "Range iterator outside integer range");
/* Control. */
+static char *context_name[] = {
+ "pseudo-block",
+ "subroutine",
+ "eval",
+ "loop",
+ "substitution",
+ "block",
+ "format"
+};
+
STATIC I32
S_dopoptolabel(pTHX_ char *label)
{
cx = &cxstack[i];
switch (CxTYPE(cx)) {
case CXt_SUBST:
- if (ckWARN(WARN_EXITING))
- Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting substitution via %s",
- OP_NAME(PL_op));
- break;
case CXt_SUB:
- if (ckWARN(WARN_EXITING))
- Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting subroutine via %s",
- OP_NAME(PL_op));
- break;
case CXt_FORMAT:
- if (ckWARN(WARN_EXITING))
- Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting format via %s",
- OP_NAME(PL_op));
- break;
case CXt_EVAL:
- if (ckWARN(WARN_EXITING))
- Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting eval via %s",
- OP_NAME(PL_op));
- break;
case CXt_NULL:
if (ckWARN(WARN_EXITING))
- Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting pseudo-block via %s",
- OP_NAME(PL_op));
- return -1;
+ Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
+ context_name[CxTYPE(cx)], OP_NAME(PL_op));
+ if (CxTYPE(cx) == CXt_NULL)
+ return -1;
+ break;
case CXt_LOOP:
if (!cx->blk_loop.label ||
strNE(label, cx->blk_loop.label) ) {
cx = &cxstack[i];
switch (CxTYPE(cx)) {
case CXt_SUBST:
- if (ckWARN(WARN_EXITING))
- Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting substitution via %s",
- OP_NAME(PL_op));
- break;
case CXt_SUB:
- if (ckWARN(WARN_EXITING))
- Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting subroutine via %s",
- OP_NAME(PL_op));
- break;
case CXt_FORMAT:
- if (ckWARN(WARN_EXITING))
- Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting format via %s",
- OP_NAME(PL_op));
- break;
case CXt_EVAL:
- if (ckWARN(WARN_EXITING))
- Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting eval via %s",
- OP_NAME(PL_op));
- break;
case CXt_NULL:
if (ckWARN(WARN_EXITING))
- Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting pseudo-block via %s",
- OP_NAME(PL_op));
- return -1;
+ Perl_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
+ context_name[CxTYPE(cx)], OP_NAME(PL_op));
+ if ((CxTYPE(cx)) == CXt_NULL)
+ return -1;
+ break;
case CXt_LOOP:
DEBUG_l( Perl_deb(aTHX_ "(Found loop #%ld)\n", (long)i));
return i;
Perl_die_where(pTHX_ char *message, STRLEN msglen)
{
STRLEN n_a;
- IO *io;
- MAGIC *mg;
if (PL_in_eval) {
I32 cxix;
sv_setpvn(ERRSV, message, msglen);
}
}
- else
- message = SvPVx(ERRSV, msglen);
while ((cxix = dopoptoeval(cxstack_ix)) < 0
&& PL_curstackinfo->si_prev)
POPBLOCK(cx,PL_curpm);
if (CxTYPE(cx) != CXt_EVAL) {
+ if (!message)
+ message = SvPVx(ERRSV, msglen);
PerlIO_write(Perl_error_log, "panic: die ", 11);
PerlIO_write(Perl_error_log, message, msglen);
my_exit(1);
if (!message)
message = SvPVx(ERRSV, msglen);
- /* if STDERR is tied, print to it instead */
- if (PL_stderrgv && (io = GvIOp(PL_stderrgv))
- && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar))) {
- dSP; ENTER;
- PUSHMARK(SP);
- XPUSHs(SvTIED_obj((SV*)io, mg));
- XPUSHs(sv_2mortal(newSVpvn(message, msglen)));
- PUTBACK;
- call_method("PRINT", G_SCALAR);
- LEAVE;
- }
- else {
-#ifdef USE_SFIO
- /* SFIO can really mess with your errno */
- int e = errno;
-#endif
- PerlIO *serr = Perl_error_log;
-
- PERL_WRITE_MSG_TO_CONSOLE(serr, message, msglen);
- (void)PerlIO_flush(serr);
-#ifdef USE_SFIO
- errno = e;
-#endif
- }
+ write_to_stderr(message, msglen);
my_failure_exit();
/* NOTREACHED */
return 0;
(old_warnings == pWARN_STD && (PL_dowarn & G_WARN_ON) == 0))
mask = newSVpvn(WARN_NONEstring, WARNsize) ;
else if (old_warnings == pWARN_ALL ||
- (old_warnings == pWARN_STD && PL_dowarn & G_WARN_ON))
- mask = newSVpvn(WARN_ALLstring, WARNsize) ;
+ (old_warnings == pWARN_STD && PL_dowarn & G_WARN_ON)) {
+ /* Get the bit mask for $warnings::Bits{all}, because
+ * it could have been extended by warnings::register */
+ SV **bits_all;
+ HV *bits = get_hv("warnings::Bits", FALSE);
+ if (bits && (bits_all=hv_fetch(bits, "all", 3, FALSE))) {
+ mask = newSVsv(*bits_all);
+ }
+ else {
+ mask = newSVpvn(WARN_ALLstring, WARNsize) ;
+ }
+ }
else
mask = newSVsv(old_warnings);
PUSHs(sv_2mortal(mask));
PL_stack_sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp;
FREETMPS;
- if (PL_op->op_private || SvIV(PL_DBsingle) || SvIV(PL_DBsignal) || SvIV(PL_DBtrace))
+ if (PL_op->op_flags & OPf_SPECIAL /* breakpoint */
+ || SvIV(PL_DBsingle) || SvIV(PL_DBsignal) || SvIV(PL_DBtrace))
{
dSP;
register CV *cv;
push_return(PL_op->op_next);
PUSHBLOCK(cx, CXt_SUB, SP);
- PUSHSUB(cx);
+ PUSHSUB_DB(cx);
CvDEPTH(cv)++;
(void)SvREFCNT_inc(cv);
PAD_SET_CUR(CvPADLIST(cv),1);
cx->blk_loop.iterary = (AV*)SvREFCNT_inc(POPs);
if (SvTYPE(cx->blk_loop.iterary) != SVt_PVAV) {
dPOPss;
+ /* See comment in pp_flop() */
if (SvNIOKp(sv) || !SvPOKp(sv) ||
SvNIOKp(cx->blk_loop.iterary) || !SvPOKp(cx->blk_loop.iterary) ||
(looks_like_number(sv) && *SvPVX(sv) != '0' &&
- looks_like_number((SV*)cx->blk_loop.iterary) &&
- *SvPVX(cx->blk_loop.iterary) != '0'))
+ looks_like_number((SV*)cx->blk_loop.iterary)))
{
if (SvNV(sv) < IV_MIN ||
SvNV((SV*)cx->blk_loop.iterary) >= IV_MAX)
/* Unassume the success we assumed earlier. */
SV *nsv = cx->blk_eval.old_namesv;
(void)hv_delete(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv), G_DISCARD);
- DIE(aTHX_ "%s did not return a true value", SvPVX(nsv));
+ DIE(aTHX_ "%"SVf" did not return a true value", nsv);
}
break;
case CXt_FORMAT:
}
PL_stack_sp = newsp;
+ LEAVE;
/* Stack values are safe: */
if (popsub2) {
POPSUB(cx,sv); /* release CV and @_ ... */
sv = Nullsv;
PL_curpm = newpm; /* ... and pop $1 et al */
- LEAVE;
LEAVESUB(sv);
if (clear_errsv)
sv_setpv(ERRSV,"");
SP = newsp;
PUTBACK;
+ LEAVE;
/* Stack values are safe: */
switch (pop2) {
case CXt_LOOP:
}
PL_curpm = newpm; /* ... and pop $1 et al */
- LEAVE;
LEAVESUB(sv);
return nextop;
}
if (o->op_type == OP_LEAVE ||
o->op_type == OP_SCOPE ||
o->op_type == OP_LEAVELOOP ||
+ o->op_type == OP_LEAVESUB ||
o->op_type == OP_LEAVETRY)
{
*ops++ = cUNOPo->op_first;
for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) {
if (kid == PL_lastgotoprobe)
continue;
- if ((kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) &&
- (ops == opstack ||
- (ops[-1]->op_type != OP_NEXTSTATE &&
- ops[-1]->op_type != OP_DBSTATE)))
- *ops++ = kid;
+ if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) {
+ if (ops == opstack)
+ *ops++ = kid;
+ else if (ops[-1]->op_type == OP_NEXTSTATE ||
+ ops[-1]->op_type == OP_DBSTATE)
+ ops[-1] = kid;
+ else
+ *ops++ = kid;
+ }
if ((o = dofindlabel(kid, label, ops, oplimit)))
return o;
}
goto retry;
tmpstr = sv_newmortal();
gv_efullname3(tmpstr, gv, Nullch);
- DIE(aTHX_ "Goto undefined subroutine &%s",SvPVX(tmpstr));
+ DIE(aTHX_ "Goto undefined subroutine &%"SVf"",tmpstr);
}
DIE(aTHX_ "Goto undefined subroutine");
}
/* First do some returnish stuff. */
+ SvREFCNT_inc(cv); /* avoid premature free during unwind */
+ FREETMPS;
cxix = dopoptosub(cxstack_ix);
if (cxix < 0)
DIE(aTHX_ "Can't goto subroutine outside a subroutine");
AvFLAGS(av) = AVf_REIFY;
PAD_SVl(0) = (SV*)(cx->blk_sub.argarray = av);
}
+ else
+ CLEAR_ARGARRAY(av);
}
else if (CvXSUB(cv)) { /* put GvAV(defgv) back onto stack */
AV* av;
/* Now do some callish stuff. */
SAVETMPS;
+ SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
if (CvXSUB(cv)) {
#ifdef PERL_XSUB_OLDSTYLE
if (CvOLDSTYLE(cv)) {
CV *gotocv;
if (PERLDB_SUB_NN) {
- SvIVX(sv) = PTR2IV(cv); /* Already upgraded, saved */
+ (void)SvUPGRADE(sv, SVt_PVIV);
+ (void)SvIOK_on(sv);
+ SAVEIV(SvIVX(sv));
+ SvIVX(sv) = PTR2IV(cv); /* Do it the quickest way */
} else {
save_item(sv);
gv_efullname3(sv, CvGV(cv), Nullch);
if (label && *label) {
OP *gotoprobe = 0;
bool leaving_eval = FALSE;
+ bool in_block = FALSE;
PERL_CONTEXT *last_eval_cx = 0;
/* find label */
switch (CxTYPE(cx)) {
case CXt_EVAL:
leaving_eval = TRUE;
- if (CxREALEVAL(cx)) {
+ if (!CxTRYBLOCK(cx)) {
gotoprobe = (last_eval_cx ?
last_eval_cx->blk_eval.old_eval_root :
PL_eval_root);
case CXt_SUBST:
continue;
case CXt_BLOCK:
- if (ix)
+ if (ix) {
gotoprobe = cx->blk_oldcop->op_sibling;
- else
+ in_block = TRUE;
+ } else
gotoprobe = PL_main_root;
break;
case CXt_SUB:
if (*enterops && enterops[1]) {
OP *oldop = PL_op;
- for (ix = 1; enterops[ix]; ix++) {
+ ix = enterops[1]->op_type == OP_ENTER && in_block ? 2 : 1;
+ for (; enterops[ix]; ix++) {
PL_op = enterops[ix];
/* Eventually we may want to stack the needed arguments
* for each op. For now, we punt on the hard ones. */
char tbuf[TYPE_DIGITS(long) + 12 + 10];
char *tmpbuf = tbuf;
char *safestr;
+ int runtime;
+ CV* runcv = Nullcv; /* initialise to avoid compiler warnings */
ENTER;
lex_start(sv);
#endif
PL_hints &= HINT_UTF8;
+ /* we get here either during compilation, or via pp_regcomp at runtime */
+ runtime = PL_op && (PL_op->op_type == OP_REGCOMP);
+ if (runtime)
+ runcv = find_runcv(NULL);
+
PL_op = &dummy;
PL_op->op_type = OP_ENTEREVAL;
PL_op->op_flags = 0; /* Avoid uninit warning. */
PUSHBLOCK(cx, CXt_EVAL|(PL_curcop == &PL_compiling ? 0 : CXp_REAL), SP);
PUSHEVAL(cx, 0, Nullgv);
- rop = doeval(G_SCALAR, startop);
+
+ if (runtime)
+ rop = doeval(G_SCALAR, startop, runcv, PL_curcop->cop_seq);
+ else
+ rop = doeval(G_SCALAR, startop, PL_compcv, PL_cop_seqmax);
POPBLOCK(cx,PL_curpm);
POPEVAL(cx);
return rop;
}
+
+/*
+=for apidoc find_runcv
+
+Locate the CV corresponding to the currently executing sub or eval.
+If db_seqp is non_null, skip CVs that are in the DB package and populate
+*db_seqp with the cop sequence number at the point that the DB:: code was
+entered. (allows debuggers to eval in the scope of the breakpoint rather
+than in in the scope of the debuger itself).
+
+=cut
+*/
+
+CV*
+Perl_find_runcv(pTHX_ U32 *db_seqp)
+{
+ I32 ix;
+ PERL_SI *si;
+ PERL_CONTEXT *cx;
+
+ if (db_seqp)
+ *db_seqp = PL_curcop->cop_seq;
+ for (si = PL_curstackinfo; si; si = si->si_prev) {
+ for (ix = si->si_cxix; ix >= 0; ix--) {
+ cx = &(si->si_cxstack[ix]);
+ if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
+ CV *cv = cx->blk_sub.cv;
+ /* skip DB:: code */
+ if (db_seqp && PL_debstash && CvSTASH(cv) == PL_debstash) {
+ *db_seqp = cx->blk_oldcop->cop_seq;
+ continue;
+ }
+ return cv;
+ }
+ else if (CxTYPE(cx) == CXt_EVAL && !CxTRYBLOCK(cx))
+ return PL_compcv;
+ }
+ }
+ return PL_main_cv;
+}
+
+
+/* Compile a require/do, an eval '', or a /(?{...})/.
+ * In the last case, startop is non-null, and contains the address of
+ * a pointer that should be set to the just-compiled code.
+ * outside is the lexically enclosing CV (if any) that invoked us.
+ */
+
/* With USE_5005THREADS, eval_owner must be held on entry to doeval */
STATIC OP *
-S_doeval(pTHX_ int gimme, OP** startop)
+S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
{
dSP;
OP *saveop = PL_op;
- CV *caller;
- I32 i;
PL_in_eval = ((saveop && saveop->op_type == OP_REQUIRE)
? (EVAL_INREQUIRE | (PL_in_eval & EVAL_INEVAL))
PUSHMARK(SP);
- caller = PL_compcv;
- for (i = cxstack_ix - 1; i >= 0; i--) {
- PERL_CONTEXT *cx = &cxstack[i];
- if (CxTYPE(cx) == CXt_EVAL)
- break;
- else if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
- caller = cx->blk_sub.cv;
- break;
- }
- }
-
SAVESPTR(PL_compcv);
PL_compcv = (CV*)NEWSV(1104,0);
sv_upgrade((SV *)PL_compcv, SVt_PVCV);
assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL);
cxstack[cxstack_ix].blk_eval.cv = PL_compcv;
+ CvOUTSIDE_SEQ(PL_compcv) = seq;
+ CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc(outside);
+
/* set up a scratch pad */
CvPADLIST(PL_compcv) = pad_new(padnew_SAVE);
- if (!saveop ||
- (saveop->op_type != OP_REQUIRE && saveop->op_type != OP_DOFILE))
- {
- CvOUTSIDE(PL_compcv) = (CV*)SvREFCNT_inc(caller);
- }
SAVEMORTALIZESV(PL_compcv); /* must remain until end of current statement */
else
sv_setpv(ERRSV,"");
if (yyparse() || PL_error_count || !PL_eval_root) {
- SV **newsp;
- I32 gimme;
+ SV **newsp; /* Used by POPBLOCK. */
PERL_CONTEXT *cx;
I32 optype = 0; /* Might be reset by POPEVAL. */
STRLEN n_a;
Perl_croak(aTHX_ "%sCompilation failed in regexp",
(*msg ? msg : "Unknown error\n"));
}
+ else {
+ char* msg = SvPVx(ERRSV, n_a);
+ if (!*msg) {
+ sv_setpv(ERRSV, "Compilation error");
+ }
+ }
RETPUSHUNDEF;
}
CopLINE_set(&PL_compiling, 0);
if (startop) {
*startop = PL_eval_root;
- SvREFCNT_dec(CvOUTSIDE(PL_compcv));
- CvOUTSIDE(PL_compcv) = Nullcv;
} else
SAVEFREEOP(PL_eval_root);
- if (gimme & G_VOID)
+
+ /* Set the context for this new optree.
+ * If the last op is an OP_REQUIRE, force scalar context.
+ * Otherwise, propagate the context from the eval(). */
+ if (PL_eval_root->op_type == OP_LEAVEEVAL
+ && cUNOPx(PL_eval_root)->op_first->op_type == OP_LINESEQ
+ && cLISTOPx(cUNOPx(PL_eval_root)->op_first)->op_last->op_type
+ == OP_REQUIRE)
+ scalar(PL_eval_root);
+ else if (gimme & G_VOID)
scalarvoid(PL_eval_root);
else if (gimme & G_ARRAY)
list(PL_eval_root);
}
STATIC PerlIO *
-S_doopen_pmc(pTHX_ const char *name, const char *mode)
+S_doopen_pm(pTHX_ const char *name, const char *mode)
{
+#ifndef PERL_DISABLE_PMC
STRLEN namelen = strlen(name);
PerlIO *fp;
fp = PerlIO_open(name, mode);
}
return fp;
+#else
+ return PerlIO_open(name, mode);
+#endif /* !PERL_DISABLE_PMC */
}
PP(pp_require)
if (path_is_absolute(name)) {
tryname = name;
- tryrsfp = doopen_pmc(name,PERL_SCRIPT_MODE);
+ tryrsfp = doopen_pm(name,PERL_SCRIPT_MODE);
}
#ifdef MACOS_TRADITIONAL
if (!tryrsfp) {
MacPerl_CanonDir(name, newname, 1);
if (path_is_absolute(newname)) {
tryname = newname;
- tryrsfp = doopen_pmc(newname,PERL_SCRIPT_MODE);
+ tryrsfp = doopen_pm(newname,PERL_SCRIPT_MODE);
}
}
#endif
#endif
TAINT_PROPER("require");
tryname = SvPVX(namesv);
- tryrsfp = doopen_pmc(tryname, PERL_SCRIPT_MODE);
+ tryrsfp = doopen_pm(tryname, PERL_SCRIPT_MODE);
if (tryrsfp) {
if (tryname[0] == '.' && tryname[1] == '/')
tryname += 2;
encoding = PL_encoding;
PL_encoding = Nullsv;
- op = DOCATCH(doeval(gimme, NULL));
+ op = DOCATCH(doeval(gimme, NULL, Nullcv, PL_curcop->cop_seq));
/* Restore encoding. */
PL_encoding = encoding;
char *safestr;
STRLEN len;
OP *ret;
+ CV* runcv;
+ U32 seq;
if (!SvPV(sv,len))
RETPUSHUNDEF;
PL_compiling.cop_io = newSVsv(PL_curcop->cop_io);
SAVEFREESV(PL_compiling.cop_io);
}
+ /* special case: an eval '' executed within the DB package gets lexically
+ * placed in the first non-DB CV rather than the current CV - this
+ * allows the debugger to execute code, find lexicals etc, in the
+ * scope of the code being debugged. Passing &seq gets find_runcv
+ * to do the dirty work for us */
+ runcv = find_runcv(&seq);
push_return(PL_op->op_next);
PUSHBLOCK(cx, (CXt_EVAL|CXp_REAL), SP);
if (PERLDB_LINE && PL_curstash != PL_debstash)
save_lines(CopFILEAV(&PL_compiling), PL_linestr);
PUTBACK;
- ret = doeval(gimme, NULL);
+ ret = doeval(gimme, NULL, runcv, seq);
if (PERLDB_INTER && was != (I32)PL_sub_generation /* Some subs defined here. */
&& ret != PL_op->op_next) { /* Successive compilation. */
strcpy(safestr, "_<(eval )"); /* Anything fake and short. */
/* Unassume the success we assumed earlier. */
SV *nsv = cx->blk_eval.old_namesv;
(void)hv_delete(GvHVn(PL_incgv), SvPVX(nsv), SvCUR(nsv), G_DISCARD);
- retop = Perl_die(aTHX_ "%s did not return a true value", SvPVX(nsv));
+ retop = Perl_die(aTHX_ "%"SVf" did not return a true value", nsv);
/* die_where() did LEAVE, or we won't be here */
}
else {
bool noblank = FALSE;
bool repeat = FALSE;
bool postspace = FALSE;
- U16 *fops;
- register U16 *fpc;
- U16 *linepc = 0;
+ U32 *fops;
+ register U32 *fpc;
+ U32 *linepc = 0;
register I32 arg;
bool ischop;
+ int maxops = 2; /* FF_LINEMARK + FF_END) */
if (len == 0)
Perl_croak(aTHX_ "Null picture in formline");
- New(804, fops, (send - s)*3+10, U16); /* Almost certainly too long... */
+ /* estimate the buffer size needed */
+ for (base = s; s <= send; s++) {
+ if (*s == '\n' || *s == '@' || *s == '^')
+ maxops += 10;
+ }
+ s = base;
+ base = Nullch;
+
+ New(804, fops, maxops, U32);
fpc = fops;
if (s < send) {
}
*fpc++ = FF_END;
+ assert (fpc <= fops + maxops); /* ensure our buffer estimate was valid */
arg = fpc - fops;
{ /* need to jump to the next word */
int z;
z = WORD_ALIGN - SvCUR(sv) % WORD_ALIGN;
- SvGROW(sv, SvCUR(sv) + z + arg * sizeof(U16) + 4);
+ SvGROW(sv, SvCUR(sv) + z + arg * sizeof(U32) + 4);
s = SvPVX(sv) + SvCUR(sv) + z;
}
- Copy(fops, s, arg, U16);
+ Copy(fops, s, arg, U32);
Safefree(fops);
sv_magic(sv, Nullsv, PERL_MAGIC_fm, Nullch, 0);
SvCOMPILED_on(sv);