bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: no users destructors if stack 0 deleted


From: Joel E. Denny
Subject: Re: no users destructors if stack 0 deleted
Date: Sat, 3 Dec 2005 06:49:55 -0500 (EST)

On Sat, 3 Dec 2005, Paul Eggert wrote:

"Joel E. Denny" <address@hidden> writes:

Let me know if more current diffs would help.

Yes they would, please.  (The archives occasionally munge files.)

The combined diff for the two patches appears below. They separate cleanly at line 2298 in case you prefer to commit them separately.

There was also a new test case for the latter patch:

  http://lists.gnu.org/archive/html/bison-patches/2005-09/msg00109.html

Joel

Index: glr.c
===================================================================
RCS file: /cvsroot/bison/bison/data/glr.c,v
retrieving revision 1.141
diff -p -u -r1.141 glr.c
--- glr.c       1 Dec 2005 20:03:52 -0000       1.141
+++ glr.c       3 Dec 2005 11:38:21 -0000
@@ -715,10 +715,10 @@ typedef short int yySymbol;
 typedef short int yyItemNum;

 typedef struct yyGLRState yyGLRState;
+typedef struct yyGLRStateSet yyGLRStateSet;
 typedef struct yySemanticOption yySemanticOption;
 typedef union yyGLRStackItem yyGLRStackItem;
 typedef struct yyGLRStack yyGLRStack;
-typedef struct yyGLRStateSet yyGLRStateSet;

 struct yyGLRState {
   /** Type tag: always true. */
@@ -1880,16 +1880,7 @@ yyprocessOneStack (yyGLRStack* yystack,
            }

          if (yyisShiftAction (yyaction))
-           {
-             YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long int) yyk));
-             YY_SYMBOL_PRINT ("shifting", *yytokenp, yylvalp, yyllocp);
-             yyglrShift (yystack, yyk, yyaction, yyposn+1,
-                         *yylvalp, yyllocp);
-             YYDPRINTF ((stderr, "Stack %lu now in state #%d\n",
-                         (unsigned long int) yyk,
-                         yystack->yytops.yystates[yyk]->yylrState));
-             break;
-           }
+           break;
          else if (yyisErrorAction (yyaction))
            {
              YYDPRINTF ((stderr, "Stack %lu dies.\n",
@@ -2236,14 +2227,56 @@ b4_syncline(address@hidden@], address@hidden@])])dnl

       while (yytrue)
        {
+         yySymbol yytoken_to_shift;
          size_t yys;
          size_t yyn = yystack.yytops.yysize;
+         /*
+          There are 3 cases in which yyprocessOneStack() returns:
+            - Returns error flag.  If the caller is yyprocessOneStack(), it
+              immediately returns as well.  When the caller is finally
+              yyparse(), it jumps to an error label via YYCHK1().
+            - Returns yyok but has invoked yymarkStackDeleted (&yystack, yys),
+              which sets the top state of yys to NULL.  Thus, yyparse()'s
+              following invocation of yyremoveDeletes() will remove the
+              stack.
+            - Returns yyok when ready to shift a token.
+          Except in case 1, yyparse() will invoke yyremoveDeletes() and then
+          shift the next token onto all remaining stacks.  This
+          synchronization of the shift (that is, after all preceding
+          reductions on all stacks) helps prevents double destructor calls on
+          yylval in the event of memory exhaustion.
+         */
          for (yys = 0; yys < yyn; yys += 1)
            YYCHK1 (yyprocessOneStack (&yystack, yys, yyposn,
                                       yylvalp, yyllocp]b4_lpure_args[));
+         yyremoveDeletes (&yystack);
+         yyn = yystack.yytops.yysize;
+         /*
+           If any yyglrShift() will fail, it will fail after shifting.  Thus,
+           a copy of yylval will already be on stack 0 in the event of a
+           failure in the following loop.  Thus, yytoken is set to YYEMPTY
+           before the loop to make sure the user destructor for yylval isn't
+           called twice.
+         */
+         yytoken_to_shift = yytoken;
          yytoken = YYEMPTY;
          yyposn += 1;
-         yyremoveDeletes (&yystack);
+         for (yys = 0; yys < yyn; yys += 1)
+            {
+             int yyaction;
+              const short int* yyconflicts;
+             yyStateNum yystate = yystack.yytops.yystates[yys]->yylrState;
+             yygetLRActions (yystate, yytoken_to_shift, &yyaction,
+                             &yyconflicts);
+             /* Note that yyconflicts were handled by yyprocessOneStack(). */
+             YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long int) yys));
+             YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, yylvalp, yyllocp);
+             yyglrShift (&yystack, yys, yyaction, yyposn,
+                         *yylvalp, yyllocp);
+             YYDPRINTF ((stderr, "Stack %lu now in state #%d\n",
+                         (unsigned long int) yys,
+                         yystack.yytops.yystates[yys]->yylrState));
+            }
          if (yystack.yytops.yysize == 0)
            {
              yyundeleteLastStack (&yystack);
@@ -2298,15 +2331,26 @@ b4_syncline(address@hidden@], address@hidden@])])dnl
     {
       yyGLRState** yystates = yystack.yytops.yystates;
       if (yystates)
-       while (yystates[0])
-         {
-           yyGLRState *yys = yystates[0];
+        {
+         size_t yysize = yystack.yytops.yysize;
+         size_t yyk;
+         for (yyk = 0; yyk < yysize; yyk += 1)
+           {
+             if (yystates[yyk])
+               {
+                 while (yystates[yyk])
+                   {
+                     yyGLRState *yys = yystates[yyk];
 ]b4_location_if([[       yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;]]
-)[         yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[);
-           yystates[0] = yys->yypred;
-           yystack.yynextFree -= 1;
-           yystack.yyspaceLeft += 1;
-         }
+)[                   yydestroyGLRState ("Cleanup: popping", yys]b4_user_args[);
+                     yystates[yyk] = yys->yypred;
+                     yystack.yynextFree -= 1;
+                     yystack.yyspaceLeft += 1;
+                   }
+                  break;
+                }
+           }
+       }
       yyfreeGLRStack (&yystack);
     }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]