Bug 1494930 - Part 1: Various BinAST parser correctness fixes. (r=arai)
authorEric Faust <efaustbmo@gmail.com>
Tue, 02 Oct 2018 01:16:51 -0700
changeset 494885 90003e4c4f3a7dd9aa624371516d13340a05bed9
parent 494884 912ad8891041d872998e36a7090ea60246310ceb
child 494886 9fc8180f36219eeb95f900c35da744f0aee4a96d
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1494930
milestone64.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 1494930 - Part 1: Various BinAST parser correctness fixes. (r=arai)
js/src/frontend/BinSource-auto.cpp
js/src/frontend/BinSource.cpp
js/src/frontend/BinSource.yaml
js/src/frontend/BinTokenReaderMultipart.cpp
--- a/js/src/frontend/BinSource-auto.cpp
+++ b/js/src/frontend/BinSource-auto.cpp
@@ -2593,16 +2593,19 @@ BinASTParser<Tok>::parseInterfaceArrayEx
 
 #if defined(DEBUG)
     const BinField expected_fields[1] = { BinField::Elements };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
     BINJS_MOZ_TRY_DECL(elements, parseListOfOptionalSpreadElementOrExpression());
 
+    if (elements->empty()) {
+        elements->setHasNonConstInitializer();
+    }
     auto result = elements;
     return result;
 }
 
 
 /*
  interface ArrowExpressionContentsWithExpression : Node {
     AssertedParameterScope parameterScope;
@@ -3916,16 +3919,17 @@ BinASTParser<Tok>::parseInterfaceCatchCl
     BINJS_TRY(currentScope.init(parseContext_));
 
     MOZ_TRY(parseAssertedBoundNamesScope());
 
     BINJS_MOZ_TRY_DECL(binding, parseBinding());
 
     BINJS_MOZ_TRY_DECL(body, parseBlock());
 
+    MOZ_TRY(checkClosedVars(currentScope));
     BINJS_TRY_DECL(bindings, NewLexicalScopeData(cx_, currentScope, alloc_, parseContext_));
     BINJS_TRY_DECL(result, factory_.newLexicalScope(*bindings, body));
     BINJS_TRY(factory_.setupCatchScope(result, binding, body));
     return result;
 }
 
 
 /*
@@ -8347,16 +8351,18 @@ BinASTParser<Tok>::parseListOfObjectProp
     AutoList guard(*tokenizer_);
 
     const auto start = tokenizer_->offset();
     MOZ_TRY(tokenizer_->enterList(length, guard));
     BINJS_TRY_DECL(result, factory_.newObjectLiteral(start));
 
     for (uint32_t i = 0; i < length; ++i) {
         BINJS_MOZ_TRY_DECL(item, parseObjectProperty());
+        if (!item->isConstant())
+            result->setHasNonConstInitializer();
         result->appendWithoutOrderAssumption(item);
     }
 
     MOZ_TRY(guard.done());
     return result;
 }
 
 template<typename Tok> JS::Result<ParseNode*>
--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -216,16 +216,33 @@ BinASTParser<Tok>::buildFunction(const s
         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.
     }
 
+    // This models PerHandlerParser::declaeFunctionArgumentsObject, with some subtleties removed,
+    // as they don't yet apply to us.
+    HandlePropertyName arguments = cx_->names().arguments;
+    if (hasUsedName(arguments) || parseContext_->functionBox()->bindingsAccessedDynamically()) {
+        ParseContext::Scope& funScope = parseContext_->functionScope();
+        ParseContext::Scope::AddDeclaredNamePtr p = funScope.lookupDeclaredNameForAdd(arguments);
+        if (!p) {
+            BINJS_TRY(funScope.addDeclaredName(parseContext_, p, arguments, DeclarationKind::Var,
+                                               DeclaredNameInfo::npos));
+            funbox->declaredArguments = true;
+            funbox->usesArguments = true;
+
+            funbox->setArgumentsHasLocalBinding();
+            funbox->setDefinitelyNeedsArgsObj();
+        }
+    }
+
     // 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);
@@ -462,16 +479,19 @@ BinASTParser<Tok>::appendDirectivesToBod
         ParseNode* iter = body->head();
         while (iter) {
             ParseNode* next = iter->pn_next;
             prefix->appendWithoutOrderAssumption(iter);
             iter = next;
         }
         prefix->setKind(body->getKind());
         prefix->setOp(body->getOp());
+        if (body->hasTopLevelFunctionDeclarations()) {
+            prefix->setHasTopLevelFunctionDeclarations();
+        }
         result = prefix;
     }
 
     return result;
 }
 
 template<typename Tok> mozilla::GenericErrorResult<JS::Error&>
 BinASTParser<Tok>::raiseInvalidClosedVar(JSAtom* name)
--- a/js/src/frontend/BinSource.yaml
+++ b/js/src/frontend/BinSource.yaml
@@ -207,17 +207,20 @@ hpp:
 
 Arguments:
     init:
         BINJS_TRY_DECL(result, factory_.newList(ParseNodeKind::Arguments, tokenizer_->pos(start)));
     append:
         factory_.addList(/* list = */ result, /* kid = */ item);
 
 ArrayExpression:
-    build:
+    build: |
+        if (elements->empty()) {
+            elements->setHasNonConstInitializer();
+        }
         auto result = elements;
 
 AssertedBlockScope:
     type-ok:
         Ok
     init: |
         const auto scopeKind = AssertedScopeKind::Block;
     fields:
@@ -499,16 +502,17 @@ CallExpression:
 CatchClause:
     type-ok:
         LexicalScopeNode*
     init: |
         ParseContext::Statement stmt(parseContext_, StatementKind::Catch);
         ParseContext::Scope currentScope(cx_, parseContext_, usedNames_);
         BINJS_TRY(currentScope.init(parseContext_));
     build: |
+        MOZ_TRY(checkClosedVars(currentScope));
         BINJS_TRY_DECL(bindings, NewLexicalScopeData(cx_, currentScope, alloc_, parseContext_));
         BINJS_TRY_DECL(result, factory_.newLexicalScope(*bindings, body));
         BINJS_TRY(factory_.setupCatchScope(result, binding, body));
 
 CompoundAssignmentExpression:
     build: |
         ParseNodeKind pnk;
         switch (operator_){
@@ -866,16 +870,20 @@ ListOfDirective:
     append:
         factory_.addStatementToList(result, item);
 
 ListOfObjectProperty:
     type-ok:
         ListNode*
     init:
         BINJS_TRY_DECL(result, factory_.newObjectLiteral(start));
+    append: |
+        if (!item->isConstant())
+            result->setHasNonConstInitializer();
+        result->appendWithoutOrderAssumption(item);
 
 ListOfOptionalSpreadElementOrExpression:
     type-ok:
         ListNode*
     init:
         BINJS_TRY_DECL(result, factory_.newArrayLiteral(start));
     append: |
         if (item) {
--- a/js/src/frontend/BinTokenReaderMultipart.cpp
+++ b/js/src/frontend/BinTokenReaderMultipart.cpp
@@ -143,17 +143,17 @@ BinTokenReaderMultipart::readHeader()
         if (current_ + byteLen > stop_ || current_ + byteLen < current_) {
             return raiseError("Invalid byte length in individual string");
         }
 
         // Check null string.
         if (byteLen == 2 && *current_ == 255 && *(current_ + 1) == 0) {
             atom = nullptr;
         } else {
-            BINJS_TRY_VAR(atom, Atomize(cx_, (const char*)current_, byteLen));
+            BINJS_TRY_VAR(atom, AtomizeUTF8Chars(cx_, (const char*)current_, byteLen));
         }
 
         // Populate `atomsTable_`: i => atom.
         atomsTable_.infallibleAppend(atom); // We have reserved before entering the loop.
 
         // Populate `slicesTable_`: i => slice
         Chars slice((const char*)current_, byteLen);
         slicesTable_.infallibleAppend(std::move(slice)); // We have reserved before entering the loop.