Bug 1456766 - [BinAST] Bind |this| in functions. Don't yet handle lexical |this| closure. (r=Yoric)
authorEric Faust <efaustbmo@gmail.com>
Mon, 30 Apr 2018 23:55:36 -0700
changeset 472560 b7662a1cd8cbf0ea1bb49231a8c35d6fcb0a24b3
parent 472559 6fdf52934a04f7aca7e3a0a1e8a180b7c9e0305b
child 472561 788d134870102c3333a4564db7eef0d4ea8c52ba
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersYoric
bugs1456766
milestone61.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 1456766 - [BinAST] Bind |this| in functions. Don't yet handle lexical |this| closure. (r=Yoric)
js/src/frontend/BinSource-auto.cpp
js/src/frontend/BinSource.cpp
js/src/frontend/BinSource.yaml
--- a/js/src/frontend/BinSource-auto.cpp
+++ b/js/src/frontend/BinSource-auto.cpp
@@ -7127,18 +7127,21 @@ BinASTParser<Tok>::parseInterfaceThisExp
 
 MOZ_TRY(tokenizer_->checkFields0(kind, fields));
 
     if (parseContext_->isFunctionBox())
         parseContext_->functionBox()->usesThis = true;
 
     TokenPos pos = tokenizer_->pos(start);
     ParseNode* thisName(nullptr);
-    if (parseContext_->sc()->thisBinding() == ThisBinding::Function)
-        BINJS_TRY_VAR(thisName, factory_.newName(cx_->names().dotThis, pos, cx_));
+    if (parseContext_->sc()->thisBinding() == ThisBinding::Function) {
+        HandlePropertyName dotThis = cx_->names().dotThis;
+        BINJS_TRY(usedNames_.noteUse(cx_, dotThis, parseContext_->scriptId(), parseContext_->innermostScope()->id()));
+        BINJS_TRY_VAR(thisName, factory_.newName(dotThis, pos, cx_));
+    }
 
     BINJS_TRY_DECL(result, factory_.newThisLiteral(pos, thisName));
     return result;
 }
 
 
 /*
  interface ThrowStatement : Node {
--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -149,21 +149,20 @@ BinASTParser<Tok>::buildFunctionBox(Gene
     funbox->initWithEnclosingParseContext(parseContext_, syntax);
     return funbox;
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::buildFunction(const size_t start, const BinKind kind, ParseNode* name,
                                  ParseNode* params, ParseNode* body, FunctionBox* funbox)
 {
-    // Check all our bindings before doing anything else.
-    MOZ_TRY(checkFunctionClosedVars());
-
     TokenPos pos = tokenizer_->pos(start);
 
+    // Set the argument count for building argument packets. Function.length is handled
+    // by setting the appropriate funbox field during argument parsing.
     funbox->function()->setArgCount(params ? uint16_t(params->pn_count) : 0);
 
     // ParseNode represents the body as concatenated after the params.
     params->appendWithoutOrderAssumption(body);
 
     bool isStatement = kind == BinKind::EagerFunctionDeclaration ||
                        kind == BinKind::SkippableFunctionDeclaration;
 
@@ -181,18 +180,23 @@ BinASTParser<Tok>::buildFunction(const s
 
     if (declareThis) {
         ParseContext::Scope& funScope = parseContext_->functionScope();
         ParseContext::Scope::AddDeclaredNamePtr p = funScope.lookupDeclaredNameForAdd(dotThis);
         MOZ_ASSERT(!p);
         BINJS_TRY(funScope.addDeclaredName(parseContext_, p, dotThis, DeclarationKind::Var,
                                      DeclaredNameInfo::npos));
         funbox->setHasThisBinding();
+
+        // TODO (efaust): This capture will have to come from encoder side for arrow functions.
     }
 
+    // Check all our bindings after maybe adding function This.
+    MOZ_TRY(checkFunctionClosedVars());
+
     BINJS_TRY_DECL(bindings,
              NewFunctionScopeData(cx_, parseContext_->functionScope(),
                                   /* hasParameterExprs = */ false, alloc_, parseContext_));
 
     funbox->functionScopeBindings().set(*bindings);
 
     if (funbox->function()->isNamedLambda()) {
         BINJS_TRY_DECL(recursiveBinding,
--- a/js/src/frontend/BinSource.yaml
+++ b/js/src/frontend/BinSource.yaml
@@ -913,18 +913,21 @@ StaticMemberExpression:
 
 ThisExpression:
     build: |
         if (parseContext_->isFunctionBox())
             parseContext_->functionBox()->usesThis = true;
 
         TokenPos pos = tokenizer_->pos(start);
         ParseNode* thisName(nullptr);
-        if (parseContext_->sc()->thisBinding() == ThisBinding::Function)
-            BINJS_TRY_VAR(thisName, factory_.newName(cx_->names().dotThis, pos, cx_));
+        if (parseContext_->sc()->thisBinding() == ThisBinding::Function) {
+            HandlePropertyName dotThis = cx_->names().dotThis;
+            BINJS_TRY(usedNames_.noteUse(cx_, dotThis, parseContext_->scriptId(), parseContext_->innermostScope()->id()));
+            BINJS_TRY_VAR(thisName, factory_.newName(dotThis, pos, cx_));
+        }
 
         BINJS_TRY_DECL(result, factory_.newThisLiteral(pos, thisName));
 
 ThrowStatement:
     build:
         BINJS_TRY_DECL(result, factory_.newThrowStatement(expression, tokenizer_->pos(start)));
 
 TryCatchStatement: