Bug 541455 - Do not drop "mumble"; would-be directives in the parser, let them be completion values (or useless expressions for the emitter to cull) (r=jimb).
authorBrendan Eich <brendan@mozilla.org>
Fri, 22 Jan 2010 12:17:13 -0800
changeset 37740 92194c270bcd4cf79585ffe7b92f90323ce2a8d5
parent 37739 e015dc555e9c0151f462b985969daec366be2bfd
child 37741 d3e1459bc81c754487b54cc707f8306426a38c89
push idunknown
push userunknown
push dateunknown
reviewersjimb
bugs541455
milestone1.9.3a1pre
Bug 541455 - Do not drop "mumble"; would-be directives in the parser, let them be completion values (or useless expressions for the emitter to cull) (r=jimb).
js/src/jsparse.cpp
js/src/jsparse.h
--- a/js/src/jsparse.cpp
+++ b/js/src/jsparse.cpp
@@ -142,18 +142,18 @@ static JSParser RelExpr;
 static JSParser ShiftExpr;
 static JSParser AddExpr;
 static JSParser MulExpr;
 static JSParser UnaryExpr;
 static JSMemberParser  MemberExpr;
 static JSPrimaryParser PrimaryExpr;
 static JSParenParser   ParenExpr;
 
-static bool RecognizeDirectivePrologue(JSContext *cx, JSTokenStream *ts,
-                                       JSTreeContext *tc, JSParseNode *pn);
+static bool
+RecognizeDirectivePrologue(JSContext *cx, JSTreeContext *tc, JSParseNode *pn);
 
 /*
  * Insist that the next token be of type tt, or report errno and return null.
  * NB: this macro uses cx and ts from its lexical environment.
  */
 #define MUST_MATCH_TOKEN(tt, errno)                                           \
     JS_BEGIN_MACRO                                                            \
         if (js_GetToken(cx, ts) != tt) {                                      \
@@ -930,17 +930,17 @@ JSCompiler::compileScript(JSContext *cx,
         }
 
         pn = Statement(cx, &jsc.tokenStream, &cg);
         if (!pn)
             goto out;
         JS_ASSERT(!cg.blockNode);
 
         if (inDirectivePrologue)
-            inDirectivePrologue = RecognizeDirectivePrologue(cx, &jsc.tokenStream, &cg, pn);
+            inDirectivePrologue = RecognizeDirectivePrologue(cx, &cg, pn);
 
         if (!js_FoldConstants(cx, pn, &cg))
             goto out;
 
         if (cg.functionList) {
             if (!jsc.analyzeFunctions(cg.functionList, cg.flags))
                 goto out;
             cg.functionList = NULL;
@@ -3076,26 +3076,25 @@ FunctionExpr(JSContext *cx, JSTokenStrea
  *   "use\x20loose"
  *   "use strict"
  * }
  *
  * That is, a statement can be a Directive Prologue member, even
  * if it can't possibly be a directive, now or in the future.
  */
 static bool
-RecognizeDirectivePrologue(JSContext *cx, JSTokenStream *ts,
-                           JSTreeContext *tc, JSParseNode *pn)
+RecognizeDirectivePrologue(JSContext *cx, JSTreeContext *tc, JSParseNode *pn)
 {
     if (!pn->isDirectivePrologueMember())
         return false;
     if (pn->isDirective()) {
         JSAtom *directive = pn->pn_kid->pn_atom;
         if (directive == cx->runtime->atomState.useStrictAtom) {
             tc->flags |= TCF_STRICT_MODE_CODE;
-            ts->flags |= TSF_STRICT_MODE_CODE;
+            tc->compiler->tokenStream.flags |= TSF_STRICT_MODE_CODE;
         }
     }
     return true;
 }
 
 /*
  * Parse the statements in a block, creating a TOK_LC node that lists the
  * statements' trees.  If called from block-parsing code, the caller must
@@ -3133,25 +3132,18 @@ Statements(JSContext *cx, JSTokenStream 
         }
         pn2 = Statement(cx, ts, tc);
         if (!pn2) {
             if (ts->flags & TSF_EOF)
                 ts->flags |= TSF_UNEXPECTED_EOF;
             return NULL;
         }
 
-        if (inDirectivePrologue) {
-            if (RecognizeDirectivePrologue(cx, ts, tc, pn2)) {
-                /* A Directive Prologue member is dead code.  Omit it from the statement list. */
-                RecycleTree(pn2, tc);
-                continue;
-            } else {
-                inDirectivePrologue = false;
-            }
-        }
+        if (inDirectivePrologue)
+            inDirectivePrologue = RecognizeDirectivePrologue(cx, tc, pn2);
 
         if (pn2->pn_type == TOK_FUNCTION) {
             /*
              * PNX_FUNCDEFS notifies the emitter that the block contains top-
              * level function definitions that should be processed before the
              * rest of nodes.
              *
              * TCF_HAS_FUNCTION_STMT is for the TOK_LC case in Statement. It
--- a/js/src/jsparse.h
+++ b/js/src/jsparse.h
@@ -486,18 +486,18 @@ struct JSParseNode {
     /* 
      * True if this statement node could be a member of a Directive
      * Prologue.  Note that the prologue may contain strings that
      * cannot themselves be directives; that's a stricter test.
      * If Statement begins to simplify trees into this form, then
      * we'll need additional flags that we can test here.
      */
     bool isDirectivePrologueMember() const {
-        if (PN_TYPE(this) == TOK_SEMI &&
-            pn_arity == PN_UNARY) {
+        if (PN_TYPE(this) == TOK_SEMI) {
+            JS_ASSERT(pn_arity == PN_UNARY);
             JSParseNode *kid = pn_kid;
             return kid && PN_TYPE(kid) == TOK_STRING && !kid->pn_parens;
         }
         return false;
     }
 
     /*
      * True if this node, known to be a Directive Prologue member,