Backed out changeset b29cead870d9 (bug 1526031) for spidermonkey bustages CLOSED TREE

This commit is contained in:
arthur.iakab 2019-02-16 00:50:34 +02:00
parent 2ecce7b6b7
commit 84ded0052b
13 changed files with 137 additions and 162 deletions

View File

@ -1939,7 +1939,8 @@ bool ASTSerializer::variableDeclarator(ParseNode* pn, MutableHandleValue dst) {
if (pn->isKind(ParseNodeKind::Name)) {
patternNode = pn;
initNode = nullptr;
initNode = pn->as<NameNode>().initializer();
MOZ_ASSERT_IF(initNode, pn->pn_pos.encloses(initNode->pn_pos));
} else if (pn->isKind(ParseNodeKind::AssignExpr)) {
AssignmentNode* assignNode = &pn->as<AssignmentNode>();
patternNode = assignNode->left();

View File

@ -4261,11 +4261,9 @@ 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_VAR(
result, factory_.finishInitializerAssignment(bindingNameNode, init));
} else {
result = bindingNameNode;
BINJS_TRY(factory_.finishInitializerAssignment(bindingNameNode, init));
}
} else {
// `var pattern = bar`

View File

@ -1618,11 +1618,9 @@ VariableDeclarator:
// `var foo [= bar]``
NameNode* bindingNameNode = &binding->template as<NameNode>();
MOZ_TRY(checkBinding(bindingNameNode->atom()->asPropertyName()));
result = bindingNameNode;
if (init) {
BINJS_TRY_VAR(result,
factory_.finishInitializerAssignment(bindingNameNode, init));
} else {
result = bindingNameNode;
BINJS_TRY(factory_.finishInitializerAssignment(bindingNameNode, init));
}
} else {
// `var pattern = bar`

View File

@ -4011,49 +4011,36 @@ bool BytecodeEmitter::emitDeclarationList(ListNode* declList) {
MOZ_ASSERT(declList->isOp(JSOP_NOP));
for (ParseNode* decl : declList->contents()) {
ParseNode* pattern;
ParseNode* initializer;
if (decl->isKind(ParseNodeKind::Name)) {
pattern = decl;
initializer = nullptr;
} else {
if (decl->isKind(ParseNodeKind::AssignExpr)) {
MOZ_ASSERT(decl->isOp(JSOP_NOP));
AssignmentNode* assignNode = &decl->as<AssignmentNode>();
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));
ListNode* pattern = &assignNode->left()->as<ListNode>();
MOZ_ASSERT(pattern->isKind(ParseNodeKind::ArrayExpr) ||
pattern->isKind(ParseNodeKind::ObjectExpr));
MOZ_ASSERT(initializer != nullptr);
if (!updateSourceCoordNotes(initializer->pn_pos.begin)) {
if (!updateSourceCoordNotes(assignNode->right()->pn_pos.begin)) {
return false;
}
if (!markStepBreakpoint()) {
return false;
}
if (!emitTree(initializer)) {
if (!emitTree(assignNode->right())) {
return false;
}
if (!emitDestructuringOps(&pattern->as<ListNode>(),
DestructuringDeclaration)) {
if (!emitDestructuringOps(pattern, 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;
@ -5305,17 +5292,8 @@ bool BytecodeEmitter::emitInitializeForInOrOfTarget(TernaryNode* forHead) {
target = parser->astGenerator().singleBindingFromDeclaration(
&target->as<ListNode>());
NameNode* nameNode = nullptr;
if (target->isKind(ParseNodeKind::Name)) {
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) {
NameNode* nameNode = &target->as<NameNode>();
NameOpEmitter noe(this, nameNode->name(), NameOpEmitter::Kind::Initialize);
if (!noe.prepareForRhs()) {
return false;
@ -5448,11 +5426,8 @@ bool BytecodeEmitter::emitForIn(ForNode* forInLoop,
if (parser->astGenerator().isDeclarationList(forInTarget)) {
ParseNode* decl = parser->astGenerator().singleBindingFromDeclaration(
&forInTarget->as<ListNode>());
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();
if (decl->isKind(ParseNodeKind::Name)) {
if (ParseNode* initializer = decl->as<NameNode>().initializer()) {
MOZ_ASSERT(
forInTarget->isKind(ParseNodeKind::VarStmt),
"for-in initializers are only permitted for |var| declarations");
@ -5461,12 +5436,13 @@ 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, nameNode)) {
if (!emitInitializer(initializer, decl)) {
return false;
}
if (!noe.emitAssignment()) {

View File

@ -875,15 +875,8 @@ class FullParseHandler {
node->isKind(ParseNodeKind::ComputedName);
}
AssignmentNodeType finishInitializerAssignment(NameNodeType nameNode,
Node init) {
MOZ_ASSERT(nameNode->isKind(ParseNodeKind::Name));
MOZ_ASSERT(!nameNode->isInParens());
checkAndSetIsDirectRHSAnonFunction(init);
return newAssignment(ParseNodeKind::AssignExpr, nameNode, init);
}
inline MOZ_MUST_USE bool finishInitializerAssignment(NameNodeType nameNode,
Node init);
void setBeginPosition(Node pn, Node oth) {
setBeginPosition(pn, oth->pn_pos.begin);
@ -1030,6 +1023,21 @@ 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

View File

@ -448,7 +448,6 @@ class NameResolver {
MOZ_ASSERT(cur->is<ContinueStatement>());
break;
case ParseNodeKind::Name:
case ParseNodeKind::ObjectPropertyName:
case ParseNodeKind::PrivateName: // TODO(khyperia): Implement private
// field access.
@ -472,6 +471,7 @@ class NameResolver {
case ParseNodeKind::TypeOfNameExpr:
case ParseNodeKind::SuperBase:
MOZ_ASSERT(cur->as<UnaryNode>().kid()->isKind(ParseNodeKind::Name));
MOZ_ASSERT(!cur->as<UnaryNode>().kid()->as<NameNode>().initializer());
break;
case ParseNodeKind::NewTargetExpr:
@ -714,10 +714,12 @@ class NameResolver {
ClassNames* names = classNode->names();
if (NameNode* outerBinding = names->outerBinding()) {
MOZ_ASSERT(outerBinding->isKind(ParseNodeKind::Name));
MOZ_ASSERT(!outerBinding->initializer());
}
NameNode* innerBinding = names->innerBinding();
MOZ_ASSERT(innerBinding->isKind(ParseNodeKind::Name));
MOZ_ASSERT(!innerBinding->initializer());
}
#endif
if (ParseNode* heritage = classNode->heritage()) {
@ -898,7 +900,9 @@ class 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
break;
@ -930,6 +934,14 @@ class NameResolver {
}
break;
case ParseNodeKind::Name:
if (ParseNode* init = cur->as<NameNode>().initializer()) {
if (!resolve(init, prefix)) {
return false;
}
}
break;
case ParseNodeKind::LexicalScope:
if (!resolve(cur->as<LexicalScopeNode>().scopeBody(), prefix)) {
return false;

View File

@ -346,8 +346,12 @@ void NameNode::dump(GenericPrinter& out, int indent) {
out.put("#<null name>");
} else if (getOp() == JSOP_GETARG && atom()->length() == 0) {
// Dump destructuring parameter.
static const char ZeroLengthName[] = "(#<zero-length name>)";
out.put(ZeroLengthName);
static const char ZeroLengthPrefix[] = "(#<zero-length name> ";
constexpr size_t ZeroLengthPrefixLength =
ArrayLength(ZeroLengthPrefix) - 1;
out.put(ZeroLengthPrefix);
DumpParseTree(initializer(), out, indent + ZeroLengthPrefixLength);
out.printf(")");
} else {
JS::AutoCheckCannotGC nogc;
if (atom()->hasLatin1Chars()) {
@ -359,28 +363,26 @@ void NameNode::dump(GenericPrinter& out, int indent) {
return;
case ParseNodeKind::LabelStmt: {
this->as<LabeledStatement>().dump(out, indent);
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(")");
return;
}
default: {
const char* name = parseNodeNames[size_t(getKind())];
out.printf("(%s)", name);
out.printf("(%s ", name);
indent += strlen(name) + 2;
DumpParseTree(initializer(), out, indent);
out.printf(")");
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 ClassField::dump(GenericPrinter& out, int indent) {
out.printf("(");
if (hasInitializer()) {

View File

@ -792,11 +792,20 @@ class NullaryNode : public ParseNode {
};
class NameNode : public ParseNode {
JSAtom* atom_; /* lexical name or label atom */
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>());
}
public:
NameNode(ParseNodeKind kind, JSOp op, JSAtom* atom, const TokenPos& pos)
: ParseNode(kind, op, pos), atom_(atom) {
: ParseNode(kind, op, pos), atom_(atom), initOrStmt(nullptr) {
MOZ_ASSERT(is<NameNode>());
}
@ -806,6 +815,11 @@ class NameNode : public ParseNode {
template <typename Visitor>
bool accept(Visitor& visitor) {
if (initOrStmt) {
if (!visitor.visit(initOrStmt)) {
return false;
}
}
return true;
}
@ -820,7 +834,11 @@ 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 {
@ -1574,17 +1592,14 @@ 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,
TokenPos(begin, stmt->pn_pos.end)),
statement_(stmt) {}
: NameNode(ParseNodeKind::LabelStmt, JSOP_NOP, label, stmt,
TokenPos(begin, stmt->pn_pos.end)) {}
PropertyName* label() const { return atom()->asPropertyName(); }
ParseNode* statement() const { return statement_; }
ParseNode* statement() const { return initializer(); }
static bool test(const ParseNode& node) {
bool match = node.isKind(ParseNodeKind::LabelStmt);
@ -1592,20 +1607,6 @@ class LabeledStatement : public NameNode {
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
};
// Inside a switch statement, a CaseClause is a case-label and the subsequent

View File

@ -4207,8 +4207,7 @@ GeneralParser<ParseHandler, Unit>::declarationPattern(
}
template <class ParseHandler, typename Unit>
typename ParseHandler::Node
GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
bool GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
NameNodeType binding, DeclarationKind declKind, bool initialDeclaration,
YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
Node* forInOrOfExpression) {
@ -4216,19 +4215,19 @@ GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
uint32_t initializerOffset;
if (!tokenStream.peekOffset(&initializerOffset, TokenStream::Operand)) {
return null();
return false;
}
Node initializer = assignExpr(forHeadKind ? InProhibited : InAllowed,
yieldHandling, TripledotProhibited);
if (!initializer) {
return null();
return false;
}
if (forHeadKind && initialDeclaration) {
bool isForIn, isForOf;
if (!matchInOrOf(&isForIn, &isForOf)) {
return null();
return false;
}
// An initialized declaration can't appear in a for-of:
@ -4236,7 +4235,7 @@ GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
// for (var/let/const x = ... of ...); // BAD
if (isForOf) {
errorAt(initializerOffset, JSMSG_OF_AFTER_FOR_LOOP_DECL);
return null();
return false;
}
if (isForIn) {
@ -4245,7 +4244,7 @@ GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
// for (let/const x = ... in ...); // BAD
if (DeclarationKindIsLexical(declKind)) {
errorAt(initializerOffset, JSMSG_IN_AFTER_LEXICAL_FOR_DECL);
return null();
return false;
}
// This leaves only initialized for-in |var| declarations. ES6
@ -4253,13 +4252,13 @@ GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
*forHeadKind = ParseNodeKind::ForIn;
if (!strictModeErrorAt(initializerOffset,
JSMSG_INVALID_FOR_IN_DECL_WITH_INIT)) {
return null();
return false;
}
*forInOrOfExpression =
expressionAfterForInOrOf(ParseNodeKind::ForIn, yieldHandling);
if (!*forInOrOfExpression) {
return null();
return false;
}
} else {
*forHeadKind = ParseNodeKind::ForHead;
@ -4270,10 +4269,13 @@ GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
}
template <class ParseHandler, typename Unit>
typename ParseHandler::Node GeneralParser<ParseHandler, Unit>::declarationName(
DeclarationKind declKind, TokenKind tt, bool initialDeclaration,
YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
Node* forInOrOfExpression) {
typename ParseHandler::NameNodeType
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);
@ -4305,17 +4307,13 @@ typename ParseHandler::Node GeneralParser<ParseHandler, Unit>::declarationName(
return null();
}
Node declaration;
if (matched) {
declaration = initializerInNameDeclaration(
binding, declKind, initialDeclaration, yieldHandling, forHeadKind,
forInOrOfExpression);
if (!declaration) {
if (!initializerInNameDeclaration(binding, declKind, initialDeclaration,
yieldHandling, forHeadKind,
forInOrOfExpression)) {
return null();
}
} else {
declaration = binding;
if (initialDeclaration && forHeadKind) {
bool isForIn, isForOf;
if (!matchInOrOf(&isForIn, &isForOf)) {
@ -4353,7 +4351,7 @@ typename ParseHandler::Node GeneralParser<ParseHandler, Unit>::declarationName(
return null();
}
return declaration;
return binding;
}
template <class ParseHandler, typename Unit>

View File

@ -1188,16 +1188,18 @@ class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
bool initialDeclaration, YieldHandling yieldHandling,
ParseNodeKind* forHeadKind,
Node* forInOrOfExpression);
Node declarationName(DeclarationKind declKind, TokenKind tt,
bool initialDeclaration, YieldHandling yieldHandling,
ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
NameNodeType 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|.
Node initializerInNameDeclaration(NameNodeType binding,
bool initializerInNameDeclaration(NameNodeType binding,
DeclarationKind declKind,
bool initialDeclaration,
YieldHandling yieldHandling,

View File

@ -517,9 +517,9 @@ class SyntaxParseHandler {
return NodeGeneric;
}
AssignmentNodeType finishInitializerAssignment(NameNodeType nameNode,
Node init) {
return NodeUnparenthesizedAssignment;
MOZ_MUST_USE bool finishInitializerAssignment(NameNodeType nameNode,
Node init) {
return true;
}
void setBeginPosition(Node pn, Node oth) {}

View File

@ -1,9 +0,0 @@
var BUGNUMBER = 1499448;
var summary = "Constant folder should fold labeled statements";
print(BUGNUMBER + ": " + summary);
var code = disassemble(() => { x: 2+2; });
if (typeof reportCompare === "function")
reportCompare(true, /int8 4/.test(code));

View File

@ -609,6 +609,10 @@ 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);
}
@ -3036,15 +3040,8 @@ static bool CheckGlobalDotImport(ModuleValidatorShared& m,
return m.addFFI(varName, field);
}
static bool CheckModuleGlobal(ModuleValidatorShared& m, ParseNode* decl,
static bool CheckModuleGlobal(ModuleValidatorShared& m, ParseNode* var,
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");
}
@ -3054,7 +3051,10 @@ static bool CheckModuleGlobal(ModuleValidatorShared& m, ParseNode* decl,
return false;
}
ParseNode* initNode = assignNode->right();
ParseNode* initNode = MaybeInitializer(var);
if (!initNode) {
return m.fail(var, "module import needs initializer");
}
if (IsNumericLiteral(m, initNode)) {
return CheckGlobalVariableInitConstant(m, varName, initNode, isConst);
@ -3254,17 +3254,8 @@ static bool CheckFinalReturn(FunctionValidatorShared& f,
return true;
}
static bool CheckVariable(FunctionValidatorShared& f, ParseNode* decl,
static bool CheckVariable(FunctionValidatorShared& f, ParseNode* var,
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");
}
@ -3275,7 +3266,12 @@ static bool CheckVariable(FunctionValidatorShared& f, ParseNode* decl,
return false;
}
ParseNode* initNode = assignNode->right();
ParseNode* initNode = MaybeInitializer(var);
if (!initNode) {
return f.failName(
var, "var '%s' needs explicit type declaration via an initial value",
name);
}
NumLit lit;
if (!IsLiteralOrConst(f, initNode, &lit)) {
@ -6158,21 +6154,13 @@ static bool CheckFunctions(ModuleValidator<Unit>& m) {
}
template <typename Unit>
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();
static bool CheckFuncPtrTable(ModuleValidator<Unit>& m, ParseNode* var) {
if (!var->isKind(ParseNodeKind::Name)) {
return m.fail(var, "function-pointer table name is not a plain name");
}
ParseNode* arrayLiteral = assignNode->right();
if (!arrayLiteral->isKind(ParseNodeKind::ArrayExpr)) {
ParseNode* arrayLiteral = MaybeInitializer(var);
if (!arrayLiteral || !arrayLiteral->isKind(ParseNodeKind::ArrayExpr)) {
return m.fail(
var, "function-pointer table's initializer must be an array literal");
}