summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embed.h2
-rw-r--r--global.sym2
-rw-r--r--gv.c2
-rw-r--r--op.c2
-rw-r--r--perl.c4
-rw-r--r--perl.h22
-rw-r--r--pp_ctl.c2
-rw-r--r--pp_sys.c4
-rw-r--r--proto.h1
-rw-r--r--scope.c12
-rw-r--r--scope.h14
-rw-r--r--thread.h10
12 files changed, 66 insertions, 11 deletions
diff --git a/embed.h b/embed.h
index 18368fa271..801ccf7be5 100644
--- a/embed.h
+++ b/embed.h
@@ -491,6 +491,7 @@
#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
@@ -941,6 +942,7 @@
#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
diff --git a/global.sym b/global.sym
index 219e9a518e..85c90ce030 100644
--- a/global.sym
+++ b/global.sym
@@ -150,6 +150,7 @@ op_desc
op_name
op_seqmax
opargs
+opsave
origalen
origenviron
osname
@@ -1045,6 +1046,7 @@ save_iv
save_list
save_long
save_nogv
+save_op
save_pptr
save_scalar
save_sptr
diff --git a/gv.c b/gv.c
index 50e90409c1..01cad2e149 100644
--- a/gv.c
+++ b/gv.c
@@ -1346,7 +1346,7 @@ int flags;
myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED;
ENTER;
- SAVESPTR(op);
+ SAVEOP();
op = (OP *) &myop;
if (perldb && curstash != debstash)
op->op_private |= OPpENTERSUB_DB;
diff --git a/op.c b/op.c
index 1f673da916..3e5cf6e9bd 100644
--- a/op.c
+++ b/op.c
@@ -4766,7 +4766,7 @@ register OP* o;
if (!o || o->op_seq)
return;
ENTER;
- SAVESPTR(op);
+ SAVEOP();
SAVESPTR(curcop);
for (; o; o = o->op_next) {
if (o->op_seq)
diff --git a/perl.c b/perl.c
index 242535a8cb..3e8cee7dc9 100644
--- a/perl.c
+++ b/perl.c
@@ -1126,7 +1126,7 @@ I32 flags; /* See G_* flags in cop.h */
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);
@@ -1259,7 +1259,7 @@ I32 flags; /* See G_* flags in cop.h */
SAVETMPS;
}
- SAVESPTR(op);
+ SAVEOP();
op = (OP*)&myop;
Zero(op, 1, UNOP);
EXTEND(stack_sp, 1);
diff --git a/perl.h b/perl.h
index 744905f453..4d229b97e6 100644
--- a/perl.h
+++ b/perl.h
@@ -29,6 +29,14 @@
#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
@@ -52,6 +60,8 @@
# endif
#endif
+#define NOOP (void)0
+
#ifdef USE_THREADS
#include <pthread.h>
#endif
@@ -843,6 +853,11 @@
#endif
+/* Digital UNIX defines CONTEXT when pthreads is in use */
+#ifdef CONTEXT
+# undef CONTEXT
+#endif
+
typedef MEM_SIZE STRLEN;
typedef struct op OP;
@@ -1361,8 +1376,11 @@ EXT SV ** stack_max; /* stack->array_ary + stack->array_max */
/* 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;
diff --git a/pp_ctl.c b/pp_ctl.c
index 2f3b2b7765..317ed70897 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -698,7 +698,7 @@ PP(pp_sort)
bool oldcatch = CATCH_GET;
SAVETMPS;
- SAVESPTR(op);
+ SAVEOP();
oldstack = curstack;
if (!sortstack) {
diff --git a/pp_sys.c b/pp_sys.c
index 1b25bf4c55..94f84b77be 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -522,7 +522,7 @@ PP(pp_tie)
CATCH_SET(TRUE);
ENTER;
- SAVESPTR(op);
+ SAVEOP();
op = (OP *) &myop;
if (perldb && curstash != debstash)
op->op_private |= OPpENTERSUB_DB;
@@ -633,7 +633,7 @@ PP(pp_dbmopen)
CATCH_SET(TRUE);
ENTER;
- SAVESPTR(op);
+ SAVEOP();
op = (OP *) &myop;
if (perldb && curstash != debstash)
op->op_private |= OPpENTERSUB_DB;
diff --git a/proto.h b/proto.h
index 28f239c412..5fbd81dd48 100644
--- a/proto.h
+++ b/proto.h
@@ -432,6 +432,7 @@ void save_iv _((IV* iv));
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));
diff --git a/scope.c b/scope.c
index 50c843d108..01b1fa9f59 100644
--- a/scope.c
+++ b/scope.c
@@ -438,6 +438,15 @@ void* p;
}
void
+save_op()
+{
+ dTHR;
+ SSCHECK(2);
+ SSPUSHPTR(op);
+ SSPUSHINT(SAVEt_OP);
+}
+
+void
leave_scope(base)
I32 base;
{
@@ -636,6 +645,9 @@ I32 base;
stack_sp = stack_base + delta;
}
break;
+ case SAVEt_OP:
+ op = (OP*)SSPOPPTR;
+ break;
default:
croak("panic: leave_scope inconsistency");
}
diff --git a/scope.h b/scope.h
index debe1f88a7..d9fe15a0a3 100644
--- a/scope.h
+++ b/scope.h
@@ -22,6 +22,7 @@
#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))
@@ -69,7 +70,7 @@
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
@@ -95,11 +96,21 @@ struct jmpenv {
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; \
@@ -108,6 +119,7 @@ typedef struct jmpenv JMPENV;
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) \
diff --git a/thread.h b/thread.h
index ac4a44f7a2..b2078620d3 100644
--- a/thread.h
+++ b/thread.h
@@ -60,7 +60,11 @@ struct thread {
SV ** Tstack_sp;
SV ** Tstack_max;
+#ifdef OP_IN_REGISTER
+ OP * Topsave;
+#else
OP * Top;
+#endif
I32 * Tscopestack;
I32 Tscopestack_ix;
@@ -176,7 +180,6 @@ typedef struct condpair {
#undef curpad
#undef Sv
#undef Xpv
-#undef op
#undef top_env
#undef runlevel
#undef in_eval
@@ -185,7 +188,12 @@ typedef struct condpair {
#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)