зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1526031 - remove initOrStmt field from NameNode. r=jorendorff,arai
Differential Revision: https://phabricator.services.mozilla.com/D19054 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
7a132cc405
Коммит
83ff13eec8
|
@ -1939,8 +1939,7 @@ bool ASTSerializer::variableDeclarator(ParseNode* pn, MutableHandleValue dst) {
|
|||
|
||||
if (pn->isKind(ParseNodeKind::Name)) {
|
||||
patternNode = pn;
|
||||
initNode = pn->as<NameNode>().initializer();
|
||||
MOZ_ASSERT_IF(initNode, pn->pn_pos.encloses(initNode->pn_pos));
|
||||
initNode = nullptr;
|
||||
} else if (pn->isKind(ParseNodeKind::AssignExpr)) {
|
||||
AssignmentNode* assignNode = &pn->as<AssignmentNode>();
|
||||
patternNode = assignNode->left();
|
||||
|
|
|
@ -2629,7 +2629,11 @@ JS::Result<ParseNode*> BinASTParser<Tok>::parseInterfaceEagerGetter(
|
|||
ListNode* body;
|
||||
MOZ_TRY(parseGetterContents(length, ¶ms, &body));
|
||||
MOZ_TRY(prependDirectivesToBody(body, directives));
|
||||
BINJS_MOZ_TRY_DECL(method, buildFunction(start, kind, name, params, body));
|
||||
BINJS_TRY_DECL(lexicalScopeData,
|
||||
NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_));
|
||||
BINJS_TRY_DECL(bodyScope, handler_.newLexicalScope(*lexicalScopeData, body));
|
||||
BINJS_MOZ_TRY_DECL(method,
|
||||
buildFunction(start, kind, name, params, bodyScope));
|
||||
BINJS_TRY_DECL(result, handler_.newObjectMethodOrPropertyDefinition(
|
||||
name, method, accessorType));
|
||||
return result;
|
||||
|
@ -2691,7 +2695,11 @@ JS::Result<ParseNode*> BinASTParser<Tok>::parseInterfaceEagerMethod(
|
|||
ListNode* body;
|
||||
MOZ_TRY(parseFunctionOrMethodContents(length, ¶ms, &body));
|
||||
MOZ_TRY(prependDirectivesToBody(body, directives));
|
||||
BINJS_MOZ_TRY_DECL(method, buildFunction(start, kind, name, params, body));
|
||||
BINJS_TRY_DECL(lexicalScopeData,
|
||||
NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_));
|
||||
BINJS_TRY_DECL(bodyScope, handler_.newLexicalScope(*lexicalScopeData, body));
|
||||
BINJS_MOZ_TRY_DECL(method,
|
||||
buildFunction(start, kind, name, params, bodyScope));
|
||||
BINJS_TRY_DECL(result, handler_.newObjectMethodOrPropertyDefinition(
|
||||
name, method, accessorType));
|
||||
return result;
|
||||
|
@ -2746,7 +2754,11 @@ JS::Result<ParseNode*> BinASTParser<Tok>::parseInterfaceEagerSetter(
|
|||
ListNode* body;
|
||||
MOZ_TRY(parseSetterContents(length, ¶ms, &body));
|
||||
MOZ_TRY(prependDirectivesToBody(body, directives));
|
||||
BINJS_MOZ_TRY_DECL(method, buildFunction(start, kind, name, params, body));
|
||||
BINJS_TRY_DECL(lexicalScopeData,
|
||||
NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_));
|
||||
BINJS_TRY_DECL(bodyScope, handler_.newLexicalScope(*lexicalScopeData, body));
|
||||
BINJS_MOZ_TRY_DECL(method,
|
||||
buildFunction(start, kind, name, params, bodyScope));
|
||||
BINJS_TRY_DECL(result, handler_.newObjectMethodOrPropertyDefinition(
|
||||
name, method, accessorType));
|
||||
return result;
|
||||
|
@ -4244,9 +4256,11 @@ JS::Result<ParseNode*> BinASTParser<Tok>::parseInterfaceVariableDeclarator(
|
|||
// `var foo [= bar]``
|
||||
NameNode* bindingNameNode = &binding->template as<NameNode>();
|
||||
MOZ_TRY(checkBinding(bindingNameNode->atom()->asPropertyName()));
|
||||
result = bindingNameNode;
|
||||
if (init) {
|
||||
BINJS_TRY(handler_.finishInitializerAssignment(bindingNameNode, init));
|
||||
BINJS_TRY_VAR(
|
||||
result, handler_.finishInitializerAssignment(bindingNameNode, init));
|
||||
} else {
|
||||
result = bindingNameNode;
|
||||
}
|
||||
} else {
|
||||
// `var pattern = bar`
|
||||
|
|
|
@ -1006,8 +1006,12 @@ EagerMethod:
|
|||
const auto accessorType = AccessorType::None;
|
||||
inherits: EagerFunctionExpression
|
||||
build: |
|
||||
BINJS_TRY_DECL(lexicalScopeData,
|
||||
NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_));
|
||||
BINJS_TRY_DECL(bodyScope,
|
||||
handler_.newLexicalScope(*lexicalScopeData, body));
|
||||
BINJS_MOZ_TRY_DECL(method,
|
||||
buildFunction(start, kind, name, params, body));
|
||||
buildFunction(start, kind, name, params, bodyScope));
|
||||
BINJS_TRY_DECL(result,
|
||||
handler_.newObjectMethodOrPropertyDefinition(name, method,
|
||||
accessorType));
|
||||
|
@ -1603,9 +1607,11 @@ VariableDeclarator:
|
|||
// `var foo [= bar]``
|
||||
NameNode* bindingNameNode = &binding->template as<NameNode>();
|
||||
MOZ_TRY(checkBinding(bindingNameNode->atom()->asPropertyName()));
|
||||
result = bindingNameNode;
|
||||
if (init) {
|
||||
BINJS_TRY(handler_.finishInitializerAssignment(bindingNameNode, init));
|
||||
BINJS_TRY_VAR(result,
|
||||
handler_.finishInitializerAssignment(bindingNameNode, init));
|
||||
} else {
|
||||
result = bindingNameNode;
|
||||
}
|
||||
} else {
|
||||
// `var pattern = bar`
|
||||
|
|
|
@ -4039,36 +4039,49 @@ bool BytecodeEmitter::emitDeclarationList(ListNode* declList) {
|
|||
MOZ_ASSERT(declList->isOp(JSOP_NOP));
|
||||
|
||||
for (ParseNode* decl : declList->contents()) {
|
||||
if (decl->isKind(ParseNodeKind::AssignExpr)) {
|
||||
ParseNode* pattern;
|
||||
ParseNode* initializer;
|
||||
if (decl->isKind(ParseNodeKind::Name)) {
|
||||
pattern = decl;
|
||||
initializer = nullptr;
|
||||
} else {
|
||||
MOZ_ASSERT(decl->isOp(JSOP_NOP));
|
||||
|
||||
AssignmentNode* assignNode = &decl->as<AssignmentNode>();
|
||||
ListNode* pattern = &assignNode->left()->as<ListNode>();
|
||||
pattern = assignNode->left();
|
||||
initializer = assignNode->right();
|
||||
}
|
||||
|
||||
if (pattern->isKind(ParseNodeKind::Name)) {
|
||||
// initializer can be null here.
|
||||
if (!emitSingleDeclaration(declList, &pattern->as<NameNode>(),
|
||||
initializer)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
MOZ_ASSERT(decl->isOp(JSOP_NOP));
|
||||
MOZ_ASSERT(pattern->isKind(ParseNodeKind::ArrayExpr) ||
|
||||
pattern->isKind(ParseNodeKind::ObjectExpr));
|
||||
MOZ_ASSERT(initializer != nullptr);
|
||||
|
||||
if (!updateSourceCoordNotes(assignNode->right()->pn_pos.begin)) {
|
||||
if (!updateSourceCoordNotes(initializer->pn_pos.begin)) {
|
||||
return false;
|
||||
}
|
||||
if (!markStepBreakpoint()) {
|
||||
return false;
|
||||
}
|
||||
if (!emitTree(assignNode->right())) {
|
||||
if (!emitTree(initializer)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!emitDestructuringOps(pattern, DestructuringDeclaration)) {
|
||||
if (!emitDestructuringOps(&pattern->as<ListNode>(),
|
||||
DestructuringDeclaration)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!emit1(JSOP_POP)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
NameNode* name = &decl->as<NameNode>();
|
||||
if (!emitSingleDeclaration(declList, name, name->initializer())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
@ -5320,8 +5333,17 @@ bool BytecodeEmitter::emitInitializeForInOrOfTarget(TernaryNode* forHead) {
|
|||
target = parser->astGenerator().singleBindingFromDeclaration(
|
||||
&target->as<ListNode>());
|
||||
|
||||
NameNode* nameNode = nullptr;
|
||||
if (target->isKind(ParseNodeKind::Name)) {
|
||||
NameNode* nameNode = &target->as<NameNode>();
|
||||
nameNode = &target->as<NameNode>();
|
||||
} else if (target->isKind(ParseNodeKind::AssignExpr)) {
|
||||
AssignmentNode* assignNode = &target->as<AssignmentNode>();
|
||||
if (assignNode->left()->is<NameNode>()) {
|
||||
nameNode = &assignNode->left()->as<NameNode>();
|
||||
}
|
||||
}
|
||||
|
||||
if (nameNode) {
|
||||
NameOpEmitter noe(this, nameNode->name(), NameOpEmitter::Kind::Initialize);
|
||||
if (!noe.prepareForRhs()) {
|
||||
return false;
|
||||
|
@ -5454,8 +5476,11 @@ bool BytecodeEmitter::emitForIn(ForNode* forInLoop,
|
|||
if (parser->astGenerator().isDeclarationList(forInTarget)) {
|
||||
ParseNode* decl = parser->astGenerator().singleBindingFromDeclaration(
|
||||
&forInTarget->as<ListNode>());
|
||||
if (decl->isKind(ParseNodeKind::Name)) {
|
||||
if (ParseNode* initializer = decl->as<NameNode>().initializer()) {
|
||||
if (decl->isKind(ParseNodeKind::AssignExpr)) {
|
||||
AssignmentNode* assignNode = &decl->as<AssignmentNode>();
|
||||
if (assignNode->left()->is<NameNode>()) {
|
||||
NameNode* nameNode = &assignNode->left()->as<NameNode>();
|
||||
ParseNode* initializer = assignNode->right();
|
||||
MOZ_ASSERT(
|
||||
forInTarget->isKind(ParseNodeKind::VarStmt),
|
||||
"for-in initializers are only permitted for |var| declarations");
|
||||
|
@ -5464,13 +5489,12 @@ bool BytecodeEmitter::emitForIn(ForNode* forInLoop,
|
|||
return false;
|
||||
}
|
||||
|
||||
NameNode* nameNode = &decl->as<NameNode>();
|
||||
NameOpEmitter noe(this, nameNode->name(),
|
||||
NameOpEmitter::Kind::Initialize);
|
||||
if (!noe.prepareForRhs()) {
|
||||
return false;
|
||||
}
|
||||
if (!emitInitializer(initializer, decl)) {
|
||||
if (!emitInitializer(initializer, nameNode)) {
|
||||
return false;
|
||||
}
|
||||
if (!noe.emitAssignment()) {
|
||||
|
|
|
@ -879,8 +879,15 @@ class FullParseHandler {
|
|||
node->isKind(ParseNodeKind::ComputedName);
|
||||
}
|
||||
|
||||
inline MOZ_MUST_USE bool finishInitializerAssignment(NameNodeType nameNode,
|
||||
Node init);
|
||||
AssignmentNodeType finishInitializerAssignment(NameNodeType nameNode,
|
||||
Node init) {
|
||||
MOZ_ASSERT(nameNode->isKind(ParseNodeKind::Name));
|
||||
MOZ_ASSERT(!nameNode->isInParens());
|
||||
|
||||
checkAndSetIsDirectRHSAnonFunction(init);
|
||||
|
||||
return newAssignment(ParseNodeKind::AssignExpr, nameNode, init);
|
||||
}
|
||||
|
||||
void setBeginPosition(Node pn, Node oth) {
|
||||
setBeginPosition(pn, oth->pn_pos.begin);
|
||||
|
@ -1027,21 +1034,6 @@ inline bool FullParseHandler::setLastFunctionFormalParameterDefault(
|
|||
return true;
|
||||
}
|
||||
|
||||
inline bool FullParseHandler::finishInitializerAssignment(NameNodeType nameNode,
|
||||
Node init) {
|
||||
MOZ_ASSERT(nameNode->isKind(ParseNodeKind::Name));
|
||||
MOZ_ASSERT(!nameNode->isInParens());
|
||||
|
||||
checkAndSetIsDirectRHSAnonFunction(init);
|
||||
|
||||
nameNode->setInitializer(init);
|
||||
nameNode->setOp(JSOP_SETNAME);
|
||||
|
||||
/* The declarator's position must include the initializer. */
|
||||
nameNode->pn_pos.end = init->pn_pos.end;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace frontend
|
||||
} // namespace js
|
||||
|
||||
|
|
|
@ -419,9 +419,7 @@ class NameResolver : public ParseNodeVisitor<NameResolver> {
|
|||
MOZ_ASSERT(spec->isKind(isImport ? ParseNodeKind::ImportSpec
|
||||
: ParseNodeKind::ExportSpec));
|
||||
MOZ_ASSERT(spec->left()->isKind(ParseNodeKind::Name));
|
||||
MOZ_ASSERT(!spec->left()->as<NameNode>().initializer());
|
||||
MOZ_ASSERT(spec->right()->isKind(ParseNodeKind::Name));
|
||||
MOZ_ASSERT(!spec->right()->as<NameNode>().initializer());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -311,12 +311,8 @@ void NameNode::dumpImpl(GenericPrinter& out, int indent) {
|
|||
out.put("#<null name>");
|
||||
} else if (getOp() == JSOP_GETARG && atom()->length() == 0) {
|
||||
// Dump destructuring parameter.
|
||||
static const char ZeroLengthPrefix[] = "(#<zero-length name> ";
|
||||
constexpr size_t ZeroLengthPrefixLength =
|
||||
ArrayLength(ZeroLengthPrefix) - 1;
|
||||
out.put(ZeroLengthPrefix);
|
||||
DumpParseTree(initializer(), out, indent + ZeroLengthPrefixLength);
|
||||
out.printf(")");
|
||||
static const char ZeroLengthName[] = "(#<zero-length name>)";
|
||||
out.put(ZeroLengthName);
|
||||
} else {
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
if (atom()->hasLatin1Chars()) {
|
||||
|
@ -328,26 +324,28 @@ void NameNode::dumpImpl(GenericPrinter& out, int indent) {
|
|||
return;
|
||||
|
||||
case ParseNodeKind::LabelStmt: {
|
||||
const char* name = parseNodeNames[size_t(getKind())];
|
||||
out.printf("(%s ", name);
|
||||
atom()->dumpCharsNoNewline(out);
|
||||
indent += strlen(name) + atom()->length() + 2;
|
||||
DumpParseTree(initializer(), out, indent);
|
||||
out.printf(")");
|
||||
this->as<LabeledStatement>().dump(out, indent);
|
||||
return;
|
||||
}
|
||||
|
||||
default: {
|
||||
const char* name = parseNodeNames[size_t(getKind())];
|
||||
out.printf("(%s ", name);
|
||||
indent += strlen(name) + 2;
|
||||
DumpParseTree(initializer(), out, indent);
|
||||
out.printf(")");
|
||||
out.printf("(%s)", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LabeledStatement::dump(GenericPrinter& out, int indent) {
|
||||
const char* name = parseNodeNames[size_t(getKind())];
|
||||
out.printf("(%s ", name);
|
||||
atom()->dumpCharsNoNewline(out);
|
||||
out.printf(" ");
|
||||
indent += strlen(name) + atom()->length() + 3;
|
||||
DumpParseTree(statement(), out, indent);
|
||||
out.printf(")");
|
||||
}
|
||||
|
||||
void LexicalScopeNode::dumpImpl(GenericPrinter& out, int indent) {
|
||||
const char* name = parseNodeNames[size_t(getKind())];
|
||||
out.printf("(%s [", name);
|
||||
|
|
|
@ -796,20 +796,11 @@ class NullaryNode : public ParseNode {
|
|||
};
|
||||
|
||||
class NameNode : public ParseNode {
|
||||
JSAtom* atom_; /* lexical name or label atom */
|
||||
ParseNode* initOrStmt; /* var initializer, argument default, or label
|
||||
statement target */
|
||||
|
||||
protected:
|
||||
NameNode(ParseNodeKind kind, JSOp op, JSAtom* atom, ParseNode* initOrStmt,
|
||||
const TokenPos& pos)
|
||||
: ParseNode(kind, op, pos), atom_(atom), initOrStmt(initOrStmt) {
|
||||
MOZ_ASSERT(is<NameNode>());
|
||||
}
|
||||
JSAtom* atom_; /* lexical name or label atom */
|
||||
|
||||
public:
|
||||
NameNode(ParseNodeKind kind, JSOp op, JSAtom* atom, const TokenPos& pos)
|
||||
: ParseNode(kind, op, pos), atom_(atom), initOrStmt(nullptr) {
|
||||
: ParseNode(kind, op, pos), atom_(atom) {
|
||||
MOZ_ASSERT(is<NameNode>());
|
||||
}
|
||||
|
||||
|
@ -821,11 +812,6 @@ class NameNode : public ParseNode {
|
|||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
if (initOrStmt) {
|
||||
if (!visitor.visit(initOrStmt)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -840,11 +826,7 @@ class NameNode : public ParseNode {
|
|||
return atom()->asPropertyName();
|
||||
}
|
||||
|
||||
ParseNode* initializer() const { return initOrStmt; }
|
||||
|
||||
void setAtom(JSAtom* atom) { atom_ = atom; }
|
||||
|
||||
void setInitializer(ParseNode* init) { initOrStmt = init; }
|
||||
};
|
||||
|
||||
inline bool ParseNode::isName(PropertyName* name) const {
|
||||
|
@ -1596,14 +1578,17 @@ class LexicalScopeNode : public ParseNode {
|
|||
};
|
||||
|
||||
class LabeledStatement : public NameNode {
|
||||
ParseNode* statement_;
|
||||
|
||||
public:
|
||||
LabeledStatement(PropertyName* label, ParseNode* stmt, uint32_t begin)
|
||||
: NameNode(ParseNodeKind::LabelStmt, JSOP_NOP, label, stmt,
|
||||
TokenPos(begin, stmt->pn_pos.end)) {}
|
||||
: NameNode(ParseNodeKind::LabelStmt, JSOP_NOP, label,
|
||||
TokenPos(begin, stmt->pn_pos.end)),
|
||||
statement_(stmt) {}
|
||||
|
||||
PropertyName* label() const { return atom()->asPropertyName(); }
|
||||
|
||||
ParseNode* statement() const { return initializer(); }
|
||||
ParseNode* statement() const { return statement_; }
|
||||
|
||||
static bool test(const ParseNode& node) {
|
||||
return node.isKind(ParseNodeKind::LabelStmt);
|
||||
|
@ -1631,6 +1616,20 @@ class CaseClause : public BinaryNode {
|
|||
MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP));
|
||||
return match;
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
bool accept(Visitor& visitor) {
|
||||
if (statement_) {
|
||||
if (!visitor.visit(statement_)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void dump(GenericPrinter& out, int indent);
|
||||
#endif
|
||||
};
|
||||
|
||||
class LoopControlStatement : public ParseNode {
|
||||
|
|
|
@ -4090,7 +4090,8 @@ GeneralParser<ParseHandler, Unit>::declarationPattern(
|
|||
}
|
||||
|
||||
template <class ParseHandler, typename Unit>
|
||||
bool GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
|
||||
typename ParseHandler::Node
|
||||
GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
|
||||
NameNodeType binding, DeclarationKind declKind, bool initialDeclaration,
|
||||
YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
|
||||
Node* forInOrOfExpression) {
|
||||
|
@ -4098,19 +4099,19 @@ bool GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
|
|||
|
||||
uint32_t initializerOffset;
|
||||
if (!tokenStream.peekOffset(&initializerOffset, TokenStream::Operand)) {
|
||||
return false;
|
||||
return null();
|
||||
}
|
||||
|
||||
Node initializer = assignExpr(forHeadKind ? InProhibited : InAllowed,
|
||||
yieldHandling, TripledotProhibited);
|
||||
if (!initializer) {
|
||||
return false;
|
||||
return null();
|
||||
}
|
||||
|
||||
if (forHeadKind && initialDeclaration) {
|
||||
bool isForIn, isForOf;
|
||||
if (!matchInOrOf(&isForIn, &isForOf)) {
|
||||
return false;
|
||||
return null();
|
||||
}
|
||||
|
||||
// An initialized declaration can't appear in a for-of:
|
||||
|
@ -4118,7 +4119,7 @@ bool GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
|
|||
// for (var/let/const x = ... of ...); // BAD
|
||||
if (isForOf) {
|
||||
errorAt(initializerOffset, JSMSG_OF_AFTER_FOR_LOOP_DECL);
|
||||
return false;
|
||||
return null();
|
||||
}
|
||||
|
||||
if (isForIn) {
|
||||
|
@ -4127,7 +4128,7 @@ bool GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
|
|||
// for (let/const x = ... in ...); // BAD
|
||||
if (DeclarationKindIsLexical(declKind)) {
|
||||
errorAt(initializerOffset, JSMSG_IN_AFTER_LEXICAL_FOR_DECL);
|
||||
return false;
|
||||
return null();
|
||||
}
|
||||
|
||||
// This leaves only initialized for-in |var| declarations. ES6
|
||||
|
@ -4135,13 +4136,13 @@ bool GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
|
|||
*forHeadKind = ParseNodeKind::ForIn;
|
||||
if (!strictModeErrorAt(initializerOffset,
|
||||
JSMSG_INVALID_FOR_IN_DECL_WITH_INIT)) {
|
||||
return false;
|
||||
return null();
|
||||
}
|
||||
|
||||
*forInOrOfExpression =
|
||||
expressionAfterForInOrOf(ParseNodeKind::ForIn, yieldHandling);
|
||||
if (!*forInOrOfExpression) {
|
||||
return false;
|
||||
return null();
|
||||
}
|
||||
} else {
|
||||
*forHeadKind = ParseNodeKind::ForHead;
|
||||
|
@ -4152,13 +4153,10 @@ bool GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
|
|||
}
|
||||
|
||||
template <class ParseHandler, typename Unit>
|
||||
typename ParseHandler::NameNodeType
|
||||
GeneralParser<ParseHandler, Unit>::declarationName(DeclarationKind declKind,
|
||||
TokenKind tt,
|
||||
bool initialDeclaration,
|
||||
YieldHandling yieldHandling,
|
||||
ParseNodeKind* forHeadKind,
|
||||
Node* forInOrOfExpression) {
|
||||
typename ParseHandler::Node GeneralParser<ParseHandler, Unit>::declarationName(
|
||||
DeclarationKind declKind, TokenKind tt, bool initialDeclaration,
|
||||
YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
|
||||
Node* forInOrOfExpression) {
|
||||
// Anything other than possible identifier is an error.
|
||||
if (!TokenKindIsPossibleIdentifier(tt)) {
|
||||
error(JSMSG_NO_VARIABLE_NAME);
|
||||
|
@ -4190,13 +4188,17 @@ GeneralParser<ParseHandler, Unit>::declarationName(DeclarationKind declKind,
|
|||
return null();
|
||||
}
|
||||
|
||||
Node declaration;
|
||||
if (matched) {
|
||||
if (!initializerInNameDeclaration(binding, declKind, initialDeclaration,
|
||||
yieldHandling, forHeadKind,
|
||||
forInOrOfExpression)) {
|
||||
declaration = initializerInNameDeclaration(
|
||||
binding, declKind, initialDeclaration, yieldHandling, forHeadKind,
|
||||
forInOrOfExpression);
|
||||
if (!declaration) {
|
||||
return null();
|
||||
}
|
||||
} else {
|
||||
declaration = binding;
|
||||
|
||||
if (initialDeclaration && forHeadKind) {
|
||||
bool isForIn, isForOf;
|
||||
if (!matchInOrOf(&isForIn, &isForOf)) {
|
||||
|
@ -4234,7 +4236,7 @@ GeneralParser<ParseHandler, Unit>::declarationName(DeclarationKind declKind,
|
|||
return null();
|
||||
}
|
||||
|
||||
return binding;
|
||||
return declaration;
|
||||
}
|
||||
|
||||
template <class ParseHandler, typename Unit>
|
||||
|
|
|
@ -1200,18 +1200,16 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
|
|||
bool initialDeclaration, YieldHandling yieldHandling,
|
||||
ParseNodeKind* forHeadKind,
|
||||
Node* forInOrOfExpression);
|
||||
NameNodeType declarationName(DeclarationKind declKind, TokenKind tt,
|
||||
bool initialDeclaration,
|
||||
YieldHandling yieldHandling,
|
||||
ParseNodeKind* forHeadKind,
|
||||
Node* forInOrOfExpression);
|
||||
Node declarationName(DeclarationKind declKind, TokenKind tt,
|
||||
bool initialDeclaration, YieldHandling yieldHandling,
|
||||
ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
|
||||
|
||||
// Having parsed a name (not found in a destructuring pattern) declared by
|
||||
// a declaration, with the current token being the '=' separating the name
|
||||
// from its initializer, parse and bind that initializer -- and possibly
|
||||
// consume trailing in/of and subsequent expression, if so directed by
|
||||
// |forHeadKind|.
|
||||
bool initializerInNameDeclaration(NameNodeType binding,
|
||||
Node initializerInNameDeclaration(NameNodeType binding,
|
||||
DeclarationKind declKind,
|
||||
bool initialDeclaration,
|
||||
YieldHandling yieldHandling,
|
||||
|
|
|
@ -517,9 +517,9 @@ class SyntaxParseHandler {
|
|||
return NodeGeneric;
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool finishInitializerAssignment(NameNodeType nameNode,
|
||||
Node init) {
|
||||
return true;
|
||||
AssignmentNodeType finishInitializerAssignment(NameNodeType nameNode,
|
||||
Node init) {
|
||||
return NodeUnparenthesizedAssignment;
|
||||
}
|
||||
|
||||
void setBeginPosition(Node pn, Node oth) {}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
var BUGNUMBER = 1499448;
|
||||
var summary = "Constant folder should fold labeled statements";
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
if (typeof disassemble === "function") {
|
||||
var code = disassemble(() => { x: 2+2; });
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, /int8 4/.test(code));
|
||||
}
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
|
@ -609,10 +609,6 @@ static inline ParseNode* ObjectNormalFieldInitializer(ParseNode* pn) {
|
|||
return BinaryRight(pn);
|
||||
}
|
||||
|
||||
static inline ParseNode* MaybeInitializer(ParseNode* pn) {
|
||||
return pn->as<NameNode>().initializer();
|
||||
}
|
||||
|
||||
static inline bool IsUseOfName(ParseNode* pn, PropertyName* name) {
|
||||
return pn->isName(name);
|
||||
}
|
||||
|
@ -3040,8 +3036,15 @@ static bool CheckGlobalDotImport(ModuleValidatorShared& m,
|
|||
return m.addFFI(varName, field);
|
||||
}
|
||||
|
||||
static bool CheckModuleGlobal(ModuleValidatorShared& m, ParseNode* var,
|
||||
static bool CheckModuleGlobal(ModuleValidatorShared& m, ParseNode* decl,
|
||||
bool isConst) {
|
||||
if (!decl->isKind(ParseNodeKind::AssignExpr)) {
|
||||
return m.fail(decl, "module import needs initializer");
|
||||
}
|
||||
AssignmentNode* assignNode = &decl->as<AssignmentNode>();
|
||||
|
||||
ParseNode* var = assignNode->left();
|
||||
|
||||
if (!var->isKind(ParseNodeKind::Name)) {
|
||||
return m.fail(var, "import variable is not a plain name");
|
||||
}
|
||||
|
@ -3051,10 +3054,7 @@ static bool CheckModuleGlobal(ModuleValidatorShared& m, ParseNode* var,
|
|||
return false;
|
||||
}
|
||||
|
||||
ParseNode* initNode = MaybeInitializer(var);
|
||||
if (!initNode) {
|
||||
return m.fail(var, "module import needs initializer");
|
||||
}
|
||||
ParseNode* initNode = assignNode->right();
|
||||
|
||||
if (IsNumericLiteral(m, initNode)) {
|
||||
return CheckGlobalVariableInitConstant(m, varName, initNode, isConst);
|
||||
|
@ -3254,8 +3254,17 @@ static bool CheckFinalReturn(FunctionValidatorShared& f,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool CheckVariable(FunctionValidatorShared& f, ParseNode* var,
|
||||
static bool CheckVariable(FunctionValidatorShared& f, ParseNode* decl,
|
||||
ValTypeVector* types, Vector<NumLit>* inits) {
|
||||
if (!decl->isKind(ParseNodeKind::AssignExpr)) {
|
||||
return f.failName(
|
||||
decl, "var '%s' needs explicit type declaration via an initial value",
|
||||
decl->as<NameNode>().name());
|
||||
}
|
||||
AssignmentNode* assignNode = &decl->as<AssignmentNode>();
|
||||
|
||||
ParseNode* var = assignNode->left();
|
||||
|
||||
if (!var->isKind(ParseNodeKind::Name)) {
|
||||
return f.fail(var, "local variable is not a plain name");
|
||||
}
|
||||
|
@ -3266,12 +3275,7 @@ static bool CheckVariable(FunctionValidatorShared& f, ParseNode* var,
|
|||
return false;
|
||||
}
|
||||
|
||||
ParseNode* initNode = MaybeInitializer(var);
|
||||
if (!initNode) {
|
||||
return f.failName(
|
||||
var, "var '%s' needs explicit type declaration via an initial value",
|
||||
name);
|
||||
}
|
||||
ParseNode* initNode = assignNode->right();
|
||||
|
||||
NumLit lit;
|
||||
if (!IsLiteralOrConst(f, initNode, &lit)) {
|
||||
|
@ -6154,13 +6158,21 @@ static bool CheckFunctions(ModuleValidator<Unit>& m) {
|
|||
}
|
||||
|
||||
template <typename Unit>
|
||||
static bool CheckFuncPtrTable(ModuleValidator<Unit>& m, ParseNode* var) {
|
||||
static bool CheckFuncPtrTable(ModuleValidator<Unit>& m, ParseNode* decl) {
|
||||
if (!decl->isKind(ParseNodeKind::AssignExpr)) {
|
||||
return m.fail(decl, "function-pointer table must have initializer");
|
||||
}
|
||||
AssignmentNode* assignNode = &decl->as<AssignmentNode>();
|
||||
|
||||
ParseNode* var = assignNode->left();
|
||||
|
||||
if (!var->isKind(ParseNodeKind::Name)) {
|
||||
return m.fail(var, "function-pointer table name is not a plain name");
|
||||
}
|
||||
|
||||
ParseNode* arrayLiteral = MaybeInitializer(var);
|
||||
if (!arrayLiteral || !arrayLiteral->isKind(ParseNodeKind::ArrayExpr)) {
|
||||
ParseNode* arrayLiteral = assignNode->right();
|
||||
|
||||
if (!arrayLiteral->isKind(ParseNodeKind::ArrayExpr)) {
|
||||
return m.fail(
|
||||
var, "function-pointer table's initializer must be an array literal");
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче