#define op_name Perl_op_name
#define op_seqmax Perl_op_seqmax
#define opargs Perl_opargs
+#define opsave Perl_opsave
#define origalen Perl_origalen
#define origenviron Perl_origenviron
#define osname Perl_osname
#define save_list Perl_save_list
#define save_long Perl_save_long
#define save_nogv Perl_save_nogv
+#define save_op Perl_save_op
#define save_pptr Perl_save_pptr
#define save_scalar Perl_save_scalar
#define save_sptr Perl_save_sptr
op_name
op_seqmax
opargs
+opsave
origalen
origenviron
osname
save_list
save_long
save_nogv
+save_op
save_pptr
save_scalar
save_sptr
myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED;
ENTER;
- SAVESPTR(op);
+ SAVEOP();
op = (OP *) &myop;
if (perldb && curstash != debstash)
op->op_private |= OPpENTERSUB_DB;
if (!o || o->op_seq)
return;
ENTER;
- SAVESPTR(op);
+ SAVEOP();
SAVESPTR(curcop);
for (; o; o = o->op_next) {
if (o->op_seq)
myop.op_flags |= ((flags & G_VOID) ? OPf_WANT_VOID :
(flags & G_ARRAY) ? OPf_WANT_LIST :
OPf_WANT_SCALAR);
- SAVESPTR(op);
+ SAVEOP();
op = (OP*)&myop;
EXTEND(stack_sp, 1);
SAVETMPS;
}
- SAVESPTR(op);
+ SAVEOP();
op = (OP*)&myop;
Zero(op, 1, UNOP);
EXTEND(stack_sp, 1);
#include "embed.h"
+#ifdef OP_IN_REGISTER
+# ifdef __GNUC__
+# define stringify_immed(s) #s
+# define stringify(s) stringify_immed(s)
+register struct op *op asm(stringify(OP_IN_REGISTER));
+# endif
+#endif
+
/*
* STMT_START { statements; } STMT_END;
* can be used as a single statement, as in
# endif
#endif
+#define NOOP (void)0
+
#ifdef USE_THREADS
#include <pthread.h>
#endif
#endif
+/* Digital UNIX defines CONTEXT when pthreads is in use */
+#ifdef CONTEXT
+# undef CONTEXT
+#endif
+
typedef MEM_SIZE STRLEN;
typedef struct op OP;
/* likewise for these */
-EXT OP * op; /* current op--oughta be in a global register */
-
+#ifdef OP_IN_REGISTER
+EXT OP * opsave; /* save current op register across longjmps */
+#else
+EXT OP * op; /* current op--when not in a global register */
+#endif
EXT I32 * scopestack; /* blocks we've entered */
EXT I32 scopestack_ix;
EXT I32 scopestack_max;
bool oldcatch = CATCH_GET;
SAVETMPS;
- SAVESPTR(op);
+ SAVEOP();
oldstack = curstack;
if (!sortstack) {
CATCH_SET(TRUE);
ENTER;
- SAVESPTR(op);
+ SAVEOP();
op = (OP *) &myop;
if (perldb && curstash != debstash)
op->op_private |= OPpENTERSUB_DB;
CATCH_SET(TRUE);
ENTER;
- SAVESPTR(op);
+ SAVEOP();
op = (OP *) &myop;
if (perldb && curstash != debstash)
op->op_private |= OPpENTERSUB_DB;
void save_list _((SV** sarg, I32 maxsarg));
void save_long _((long* longp));
void save_nogv _((GV* gv));
+void save_op _((void));
SV* save_scalar _((GV* gv));
void save_pptr _((char** pptr));
void save_sptr _((SV** sptr));
}
void
+save_op()
+{
+ dTHR;
+ SSCHECK(2);
+ SSPUSHPTR(op);
+ SSPUSHINT(SAVEt_OP);
+}
+
+void
leave_scope(base)
I32 base;
{
stack_sp = stack_base + delta;
}
break;
+ case SAVEt_OP:
+ op = (OP*)SSPOPPTR;
+ break;
default:
croak("panic: leave_scope inconsistency");
}
#define SAVEt_REGCONTEXT 21
#define SAVEt_STACK_POS 22
#define SAVEt_I16 23
+#define SAVEt_OP 24
#define SSCHECK(need) if (savestack_ix + need > savestack_max) savestack_grow()
#define SSPUSHINT(i) (savestack[savestack_ix++].any_i32 = (I32)(i))
SSPUSHINT(stack_sp - stack_base); \
SSPUSHINT(SAVEt_STACK_POS); \
} STMT_END
-
+#define SAVEOP() save_op()
/* A jmpenv packages the state required to perform a proper non-local jump.
* Note that there is a start_env initialized when perl starts, and top_env
typedef struct jmpenv JMPENV;
+#ifdef OP_IN_REGISTER
+#define OP_REG_TO_MEM opsave = op
+#define OP_MEM_TO_REG op = opsave
+#else
+#define OP_REG_TO_MEM NOOP
+#define OP_MEM_TO_REG NOOP
+#endif
+
#define dJMPENV JMPENV cur_env
#define JMPENV_PUSH(v) \
STMT_START { \
cur_env.je_prev = top_env; \
+ OP_REG_TO_MEM; \
cur_env.je_ret = Sigsetjmp(cur_env.je_buf, 1); \
+ OP_MEM_TO_REG; \
top_env = &cur_env; \
cur_env.je_mustcatch = FALSE; \
(v) = cur_env.je_ret; \
STMT_START { top_env = cur_env.je_prev; } STMT_END
#define JMPENV_JUMP(v) \
STMT_START { \
+ OP_REG_TO_MEM; \
if (top_env->je_prev) \
Siglongjmp(top_env->je_buf, (v)); \
if ((v) == 2) \
SV ** Tstack_sp;
SV ** Tstack_max;
+#ifdef OP_IN_REGISTER
+ OP * Topsave;
+#else
OP * Top;
+#endif
I32 * Tscopestack;
I32 Tscopestack_ix;
#undef curpad
#undef Sv
#undef Xpv
-#undef op
#undef top_env
#undef runlevel
#undef in_eval
#define stack_base (thr->Tstack_base)
#define stack_sp (thr->Tstack_sp)
#define stack_max (thr->Tstack_max)
+#ifdef OP_IN_REGISTER
+#define opsave (thr->Topsave)
+#else
+#undef op
#define op (thr->Top)
+#endif
#define stack (thr->Tstack)
#define mainstack (thr->Tmainstack)
#define markstack (thr->Tmarkstack)