Bug 384758 - A statement can follow an expclo without an intervening semicolon. r=igor.
authorJason Orendorff <jorendorff@mozilla.com>
Mon, 16 Feb 2009 16:37:08 -0600
changeset 23551 08894b2b76cbd2a0c1523e555326e6b397b04886
parent 23550 91290ee5025fe9090cbfae80822e585aa1ce41b5
child 23552 8b558153923a3b9e9a31f4a98457c9018425428a
push id802
push userrsayre@mozilla.com
push dateFri, 27 Feb 2009 07:52:36 +0000
reviewersigor
bugs384758
milestone1.9.1b3pre
Bug 384758 - A statement can follow an expclo without an intervening semicolon. r=igor.
js/src/jsparse.cpp
--- a/js/src/jsparse.cpp
+++ b/js/src/jsparse.cpp
@@ -1093,16 +1093,35 @@ NewCompilerFunction(JSContext *cx, JSTre
                          parent, atom);
     if (fun && !(tc->flags & TCF_COMPILE_N_GO)) {
         STOBJ_CLEAR_PARENT(FUN_OBJECT(fun));
         STOBJ_CLEAR_PROTO(FUN_OBJECT(fun));
     }
     return fun;
 }
 
+static JSBool
+MatchOrInsertSemicolon(JSContext *cx, JSTokenStream *ts)
+{
+    JSTokenType tt;
+
+    ts->flags |= TSF_OPERAND;
+    tt = js_PeekTokenSameLine(cx, ts);
+    ts->flags &= ~TSF_OPERAND;
+    if (tt == TOK_ERROR)
+        return JS_FALSE;
+    if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
+        js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
+                                    JSMSG_SEMI_BEFORE_STMNT);
+        return JS_FALSE;
+    }
+    (void) js_MatchToken(cx, ts, TOK_SEMI);
+    return JS_TRUE;
+}
+
 static JSParseNode *
 FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
             uintN lambda)
 {
     JSOp op, prevop;
     JSParseNode *pn, *body, *result;
     JSTokenType tt;
     JSAtom *funAtom;
@@ -1315,18 +1334,18 @@ FunctionDef(JSContext *cx, JSTokenStream
 
     body = FunctionBody(cx, ts, &funtc);
     if (!body)
         return NULL;
 
 #if JS_HAS_EXPR_CLOSURES
     if (tt == TOK_LC)
         MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY);
-    else if (lambda == 0)
-        js_MatchToken(cx, ts, TOK_SEMI);
+    else if (lambda == 0 && !MatchOrInsertSemicolon(cx, ts))
+        return NULL;
 #else
     MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY);
 #endif
     pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
 
 #if JS_HAS_DESTRUCTURING
     /*
      * If there were destructuring formal parameters, prepend the initializing
@@ -3537,31 +3556,17 @@ Statement(JSContext *cx, JSTokenStream *
             return NULL;
         pn->pn_type = TOK_SEMI;
         pn->pn_pos = pn2->pn_pos;
         pn->pn_kid = pn2;
         break;
     }
 
     /* Check termination of this primitive statement. */
-    if (ON_CURRENT_LINE(ts, pn->pn_pos)) {
-        ts->flags |= TSF_OPERAND;
-        tt = js_PeekTokenSameLine(cx, ts);
-        ts->flags &= ~TSF_OPERAND;
-        if (tt == TOK_ERROR)
-            return NULL;
-        if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) {
-            js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
-                                        JSMSG_SEMI_BEFORE_STMNT);
-            return NULL;
-        }
-    }
-
-    (void) js_MatchToken(cx, ts, TOK_SEMI);
-    return pn;
+    return MatchOrInsertSemicolon(cx, ts) ? pn : NULL;
 }
 
 static JSParseNode *
 Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
 {
     JSTokenType tt;
     JSBool let;
     JSStmtInfo *scopeStmt;