зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1168992 - Part 2: Fix reflection of new.target. (r=Waldo)
This commit is contained in:
Родитель
919c23ca38
Коммит
371c557f97
|
@ -756,7 +756,7 @@ class NodeBuilder
|
|||
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
|
||||
|
@ -1826,13 +1826,16 @@ NodeBuilder::classDefinition(bool expr, HandleValue name, HandleValue heritage,
|
|||
}
|
||||
|
||||
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 callback(cb, meta, property, pos, dst);
|
||||
|
||||
return newNode(AST_NEWTARGET_EXPR, pos, dst);
|
||||
return newNode(AST_METAPROPERTY, pos,
|
||||
"meta", meta,
|
||||
"property", property,
|
||||
dst);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -3312,7 +3315,22 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
|
|||
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");
|
||||
|
|
|
@ -1915,7 +1915,6 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
|
|||
|
||||
switch (pn->getKind()) {
|
||||
// Trivial cases with no side effects.
|
||||
case PNK_NEWTARGET:
|
||||
case PNK_NOP:
|
||||
case PNK_STRING:
|
||||
case PNK_TEMPLATE_STRING:
|
||||
|
@ -1932,6 +1931,14 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
|
|||
*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:
|
||||
|
@ -2320,6 +2327,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
|
|||
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
|
||||
|
@ -8088,6 +8096,9 @@ BytecodeEmitter::emitTree(ParseNode* pn)
|
|||
return false;
|
||||
break;
|
||||
|
||||
case PNK_POSHOLDER:
|
||||
MOZ_ASSERT_UNREACHABLE("Should never try to emit PNK_POSHOLDER");
|
||||
|
||||
default:
|
||||
MOZ_ASSERT(0);
|
||||
}
|
||||
|
|
|
@ -417,6 +417,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
|
|||
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");
|
||||
|
||||
|
@ -1709,7 +1710,6 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
|
|||
ParseNode* pn = *pnp;
|
||||
|
||||
switch (pn->getKind()) {
|
||||
case PNK_NEWTARGET:
|
||||
case PNK_NOP:
|
||||
case PNK_REGEXP:
|
||||
case PNK_STRING:
|
||||
|
@ -1728,6 +1728,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
|
|||
case PNK_OBJECT_PROPERTY_NAME:
|
||||
case PNK_SUPERPROP:
|
||||
case PNK_FRESHENBLOCK:
|
||||
case PNK_POSHOLDER:
|
||||
MOZ_ASSERT(pn->isArity(PN_NULLARY));
|
||||
return true;
|
||||
|
||||
|
@ -1918,6 +1919,12 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo
|
|||
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) {
|
||||
|
|
|
@ -352,8 +352,11 @@ class FullParseHandler
|
|||
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) {
|
||||
|
|
|
@ -377,7 +377,6 @@ class NameResolver
|
|||
case PNK_FRESHENBLOCK:
|
||||
case PNK_SUPERPROP:
|
||||
case PNK_OBJECT_PROPERTY_NAME:
|
||||
case PNK_NEWTARGET:
|
||||
MOZ_ASSERT(cur->isArity(PN_NULLARY));
|
||||
break;
|
||||
|
||||
|
@ -387,6 +386,12 @@ class NameResolver
|
|||
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:
|
||||
|
@ -779,6 +784,7 @@ class NameResolver
|
|||
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
|
||||
|
|
|
@ -215,7 +215,7 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
|
|||
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");
|
||||
|
@ -285,6 +285,7 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
|
|||
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);
|
||||
|
|
|
@ -179,6 +179,7 @@ class PackedScopeCoordinate
|
|||
F(SUPERPROP) \
|
||||
F(SUPERELEM) \
|
||||
F(NEWTARGET) \
|
||||
F(POSHOLDER) \
|
||||
\
|
||||
/* Unary operators. */ \
|
||||
F(TYPEOFNAME) \
|
||||
|
|
|
@ -8949,9 +8949,14 @@ Parser<ParseHandler>::tryNewTarget(Node &newTarget)
|
|||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_NEW));
|
||||
|
||||
uint32_t begin = pos().begin;
|
||||
newTarget = null();
|
||||
|
||||
Node newHolder = handler.newPosHolder(pos());
|
||||
if (!newHolder)
|
||||
return false;
|
||||
|
||||
uint32_t begin = pos().begin;
|
||||
|
||||
// |new| expects to look for an operand, so we will honor that.
|
||||
TokenKind next;
|
||||
if (!tokenStream.getToken(&next, TokenStream::Operand))
|
||||
|
@ -8975,7 +8980,11 @@ Parser<ParseHandler>::tryNewTarget(Node &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;
|
||||
}
|
||||
|
||||
|
|
|
@ -281,7 +281,8 @@ class SyntaxParseHandler
|
|||
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; }
|
||||
|
|
|
@ -38,7 +38,7 @@ ASTDEF(AST_COMP_EXPR, "ComprehensionExpression", "comprehensi
|
|||
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")
|
||||
|
|
|
@ -76,7 +76,6 @@ 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";
|
||||
|
|
|
@ -176,7 +176,6 @@ 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[];
|
||||
|
|
|
@ -170,9 +170,15 @@ function arrowExpr(args, body) {
|
|||
body: body });
|
||||
}
|
||||
|
||||
function newTarget() {
|
||||
return Pattern({ type: "NewTargetExpression" });
|
||||
function metaProperty(meta, property) {
|
||||
return Pattern({ type: "MetaProperty",
|
||||
meta: meta,
|
||||
property: property });
|
||||
}
|
||||
function newTarget() {
|
||||
return metaProperty(ident("new"), ident("target"));
|
||||
}
|
||||
|
||||
function unExpr(op, arg) {
|
||||
return Pattern({ type: "UnaryExpression", operator: op, argument: arg });
|
||||
}
|
||||
|
|
|
@ -150,6 +150,7 @@
|
|||
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") \
|
||||
|
|
|
@ -769,7 +769,7 @@
|
|||
* 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]].
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче