fix a cast warning in perly.c
[p5sagit/p5-mst-13.2.git] / perly.c
diff --git a/perly.c b/perly.c
index b71f95a..e3f9357 100644 (file)
--- a/perly.c
+++ b/perly.c
@@ -1,14 +1,14 @@
 /*    perly.c
  *
- *    Copyright (c) 2004 Larry Wall
+ *    Copyright (c) 2004, 2005, 2006 Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
  * 
  *    Note that this file was originally generated as an output from
  *    GNU bison version 1.875, but now the code is statically maintained
- *    and edited; the bits that are dependent on perly.y are now #included
- *    from the files perly.tab and perly.act.
+ *    and edited; the bits that are dependent on perly.y are now
+ *    #included from the files perly.tab and perly.act.
  *
  *    Here is an important copyright statement from the original, generated
  *    file:
  *     Bison output file, you may use that output file without
  *     restriction.  This special exception was added by the Free
  *     Software Foundation in version 1.24 of Bison.
+ *
+ * Note that this file is also #included in madly.c, to allow compilation
+ * of a second parser, Perl_madparse, that is identical to Perl_yyparse,
+ * but which includes extra code for dumping the parse tree.
+ * This is controlled by the PERL_IN_MADLY_C define.
  */
 
 
+
 /* allow stack size to grow effectively without limit */
 #define YYMAXDEPTH 10000000
 
 #define PERL_IN_PERLY_C
 #include "perl.h"
 
+typedef unsigned char yytype_uint8;
+typedef signed char yytype_int8;
+typedef unsigned short int yytype_uint16;
+typedef short int yytype_int16;
 typedef signed char yysigned_char;
 
 #ifdef DEBUGGING
@@ -89,12 +99,6 @@ do {                                         \
        YYFPRINTF Args;                         \
 } while (0)
 
-#  define YYDSYMPRINT(Args)                    \
-do {                                           \
-    if (yydebug)                               \
-       yysymprint Args;                        \
-} while (0)
-
 #  define YYDSYMPRINTF(Title, Token, Value)                    \
 do {                                                           \
     if (yydebug) {                                             \
@@ -109,7 +113,7 @@ do {                                                                \
 `--------------------------------*/
 
 static void
-yysymprint (pTHX_ PerlIO *yyoutput, int yytype, const YYSTYPE *yyvaluep)
+yysymprint(pTHX_ PerlIO * const yyoutput, int yytype, const YYSTYPE * const yyvaluep)
 {
     if (yytype < YYNTOKENS) {
        YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
@@ -146,14 +150,36 @@ yy_stack_print (pTHX_ const short *yyss, const short *yyssp, const YYSTYPE *yyvs
     for (i=0; i < count; i++)
        PerlIO_printf(Perl_debug_log, " %8d", start+i);
     PerlIO_printf(Perl_debug_log, "\nstate:");
-    for (i=0, yyss += start; i < count; i++, yyss++)
-       PerlIO_printf(Perl_debug_log, " %8d", *yyss);
+    for (i=0; i < count; i++)
+       PerlIO_printf(Perl_debug_log, " %8d", yyss[start+i]);
     PerlIO_printf(Perl_debug_log, "\ntoken:");
-    for (i=0, yyns += start; i < count; i++, yyns++)
-       PerlIO_printf(Perl_debug_log, " %8.8s", *yyns);
+    for (i=0; i < count; i++)
+       PerlIO_printf(Perl_debug_log, " %8.8s", yyns[start+i]);
     PerlIO_printf(Perl_debug_log, "\nvalue:");
-    for (i=0, yyvs += start; i < count; i++, yyvs++)
-       PerlIO_printf(Perl_debug_log, " %8"UVxf, (UV)yyvs->ival);
+    for (i=0; i < count; i++) {
+       switch (yy_type_tab[yystos[yyss[start+i]]]) {
+       case toketype_opval:
+           PerlIO_printf(Perl_debug_log, " %8.8s",
+                 yyvs[start+i].opval
+                   ? PL_op_name[yyvs[start+i].opval->op_type]
+                   : "(Nullop)"
+           );
+           break;
+#ifndef PERL_IN_MADLY_C
+       case toketype_p_tkval:
+           PerlIO_printf(Perl_debug_log, " %8.8s",
+                 yyvs[start+i].pval ? yyvs[start+i].pval : "(NULL)");
+           break;
+
+       case toketype_i_tkval:
+#endif
+       case toketype_ival:
+           PerlIO_printf(Perl_debug_log, " %8"IVdf, (IV)yyvs[start+i].ival);
+           break;
+       default:
+           PerlIO_printf(Perl_debug_log, " %8"UVxf, (UV)yyvs[start+i].ival);
+       }
+    }
     PerlIO_printf(Perl_debug_log, "\n\n");
 }
 
@@ -189,7 +215,6 @@ do {                                        \
 
 #else /* !DEBUGGING */
 #  define YYDPRINTF(Args)
-#  define YYDSYMPRINT(Args)
 #  define YYDSYMPRINTF(Title, Token, Value)
 #  define YY_STACK_PRINT(yyss, yyssp, yyvs, yyns)
 #  define YY_REDUCE_PRINT(Rule)
@@ -243,13 +268,118 @@ yystpcpy (pTHX_ char *yydest, const char *yysrc)
 
 #endif /* !YYERROR_VERBOSE */
 
+
+/* a snapshot of the current stack position variables for use by
+ * S_clear_yystack */
+
+typedef struct {
+    short *yyss;
+    short *yyssp;
+    YYSTYPE *yyvsp;
+    AV **yypsp;
+    int yylen;
+} yystack_positions;
+
+/* called during cleanup (via SAVEDESTRUCTOR_X) to free any items on the
+ * parse stack, thus avoiding leaks if we die  */
+
+static void
+S_clear_yystack(pTHX_ const void *p)
+{
+    yystack_positions *y = (yystack_positions*) p;
+    int i;
+
+    if (!y->yyss)
+       return;
+    YYDPRINTF ((Perl_debug_log, "clearing the parse stack\n"));
+
+    /* Freeing ops on the stack, and the op_latefree/op_latefreed flags:
+     *
+     * When we pop tokens off the stack during error recovery, or when
+     * we pop all the tokens off the stack after a die during a shift or
+     * reduce (ie Perl_croak somewhere in yylex(), or in one of the
+     * newFOO() functions, then its possible that some of these tokens are
+     * of type opval, pointing to an OP. All these ops are orphans; each is
+     * its own miniature subtree that has not yet been attached to a
+     * larger tree. In this case, we shoould clearly free the op (making
+     * sure, for each op we free thyat we have PL_comppad pointing to the
+     * right place for freeing any SVs attached to the op in threaded
+     * builds.
+     *
+     * However, there is a particular problem if we die in newFOO called
+     * by a reducing action; e.g.
+     *
+     *    foo : bar baz boz
+     *        { $$ = newFOO($1,$2,$3) }
+     *
+     * where
+     *  OP *newFOO { .... croak .... }
+     *
+     * In this case, when we come to clean bar baz and boz off the stack,
+     * we don't know whether newFOO() has already:
+     *    * freed them
+     *    * left them as it
+     *    * attached them to part of a larger tree
+     *
+     * To get round this problem, we set the flag op_latefree on every op
+     * that gets pushed onto the parser stack. If op_free() sees this
+     * flag, it clears the op and frees any children,, but *doesn't* free
+     * the op itself; instead it sets the op_latefreed flag. This means
+     * that we can safely call op_free() multiple times on each stack op.
+     * So, when clearing the stack, we first, for each op that was being
+     * reduced, call op_free with op_latefree=1. This ensures that all ops
+     * hanging off these op are freed, but the reducing ops themselces are
+     * just undefed. Then we set op_latefreed=0 on *all* ops on the stack
+     * and free them. A little though should convince you that this
+     * two-part approach to the reducing ops should handle all three cases
+     * above safely.
+     */
+
+    /* free any reducing ops (1st pass) */
+
+    for (i=0; i< y->yylen; i++) {
+       if (yy_type_tab[yystos[y->yyssp[-i]]] == toketype_opval
+           && y->yyvsp[-i].opval) {
+           if (y->yypsp[-i] != PL_comppad) {
+               PAD_RESTORE_LOCAL(y->yypsp[-i]);
+           }
+           op_free(y->yyvsp[-i].opval);
+       }
+    }
+
+    /* now free whole the stack, including the just-reduced ops */
+
+    while (y->yyssp > y->yyss) {
+       if (yy_type_tab[yystos[*y->yyssp]] == toketype_opval
+           && y->yyvsp->opval)
+       {
+           if (*y->yypsp != PL_comppad) {
+               PAD_RESTORE_LOCAL(*y->yypsp);
+           }
+           YYDPRINTF ((Perl_debug_log, "(freeing op)\n"));
+           y->yyvsp->opval->op_latefree  = 0;
+           op_free(y->yyvsp->opval);
+       }
+       y->yyvsp--;
+       y->yyssp--;
+       y->yypsp--;
+    }
+}
+
+
+
 /*----------.
 | yyparse.  |
 `----------*/
 
 int
+#ifdef PERL_IN_MADLY_C
+Perl_madparse (pTHX)
+#else
 Perl_yyparse (pTHX)
+#endif
 {
+    dVAR;
     int yychar; /* The lookahead symbol.  */
     YYSTYPE yylval; /* The semantic value of the lookahead symbol.  */
     int yynerrs; /* Number of syntax errors so far.  */
@@ -262,9 +392,11 @@ Perl_yyparse (pTHX)
     /* Lookahead token as an internal (translated) token number.  */
     int yytoken = 0;
 
-    /* two stacks and their tools:
+    /* three stacks and their tools:
          yyss: related to states,
          yyvs: related to semantic values,
+         yyps: current value of PL_comppad for each state
+         
 
          Refer to the stacks thru separate pointers, to allow yyoverflow
          to reallocate them elsewhere.  */
@@ -277,17 +409,23 @@ Perl_yyparse (pTHX)
     YYSTYPE *yyvs;
     register YYSTYPE *yyvsp;
 
-    /* for ease of re-allocation and automatic freeing, have two SVs whose
+    AV **yyps;
+    AV **yypsp;
+
+    /* for ease of re-allocation and automatic freeing, have three SVs whose
       * SvPVX points to the stacks */
-    SV *yyss_sv, *yyvs_sv;
+    SV *yyss_sv, *yyvs_sv, *yyps_sv;
+    SV *ss_save_sv;
+    yystack_positions *ss_save;
+
 
 #ifdef DEBUGGING
     /* maintain also a stack of token/rule names for debugging with -Dpv */
     const char **yyns, **yynsp;
     SV *yyns_sv;
-#  define YYPOPSTACK   (yyvsp--, yyssp--, yynsp--)
+#  define YYPOPSTACK   (yyvsp--, yyssp--, yypsp--, yynsp--)
 #else
-#  define YYPOPSTACK   (yyvsp--, yyssp--)
+#  define YYPOPSTACK   (yyvsp--, yyssp--, yypsp--)
 #endif
 
 
@@ -302,6 +440,13 @@ Perl_yyparse (pTHX)
          rule.  */
     int yylen;
 
+#ifndef PERL_IN_MADLY_C
+#  ifdef PERL_MAD
+    if (PL_madskills)
+       return madparse();
+#  endif
+#endif
+
     YYDPRINTF ((Perl_debug_log, "Starting parse\n"));
 
     ENTER;                     /* force stack free before we return */
@@ -310,18 +455,31 @@ Perl_yyparse (pTHX)
     PL_yycharp = &yychar; /* so PL_yyerror() can access it */
     PL_yylvalp = &yylval; /* so various functions in toke.c can access it */
 
-    yyss_sv = NEWSV(73, YYINITDEPTH * sizeof(short));
-    yyvs_sv = NEWSV(73, YYINITDEPTH * sizeof(YYSTYPE));
+    yyss_sv = newSV(YYINITDEPTH * sizeof(short));
+    yyvs_sv = newSV(YYINITDEPTH * sizeof(YYSTYPE));
+    yyps_sv = newSV(YYINITDEPTH * sizeof(AV*));
+    ss_save_sv = newSV(sizeof(yystack_positions));
     SAVEFREESV(yyss_sv);
     SAVEFREESV(yyvs_sv);
+    SAVEFREESV(yyps_sv);
+    SAVEFREESV(ss_save_sv);
     yyss = (short *) SvPVX(yyss_sv);
     yyvs = (YYSTYPE *) SvPVX(yyvs_sv);
+    yyps = (AV **) SvPVX(yyps_sv);
+    ss_save = (yystack_positions *) SvPVX(ss_save_sv);
+
+    ss_save->yyss = NULL; /* disarm stack cleanup */
+    /* cleanup the parse stack on premature exit */
+    SAVEDESTRUCTOR_X(S_clear_yystack, (void*) ss_save);
+
     /* note that elements zero of yyvs and yyns are not used */
     yyssp = yyss;
     yyvsp = yyvs;
+    yypsp = yyps;
 #ifdef DEBUGGING
-    yyns_sv = NEWSV(73, YYINITDEPTH * sizeof(char *));
+    yyns_sv = newSV(YYINITDEPTH * sizeof(char *));
     SAVEFREESV(yyns_sv);
+    /* XXX This seems strange to cast char * to char ** */
     yyns = (const char **) SvPVX(yyns_sv);
     yynsp = yyns;
 #endif
@@ -331,10 +489,6 @@ Perl_yyparse (pTHX)
     yynerrs = 0;
     yychar = YYEMPTY;          /* Cause a token to be read.  */
 
-
-
-    YYDPRINTF ((Perl_debug_log, "Entering state %d\n", yystate));
-
     goto yysetstate;
 
 /*------------------------------------------------------------.
@@ -347,8 +501,20 @@ Perl_yyparse (pTHX)
     yyssp++;
 
   yysetstate:
+    YYDPRINTF ((Perl_debug_log, "Entering state %d\n", yystate));
     *yyssp = yystate;
 
+    if (yy_type_tab[yystos[yystate]] == toketype_opval && yyvsp->opval) {
+       yyvsp->opval->op_latefree  = 1;
+       yyvsp->opval->op_latefreed = 0;
+    }
+
+    ss_save->yyss = yyss;
+    ss_save->yyssp = yyssp;
+    ss_save->yyvsp = yyvsp;
+    ss_save->yypsp = yypsp;
+    ss_save->yylen = 0;
+
     if (yyss + yystacksize - 1 <= yyssp) {
         /* Get the current used size of the three stacks, in elements.  */
         const YYSIZE_T yysize = yyssp - yyss + 1;
@@ -362,20 +528,24 @@ Perl_yyparse (pTHX)
 
         SvGROW(yyss_sv, yystacksize * sizeof(short));
         SvGROW(yyvs_sv, yystacksize * sizeof(YYSTYPE));
+        SvGROW(yyps_sv, yystacksize * sizeof(AV*));
         yyss = (short *) SvPVX(yyss_sv);
         yyvs = (YYSTYPE *) SvPVX(yyvs_sv);
+        yyps = (AV **) SvPVX(yyps_sv);
 #ifdef DEBUGGING
         SvGROW(yyns_sv, yystacksize * sizeof(char *));
+        /* XXX This seems strange to cast char * to char ** */
         yyns = (const char **) SvPVX(yyns_sv);
         if (! yyns)
               goto yyoverflowlab;
         yynsp = yyns + yysize - 1;
 #endif
-        if (!yyss || ! yyvs)
+        if (!yyss || ! yyvs || ! yyps)
               goto yyoverflowlab;
 
         yyssp = yyss + yysize - 1;
         yyvsp = yyvs + yysize - 1;
+        yypsp = yyps + yysize - 1;
 
 
         YYDPRINTF ((Perl_debug_log, "Stack size increased to %lu\n",
@@ -383,6 +553,12 @@ Perl_yyparse (pTHX)
 
         if (yyss + yystacksize - 1 <= yyssp)
               YYABORT;
+
+       ss_save->yyss = yyss;
+       ss_save->yyssp = yyssp;
+       ss_save->yyvsp = yyvsp;
+       ss_save->yypsp = yypsp;
+       ss_save->yylen = 0;
     }
 
     goto yybackup;
@@ -407,7 +583,12 @@ Perl_yyparse (pTHX)
     /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
     if (yychar == YYEMPTY) {
        YYDPRINTF ((Perl_debug_log, "Reading a token: "));
+#ifdef PERL_IN_MADLY_C
+       yychar = PL_madskills ? madlex() : yylex();
+#else
        yychar = yylex();
+#endif
+
 #  ifdef EBCDIC
        if (yychar >= 0 && yychar < 255) {
            yychar = NATIVE_TO_ASCII(yychar);
@@ -448,6 +629,7 @@ Perl_yyparse (pTHX)
        yychar = YYEMPTY;
 
     *++yyvsp = yylval;
+    *++yypsp = PL_comppad;
 #ifdef DEBUGGING
     *++yynsp = (const char *)(yytname[yytoken]);
 #endif
@@ -459,7 +641,6 @@ Perl_yyparse (pTHX)
        yyerrstatus--;
 
     yystate = yyn;
-    YYDPRINTF ((Perl_debug_log, "Entering state %d\n", yystate));
 
     goto yynewstate;
 
@@ -491,29 +672,75 @@ Perl_yyparse (pTHX)
       GCC warning that YYVAL may be used uninitialized.  */
     yyval = yyvsp[1-yylen];
 
-
+    YY_STACK_PRINT (yyss, yyssp, yyvs, yyns);
     YY_REDUCE_PRINT (yyn);
+
+    /* running external code may trigger a die (eg 'use nosuchmodule'):
+     * record the current stack state so that an unwind will
+     * free all the pesky OPs lounging around on the parse stack */
+    ss_save->yyss = yyss;
+    ss_save->yyssp = yyssp;
+    ss_save->yyvsp = yyvsp;
+    ss_save->yypsp = yypsp;
+    ss_save->yylen = yylen;
+
     switch (yyn) {
 
-/* contains all the rule actions; auto-generated from perly.y */
 
 #define dep() deprecate("\"do\" to call subroutines")
+
+#ifdef PERL_IN_MADLY_C
+#  define IVAL(i) (i)->tk_lval.ival
+#  define PVAL(p) (p)->tk_lval.pval
+#  define TOKEN_GETMAD(a,b,c) token_getmad((a),(b),(c))
+#  define TOKEN_FREE(a) token_free(a)
+#  define OP_GETMAD(a,b,c) op_getmad((a),(b),(c))
+#  define IF_MAD(a,b) (a)
+#  define DO_MAD(a) a
+#  define MAD
+#else
+#  define IVAL(i) (i)
+#  define PVAL(p) (p)
+#  define TOKEN_GETMAD(a,b,c)
+#  define TOKEN_FREE(a)
+#  define OP_GETMAD(a,b,c)
+#  define IF_MAD(a,b) (b)
+#  define DO_MAD(a)
+#  undef MAD
+#endif
+
+/* contains all the rule actions; auto-generated from perly.y */
 #include "perly.act"
 
     }
 
+    /* any just-reduced ops with the op_latefreed flag cleared need to be
+     * freed; the rest need the flag resetting */
+    {
+       int i;
+       for (i=0; i< yylen; i++) {
+           if (yy_type_tab[yystos[yyssp[-i]]] == toketype_opval
+               && yyvsp[-i].opval)
+           {
+               yyvsp[-i].opval->op_latefree = 0;
+               if (yyvsp[-i].opval->op_latefreed)
+                   op_free(yyvsp[-i].opval);
+           }
+       }
+    }
+
     yyvsp -= yylen;
     yyssp -= yylen;
+    yypsp -= yylen;
 #ifdef DEBUGGING
     yynsp -= yylen;
 #endif
 
-
     *++yyvsp = yyval;
+    *++yypsp = PL_comppad;
 #ifdef DEBUGGING
     *++yynsp = (const char *)(yytname [yyr1[yyn]]);
 #endif
-
     /* Now shift the result of the reduction.  Determine what state
          that goes to, based on the state we popped back to and the rule
          number reduced by.  */
@@ -525,18 +752,6 @@ Perl_yyparse (pTHX)
        yystate = yytable[yystate];
     else
        yystate = yydefgoto[yyn - YYNTOKENS];
-
-    YYDPRINTF ((Perl_debug_log, "Entering state %d\n", yystate));
-
-#ifdef DEBUGGING
-    /* tmp push yystate for stack print; this is normally pushed later in
-     * yynewstate */
-    yyssp++;
-    *yyssp = yystate;
-    YY_STACK_PRINT (yyss, yyssp, yyvs, yyns);
-    yyssp--;
-#endif
-
     goto yynewstate;
 
 
@@ -565,7 +780,7 @@ Perl_yyparse (pTHX)
                    yysize += yystrlen (yytname[yyx]) + 15, yycount++;
            yysize += yystrlen ("syntax error, unexpected ") + 1;
            yysize += yystrlen (yytname[yytype]);
-           New(yymsg, yysize, char *);
+           Newx(yymsg, yysize, char *);
            if (yymsg != 0) {
                const char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
                yyp = yystpcpy (yyp, yytname[yytype]);
@@ -608,6 +823,16 @@ Perl_yyparse (pTHX)
            /* Pop the rest of the stack.  */
            while (yyss < yyssp) {
                YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp);
+               if (yy_type_tab[yystos[*yyssp]] == toketype_opval
+                       && yyvsp->opval)
+               {
+                   YYDPRINTF ((Perl_debug_log, "(freeing op)\n"));
+                   if (*yypsp != PL_comppad) {
+                       PAD_RESTORE_LOCAL(*yypsp);
+                   }
+                   yyvsp->opval->op_latefree  = 0;
+                   op_free(yyvsp->opval);
+               }
                YYPOPSTACK;
            }
            YYABORT;
@@ -645,7 +870,16 @@ Perl_yyparse (pTHX)
            YYABORT;
 
        YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp);
+       if (yy_type_tab[yystos[*yyssp]] == toketype_opval && yyvsp->opval) {
+           YYDPRINTF ((Perl_debug_log, "(freeing op)\n"));
+           if (*yypsp != PL_comppad) {
+               PAD_RESTORE_LOCAL(*yypsp);
+           }
+           yyvsp->opval->op_latefree  = 0;
+           op_free(yyvsp->opval);
+       }
        yyvsp--;
+       yypsp--;
 #ifdef DEBUGGING
        yynsp--;
 #endif
@@ -660,12 +894,12 @@ Perl_yyparse (pTHX)
     YYDPRINTF ((Perl_debug_log, "Shifting error token, "));
 
     *++yyvsp = yylval;
+    *++yypsp = PL_comppad;
 #ifdef DEBUGGING
     *++yynsp ="<err>";
 #endif
 
     yystate = yyn;
-    YYDPRINTF ((Perl_debug_log, "Entering state %d\n", yystate));
 
     goto yynewstate;
 
@@ -694,6 +928,7 @@ Perl_yyparse (pTHX)
 
   yyreturn:
 
+    ss_save->yyss = NULL;      /* disarm parse stack cleanup */
     LEAVE;                     /* force stack free before we return */
 
     return yyresult;