the near identical code in pp_entertry into Perl_create_eval_scope.
Move the cut & paste code from Perl_call_sv/Perl_fold_constants into
Perl_delete_eval_scope.
p4raw-id: //depot/perl@27617
#define G_KEEPERR 16 /* Append errors to $@, don't overwrite it */
#define G_NODEBUG 32 /* Disable debugging at toplevel. */
#define G_METHOD 64 /* Calling method. */
+#define G_FAKINGEVAL 256 /* Faking en eval context for call_sv or
+ fold_constants. */
/* flag bits for PL_in_eval */
#define EVAL_NULL 0 /* not in an eval */
ApR |I32 |my_chsize |int fd|Off_t length
#endif
pR |OP* |convert |I32 optype|I32 flags|NULLOK OP* o
+pM |PERL_CONTEXT* |create_eval_scope|U32 flags
: croak()'s first parm can be NULL. Otherwise, mod_perl breaks.
Afprd |void |croak |NULLOK const char* pat|...
Apr |void |vcroak |NN const char* pat|NULLOK va_list* args
Ap |I32 |debstackptrs
Ap |char* |delimcpy |NN char* to|NN const char* toend|NN const char* from \
|NN const char* fromend|int delim|NN I32* retlen
+pM |void |delete_eval_scope
p |void |deprecate |NN const char* s
p |void |deprecate_old |NN const char* s
Afp |OP* |die |NULLOK const char* pat|...
#endif
#ifdef PERL_CORE
#define convert Perl_convert
+#define create_eval_scope Perl_create_eval_scope
#endif
#define croak Perl_croak
#define vcroak Perl_vcroak
#define debstackptrs Perl_debstackptrs
#define delimcpy Perl_delimcpy
#ifdef PERL_CORE
+#define delete_eval_scope Perl_delete_eval_scope
#define deprecate Perl_deprecate
#define deprecate_old Perl_deprecate_old
#endif
#endif
#ifdef PERL_CORE
#define convert(a,b,c) Perl_convert(aTHX_ a,b,c)
+#define create_eval_scope(a) Perl_create_eval_scope(aTHX_ a)
#endif
#define vcroak(a,b) Perl_vcroak(aTHX_ a,b)
#if defined(PERL_IMPLICIT_CONTEXT)
#define debstackptrs() Perl_debstackptrs(aTHX)
#define delimcpy(a,b,c,d,e,f) Perl_delimcpy(aTHX_ a,b,c,d,e,f)
#ifdef PERL_CORE
+#define delete_eval_scope() Perl_delete_eval_scope(aTHX)
#define deprecate(a) Perl_deprecate(aTHX_ a)
#define deprecate_old(a) Perl_deprecate_old(aTHX_ a)
#endif
use Carp;
use Test::More tests => ( # per-pkg tests (function ct + require_ok)
40 + 16 # Data::Dumper, Digest::MD5
- + 511 + 234 # B::Deparse, B
+ + 511 + 235 # B::Deparse, B
+ 588 + 189 # POSIX, IO::Socket
+ 3 * ($] > 5.009)
+ 14 * ($] >= 5.009003)
PL_op = curop;
oldscope = PL_scopestack_ix;
+ create_eval_scope(G_FAKINGEVAL);
- /* we're trying to emulate pp_entertry() here */
- {
- register PERL_CONTEXT *cx;
- const I32 gimme = GIMME_V;
-
- ENTER;
- SAVETMPS;
-
- PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
- PUSHEVAL(cx, 0, 0);
- PL_eval_root = PL_op; /* Only needed so that goto works right. */
-
- PL_in_eval = EVAL_INEVAL;
- sv_setpvn(ERRSV,"",0);
- }
JMPENV_PUSH(ret);
switch (ret) {
}
JMPENV_POP;
- if (PL_scopestack_ix > oldscope) {
- SV **newsp;
- PMOP *newpm;
- I32 gimme;
- register PERL_CONTEXT *cx;
- I32 optype;
-
- POPBLOCK(cx,newpm);
- POPEVAL(cx);
- PL_curpm = newpm;
- LEAVE;
- PERL_UNUSED_VAR(newsp);
- PERL_UNUSED_VAR(gimme);
- PERL_UNUSED_VAR(optype);
- }
+
+ if (PL_scopestack_ix > oldscope)
+ delete_eval_scope();
if (ret)
goto nope;
else {
myop.op_other = (OP*)&myop;
PL_markstack_ptr--;
- /* we're trying to emulate pp_entertry() here */
- {
- register PERL_CONTEXT *cx;
- const I32 gimme = GIMME_V;
-
- ENTER;
- SAVETMPS;
-
- PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
- PUSHEVAL(cx, 0, 0);
- PL_eval_root = PL_op; /* Only needed so that goto works right. */
-
- PL_in_eval = EVAL_INEVAL;
- if (flags & G_KEEPERR)
- PL_in_eval |= EVAL_KEEPERR;
- else
- sv_setpvn(ERRSV,"",0);
- }
+ create_eval_scope(flags|G_FAKINGEVAL);
PL_markstack_ptr++;
JMPENV_PUSH(ret);
+
switch (ret) {
case 0:
redo_body:
break;
}
- if (PL_scopestack_ix > oldscope) {
- SV **newsp;
- PMOP *newpm;
- I32 gimme;
- register PERL_CONTEXT *cx;
- I32 optype;
-
- POPBLOCK(cx,newpm);
- POPEVAL(cx);
- PL_curpm = newpm;
- LEAVE;
- PERL_UNUSED_VAR(newsp);
- PERL_UNUSED_VAR(gimme);
- PERL_UNUSED_VAR(optype);
- }
+ if (PL_scopestack_ix > oldscope)
+ delete_eval_scope();
JMPENV_POP;
}
RETURNOP(retop);
}
-PP(pp_entertry)
+/* Common code for Perl_call_sv and Perl_fold_constants, put here to keep it
+ close to the related Perl_create_eval_scope. */
+void
+Perl_delete_eval_scope(pTHX)
{
- dVAR; dSP;
+ SV **newsp;
+ PMOP *newpm;
+ I32 gimme;
register PERL_CONTEXT *cx;
- const I32 gimme = GIMME_V;
+ I32 optype;
+
+ POPBLOCK(cx,newpm);
+ POPEVAL(cx);
+ PL_curpm = newpm;
+ LEAVE;
+ PERL_UNUSED_VAR(newsp);
+ PERL_UNUSED_VAR(gimme);
+ PERL_UNUSED_VAR(optype);
+}
+/* Common-ish code salvaged from Perl_call_sv and pp_entertry, because it was
+ also needed by Perl_fold_constants. */
+PERL_CONTEXT *
+Perl_create_eval_scope(pTHX_ U32 flags)
+{
+ PERL_CONTEXT *cx;
+ const I32 gimme = GIMME_V;
+
ENTER;
SAVETMPS;
- PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), SP);
+ PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
PUSHEVAL(cx, 0, 0);
- cx->blk_eval.retop = cLOGOP->op_other->op_next;
+ PL_eval_root = PL_op; /* Only needed so that goto works right. */
PL_in_eval = EVAL_INEVAL;
- sv_setpvn(ERRSV,"",0);
- PUTBACK;
+ if (flags & G_KEEPERR)
+ PL_in_eval |= EVAL_KEEPERR;
+ else
+ sv_setpvn(ERRSV,"",0);
+ if (flags & G_FAKINGEVAL) {
+ PL_eval_root = PL_op; /* Only needed so that goto works right. */
+ }
+ return cx;
+}
+
+PP(pp_entertry)
+{
+ dVAR;
+ PERL_CONTEXT *cx = create_eval_scope(0);
+ cx->blk_eval.retop = cLOGOP->op_other->op_next;
return DOCATCH(PL_op->op_next);
}
PERL_CALLCONV OP* Perl_convert(pTHX_ I32 optype, I32 flags, OP* o)
__attribute__warn_unused_result__;
+PERL_CALLCONV PERL_CONTEXT* Perl_create_eval_scope(pTHX_ U32 flags);
PERL_CALLCONV void Perl_croak(pTHX_ const char* pat, ...)
__attribute__noreturn__
__attribute__format__(__printf__,pTHX_1,pTHX_2);
__attribute__nonnull__(pTHX_4)
__attribute__nonnull__(pTHX_6);
+PERL_CALLCONV void Perl_delete_eval_scope(pTHX);
PERL_CALLCONV void Perl_deprecate(pTHX_ const char* s)
__attribute__nonnull__(pTHX_1);