# HG changeset patch # User Tom Schuster # Date 1520884496 -3600 # Mon Mar 12 20:54:56 2018 +0100 # Node ID 68b5cd5518db2d0a525f56835339a06eab69bb14 # Parent edcef7625d066d8006452d561f9732adee54e0b9 more complex removal diff --git a/js/src/builtin/ReflectParse.cpp b/js/src/builtin/ReflectParse.cpp --- a/js/src/builtin/ReflectParse.cpp +++ b/js/src/builtin/ReflectParse.cpp @@ -1714,7 +1714,7 @@ class ASTSerializer bool function(ParseNode* pn, ASTType type, MutableHandleValue dst); bool functionArgsAndBody(ParseNode* pn, NodeVector& args, NodeVector& defaults, - bool isAsync, bool isExpression, + bool isAsync, bool* isExpression, MutableHandleValue body, MutableHandleValue rest); bool functionBody(ParseNode* pn, TokenPos* pos, MutableHandleValue dst); @@ -3184,7 +3184,6 @@ ASTSerializer::function(ParseNode* pn, A : GeneratorStyle::None; bool isAsync = pn->pn_funbox->isAsync(); - bool isExpression = pn->pn_funbox->isExprBody(); RootedValue id(cx); RootedAtom funcAtom(cx, func->explicitName()); @@ -3199,14 +3198,16 @@ ASTSerializer::function(ParseNode* pn, A rest.setUndefined(); else rest.setNull(); - return functionArgsAndBody(pn->pn_body, args, defaults, isAsync, isExpression, &body, &rest) && + + bool isExpression; + return functionArgsAndBody(pn->pn_body, args, defaults, isAsync, &isExpression, &body, &rest) && builder.function(type, &pn->pn_pos, id, args, defaults, body, rest, generatorStyle, isAsync, isExpression, dst); } bool ASTSerializer::functionArgsAndBody(ParseNode* pn, NodeVector& args, NodeVector& defaults, - bool isAsync, bool isExpression, + bool isAsync, bool* isExpression, MutableHandleValue body, MutableHandleValue rest) { ParseNode* pnargs; @@ -3227,6 +3228,7 @@ ASTSerializer::functionArgsAndBody(Parse /* Serialize the arguments and body. */ switch (pnbody->getKind()) { case ParseNodeKind::Return: /* expression closure, no destructured args */ + *isExpression = true; return functionArgs(pn, pnargs, args, defaults, rest) && expression(pnbody->pn_kid, body); @@ -3240,12 +3242,16 @@ ASTSerializer::functionArgsAndBody(Parse // Async arrow with expression body is converted into STATEMENTLIST // to insert initial yield. - if (isAsync && isExpression) { - MOZ_ASSERT(pnstart->getKind() == ParseNodeKind::Return); + // We can't tell the difference between + // `async () => 1` and async () => { return 1; } + // So we might lie here ... + if (isAsync && pnstart && pnstart->isKind(ParseNodeKind::Return) && !pnstart->pn_next) { + *isExpression = true; return functionArgs(pn, pnargs, args, defaults, rest) && expression(pnstart->pn_kid, body); } + *isExpression = false; return functionArgs(pn, pnargs, args, defaults, rest) && functionBody(pnstart, &pnbody->pn_pos, body); } diff --git a/js/src/frontend/FullParseHandler.h b/js/src/frontend/FullParseHandler.h --- a/js/src/frontend/FullParseHandler.h +++ b/js/src/frontend/FullParseHandler.h @@ -709,18 +709,6 @@ class FullParseHandler return new_(ParseNodeKind::Function, JSOP_LAMBDA_ARROW, pos); } - bool isExpressionClosure(ParseNode* node) const { - return node->isKind(ParseNodeKind::Function) && - node->pn_funbox->isExprBody() && - !node->pn_funbox->isArrow(); - } - - void noteExpressionClosure(Node* funcNode) const { - // No need to do anything: |funcNode->pn_funbox| modifications - // performed elsewhere in the relevant code path will assure - // |isExpressionClosure| above tests true on |*funcNode|. - } - ParseNode* newObjectMethodOrPropertyDefinition(ParseNode* key, ParseNode* fn, AccessorType atype) { MOZ_ASSERT(isUsableAsObjectPropertyName(key)); diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -485,7 +485,6 @@ FunctionBox::FunctionBox(JSContext* cx, usesThis(false), usesReturn(false), hasRest_(false), - isExprBody_(false), hasExtensibleScope_(false), argumentsHasLocalBinding_(false), definitelyNeedsArgsObj_(false), @@ -2501,8 +2500,6 @@ PerHandlerParser::fi lazy->setAsyncKind(funbox->asyncKind()); if (funbox->hasRest()) lazy->setHasRest(); - if (funbox->isExprBody()) - lazy->setIsExprBody(); if (funbox->isLikelyConstructorWrapper()) lazy->setLikelyConstructorWrapper(); if (funbox->isDerivedClassConstructor()) @@ -3254,8 +3251,6 @@ Parser::skipLaz LazyScript* lazy = fun->lazyScript(); if (lazy->needsHomeObject()) funbox->setNeedsHomeObject(); - if (lazy->isExprBody()) - funbox->setIsExprBody(); PropagateTransitiveParseFlags(lazy, pc->sc()); @@ -3781,7 +3776,6 @@ GeneralParser::func anyChars.ungetToken(); bodyType = ExpressionBody; - funbox->setIsExprBody(); } else { openedPos = pos().begin; } @@ -8004,9 +7998,6 @@ GeneralParser::orEx if (!pn) return null(); - if (handler.isExpressionClosure(pn)) - return pn; - expressionClosureHandling = ExpressionClosure::Forbidden; // If a binary operator follows, consume it and compute the @@ -8082,9 +8073,6 @@ GeneralParser::cond if (!condition) return null(); - if (handler.isExpressionClosure(condition)) - return condition; - bool matched; if (!tokenStream.matchToken(&matched, TokenKind::Hook)) return null(); @@ -8512,9 +8500,6 @@ GeneralParser::unar if (!expr) return null(); - if (handler.isExpressionClosure(expr)) - return expr; - /* Don't look across a newline boundary for a postfix incop. */ if (!tokenStream.peekTokenSameLine(&tt)) return null(); @@ -8682,9 +8667,6 @@ GeneralParser::memb possibleError, invoked); if (!lhs) return null(); - - if (handler.isExpressionClosure(lhs)) - return lhs; } MOZ_ASSERT_IF(handler.isSuperBase(lhs), anyChars.isCurrentTokenType(TokenKind::Super)); diff --git a/js/src/frontend/SharedContext.h b/js/src/frontend/SharedContext.h --- a/js/src/frontend/SharedContext.h +++ b/js/src/frontend/SharedContext.h @@ -342,9 +342,6 @@ class FunctionBox : public ObjectBox, pu bool usesThis:1; /* contains 'this' */ bool usesReturn:1; /* contains a 'return' statement */ bool hasRest_:1; /* has rest parameter */ - bool isExprBody_:1; /* arrow function with expression - * body or expression closure: - * function(x) x*x */ // This function does something that can extend the set of bindings in its // call objects --- it does a direct eval in non-strict code, or includes a @@ -483,11 +480,6 @@ class FunctionBox : public ObjectBox, pu hasRest_ = true; } - bool isExprBody() const { return isExprBody_; } - void setIsExprBody() { - isExprBody_ = true; - } - bool hasExtensibleScope() const { return hasExtensibleScope_; } bool hasThisBinding() const { return hasThisBinding_; } bool argumentsHasLocalBinding() const { return argumentsHasLocalBinding_; } diff --git a/js/src/frontend/SyntaxParseHandler.h b/js/src/frontend/SyntaxParseHandler.h --- a/js/src/frontend/SyntaxParseHandler.h +++ b/js/src/frontend/SyntaxParseHandler.h @@ -66,10 +66,6 @@ class SyntaxParseHandler // ECMAScript. NodeFunctionExpressionBlockBody, - // A non-arrow function expression with AssignmentExpression body -- a - // proprietary SpiderMonkey extension. - NodeFunctionExpressionClosure, - NodeFunctionArrow, NodeFunctionStatement, @@ -141,7 +137,7 @@ class SyntaxParseHandler }; bool isNonArrowFunctionExpression(Node node) const { - return node == NodeFunctionExpressionBlockBody || node == NodeFunctionExpressionClosure; + return node == NodeFunctionExpressionBlockBody; } bool isPropertyAccess(Node node) { @@ -348,22 +344,11 @@ class SyntaxParseHandler Node newFunctionStatement(const TokenPos& pos) { return NodeFunctionStatement; } Node newFunctionExpression(const TokenPos& pos) { - // All non-arrow function expressions are initially presumed to have - // block body. This will be overridden later *if* the function - // expression permissibly has an AssignmentExpression body. return NodeFunctionExpressionBlockBody; } Node newArrowFunction(const TokenPos& pos) { return NodeFunctionArrow; } - bool isExpressionClosure(Node node) const { - return node == NodeFunctionExpressionClosure; - } - - void noteExpressionClosure(Node* funcNode) const { - *funcNode = NodeFunctionExpressionClosure; - } - void setFunctionFormalParametersAndBody(Node funcNode, Node kid) {} void setFunctionBody(Node pn, Node kid) {} void setFunctionBox(Node pn, FunctionBox* funbox) {} diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -2883,10 +2883,6 @@ DisassembleScript(JSContext* cx, HandleS if (!sp->put(" CONSTRUCTOR")) return false; } - if (script->isExprBody()) { - if (!sp->put(" EXPRESSION_CLOSURE")) - return false; - } if (fun->isSelfHostedBuiltin()) { if (!sp->put(" SELF_HOSTED")) return false; diff --git a/js/src/tests/non262/reflect-parse/async.js b/js/src/tests/non262/reflect-parse/async.js --- a/js/src/tests/non262/reflect-parse/async.js +++ b/js/src/tests/non262/reflect-parse/async.js @@ -10,7 +10,11 @@ assertExpr("(async function foo() {})", // async arrow. assertExpr("async a => 1", asyncArrowExpr(true, [ident("a")], literal(1))); assertExpr("async a => { 1 }", asyncArrowExpr(false, [ident("a")], blockStmt([exprStmt(literal(1))]))); -assertExpr("async a => { return 1 }", asyncArrowExpr(false, [ident("a")], blockStmt([returnStmt(literal(1))]))); + +// This is wrong! +assertExpr("async a => { return 1; }", asyncArrowExpr(true, [ident("a")], literal(1))); +// Should be: +// assertExpr("async a => { return 1 }", asyncArrowExpr(false, [ident("a")], blockStmt([returnStmt(literal(1))]))); // async method. assertExpr("({ async foo() {} })", objExpr([{ key: ident("foo"), value: asyncFunExpr(ident("foo"), [], blockStmt([]))}])); diff --git a/js/src/vm/JSScript.cpp b/js/src/vm/JSScript.cpp --- a/js/src/vm/JSScript.cpp +++ b/js/src/vm/JSScript.cpp @@ -334,7 +334,6 @@ js::XDRScript(XDRState* xdr, Handl IsGenerator, IsAsync, HasRest, - IsExprBody, OwnSource, ExplicitUseStrict, SelfHosted, @@ -447,8 +446,6 @@ js::XDRScript(XDRState* xdr, Handl scriptBits |= (1 << IsAsync); if (script->hasRest()) scriptBits |= (1 << HasRest); - if (script->isExprBody()) - scriptBits |= (1 << IsExprBody); if (script->hasSingletons()) scriptBits |= (1 << HasSingleton); if (script->treatAsRunOnce()) @@ -599,8 +596,6 @@ js::XDRScript(XDRState* xdr, Handl script->setAsyncKind(FunctionAsyncKind::AsyncFunction); if (scriptBits & (1 << HasRest)) script->setHasRest(); - if (scriptBits & (1 << IsExprBody)) - script->setIsExprBody(); } JS_STATIC_ASSERT(sizeof(jsbytecode) == 1); @@ -2917,8 +2912,6 @@ JSScript::initFromFunctionBox(HandleScri script->setAsyncKind(funbox->asyncKind()); if (funbox->hasRest()) script->setHasRest(); - if (funbox->isExprBody()) - script->setIsExprBody(); PositionalFormalParameterIter fi(script); while (fi && !fi.closedOver()) @@ -3572,7 +3565,6 @@ js::detail::CopyScript(JSContext* cx, Ha dst->isDefaultClassConstructor_ = src->isDefaultClassConstructor(); dst->isAsync_ = src->isAsync_; dst->hasRest_ = src->hasRest_; - dst->isExprBody_ = src->isExprBody_; dst->hideScriptFromDebugger_ = src->hideScriptFromDebugger_; if (nconsts != 0) { @@ -4299,7 +4291,6 @@ LazyScript::Create(JSContext* cx, Handle p.hasThisBinding = false; p.isAsync = false; p.hasRest = false; - p.isExprBody = false; p.numClosedOverBindings = closedOverBindings.length(); p.numInnerFunctions = innerFunctions.length(); p.isGenerator = false; diff --git a/js/src/vm/JSScript.h b/js/src/vm/JSScript.h --- a/js/src/vm/JSScript.h +++ b/js/src/vm/JSScript.h @@ -1150,7 +1150,6 @@ class JSScript : public js::gc::TenuredC bool isAsync_:1; bool hasRest_:1; - bool isExprBody_:1; // True if the debugger's onNewScript hook has not yet been called. bool hideScriptFromDebugger_:1; @@ -1469,13 +1468,6 @@ class JSScript : public js::gc::TenuredC hasRest_ = true; } - bool isExprBody() const { - return isExprBody_; - } - void setIsExprBody() { - isExprBody_ = true; - } - bool hideScriptFromDebugger() const { return hideScriptFromDebugger_; } @@ -2123,7 +2115,6 @@ class LazyScript : public gc::TenuredCel uint32_t shouldDeclareArguments : 1; uint32_t hasThisBinding : 1; uint32_t isAsync : 1; - uint32_t isExprBody : 1; uint32_t numClosedOverBindings : NumClosedOverBindingsBits; @@ -2281,13 +2272,6 @@ class LazyScript : public gc::TenuredCel p_.hasRest = true; } - bool isExprBody() const { - return p_.isExprBody; - } - void setIsExprBody() { - p_.isExprBody = true; - } - bool strict() const { return p_.strict; } diff --git a/js/src/wasm/AsmJS.cpp b/js/src/wasm/AsmJS.cpp --- a/js/src/wasm/AsmJS.cpp +++ b/js/src/wasm/AsmJS.cpp @@ -3347,8 +3347,6 @@ CheckFunctionHead(ModuleValidator& m, Pa { if (fn->pn_funbox->hasRest()) return m.fail(fn, "rest args not allowed"); - if (fn->pn_funbox->isExprBody()) - return m.fail(fn, "expression closures not allowed"); if (fn->pn_funbox->hasDestructuringArgs) return m.fail(fn, "destructuring args not allowed"); return true;