handle cloning of parsers on the save stack
Dave Mitchell [Wed, 3 Jan 2007 22:17:48 +0000 (22:17 +0000)]
p4raw-id: //depot/perl@29678

perly.c
scope.c
scope.h
sv.c

diff --git a/perly.c b/perly.c
index 4e3a7e2..8ce76ab 100644 (file)
--- a/perly.c
+++ b/perly.c
@@ -348,7 +348,7 @@ Perl_yyparse (pTHX)
     ps = parser->ps;
 
     ENTER;  /* force parser free before we return */
-    SAVEDESTRUCTOR_X(Perl_parser_free, (void*) parser);
+    SAVEPARSER(parser);
 
 /*------------------------------------------------------------.
 | yynewstate -- Push a new state, which is found in yystate.  |
diff --git a/scope.c b/scope.c
index abe9a05..d15d2d9 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -1023,6 +1023,10 @@ Perl_leave_scope(pTHX_ I32 base)
                Copy(state, &PL_reg_state, 1, struct re_save_state);
            }
            break;
+       case SAVEt_PARSER:
+           ptr = SSPOPPTR;
+           parser_free((yy_parser *) ptr);
+           break;
        default:
            Perl_croak(aTHX_ "panic: leave_scope inconsistency");
        }
diff --git a/scope.h b/scope.h
index c804300..40e9fe6 100644 (file)
--- a/scope.h
+++ b/scope.h
@@ -53,6 +53,7 @@
 #define SAVEt_RE_STATE         42
 #define SAVEt_COMPILE_WARNINGS 43
 #define SAVEt_STACK_CXPOS      44
+#define SAVEt_PARSER           45
 
 #ifndef SCOPE_SAVES_SIGNAL_MASK
 #define SCOPE_SAVES_SIGNAL_MASK 0
@@ -214,6 +215,13 @@ Closing bracket on a callback.  See C<ENTER> and L<perlcall>.
         SSPUSHINT(SAVEt_STACK_CXPOS);             \
     } STMT_END
 
+#define SAVEPARSER(p) \
+    STMT_START {                                  \
+        SSCHECK(2);                               \
+        SSPUSHPTR(p);                            \
+        SSPUSHINT(SAVEt_PARSER);                 \
+    } STMT_END
+
 #ifdef USE_ITHREADS
 #  define SAVECOPSTASH(c)      SAVEPPTR(CopSTASHPV(c))
 #  define SAVECOPSTASH_FREE(c) SAVESHAREDPV(CopSTASHPV(c))
diff --git a/sv.c b/sv.c
index 8bed941..15f54d8 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -9498,7 +9498,14 @@ Perl_parser_dup(pTHX_ const yy_parser *proto, CLONE_PARAMS* param)
     if (!proto)
        return NULL;
 
+    /* look for it in the table first */
+    parser = (yy_parser *)ptr_table_fetch(PL_ptr_table, proto);
+    if (parser)
+       return parser;
+
+    /* create anew and remember what it is */
     Newxz(parser, 1, yy_parser);
+    ptr_table_store(PL_ptr_table, proto, parser);
 
     parser->yyerrstatus = 0;
     parser->yychar = YYEMPTY;          /* Cause a token to be read.  */
@@ -10670,6 +10677,10 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = DUP_WARNINGS((STRLEN*)ptr);
            break;
+       case SAVEt_PARSER:
+           ptr = POPPTR(ss,ix);
+           TOPPTR(nss,ix) = parser_dup(ptr, param);
+           break;
        default:
            Perl_croak(aTHX_
                       "panic: ss_dup inconsistency (%"IVdf")", (IV) type);