Don't use setjmp() and longjmp() in complex exprs
Chip Salzenberg [Mon, 31 Mar 1997 06:38:42 +0000 (18:38 +1200)]
perl.c
pp_ctl.c
scope.h

diff --git a/perl.c b/perl.c
index 8cbdd87..9f06f13 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -457,6 +457,7 @@ char **env;
     I32 oldscope;
     AV* comppadlist;
     dJMPENV;
+    int ret;
 
 #ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
 #ifdef IAMSUID
@@ -505,7 +506,8 @@ setuid perl scripts securely.\n");
     time(&basetime);
     oldscope = scopestack_ix;
 
-    switch (JMPENV_PUSH) {
+    JMPENV_PUSH(ret);
+    switch (ret) {
     case 1:
        STATUS_ALL_FAILURE;
        /* FALL THROUGH */
@@ -821,15 +823,17 @@ int
 perl_run(sv_interp)
 PerlInterpreter *sv_interp;
 {
-    dJMPENV;
     I32 oldscope;
+    dJMPENV;
+    int ret;
 
     if (!(curinterp = sv_interp))
        return 255;
 
     oldscope = scopestack_ix;
 
-    switch (JMPENV_PUSH) {
+    JMPENV_PUSH(ret);
+    switch (ret) {
     case 1:
        cxstack_ix = -1;                /* start context stack again */
        break;
@@ -1005,6 +1009,7 @@ I32 flags;                /* See G_* flags in cop.h */
     static CV *DBcv;
     bool oldcatch = CATCH_GET;
     dJMPENV;
+    int ret;
 
     if (flags & G_DISCARD) {
        ENTER;
@@ -1058,7 +1063,8 @@ I32 flags;                /* See G_* flags in cop.h */
        }
        markstack_ptr++;
 
-       switch (JMPENV_PUSH) {
+       JMPENV_PUSH(ret);
+       switch (ret) {
        case 0:
            break;
        case 1:
@@ -1142,6 +1148,7 @@ I32 flags;                /* See G_* flags in cop.h */
     I32 retval;
     I32 oldscope;
     dJMPENV;
+    int ret;
     
     if (flags & G_DISCARD) {
        ENTER;
@@ -1165,7 +1172,8 @@ I32 flags;                /* See G_* flags in cop.h */
     if (flags & G_KEEPERR)
        myop.op_flags |= OPf_SPECIAL;
 
-    switch (JMPENV_PUSH) {
+    JMPENV_PUSH(ret);
+    switch (ret) {
     case 0:
        break;
     case 1:
@@ -2467,16 +2475,18 @@ call_list(oldscope, list)
 I32 oldscope;
 AV* list;
 {
-    dJMPENV;
-    STRLEN len;
     line_t oldline = curcop->cop_line;
+    STRLEN len;
+    dJMPENV;
+    int ret;
 
     while (AvFILL(list) >= 0) {
        CV *cv = (CV*)av_shift(list);
 
        SAVEFREESV(cv);
 
-       switch (JMPENV_PUSH) {
+       JMPENV_PUSH(ret);
+       switch (ret) {
        case 0: {
                SV* atsv = GvSV(errgv);
                PUSHMARK(stack_sp);
index 7920e51..d51569d 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1972,7 +1972,8 @@ OP *o;
     assert(CATCH_GET == TRUE);
     DEBUG_l(deb("(Setting up local jumplevel, runlevel = %d)\n", runlevel+1));
 #endif
-    switch ((ret = JMPENV_PUSH)) {
+    JMPENV_PUSH(ret);
+    switch (ret) {
     default:                           /* topmost level handles it */
        JMPENV_POP;
        runlevel = oldrunlevel;
diff --git a/scope.h b/scope.h
index d6eb270..debe1f8 100644 (file)
--- a/scope.h
+++ b/scope.h
@@ -96,16 +96,25 @@ struct jmpenv {
 typedef struct jmpenv JMPENV;
 
 #define dJMPENV                JMPENV cur_env
-#define JMPENV_PUSH    (cur_env.je_prev = top_env,                     \
-                        cur_env.je_ret = Sigsetjmp(cur_env.je_buf,1),  \
-                        top_env = &cur_env,                            \
-                        cur_env.je_mustcatch = FALSE,                  \
-                        cur_env.je_ret)
-#define JMPENV_POP     (top_env = cur_env.je_prev)
-#define JMPENV_JUMP(v) (top_env->je_prev ? Siglongjmp(top_env->je_buf, (v))    \
-                        : ((v) == 2) ? exit(STATUS_NATIVE_EXPORT)              \
-                        : (PerlIO_printf(PerlIO_stderr(), "panic: top_env\n"), \
-                            exit(1)))
+#define JMPENV_PUSH(v) \
+    STMT_START {                                       \
+       cur_env.je_prev = top_env;                      \
+       cur_env.je_ret = Sigsetjmp(cur_env.je_buf, 1);  \
+       top_env = &cur_env;                             \
+       cur_env.je_mustcatch = FALSE;                   \
+       (v) = cur_env.je_ret;                           \
+    } STMT_END
+#define JMPENV_POP \
+    STMT_START { top_env = cur_env.je_prev; } STMT_END
+#define JMPENV_JUMP(v) \
+    STMT_START {                                               \
+       if (top_env->je_prev)                                   \
+           Siglongjmp(top_env->je_buf, (v));                   \
+       if ((v) == 2)                                           \
+           exit(STATUS_NATIVE_EXPORT);                         \
+       PerlIO_printf(PerlIO_stderr(), "panic: top_env\n");     \
+       exit(1);                                                \
+    } STMT_END
    
 #define CATCH_GET      (top_env->je_mustcatch)
 #define CATCH_SET(v)   (top_env->je_mustcatch = (v))