[5.004_61 PATCH] Make incompatible changes to RE engine NOW
[p5sagit/p5-mst-13.2.git] / scope.c
diff --git a/scope.c b/scope.c
index 61bc731..65ac0b5 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -258,12 +258,11 @@ void
 save_item(register SV *item)
 {
     dTHR;
-    register SV *sv;
+    register SV *sv = NEWSV(0,0);
 
+    sv_setsv(sv,item);
     SSCHECK(3);
     SSPUSHPTR(item);           /* remember the pointer */
-    sv = NEWSV(0,0);
-    sv_setsv(sv,item);
     SSPUSHPTR(sv);             /* remember the value */
     SSPUSHINT(SAVEt_ITEM);
 }
@@ -346,7 +345,7 @@ save_threadsv(PADOFFSET i)
 {
 #ifdef USE_THREADS
     dTHR;
-    SV **svp = av_fetch(thr->threadsv, i, FALSE);
+    SV **svp = &THREADSV(i);   /* XXX Change to save by offset */
     DEBUG_L(PerlIO_printf(PerlIO_stderr(), "save_threadsv %u: %p %p:%s\n",
                          i, svp, *svp, SvPEEK(*svp)));
     save_svref(svp);
@@ -434,17 +433,39 @@ save_delete(HV *hv, char *key, I32 klen)
 }
 
 void
+save_aelem(AV *av, I32 idx, SV **sptr)
+{
+    SSCHECK(4);
+    SSPUSHPTR(av);
+    SSPUSHINT(idx);
+    SSPUSHPTR(*sptr);
+    SSPUSHINT(SAVEt_AELEM);
+    save_scalar_at(sptr);
+}
+
+void
+save_helem(HV *hv, SV *key, SV **sptr)
+{
+    SSCHECK(4);
+    SSPUSHPTR(hv);
+    SSPUSHPTR(key);
+    SSPUSHPTR(*sptr);
+    SSPUSHINT(SAVEt_HELEM);
+    save_scalar_at(sptr);
+}
+
+void
 save_list(register SV **sarg, I32 maxsarg)
 {
     dTHR;
     register SV *sv;
     register I32 i;
 
-    SSCHECK(3 * maxsarg);
     for (i = 1; i <= maxsarg; i++) {
-       SSPUSHPTR(sarg[i]);             /* remember the pointer */
        sv = NEWSV(0,0);
        sv_setsv(sv,sarg[i]);
+       SSCHECK(3);
+       SSPUSHPTR(sarg[i]);             /* remember the pointer */
        SSPUSHPTR(sv);                  /* remember the value */
        SSPUSHINT(SAVEt_ITEM);
     }
@@ -479,6 +500,7 @@ leave_scope(I32 base)
     register AV *av;
     register HV *hv;
     register void* ptr;
+    I32 i;
 
     if (base < -1)
        croak("panic: corrupt saved stack index");
@@ -607,14 +629,14 @@ leave_scope(I32 base)
        case SAVEt_GP:                          /* scalar reference */
            ptr = SSPOPPTR;
            gv = (GV*)SSPOPPTR;
-            gp_free(gv);
-            GvGP(gv) = (GP*)ptr;
             if (SvPOK(gv) && SvLEN(gv) > 0) {
                 Safefree(SvPVX(gv));
             }
             SvPVX(gv) = (char *)SSPOPPTR;
             SvCUR(gv) = (STRLEN)SSPOPIV;
             SvLEN(gv) = (STRLEN)SSPOPIV;
+            gp_free(gv);
+            GvGP(gv) = (GP*)ptr;
            SvREFCNT_dec(gv);
             break;
        case SAVEt_FREESV:
@@ -690,17 +712,26 @@ leave_scope(I32 base)
            (*SSPOPDPTR)(ptr);
            break;
        case SAVEt_REGCONTEXT:
-           {
-               I32 delta = SSPOPINT;
-               savestack_ix -= delta;  /* regexp must have croaked */
-           }
+           i = SSPOPINT;
+           savestack_ix -= i;          /* regexp must have croaked */
            break;
        case SAVEt_STACK_POS:           /* Position on Perl stack */
-           {
-               I32 delta = SSPOPINT;
-               stack_sp = stack_base + delta;
-           }
+           i = SSPOPINT;
+           stack_sp = stack_base + i;
            break;
+       case SAVEt_AELEM:               /* array element */
+           value = (SV*)SSPOPPTR;
+           i = SSPOPINT;
+           av = (AV*)SSPOPPTR;
+           ptr = av_fetch(av,i,1);
+           goto restore_sv;
+       case SAVEt_HELEM:               /* hash element */
+           value = (SV*)SSPOPPTR;
+           sv = (SV*)SSPOPINT;
+           hv = (HV*)SSPOPPTR;
+           ptr = hv_fetch_ent(hv, sv, 1, 0);
+           ptr = &HeVAL((HE*)ptr);
+           goto restore_sv;
        case SAVEt_OP:
            op = (OP*)SSPOPPTR;
            break;