REGEXP *re = NULL;
REGEXP *new_re;
const regexp_engine *eng;
- bool is_bare_re;
+ bool is_bare_re= FALSE;
if (PL_op->op_flags & OPf_STACKED) {
dMARK;
assert (re != (REGEXP*) &PL_sv_undef);
eng = re ? RX_ENGINE(re) : current_re_engine();
+ /*
+ In the below logic: these are basically the same - check if this regcomp is part of a split.
+
+ (PL_op->op_pmflags & PMf_split )
+ (PL_op->op_next->op_type == OP_PUSHRE)
+
+ We could add a new mask for this and copy the PMf_split, if we did
+ some bit definition fiddling first.
+
+ For now we leave this
+ */
+
new_re = (eng->op_comp
? eng->op_comp
: &Perl_re_op_compile
)(aTHX_ args, nargs, pm->op_code_list, eng, re,
&is_bare_re,
- (pm->op_pmflags & RXf_PMf_COMPILETIME),
+ (pm->op_pmflags & RXf_PMf_FLAGCOPYMASK),
pm->op_pmflags |
(PL_op->op_flags & OPf_SPECIAL ? PMf_USE_RE_EVAL : 0));
+
if (pm->op_pmflags & PMf_HAS_CV)
ReANY(new_re)->qr_anoncv
= (CV*) SvREFCNT_inc(PAD_SV(PL_op->op_targ));
modified by get-magic), to avoid incorrectly setting the
RXf_TAINTED flag with RX_TAINT_on further down. */
TAINT_set(was_tainted);
+#if NO_TAINT_SUPPORT
+ PERL_UNUSED_VAR(was_tainted);
+#endif
}
tmp = reg_temp_copy(NULL, new_re);
ReREFCNT_dec(new_re);
new_re = tmp;
}
+
if (re != new_re) {
ReREFCNT_dec(re);
PM_SETRE(pm, new_re);
}
+
#ifndef INCOMPLETE_TAINTS
if (TAINTING_get && TAINT_get) {
SvTAINTED_on((SV*)new_re);
}
rxres_restore(&cx->sb_rxres, rx);
- RX_MATCH_UTF8_set(rx, DO_UTF8(cx->sb_targ));
if (cx->sb_iters++) {
const I32 saviters = cx->sb_iters;
if (SvTAINTED(TOPs))
cx->sb_rxtainted |= SUBST_TAINT_REPL;
sv_catsv_nomg(dstr, POPs);
- /* XXX: adjust for positive offsets of \G for instance s/(.)\G//g with positive pos() */
- s -= RX_GOFS(rx);
-
- /* Are we done */
if (CxONCE(cx) || s < orig ||
- !CALLREGEXEC(rx, s, cx->sb_strend, orig,
- (s == m) + RX_GOFS(rx), cx->sb_targ, NULL,
- (REXEC_IGNOREPOS|REXEC_NOT_FIRST)))
+ !CALLREGEXEC(rx, s, cx->sb_strend, orig,
+ (s == m), cx->sb_targ, NULL,
+ (REXEC_IGNOREPOS|REXEC_NOT_FIRST|REXEC_FAIL_ON_UNDERFLOW)))
{
SV *targ = cx->sb_targ;
TAINT_NOT;
LEAVE_SCOPE(cx->sb_oldsave);
POPSUBST(cx);
+ PERL_ASYNC_CHECK();
RETURNOP(pm->op_next);
assert(0); /* NOTREACHED */
}
SV * const sv
= (pm->op_pmflags & PMf_NONDESTRUCT) ? cx->sb_dstr : cx->sb_targ;
MAGIC *mg;
- SvUPGRADE(sv, SVt_PVMG);
- if (!(mg = mg_find(sv, PERL_MAGIC_regex_global))) {
-#ifdef PERL_OLD_COPY_ON_WRITE
- if (SvIsCOW(sv))
- sv_force_normal_flags(sv, 0);
-#endif
- mg = sv_magicext(sv, NULL, PERL_MAGIC_regex_global, &PL_vtbl_mglob,
- NULL, 0);
+ if (!(mg = mg_find_mglob(sv))) {
+ mg = sv_magicext_mglob(sv);
}
mg->mg_len = m - orig;
}
PERL_UNUSED_CONTEXT;
if (!p || p[1] < RX_NPARENS(rx)) {
-#ifdef PERL_OLD_COPY_ON_WRITE
+#ifdef PERL_ANY_COW
i = 7 + (RX_NPARENS(rx)+1) * 2;
#else
i = 6 + (RX_NPARENS(rx)+1) * 2;
RX_MATCH_COPIED_off(rx);
*p++ = RX_NPARENS(rx);
-#ifdef PERL_OLD_COPY_ON_WRITE
+#ifdef PERL_ANY_COW
*p++ = PTR2UV(RX_SAVED_COPY(rx));
RX_SAVED_COPY(rx) = NULL;
#endif
*p++ = 0;
RX_NPARENS(rx) = *p++;
-#ifdef PERL_OLD_COPY_ON_WRITE
+#ifdef PERL_ANY_COW
if (RX_SAVED_COPY(rx))
SvREFCNT_dec (RX_SAVED_COPY(rx));
RX_SAVED_COPY(rx) = INT2PTR(SV*,*p);
if (p) {
void *tmp = INT2PTR(char*,*p);
#ifdef PERL_POISON
-#ifdef PERL_OLD_COPY_ON_WRITE
+#ifdef PERL_ANY_COW
U32 i = 9 + p[1] * 2;
#else
U32 i = 8 + p[1] * 2;
#endif
#endif
-#ifdef PERL_OLD_COPY_ON_WRITE
+#ifdef PERL_ANY_COW
SvREFCNT_dec (INT2PTR(SV*,p[2]));
#endif
#ifdef PERL_POISON
SAVEVPTR(PL_curpm);
src = PL_stack_base[*PL_markstack_ptr];
+ if (SvPADTMP(src) && !IS_PADGV(src)) {
+ src = PL_stack_base[*PL_markstack_ptr] = sv_mortalcopy(src);
+ PL_tmps_floor++;
+ }
SvTEMP_off(src);
if (PL_op->op_private & OPpGREP_LEX)
PAD_SVl(PL_op->op_targ) = src;
/* set $_ to the new source item */
src = PL_stack_base[PL_markstack_ptr[-1]];
+ if (SvPADTMP(src) && !IS_PADGV(src)) src = sv_mortalcopy(src);
SvTEMP_off(src);
if (PL_op->op_private & OPpGREP_LEX)
PAD_SVl(PL_op->op_targ) = src;
switch (CxTYPE(cx)) {
default:
continue;
- case CXt_EVAL:
case CXt_SUB:
+ /* in sub foo { /(?{...})/ }, foo ends up on the CX stack
+ * twice; the first for the normal foo() call, and the second
+ * for a faked up re-entry into the sub to execute the
+ * code block. Hide this faked entry from the world. */
+ if (cx->cx_type & CXp_SUB_RE_FAKE)
+ continue;
+ case CXt_EVAL:
case CXt_FORMAT:
DEBUG_l( Perl_deb(aTHX_ "(dopoptosub_at(): found sub at cx=%ld)\n", (long)i));
return i;
sv_setsv(ERRSV, exceptsv);
}
+ if (in_eval & EVAL_KEEPERR) {
+ Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "\t(in cleanup) %"SVf,
+ SVfARG(exceptsv));
+ }
+
while ((cxix = dopoptoeval(cxstack_ix)) < 0
&& PL_curstackinfo->si_prev)
{
SVfARG(exceptsv ? exceptsv : newSVpvs_flags("Unknown error\n",
SVs_TEMP)));
}
- if (in_eval & EVAL_KEEPERR) {
- Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "\t(in cleanup) %"SVf,
- SVfARG(exceptsv));
- }
- else {
+ if (!(in_eval & EVAL_KEEPERR))
sv_setsv(ERRSV, exceptsv);
- }
PL_restartjmpenv = restartjmpenv;
PL_restartop = restartop;
JMPENV_JUMP(3);
PUSHSUB_DB(cx);
cx->blk_sub.retop = PL_op->op_next;
CvDEPTH(cv)++;
+ if (CvDEPTH(cv) >= 2) {
+ PERL_STACK_OVERFLOW_CHECK();
+ pad_push(CvPADLIST(cv), CvDEPTH(cv));
+ }
SAVECOMPPAD();
- PAD_SET_CUR_NOSAVE(CvPADLIST(cv), 1);
+ PAD_SET_CUR_NOSAVE(CvPADLIST(cv), CvDEPTH(cv));
RETURNOP(CvSTART(cv));
}
}
if (PL_scopestack_ix < inner)
leave_scope(PL_scopestack[PL_scopestack_ix]);
PL_curcop = cx->blk_oldcop;
+ PERL_ASYNC_CHECK();
return (cx)->blk_loop.my_op->op_nextop;
}
LEAVE_SCOPE(oldsave);
FREETMPS;
PL_curcop = cx->blk_oldcop;
+ PERL_ASYNC_CHECK();
return redo_op;
}
{
dVAR;
OP **ops = opstack;
- static const char too_deep[] = "Target of goto is too deeply nested";
+ static const char* const too_deep = "Target of goto is too deeply nested";
PERL_ARGS_ASSERT_DOFINDLABEL;
if (ops >= oplimit)
- Perl_croak(aTHX_ too_deep);
+ Perl_croak(aTHX_ "%s", too_deep);
if (o->op_type == OP_LEAVE ||
o->op_type == OP_SCOPE ||
o->op_type == OP_LEAVELOOP ||
{
*ops++ = cUNOPo->op_first;
if (ops >= oplimit)
- Perl_croak(aTHX_ too_deep);
+ Perl_croak(aTHX_ "%s", too_deep);
}
*ops = 0;
if (o->op_flags & OPf_KIDS) {
STRLEN label_len = 0;
U32 label_flags = 0;
const bool do_dump = (PL_op->op_type == OP_DUMP);
- static const char must_have_label[] = "goto must have label";
+ static const char* const must_have_label = "goto must have label";
if (PL_op->op_flags & OPf_STACKED) {
SV * const sv = POPs;
+ SvGETMAGIC(sv);
/* This egregious kludge implements goto &subroutine */
if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVCV) {
SvREFCNT_inc_simple_void(cv); /* avoid premature free during unwind */
FREETMPS;
cxix = dopoptosub(cxstack_ix);
- if (cxix < 0)
- {
- SvREFCNT_dec(cv);
- DIE(aTHX_ "Can't goto subroutine outside a subroutine");
- }
- if (cxix < cxstack_ix)
+ if (cxix < cxstack_ix) {
+ if (cxix < 0) {
+ SvREFCNT_dec(cv);
+ DIE(aTHX_ "Can't goto subroutine outside a subroutine");
+ }
dounwind(cxix);
+ }
TOPBLOCK(cx);
SPAGAIN;
/* ban goto in eval: see <20050521150056.GC20213@iabyn.com> */
SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
if (CvISXSUB(cv)) {
OP* const retop = cx->blk_sub.retop;
- SV **newsp PERL_UNUSED_DECL;
- I32 gimme PERL_UNUSED_DECL;
+ SV **newsp;
+ I32 gimme;
const SSize_t items = AvFILLp(arg) + 1;
SV** mark;
+ PERL_UNUSED_VAR(newsp);
+ PERL_UNUSED_VAR(gimme);
+
/* put GvAV(defgv) back onto stack */
EXTEND(SP, items+1); /* @_ could have been extended. */
Copy(AvARRAY(arg), SP + 1, items, SV*);
PUTBACK;
(void)(*CvXSUB(cv))(aTHX_ cv);
LEAVE;
+ PERL_ASYNC_CHECK();
return retop;
}
else {
}
}
}
+ PERL_ASYNC_CHECK();
RETURNOP(CvSTART(cv));
}
}
else {
- label = SvPV_const(sv, label_len);
+ label = SvPV_nomg_const(sv, label_len);
label_flags = SvUTF8(sv);
}
}
label_flags = (cPVOP->op_private & OPpPV_IS_UTF8) ? SVf_UTF8 : 0;
label_len = strlen(label);
}
- if (!(do_dump || label_len)) DIE(aTHX_ must_have_label);
+ if (!(do_dump || label_len)) DIE(aTHX_ "%s", must_have_label);
PERL_ASYNC_CHECK();
PL_lastgotoprobe = gotoprobe;
}
if (!retop)
- DIE(aTHX_ "Can't find label %"SVf,
- SVfARG(newSVpvn_flags(label, label_len,
- SVs_TEMP | label_flags)));
+ DIE(aTHX_ "Can't find label %"UTF8f,
+ UTF8fARG(label_flags, label_len, label));
/* if we're leaving an eval, check before we pop any frames
that we're not going to punt, otherwise the error
PL_do_undump = FALSE;
}
+ PERL_ASYNC_CHECK();
RETURNOP(retop);
}
*db_seqp = cx->blk_oldcop->cop_seq;
continue;
}
+ if (cx->cx_type & CXp_SUB_RE)
+ continue;
}
else if (CxTYPE(cx) == CXt_EVAL && !CxTRYBLOCK(cx))
cv = cx->blk_eval.cv;
PL_in_eval = (in_require
? (EVAL_INREQUIRE | (PL_in_eval & EVAL_INEVAL))
- : EVAL_INEVAL);
+ : (EVAL_INEVAL |
+ ((PL_op->op_private & OPpEVAL_RE_REPARSING)
+ ? EVAL_RE_REPARSING : 0)));
PUSHMARK(SP);
if (CopSTASH_ne(PL_curcop, PL_curstash)) {
SAVEGENERICSV(PL_curstash);
- PL_curstash = (HV *)SvREFCNT_inc_simple(CopSTASH(PL_curcop));
+ PL_curstash = (HV *)CopSTASH(PL_curcop);
+ if (SvTYPE(PL_curstash) != SVt_PVHV) PL_curstash = NULL;
+ else SvREFCNT_inc_simple_void(PL_curstash);
}
/* XXX:ajgo do we really need to alloc an AV for begin/checkunit */
SAVESPTR(PL_beginav);
else {
PL_hints = saveop->op_private & OPpEVAL_COPHH
? oldcurcop->cop_hints : saveop->op_targ;
+
+ /* making 'use re eval' not be in scope when compiling the
+ * qr/mabye_has_runtime_code_block/ ensures that we don't get
+ * infinite recursion when S_has_runtime_code() gives a false
+ * positive: the second time round, HINT_RE_EVAL isn't set so we
+ * don't bother calling S_has_runtime_code() */
+ if (PL_in_eval & EVAL_RE_REPARSING)
+ PL_hints &= ~HINT_RE_EVAL;
+
if (hh) {
/* SAVEHINTS created a new HV in PL_hintgv, which we need to GC */
SvREFCNT_dec(GvHV(PL_hintgv));
PERL_CONTEXT *cx;
I32 optype; /* Used by POPEVAL. */
SV *namesv;
+ SV *errsv = NULL;
cx = NULL;
namesv = NULL;
LEAVE_with_name("eval"); /* pp_entereval knows about this LEAVE. */
}
+ errsv = ERRSV;
if (in_require) {
if (!cx) {
/* If cx is still NULL, it means that we didn't go in the
SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
&PL_sv_undef, 0);
Perl_croak(aTHX_ "%"SVf"Compilation failed in require",
- SVfARG(ERRSV
- ? ERRSV
+ SVfARG(errsv
+ ? errsv
: newSVpvs_flags("Unknown error\n", SVs_TEMP)));
}
else {
- if (!*(SvPVx_nolen_const(ERRSV))) {
- sv_setpvs(ERRSV, "Compilation error");
+ if (!*(SvPV_nolen_const(errsv))) {
+ sv_setpvs(errsv, "Compilation error");
}
}
if (gimme != G_ARRAY) PUSHs(&PL_sv_undef);
# define doopen_pm(name) check_type_and_open(name)
#endif /* !PERL_DISABLE_PMC */
+/* require doesn't search for absolute names, or when the name is
+ explicity relative the current directory */
+PERL_STATIC_INLINE bool
+S_path_is_searchable(const char *name)
+{
+ PERL_ARGS_ASSERT_PATH_IS_SEARCHABLE;
+
+ if (PERL_FILE_IS_ABSOLUTE(name)
+#ifdef WIN32
+ || (*name == '.' && ((name[1] == '/' ||
+ (name[1] == '.' && name[2] == '/'))
+ || (name[1] == '\\' ||
+ ( name[1] == '.' && name[2] == '\\')))
+ )
+#else
+ || (*name == '.' && (name[1] == '/' ||
+ (name[1] == '.' && name[2] == '/')))
+#endif
+ )
+ {
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
PP(pp_require)
{
dVAR; dSP;
SV *encoding;
OP *op;
int saved_errno;
+ bool path_searchable;
sv = POPs;
if ( (SvNIOKp(sv) || SvVOK(sv)) && PL_op->op_type != OP_DOFILE) {
DIE(aTHX_ "Null filename used");
TAINT_PROPER("require");
+ path_searchable = path_is_searchable(name);
#ifdef VMS
/* The key in the %ENV hash is in the syntax of file passed as the argument
/* prepare to compile file */
- if (path_is_absolute(name)) {
+ if (!path_searchable) {
/* At this point, name is SvPVX(sv) */
tryname = name;
tryrsfp = doopen_pm(sv);
}
- if (!tryrsfp && !(errno == EACCES && path_is_absolute(name))) {
+ if (!tryrsfp && !(errno == EACCES && !path_searchable)) {
AV * const ar = GvAVn(PL_incgv);
I32 i;
#ifdef VMS
if (SvROK(arg) && (SvTYPE(SvRV(arg)) <= SVt_PVLV)
&& !isGV_with_GP(SvRV(arg))) {
filter_cache = SvRV(arg);
- SvREFCNT_inc_simple_void_NN(filter_cache);
if (i < count) {
arg = SP[i++];
}
filter_has_file = 0;
- if (filter_cache) {
- SvREFCNT_dec(filter_cache);
- filter_cache = NULL;
- }
+ filter_cache = NULL;
if (filter_state) {
SvREFCNT_dec(filter_state);
filter_state = NULL;
}
}
else {
- if (!path_is_absolute(name)
- ) {
+ if (path_searchable) {
const char *dir;
STRLEN dirlen;
memcpy(tmp, dir, dirlen);
tmp +=dirlen;
- *tmp++ = '/';
+
+ /* Avoid '<dir>//<file>' */
+ if (!dirlen || *(tmp-1) != '/') {
+ *tmp++ = '/';
+ }
+
/* name came from an SV, so it will have a '\0' at the
end that we can copy as part of this memcpy(). */
memcpy(tmp, name, len + 1);
if (tryrsfp) {
if (tryname[0] == '.' && tryname[1] == '/') {
++tryname;
- while (*++tryname == '/');
+ while (*++tryname == '/') {}
}
break;
}
than hanging another SV from it. In turn, filter_add() optionally
takes the SV to use as the filter (or creates a new SV if passed
NULL), so simply pass in whatever value filter_cache has. */
- SV * const datasv = filter_add(S_run_user_filter, filter_cache);
+ SV * const fc = filter_cache ? newSV(0) : NULL;
+ SV *datasv;
+ if (fc) sv_copypv(fc, filter_cache);
+ datasv = filter_add(S_run_user_filter, fc);
IoLINES(datasv) = filter_has_file;
IoTOP_GV(datasv) = MUTABLE_GV(filter_state);
IoBOTTOM_GV(datasv) = MUTABLE_GV(filter_sub);
leave_scope(PL_scopestack[PL_scopestack_ix]);
PL_curcop = cx->blk_oldcop;
+ PERL_ASYNC_CHECK();
return cx->blk_loop.my_op->op_nextop;
}
- else
+ else {
+ PERL_ASYNC_CHECK();
RETURNOP(cx->blk_givwhen.leave_op);
+ }
}
PP(pp_continue)
if (SvOK(out)) {
status = SvIV(out);
}
- else if (SvTRUE(ERRSV)) {
- err = newSVsv(ERRSV);
+ else {
+ SV * const errsv = ERRSV;
+ if (SvTRUE_NN(errsv))
+ err = newSVsv(errsv);
}
}
return status;
}
-/* perhaps someone can come up with a better name for
- this? it is not really "absolute", per se ... */
-static bool
-S_path_is_absolute(const char *name)
-{
- PERL_ARGS_ASSERT_PATH_IS_ABSOLUTE;
-
- if (PERL_FILE_IS_ABSOLUTE(name)
-#ifdef WIN32
- || (*name == '.' && ((name[1] == '/' ||
- (name[1] == '.' && name[2] == '/'))
- || (name[1] == '\\' ||
- ( name[1] == '.' && name[2] == '\\')))
- )
-#else
- || (*name == '.' && (name[1] == '/' ||
- (name[1] == '.' && name[2] == '/')))
-#endif
- )
- {
- return TRUE;
- }
- else
- return FALSE;
-}
-
/*
* Local variables:
* c-indentation-style: bsd