☠☠ backed out by 5e7324701130 ☠ ☠ | |
author | Eric Faust <efaustbmo@gmail.com> |
Wed, 02 Sep 2015 15:09:03 -0700 | |
changeset 260641 | a14eb650f5be7810203729832da49a95a802306b |
parent 260640 | a05bfd76c34c42dd351cd96d68bdfefb4115d597 |
child 260642 | 4f7c8a5677070cfd021dd205c90d60cebc449ee2 |
push id | 29318 |
push user | cbook@mozilla.com |
push date | Thu, 03 Sep 2015 11:15:07 +0000 |
treeherder | mozilla-central@74fbd245369c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | Waldo |
bugs | 1168992 |
milestone | 43.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
|
--- a/js/src/builtin/ReflectParse.cpp +++ b/js/src/builtin/ReflectParse.cpp @@ -751,17 +751,17 @@ class NodeBuilder bool comprehensionIf(HandleValue test, TokenPos* pos, MutableHandleValue dst); bool comprehensionExpression(HandleValue body, NodeVector& blocks, HandleValue filter, bool isLegacy, TokenPos* pos, MutableHandleValue dst); bool generatorExpression(HandleValue body, NodeVector& blocks, HandleValue filter, bool isLegacy, TokenPos* pos, MutableHandleValue dst); - bool newTargetExpression(TokenPos* pos, MutableHandleValue dst); + bool metaProperty(HandleValue meta, HandleValue property, TokenPos* pos, MutableHandleValue dst); /* * declarations */ bool variableDeclaration(NodeVector& elts, VarDeclKind kind, TokenPos* pos, MutableHandleValue dst); @@ -1821,23 +1821,26 @@ NodeBuilder::classDefinition(bool expr, return newNode(type, pos, "id", name, "superClass", heritage, "body", block, dst); } bool -NodeBuilder::newTargetExpression(TokenPos* pos, MutableHandleValue dst) +NodeBuilder::metaProperty(HandleValue meta, HandleValue property, TokenPos* pos, MutableHandleValue dst) { - RootedValue cb(cx, callbacks[AST_NEWTARGET_EXPR]); + RootedValue cb(cx, callbacks[AST_METAPROPERTY]); if (!cb.isNull()) - return callback(cb, pos, dst); - - return newNode(AST_NEWTARGET_EXPR, pos, dst); + return callback(cb, meta, property, pos, dst); + + return newNode(AST_METAPROPERTY, pos, + "meta", meta, + "property", property, + dst); } namespace { /* * Serialization of parse nodes to JavaScript objects. * * All serialization methods take a non-nullable ParseNode pointer. @@ -3307,17 +3310,32 @@ ASTSerializer::expression(ParseNode* pn, /* NB: it's no longer the case that pn_count could be 2. */ LOCAL_ASSERT(pn->pn_count == 1); return comprehension(pn->pn_head, dst); case PNK_CLASS: return classDefinition(pn, true, dst); case PNK_NEWTARGET: - return builder.newTargetExpression(&pn->pn_pos, dst); + { + MOZ_ASSERT(pn->pn_left->isKind(PNK_POSHOLDER)); + MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos)); + MOZ_ASSERT(pn->pn_right->isKind(PNK_POSHOLDER)); + MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos)); + + RootedValue newIdent(cx); + RootedValue targetIdent(cx); + + RootedAtom newStr(cx, cx->names().new_); + RootedAtom targetStr(cx, cx->names().target); + + return identifier(newStr, &pn->pn_left->pn_pos, &newIdent) && + identifier(targetStr, &pn->pn_right->pn_pos, &targetIdent) && + builder.metaProperty(newIdent, targetIdent, &pn->pn_pos, dst); + } default: LOCAL_NOT_REACHED("unexpected expression type"); } } bool ASTSerializer::propertyName(ParseNode* pn, MutableHandleValue dst)
--- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -1910,33 +1910,40 @@ bool BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer) { JS_CHECK_RECURSION(cx, return false); restart: switch (pn->getKind()) { // Trivial cases with no side effects. - case PNK_NEWTARGET: case PNK_NOP: case PNK_STRING: case PNK_TEMPLATE_STRING: case PNK_REGEXP: case PNK_TRUE: case PNK_FALSE: case PNK_NULL: case PNK_THIS: case PNK_ELISION: case PNK_GENERATOR: case PNK_NUMBER: case PNK_OBJECT_PROPERTY_NAME: MOZ_ASSERT(pn->isArity(PN_NULLARY)); *answer = false; return true; + // Trivial binary nodes with more token pos holders. + case PNK_NEWTARGET: + MOZ_ASSERT(pn->isArity(PN_BINARY)); + MOZ_ASSERT(pn->pn_left->isKind(PNK_POSHOLDER)); + MOZ_ASSERT(pn->pn_right->isKind(PNK_POSHOLDER)); + *answer = false; + return true; + case PNK_BREAK: case PNK_CONTINUE: case PNK_DEBUGGER: MOZ_ASSERT(pn->isArity(PN_NULLARY)); *answer = true; return true; // Watch out for getters! @@ -2315,16 +2322,17 @@ BytecodeEmitter::checkSideEffects(ParseN case PNK_CLASSNAMES: // by PNK_CLASS case PNK_CLASSMETHODLIST: // by PNK_CLASS case PNK_IMPORT_SPEC_LIST: // by PNK_IMPORT case PNK_IMPORT_SPEC: // by PNK_IMPORT case PNK_EXPORT_BATCH_SPEC:// by PNK_EXPORT case PNK_EXPORT_SPEC_LIST: // by PNK_EXPORT case PNK_EXPORT_SPEC: // by PNK_EXPORT case PNK_CALLSITEOBJ: // by PNK_TAGGED_TEMPLATE + case PNK_POSHOLDER: // by PNK_NEWTARGET MOZ_CRASH("handled by parent nodes"); case PNK_LIMIT: // invalid sentinel value MOZ_CRASH("invalid node kind"); } MOZ_CRASH("invalid, unenumerated ParseNodeKind value encountered in " "BytecodeEmitter::checkSideEffects"); @@ -8083,16 +8091,19 @@ BytecodeEmitter::emitTree(ParseNode* pn) ok = emitClass(pn); break; case PNK_NEWTARGET: if (!emit1(JSOP_NEWTARGET)) return false; break; + case PNK_POSHOLDER: + MOZ_ASSERT_UNREACHABLE("Should never try to emit PNK_POSHOLDER"); + default: MOZ_ASSERT(0); } /* bce->emitLevel == 1 means we're last on the stack, so finish up. */ if (ok && emitLevel == 1) { if (!updateSourceCoordNotes(pn->pn_pos.end)) return false;
--- a/js/src/frontend/FoldConstants.cpp +++ b/js/src/frontend/FoldConstants.cpp @@ -412,16 +412,17 @@ ContainsHoistedDeclaration(ExclusiveCont case PNK_FORHEAD: case PNK_FRESHENBLOCK: case PNK_CLASSMETHOD: case PNK_CLASSMETHODLIST: case PNK_CLASSNAMES: case PNK_SUPERPROP: case PNK_SUPERELEM: case PNK_NEWTARGET: + case PNK_POSHOLDER: MOZ_CRASH("ContainsHoistedDeclaration should have indicated false on " "some parent node without recurring to test this node"); case PNK_GLOBALCONST: MOZ_CRASH("ContainsHoistedDeclaration is only called on nested nodes where " "globalconst nodes should never have been generated"); case PNK_LIMIT: // invalid sentinel value @@ -1704,17 +1705,16 @@ FoldName(ExclusiveContext* cx, ParseNode bool Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bool inGenexpLambda) { JS_CHECK_RECURSION(cx, return false); ParseNode* pn = *pnp; switch (pn->getKind()) { - case PNK_NEWTARGET: case PNK_NOP: case PNK_REGEXP: case PNK_STRING: case PNK_TRUE: case PNK_FALSE: case PNK_NULL: case PNK_ELISION: case PNK_NUMBER: @@ -1723,16 +1723,17 @@ Fold(ExclusiveContext* cx, ParseNode** p case PNK_CONTINUE: case PNK_TEMPLATE_STRING: case PNK_THIS: case PNK_GENERATOR: case PNK_EXPORT_BATCH_SPEC: case PNK_OBJECT_PROPERTY_NAME: case PNK_SUPERPROP: case PNK_FRESHENBLOCK: + case PNK_POSHOLDER: MOZ_ASSERT(pn->isArity(PN_NULLARY)); return true; case PNK_TYPEOFNAME: MOZ_ASSERT(pn->isArity(PN_UNARY)); MOZ_ASSERT(pn->pn_kid->isKind(PNK_NAME)); MOZ_ASSERT(!pn->pn_kid->maybeExpr()); return true; @@ -1913,16 +1914,22 @@ Fold(ExclusiveContext* cx, ParseNode** p case PNK_FOR: case PNK_CLASSMETHOD: case PNK_IMPORT_SPEC: case PNK_EXPORT_SPEC: MOZ_ASSERT(pn->isArity(PN_BINARY)); return Fold(cx, &pn->pn_left, parser, inGenexpLambda) && Fold(cx, &pn->pn_right, parser, inGenexpLambda); + case PNK_NEWTARGET: + MOZ_ASSERT(pn->isArity(PN_BINARY)); + MOZ_ASSERT(pn->pn_left->isKind(PNK_POSHOLDER)); + MOZ_ASSERT(pn->pn_right->isKind(PNK_POSHOLDER)); + return true; + case PNK_CLASSNAMES: MOZ_ASSERT(pn->isArity(PN_BINARY)); if (ParseNode*& outerBinding = pn->pn_left) { if (!Fold(cx, &outerBinding, parser, inGenexpLambda)) return false; } return Fold(cx, &pn->pn_right, parser, inGenexpLambda);
--- a/js/src/frontend/FullParseHandler.h +++ b/js/src/frontend/FullParseHandler.h @@ -347,18 +347,21 @@ class FullParseHandler return new_<ClassNames>(outer, inner, pos); } ParseNode* newSuperProperty(JSAtom* atom, const TokenPos& pos) { return new_<SuperProperty>(atom, pos); } ParseNode* newSuperElement(ParseNode* expr, const TokenPos& pos) { return new_<SuperElement>(expr, pos); } - ParseNode* newNewTarget(const TokenPos& pos) { - return new_<NullaryNode>(PNK_NEWTARGET, pos); + ParseNode* newNewTarget(ParseNode* newHolder, ParseNode* targetHolder) { + return new_<BinaryNode>(PNK_NEWTARGET, JSOP_NOP, newHolder, targetHolder); + } + ParseNode* newPosHolder(const TokenPos& pos) { + return new_<NullaryNode>(PNK_POSHOLDER, pos); } bool addPrototypeMutation(ParseNode* literal, uint32_t begin, ParseNode* expr) { // Object literals with mutated [[Prototype]] are non-constant so that // singleton objects will have Object.prototype as their [[Prototype]]. setListFlag(literal, PNX_NONCONST); ParseNode* mutation = newUnary(PNK_MUTATEPROTO, JSOP_NOP, begin, expr);
--- a/js/src/frontend/NameFunctions.cpp +++ b/js/src/frontend/NameFunctions.cpp @@ -372,26 +372,31 @@ class NameResolver case PNK_NUMBER: case PNK_BREAK: case PNK_CONTINUE: case PNK_DEBUGGER: case PNK_EXPORT_BATCH_SPEC: case PNK_FRESHENBLOCK: case PNK_SUPERPROP: case PNK_OBJECT_PROPERTY_NAME: - case PNK_NEWTARGET: MOZ_ASSERT(cur->isArity(PN_NULLARY)); break; case PNK_TYPEOFNAME: MOZ_ASSERT(cur->isArity(PN_UNARY)); MOZ_ASSERT(cur->pn_kid->isKind(PNK_NAME)); MOZ_ASSERT(!cur->pn_kid->maybeExpr()); break; + case PNK_NEWTARGET: + MOZ_ASSERT(cur->isArity(PN_BINARY)); + MOZ_ASSERT(cur->pn_left->isKind(PNK_POSHOLDER)); + MOZ_ASSERT(cur->pn_right->isKind(PNK_POSHOLDER)); + break; + // Nodes with a single non-null child requiring name resolution. case PNK_TYPEOFEXPR: case PNK_VOID: case PNK_NOT: case PNK_BITNOT: case PNK_THROW: case PNK_DELETENAME: case PNK_DELETEPROP: @@ -774,16 +779,17 @@ class NameResolver break; // Kinds that should be handled by parent node resolution. case PNK_IMPORT_SPEC: // by PNK_IMPORT_SPEC_LIST case PNK_EXPORT_SPEC: // by PNK_EXPORT_SPEC_LIST case PNK_CALLSITEOBJ: // by PNK_TAGGED_TEMPLATE case PNK_CLASSNAMES: // by PNK_CLASS + case PNK_POSHOLDER: // by PNK_NEWTARGET MOZ_CRASH("should have been handled by a parent node"); case PNK_LIMIT: // invalid sentinel value MOZ_CRASH("invalid node kind"); } nparents--; return true;
--- a/js/src/frontend/ParseNode.cpp +++ b/js/src/frontend/ParseNode.cpp @@ -210,17 +210,17 @@ PushNodeChildren(ParseNode* pn, NodeStac case PNK_NUMBER: case PNK_BREAK: case PNK_CONTINUE: case PNK_DEBUGGER: case PNK_EXPORT_BATCH_SPEC: case PNK_OBJECT_PROPERTY_NAME: case PNK_FRESHENBLOCK: case PNK_SUPERPROP: - case PNK_NEWTARGET: + case PNK_POSHOLDER: MOZ_ASSERT(pn->isArity(PN_NULLARY)); MOZ_ASSERT(!pn->isUsed(), "handle non-trivial cases separately"); MOZ_ASSERT(!pn->isDefn(), "handle non-trivial cases separately"); return PushResult::Recyclable; // Nodes with a single non-null child. case PNK_TYPEOFNAME: case PNK_TYPEOFEXPR: @@ -280,16 +280,17 @@ PushNodeChildren(ParseNode* pn, NodeStac case PNK_COLON: case PNK_CASE: case PNK_SHORTHAND: case PNK_DOWHILE: case PNK_WHILE: case PNK_SWITCH: case PNK_LETBLOCK: case PNK_CLASSMETHOD: + case PNK_NEWTARGET: case PNK_FOR: { MOZ_ASSERT(pn->isArity(PN_BINARY)); stack->push(pn->pn_left); stack->push(pn->pn_right); return PushResult::Recyclable; } // Named class expressions do not have outer binding nodes
--- a/js/src/frontend/ParseNode.h +++ b/js/src/frontend/ParseNode.h @@ -174,16 +174,17 @@ class PackedScopeCoordinate F(MUTATEPROTO) \ F(CLASS) \ F(CLASSMETHOD) \ F(CLASSMETHODLIST) \ F(CLASSNAMES) \ F(SUPERPROP) \ F(SUPERELEM) \ F(NEWTARGET) \ + F(POSHOLDER) \ \ /* Unary operators. */ \ F(TYPEOFNAME) \ F(TYPEOFEXPR) \ F(VOID) \ F(NOT) \ F(BITNOT) \ \
--- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -8944,18 +8944,23 @@ Parser<ParseHandler>::methodDefinition(Y } template <typename ParseHandler> bool Parser<ParseHandler>::tryNewTarget(Node &newTarget) { MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_NEW)); + newTarget = null(); + + Node newHolder = handler.newPosHolder(pos()); + if (!newHolder) + return false; + uint32_t begin = pos().begin; - newTarget = null(); // |new| expects to look for an operand, so we will honor that. TokenKind next; if (!tokenStream.getToken(&next, TokenStream::Operand)) return false; // Don't unget the token, since lookahead cannot handle someone calling // getToken() with a different modifier. Callers should inspect currentToken(). @@ -8970,17 +8975,21 @@ Parser<ParseHandler>::tryNewTarget(Node return false; } if (!pc->sc->allowNewTarget()) { reportWithOffset(ParseError, false, begin, JSMSG_BAD_NEWTARGET); return false; } - newTarget = handler.newNewTarget(TokenPos(begin, pos().end)); + Node targetHolder = handler.newPosHolder(pos()); + if (!targetHolder) + return false; + + newTarget = handler.newNewTarget(newHolder, targetHolder); return !!newTarget; } template <typename ParseHandler> typename ParseHandler::Node Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TokenKind tt, InvokedPrediction invoked) {
--- a/js/src/frontend/SyntaxParseHandler.h +++ b/js/src/frontend/SyntaxParseHandler.h @@ -276,17 +276,18 @@ class SyntaxParseHandler Node newSuperProperty(PropertyName* prop, const TokenPos& pos) { return NodeSuperProperty; } Node newSuperElement(Node expr, const TokenPos& pos) { return NodeSuperElement; } - Node newNewTarget(const TokenPos& pos) { return NodeGeneric; } + Node newNewTarget(Node newHolder, Node targetHolder) { return NodeGeneric; } + Node newPosHolder(const TokenPos& pos) { return NodeGeneric; } bool addPrototypeMutation(Node literal, uint32_t begin, Node expr) { return true; } bool addPropertyDefinition(Node literal, Node name, Node expr) { return true; } bool addShorthand(Node literal, Node name, Node expr) { return true; } bool addObjectMethodDefinition(Node literal, Node name, Node fn, JSOp op) { return true; } bool addClassMethodDefinition(Node literal, Node name, Node fn, JSOp op, bool isStatic) { return true; } Node newYieldExpression(uint32_t begin, Node value, Node gen) { return NodeUnparenthesizedYieldExpr; } Node newYieldStarExpression(uint32_t begin, Node value, Node gen) { return NodeGeneric; }
--- a/js/src/jsast.tbl +++ b/js/src/jsast.tbl @@ -33,17 +33,17 @@ ASTDEF(AST_ARROW_EXPR, "Arrow ASTDEF(AST_ARRAY_EXPR, "ArrayExpression", "arrayExpression") ASTDEF(AST_SPREAD_EXPR, "SpreadExpression", "spreadExpression") ASTDEF(AST_OBJECT_EXPR, "ObjectExpression", "objectExpression") ASTDEF(AST_THIS_EXPR, "ThisExpression", "thisExpression") ASTDEF(AST_COMP_EXPR, "ComprehensionExpression", "comprehensionExpression") ASTDEF(AST_GENERATOR_EXPR, "GeneratorExpression", "generatorExpression") ASTDEF(AST_YIELD_EXPR, "YieldExpression", "yieldExpression") ASTDEF(AST_CLASS_EXPR, "ClassExpression", "classExpression") -ASTDEF(AST_NEWTARGET_EXPR, "NewTargetExpression", "newTargetExpression") +ASTDEF(AST_METAPROPERTY, "MetaProperty", "metaProperty") ASTDEF(AST_EMPTY_STMT, "EmptyStatement", "emptyStatement") ASTDEF(AST_BLOCK_STMT, "BlockStatement", "blockStatement") ASTDEF(AST_EXPR_STMT, "ExpressionStatement", "expressionStatement") ASTDEF(AST_LAB_STMT, "LabeledStatement", "labeledStatement") ASTDEF(AST_IF_STMT, "IfStatement", "ifStatement") ASTDEF(AST_SWITCH_STMT, "SwitchStatement", "switchStatement") ASTDEF(AST_WHILE_STMT, "WhileStatement", "whileStatement")
--- a/js/src/jsatom.cpp +++ b/js/src/jsatom.cpp @@ -71,17 +71,16 @@ const char js_finally_str[] = "f const char js_for_str[] = "for"; const char js_getter_str[] = "getter"; const char js_if_str[] = "if"; const char js_implements_str[] = "implements"; const char js_import_str[] = "import"; const char js_in_str[] = "in"; const char js_instanceof_str[] = "instanceof"; const char js_interface_str[] = "interface"; -const char js_new_str[] = "new"; const char js_package_str[] = "package"; const char js_private_str[] = "private"; const char js_protected_str[] = "protected"; const char js_public_str[] = "public"; const char js_send_str[] = "send"; const char js_setter_str[] = "setter"; const char js_switch_str[] = "switch"; const char js_this_str[] = "this";
--- a/js/src/jsatom.h +++ b/js/src/jsatom.h @@ -171,17 +171,16 @@ extern const char js_finally_str[]; extern const char js_for_str[]; extern const char js_getter_str[]; extern const char js_if_str[]; extern const char js_implements_str[]; extern const char js_import_str[]; extern const char js_in_str[]; extern const char js_instanceof_str[]; extern const char js_interface_str[]; -extern const char js_new_str[]; extern const char js_package_str[]; extern const char js_private_str[]; extern const char js_protected_str[]; extern const char js_public_str[]; extern const char js_send_str[]; extern const char js_setter_str[]; extern const char js_static_str[]; extern const char js_super_str[];
--- a/js/src/tests/js1_8_5/reflect-parse/PatternBuilders.js +++ b/js/src/tests/js1_8_5/reflect-parse/PatternBuilders.js @@ -165,19 +165,25 @@ function genFunExpr(id, args, body) { generator: true }); } function arrowExpr(args, body) { return Pattern({ type: "ArrowFunctionExpression", params: args, body: body }); } +function metaProperty(meta, property) { + return Pattern({ type: "MetaProperty", + meta: meta, + property: property }); +} function newTarget() { - return Pattern({ type: "NewTargetExpression" }); + return metaProperty(ident("new"), ident("target")); } + function unExpr(op, arg) { return Pattern({ type: "UnaryExpression", operator: op, argument: arg }); } function binExpr(op, left, right) { return Pattern({ type: "BinaryExpression", operator: op, left: left, right: right }); } function aExpr(op, left, right) { return Pattern({ type: "AssignmentExpression", operator: op, left: left, right: right });
--- a/js/src/vm/CommonPropertyNames.h +++ b/js/src/vm/CommonPropertyNames.h @@ -145,16 +145,17 @@ macro(minimumFractionDigits, minimumFractionDigits, "minimumFractionDigits") \ macro(minimumIntegerDigits, minimumIntegerDigits, "minimumIntegerDigits") \ macro(minimumSignificantDigits, minimumSignificantDigits, "minimumSignificantDigits") \ macro(missingArguments, missingArguments, "missingArguments") \ macro(module, module, "module") \ macro(multiline, multiline, "multiline") \ macro(name, name, "name") \ macro(NaN, NaN, "NaN") \ + macro(new, new_, "new") \ macro(next, next, "next") \ macro(NFC, NFC, "NFC") \ macro(NFD, NFD, "NFD") \ macro(NFKC, NFKC, "NFKC") \ macro(NFKD, NFKD, "NFKD") \ macro(nonincrementalReason, nonincrementalReason, "nonincrementalReason") \ macro(noStack, noStack, "noStack") \ macro(noSuchMethod, noSuchMethod, "__noSuchMethod__") \
--- a/js/src/vm/Opcodes.h +++ b/js/src/vm/Opcodes.h @@ -764,17 +764,17 @@ 1234567890123456789012345678901234567890 * Invokes 'callee' as a constructor with 'this' and 'args', pushes return * value onto the stack. * Category: Statements * Type: Function * Operands: uint16_t argc * Stack: callee, this, args[0], ..., args[argc-1], newTarget => rval * nuses: (argc+3) */ \ - macro(JSOP_NEW, 82, js_new_str, NULL, 3, -1, 1, JOF_UINT16|JOF_INVOKE|JOF_TYPESET) \ + macro(JSOP_NEW, 82, "new", NULL, 3, -1, 1, JOF_UINT16|JOF_INVOKE|JOF_TYPESET) \ /* * Pushes newly created object onto the stack with provided [[Prototype]]. * * Category: Literals * Type: Object * Operands: * Stack: proto => obj */ \