Bug 1297706 - Syntax parse arrow functions. r=shu
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 13 Sep 2016 14:14:32 +0200
changeset 354943 d1bf9267ba7da182771c43aec042f0f5f579de93
parent 354942 5011ecc316111a8c6a3a6260d2b9dab941405970
child 354944 799275459ccb35cfc023fd3a3ae820df94095dce
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu
bugs1297706
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1297706 - Syntax parse arrow functions. r=shu
js/src/frontend/Parser.cpp
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -465,16 +465,18 @@ FunctionBox::FunctionBox(ExclusiveContex
 
 void
 FunctionBox::initFromLazyFunction()
 {
     JSFunction* fun = function();
     length = fun->nargs() - fun->hasRest();
     if (fun->lazyScript()->isDerivedClassConstructor())
         setDerivedClassConstructor();
+    if (fun->lazyScript()->needsHomeObject())
+        setNeedsHomeObject();
     enclosingScope_ = fun->lazyScript()->enclosingScope();
     initWithEnclosingScope(enclosingScope_);
 }
 
 void
 FunctionBox::initStandaloneFunction(Scope* enclosingScope)
 {
     // Standalone functions are Function or Generator constructors and are
@@ -2820,24 +2822,17 @@ Parser<ParseHandler>::checkFunctionDefin
                 return false;
 
             // Body-level functions in modules are always closed over.
             if (pc->atModuleLevel())
                 pc->varScope().lookupDeclaredName(funName)->value()->setClosedOver();
         }
     } else {
         // A function expression does not introduce any binding.
-        if (kind == Arrow) {
-            /* Arrow functions cannot yet be parsed lazily. */
-            if (!abortIfSyntaxParser())
-                return false;
-            handler.setOp(pn, JSOP_LAMBDA_ARROW);
-        } else {
-            handler.setOp(pn, JSOP_LAMBDA);
-        }
+        handler.setOp(pn, kind == Arrow ? JSOP_LAMBDA_ARROW : JSOP_LAMBDA);
     }
 
     return true;
 }
 
 template <>
 bool
 Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, bool tryAnnexB)
@@ -3183,43 +3178,50 @@ Parser<FullParseHandler>::standaloneLazy
                                                  GeneratorKind generatorKind)
 {
     MOZ_ASSERT(checkOptionsCalled);
 
     Node pn = handler.newFunctionDefinition();
     if (!pn)
         return null();
 
-    // Our tokenStream has no current token, so pn's position is garbage.
-    // Substitute the position of the first token in our source.
-    if (!tokenStream.peekTokenPos(&pn->pn_pos))
-        return null();
-
     Directives directives(strict);
     FunctionBox* funbox = newFunctionBox(pn, fun, directives, generatorKind,
                                          /* tryAnnexB = */ false);
     if (!funbox)
         return null();
     funbox->initFromLazyFunction();
 
     Directives newDirectives = directives;
     ParseContext funpc(this, funbox, &newDirectives);
     if (!funpc.init())
         return null();
 
+    // Our tokenStream has no current token, so pn's position is garbage.
+    // Substitute the position of the first token in our source. If the function
+    // is an arrow, use TokenStream::Operand to keep verifyConsistentModifier
+    // from complaining (we will use TokenStream::Operand in functionArguments).
+    if (!tokenStream.peekTokenPos(&pn->pn_pos,
+                                  fun->isArrow() ? TokenStream::Operand : TokenStream::None))
+    {
+        return null();
+    }
+
     YieldHandling yieldHandling = generatorKind != NotGenerator ? YieldIsKeyword : YieldIsName;
     FunctionSyntaxKind syntaxKind = Statement;
     if (fun->isClassConstructor())
         syntaxKind = ClassConstructor;
     else if (fun->isMethod())
         syntaxKind = Method;
     else if (fun->isGetter())
         syntaxKind = Getter;
     else if (fun->isSetter())
         syntaxKind = Setter;
+    else if (fun->isArrow())
+        syntaxKind = Arrow;
 
     if (!functionFormalParametersAndBody(InAllowed, yieldHandling, pn, syntaxKind)) {
         MOZ_ASSERT(directives == newDirectives);
         return null();
     }
 
     if (!FoldConstants(context, &pn, this))
         return null();
@@ -7298,18 +7300,16 @@ Parser<ParseHandler>::assignExpr(InHandl
 
         bool isBlock = false;
         if (!tokenStream.peekToken(&next, TokenStream::Operand))
             return null();
         if (next == TOK_LC)
             isBlock = true;
 
         tokenStream.seek(start);
-        if (!abortIfSyntaxParser())
-            return null();
 
         TokenKind ignored;
         if (!tokenStream.peekToken(&ignored, TokenStream::Operand))
             return null();
 
         Node arrowFunc = functionDefinition(inHandling, yieldHandling, nullptr,
                                             Arrow, NotGenerator);
         if (!arrowFunc)