Support for op in global register (still buggy)
Malcolm Beattie [Tue, 1 Jul 1997 12:24:28 +0000 (12:24 +0000)]
p4raw-id: //depot/perl@34

12 files changed:
embed.h
global.sym
gv.c
op.c
perl.c
perl.h
pp_ctl.c
pp_sys.c
proto.h
scope.c
scope.h
thread.h

diff --git a/embed.h b/embed.h
index 18368fa..801ccf7 100644 (file)
--- a/embed.h
+++ b/embed.h
 #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
index 219e9a5..85c90ce 100644 (file)
@@ -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 50e9040..01cad2e 100644 (file)
--- 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 1f673da..3e5cf6e 100644 (file)
--- 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 242535a..3e8cee7 100644 (file)
--- 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 744905f..4d229b9 100644 (file)
--- a/perl.h
+++ b/perl.h
 
 #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
 
 #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;
index 2f3b2b7..317ed70 100644 (file)
--- 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) {
index 1b25bf4..94f84b7 100644 (file)
--- 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 28f239c..5fbd81d 100644 (file)
--- 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 50c843d..01b1fa9 100644 (file)
--- 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 debe1f8..d9fe15a 100644 (file)
--- 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)                                           \
index ac4a44f..b207862 100644 (file)
--- 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)