diff options
author | Martok <martok@martoks-place.de> | 2023-03-31 23:52:57 +0200 |
---|---|---|
committer | Martok <martok@martoks-place.de> | 2023-04-03 16:50:23 +0200 |
commit | 88f7cba9c98e2671ce1fdf0f8c2df1bc9317e3ba (patch) | |
tree | 5db8ad3373aa5b519b40811a9d4f1ed4e235ab83 /js/src/frontend | |
parent | 6cea01f81194b8823c285418997f31bde897b700 (diff) | |
download | uxp-88f7cba9c98e2671ce1fdf0f8c2df1bc9317e3ba.tar.gz |
Issue #2173 - Add accessors to NameNode, CodeNode, RegExpLiteral, and add NumericLiteral
Based-on: m-c 1479659/{5,9,10}, m-c 1491147
Diffstat (limited to 'js/src/frontend')
-rw-r--r-- | js/src/frontend/BytecodeCompiler.cpp | 19 | ||||
-rw-r--r-- | js/src/frontend/BytecodeEmitter.cpp | 172 | ||||
-rw-r--r-- | js/src/frontend/BytecodeEmitter.h | 4 | ||||
-rw-r--r-- | js/src/frontend/FoldConstants.cpp | 133 | ||||
-rw-r--r-- | js/src/frontend/FullParseHandler.h | 122 | ||||
-rw-r--r-- | js/src/frontend/NameFunctions.cpp | 74 | ||||
-rw-r--r-- | js/src/frontend/ParseNode-inl.h | 11 | ||||
-rw-r--r-- | js/src/frontend/ParseNode.cpp | 171 | ||||
-rw-r--r-- | js/src/frontend/ParseNode.h | 358 | ||||
-rw-r--r-- | js/src/frontend/Parser.cpp | 307 | ||||
-rw-r--r-- | js/src/frontend/Parser.h | 90 | ||||
-rw-r--r-- | js/src/frontend/SharedContext.h | 2 | ||||
-rw-r--r-- | js/src/frontend/SyntaxParseHandler.h | 51 |
13 files changed, 854 insertions, 660 deletions
diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index 6dc837eb3b..d2edd786a6 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -413,7 +413,7 @@ BytecodeCompiler::compileModule() Maybe<BytecodeEmitter> emitter; if (!emplaceEmitter(emitter, &modulesc)) return nullptr; - if (!emitter->emitScript(pn->pn_body)) + if (!emitter->emitScript(pn->as<CodeNode>().body())) return nullptr; if (!NameFunctions(cx, pn)) @@ -466,19 +466,20 @@ BytecodeCompiler::compileStandaloneFunction(MutableHandleFunction fun, return false; } while (!fn); - if (fn->pn_funbox->function()->isInterpreted()) { - MOZ_ASSERT(fun == fn->pn_funbox->function()); + FunctionBox* funbox = fn->as<CodeNode>().funbox(); + if (funbox->function()->isInterpreted()) { + MOZ_ASSERT(fun == funbox->function()); - if (!createScript(fn->pn_funbox->toStringStart, fn->pn_funbox->toStringEnd)) + if (!createScript(funbox->toStringStart, funbox->toStringEnd)) return false; Maybe<BytecodeEmitter> emitter; - if (!emplaceEmitter(emitter, fn->pn_funbox)) + if (!emplaceEmitter(emitter, funbox)) return false; - if (!emitter->emitFunctionScript(fn->pn_body)) + if (!emitter->emitFunctionScript(&fn->as<CodeNode>())) return false; } else { - fun.set(fn->pn_funbox->function()); + fun.set(funbox->function()); MOZ_ASSERT(IsAsmJSModule(fun)); } @@ -673,12 +674,12 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha if (lazy->hasBeenCloned()) script->setHasBeenCloned(); - BytecodeEmitter bce(/* parent = */ nullptr, &parser, pn->pn_funbox, script, lazy, + BytecodeEmitter bce(/* parent = */ nullptr, &parser, pn->as<CodeNode>().funbox(), script, lazy, pn->pn_pos, BytecodeEmitter::LazyFunction); if (!bce.init()) return false; - if (!bce.emitFunctionScript(pn->pn_body)) + if (!bce.emitFunctionScript(&pn->as<CodeNode>())) return false; if (!NameFunctions(cx, pn)) diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index fa3f2ddded..1153b0896f 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -1054,21 +1054,33 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer) switch (pn->getKind()) { // Trivial cases with no side effects. case PNK_NOP: - case PNK_STRING: - case PNK_TEMPLATE_STRING: - case PNK_REGEXP: case PNK_TRUE: case PNK_FALSE: case PNK_NULL: case PNK_RAW_UNDEFINED: case PNK_ELISION: case PNK_GENERATOR: - case PNK_NUMBER: - case PNK_OBJECT_PROPERTY_NAME: MOZ_ASSERT(pn->isArity(PN_NULLARY)); *answer = false; return true; + case PNK_OBJECT_PROPERTY_NAME: + case PNK_STRING: + case PNK_TEMPLATE_STRING: + MOZ_ASSERT(pn->is<NameNode>()); + *answer = false; + return true; + + case PNK_REGEXP: + MOZ_ASSERT(pn->is<RegExpLiteral>()); + *answer = false; + return true; + + case PNK_NUMBER: + MOZ_ASSERT(pn->is<NumericLiteral>()); + *answer = false; + return true; + // |this| can throw in derived class constructors, including nested arrow // functions or eval. case PNK_THIS: @@ -1381,7 +1393,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer) return true; case PNK_NAME: - MOZ_ASSERT(pn->isArity(PN_NAME)); + MOZ_ASSERT(pn->is<NameNode>()); *answer = true; return true; @@ -1395,7 +1407,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer) return true; case PNK_FUNCTION: - MOZ_ASSERT(pn->isArity(PN_CODE)); + MOZ_ASSERT(pn->is<CodeNode>()); /* * A named function, contrary to ES3, is no longer effectful, because * we bind its name lexically (using JSOP_CALLEE) instead of creating @@ -1463,8 +1475,7 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer) } case PNK_LABEL: - MOZ_ASSERT(pn->isArity(PN_NAME)); - return checkSideEffects(pn->expr(), answer); + return checkSideEffects(pn->as<LabeledStatement>().statement(), answer); case PNK_LEXICALSCOPE: MOZ_ASSERT(pn->isArity(PN_SCOPE)); @@ -1855,7 +1866,7 @@ BytecodeEmitter::emitPropLHS(PropertyAccess* prop) while (true) { /* Walk back up the list, emitting annotated name ops. */ - if (!emitAtomOp(pndot->key().pn_atom, JSOP_GETPROP)) + if (!emitAtomOp(pndot->key().atom(), JSOP_GETPROP)) return false; /* Reverse the pn_left link again. */ @@ -1897,7 +1908,7 @@ BytecodeEmitter::emitPropIncDec(UnaryNode* incDec) if (!emitPropLHS(prop)) // OBJ return false; } - if (!poe.emitIncDec(prop->key().pn_atom)) { // RESULT + if (!poe.emitIncDec(prop->key().atom())) { // RESULT return false; } @@ -1911,7 +1922,7 @@ BytecodeEmitter::emitNameIncDec(UnaryNode* incDec) ParseNodeKind kind = incDec->getKind(); NameNode* name = &incDec->kid()->as<NameNode>(); - NameOpEmitter noe(this, name->pn_atom, + NameOpEmitter noe(this, name->atom(), kind == PNK_POSTINCREMENT ? NameOpEmitter::Kind::PostIncrement : kind == PNK_PREINCREMENT ? NameOpEmitter::Kind::PreIncrement : kind == PNK_POSTDECREMENT ? NameOpEmitter::Kind::PostDecrement @@ -2113,7 +2124,7 @@ BytecodeEmitter::emitSwitch(SwitchStatement* switchStmt) } int32_t i; - if (!NumberIsInt32(caseValue->pn_dval, &i)) { + if (!NumberIsInt32(caseValue->as<NumericLiteral>().value(), &i)) { tableGen.setInvalid(); break; } @@ -2166,8 +2177,15 @@ BytecodeEmitter::emitSwitch(SwitchStatement* switchStmt) ParseNode* caseValue = caseClause->caseExpression(); MOZ_ASSERT(caseValue->isKind(PNK_NUMBER)); - int32_t i = int32_t(caseValue->pn_dval); - MOZ_ASSERT(double(i) == caseValue->pn_dval); + NumericLiteral* literal = &caseValue->as<NumericLiteral>(); +#ifdef DEBUG + // Use NumberEqualsInt32 here because switches compare using + // strict equality, which will equate -0 and +0. In contrast + // NumberIsInt32 would return false for -0. + int32_t v; + MOZ_ASSERT(mozilla::NumberEqualsInt32(literal->value(), &v)); +#endif + int32_t i = int32_t(literal->value()); if (!se.emitCaseBody(i, tableGen)) return false; @@ -2360,8 +2378,10 @@ BytecodeEmitter::emitScript(ParseNode* body) } bool -BytecodeEmitter::emitFunctionScript(ParseNode* body) +BytecodeEmitter::emitFunctionScript(CodeNode* funNode) { + MOZ_ASSERT(funNode->isKind(PNK_FUNCTION)); + ParseNode* body = funNode->body(); FunctionBox* funbox = sc->asFunctionBox(); // The ordering of these EmitterScopes is important. The named lambda @@ -2619,8 +2639,8 @@ BytecodeEmitter::emitSetOrInitializeDestructuring(ParseNode* target, Destructuri if (!poe.skipObjAndRhs()) { return false; } - if (!poe.emitAssignment(prop->key().pn_atom)) { - return false; // VAL + if (!poe.emitAssignment(prop->key().atom())) { // VAL + return false; } break; } @@ -2943,7 +2963,7 @@ BytecodeEmitter::setOrEmitSetFunName(ParseNode* maybeFun, HandleAtom name, if (maybeFun->isKind(PNK_FUNCTION)) { // Function doesn't have 'name' property at this point. // Set function's name at compile time. - RootedFunction fun(cx, maybeFun->pn_funbox->function()); + RootedFunction fun(cx, maybeFun->as<CodeNode>().funbox()->function()); // Single node can be emitted multiple times if it appears in // array destructuring default. If function already has a name, @@ -2953,7 +2973,7 @@ BytecodeEmitter::setOrEmitSetFunName(ParseNode* maybeFun, HandleAtom name, RootedAtom funName(cx, NameToFunctionName(cx, name, prefixKind)); if (!funName) return false; - MOZ_ASSERT(funName == maybeFun->pn_funbox->function()->compileTimeName()); + MOZ_ASSERT(funName == fun->compileTimeName()); #endif return true; } @@ -3409,11 +3429,11 @@ BytecodeEmitter::emitDestructuringOpsObject(ListNode* pattern, DestructuringFlav ParseNode* key = member->as<BinaryNode>().left(); if (key->isKind(PNK_NUMBER)) { - if (!emitNumberOp(key->pn_dval)) // ... *SET RHS *LREF RHS KEY - return false; + if (!emitNumberOp(key->as<NumericLiteral>().value())) + return false; // ... *SET RHS *LREF RHS KEY } else if (key->isKind(PNK_OBJECT_PROPERTY_NAME) || key->isKind(PNK_STRING)) { - if (!emitAtomOp(key->pn_atom, JSOP_GETPROP)) // ... *SET RHS *LREF PROP - return false; + if (!emitAtomOp(key->as<NameNode>().atom(), JSOP_GETPROP)) + return false; // ... *SET RHS *LREF PROP needsGetElem = false; } else { if (!emitComputedPropertyName(&key->as<UnaryNode>())) // ... *SET RHS *LREF RHS KEY @@ -3486,11 +3506,11 @@ BytecodeEmitter::emitDestructuringObjRestExclusionSet(ListNode* pattern) } else { ParseNode* key = member->as<BinaryNode>().left(); if (key->isKind(PNK_NUMBER)) { - if (!emitNumberOp(key->pn_dval)) + if (!emitNumberOp(key->as<NumericLiteral>().value())) return false; isIndex = true; } else if (key->isKind(PNK_OBJECT_PROPERTY_NAME) || key->isKind(PNK_STRING)) { - pnatom.set(key->pn_atom); + pnatom.set(key->as<NameNode>().atom()); } else { // Otherwise this is a computed property name which needs to // be added dynamically. @@ -3558,7 +3578,7 @@ BytecodeEmitter::emitTemplateString(ListNode* templateString) // Skip empty strings. These are very common: a template string like // `${a}${b}` has three empty strings and without this optimization // we'd emit four JSOP_ADD operations instead of just one. - if (isString && item->pn_atom->empty()) + if (isString && item->as<NameNode>().atom()->empty()) continue; if (!isString) { @@ -3618,7 +3638,7 @@ BytecodeEmitter::emitDeclarationList(ListNode* declList) if (!emit1(JSOP_POP)) return false; } else { - if (!emitSingleDeclaration(declList, decl, decl->expr())) + if (!emitSingleDeclaration(declList, decl, decl->as<NameNode>().initializer())) return false; } } @@ -3809,7 +3829,7 @@ BytecodeEmitter::emitAssignment(ParseNode* lhs, JSOp compoundOp, ParseNode* rhs) switch (lhs->getKind()) { case PNK_DOT: { PropertyAccess* prop = &lhs->as<PropertyAccess>(); - if (!poe->emitGet(prop->key().pn_atom)) { // [Super] + if (!poe->emitGet(prop->key().atom())) { // [Super] // // THIS SUPERBASE PROP // // [Other] // // OBJ PROP @@ -3878,7 +3898,7 @@ BytecodeEmitter::emitAssignment(ParseNode* lhs, JSOp compoundOp, ParseNode* rhs) switch (lhs->getKind()) { case PNK_DOT: { PropertyAccess* prop = &lhs->as<PropertyAccess>(); - if (!poe->emitAssignment(prop->key().pn_atom)) { // VAL + if (!poe->emitAssignment(prop->key().atom())) { // VAL return false; } @@ -3916,11 +3936,11 @@ ParseNode::getConstantValue(ExclusiveContext* cx, AllowConstantObjects allowObje switch (getKind()) { case PNK_NUMBER: - vp.setNumber(pn_dval); + vp.setNumber(as<NumericLiteral>().value()); return true; case PNK_TEMPLATE_STRING: case PNK_STRING: - vp.setString(pn_atom); + vp.setString(as<NameNode>().atom()); return true; case PNK_TRUE: vp.setBoolean(true); @@ -4009,12 +4029,12 @@ ParseNode::getConstantValue(ExclusiveContext* cx, AllowConstantObjects allowObje ParseNode* key = prop->left(); if (key->isKind(PNK_NUMBER)) { - idvalue = NumberValue(key->pn_dval); + idvalue = NumberValue(key->as<NumericLiteral>().value()); } else { MOZ_ASSERT(key->isKind(PNK_OBJECT_PROPERTY_NAME) || key->isKind(PNK_STRING)); - MOZ_ASSERT(key->pn_atom != cx->names().proto); - idvalue = StringValue(key->pn_atom); + MOZ_ASSERT(key->as<NameNode>().atom() != cx->names().proto); + idvalue = StringValue(key->as<NameNode>().atom()); } RootedId id(cx); @@ -4330,7 +4350,7 @@ BytecodeEmitter::emitHoistedFunctionsInList(ListNode* stmtList) maybeFun = maybeFun->as<LabeledStatement>().statement(); } - if (maybeFun->isKind(PNK_FUNCTION) && maybeFun->functionIsHoisted()) { + if (maybeFun->isKind(PNK_FUNCTION) && maybeFun->as<CodeNode>().functionIsHoisted()) { if (!emitTree(maybeFun)) return false; } @@ -4935,7 +4955,7 @@ BytecodeEmitter::emitForIn(ForNode* forNode, EmitterScope* headLexicalEmitterSco if (parser->handler.isDeclarationList(forInTarget)) { ParseNode* decl = parser->handler.singleBindingFromDeclaration(&forInTarget->as<ListNode>()); if (decl->isKind(PNK_NAME)) { - if (ParseNode* initializer = decl->expr()) { + if (ParseNode* initializer = decl->as<NameNode>().initializer()) { MOZ_ASSERT(forInTarget->isKind(PNK_VAR), "for-in initializers are only permitted for |var| declarations"); @@ -5341,7 +5361,7 @@ BytecodeEmitter::emitComprehensionForOf(ForNode* forNode) Maybe<EmitterScope> emitterScope; ParseNode* loopVariableName; if (lexicalScope) { - loopVariableName = parser->handler.singleBindingFromDeclaration(&loopDecl->pn_expr->as<ListNode>()); + loopVariableName = parser->handler.singleBindingFromDeclaration(&loopDecl->scopeBody()->as<ListNode>()); emitterScope.emplace(this); if (!emitterScope->enterComprehensionFor(this, loopDecl->scopeBindings())) return false; @@ -5584,9 +5604,9 @@ BytecodeEmitter::emitComprehensionFor(ForNode* forNode) } MOZ_NEVER_INLINE bool -BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto) +BytecodeEmitter::emitFunction(CodeNode* funNode, bool needsProto) { - FunctionBox* funbox = pn->pn_funbox; + FunctionBox* funbox = funNode->funbox(); RootedFunction fun(cx, funbox->function()); RootedAtom name(cx, fun->explicitName()); MOZ_ASSERT_IF(fun->isInterpretedLazy(), fun->lazyScript()); @@ -5637,7 +5657,7 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto) } MOZ_ASSERT_IF(fun->hasScript(), fun->nonLazyScript()); - MOZ_ASSERT(pn->functionIsHoisted()); + MOZ_ASSERT(funNode->functionIsHoisted()); return true; } @@ -5687,12 +5707,12 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto) return false; BytecodeEmitter bce2(this, parser, funbox, script, /* lazyScript = */ nullptr, - pn->pn_pos, emitterMode); + funNode->pn_pos, emitterMode); if (!bce2.init()) return false; /* We measured the max scope depth when we parsed the function. */ - if (!bce2.emitFunctionScript(pn->pn_body)) + if (!bce2.emitFunctionScript(funNode)) return false; if (funbox->isLikelyConstructorWrapper()) @@ -5706,12 +5726,12 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto) } /* Make the function object a literal in the outer script's pool. */ - unsigned index = objectList.add(pn->pn_funbox); + unsigned index = objectList.add(funNode->funbox()); /* Non-hoisted functions simply emit their respective op. */ - if (!pn->functionIsHoisted()) { + if (!funNode->functionIsHoisted()) { /* JSOP_LAMBDA_ARROW is always preceded by a new.target */ - MOZ_ASSERT(fun->isArrow() == (pn->getOp() == JSOP_LAMBDA_ARROW)); + MOZ_ASSERT(fun->isArrow() == (funNode->getOp() == JSOP_LAMBDA_ARROW)); if (funbox->isAsync()) { MOZ_ASSERT(!needsProto); return emitAsyncWrapper(index, funbox->needsHomeObject(), fun->isArrow(), @@ -5729,17 +5749,17 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto) } if (needsProto) { - MOZ_ASSERT(pn->getOp() == JSOP_LAMBDA); - pn->setOp(JSOP_FUNWITHPROTO); + MOZ_ASSERT(funNode->getOp() == JSOP_LAMBDA); + funNode->setOp(JSOP_FUNWITHPROTO); } - if (pn->getOp() == JSOP_DEFFUN) { + if (funNode->getOp() == JSOP_DEFFUN) { if (!emitIndex32(JSOP_LAMBDA, index)) return false; return emit1(JSOP_DEFFUN); } - return emitIndex32(pn->getOp(), index); + return emitIndex32(funNode->getOp(), index); } MOZ_ASSERT(!needsProto); @@ -5767,7 +5787,7 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto) return false; } else { MOZ_ASSERT(sc->isGlobalContext() || sc->isEvalContext()); - MOZ_ASSERT(pn->getOp() == JSOP_NOP); + MOZ_ASSERT(funNode->getOp() == JSOP_NOP); switchToPrologue(); if (funbox->isAsync()) { if (!emitAsyncWrapper(index, fun->isMethod(), fun->isArrow(), @@ -5781,7 +5801,7 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto) } if (!emit1(JSOP_DEFFUN)) return false; - if (!updateSourceCoordNotes(pn->pn_pos.begin)) + if (!updateSourceCoordNotes(funNode->pn_pos.begin)) return false; switchToMain(); } @@ -6693,10 +6713,10 @@ BytecodeEmitter::emitDeleteName(UnaryNode* deleteNode) { MOZ_ASSERT(deleteNode->isKind(PNK_DELETENAME)); - ParseNode* nameExpr = deleteNode->kid(); + NameNode* nameExpr = &deleteNode->kid()->as<NameNode>(); MOZ_ASSERT(nameExpr->isKind(PNK_NAME)); - return emitAtomOp(nameExpr->pn_atom, JSOP_DELNAME); + return emitAtomOp(nameExpr->atom(), JSOP_DELNAME); } bool @@ -6731,7 +6751,8 @@ BytecodeEmitter::emitDeleteProperty(UnaryNode* deleteNode) } } - if (!poe.emitDelete(propExpr->key().pn_atom)) { // [Super] + if (!poe.emitDelete(propExpr->key().atom())) { + // // [Super] // // THIS // // [Other] // // SUCCEEDED @@ -6884,7 +6905,7 @@ BytecodeEmitter::emitDeletePropertyInOptChain( } JSOp delOp = sc->strict() ? JSOP_STRICTDELPROP : JSOP_DELPROP; - if (!emitAtomOp(propExpr->pn_atom, delOp)) { + if (!emitAtomOp(propExpr->key().atom(), delOp)) { return false; } @@ -7034,7 +7055,7 @@ BytecodeEmitter::emitSelfHostedResumeGenerator(BinaryNode* callNode) ParseNode* kindNode = valNode->pn_next; MOZ_ASSERT(kindNode->isKind(PNK_STRING)); - uint16_t operand = GeneratorObject::getResumeKind(cx, kindNode->pn_atom); + uint16_t operand = GeneratorObject::getResumeKind(cx, kindNode->as<NameNode>().atom()); MOZ_ASSERT(!kindNode->pn_next); if (!emitCall(JSOP_RESUME, operand)) @@ -7472,7 +7493,7 @@ BytecodeEmitter::emitCalleeAndThis( return false; } } - if (!poe.emitGet(prop->key().pn_atom)) { // CALLEE THIS? + if (!poe.emitGet(prop->key().atom())) { // CALLEE THIS? return false; } break; @@ -7752,12 +7773,12 @@ BytecodeEmitter::emitPropertyList(ListNode* obj, MutableHandlePlainObject objp, ParseNode* key = propdef->as<BinaryNode>().left(); bool isIndex = false; if (key->isKind(PNK_NUMBER)) { - if (!emitNumberOp(key->pn_dval)) + if (!emitNumberOp(key->as<NumericLiteral>().value())) return false; isIndex = true; } else if (key->isKind(PNK_OBJECT_PROPERTY_NAME) || key->isKind(PNK_STRING)) { // EmitClass took care of constructor already. - if (type == ClassBody && key->pn_atom == cx->names().constructor && + if (type == ClassBody && key->as<NameNode>().atom() == cx->names().constructor && !propdef->as<ClassMethod>().isStatic()) { continue; @@ -7787,10 +7808,11 @@ BytecodeEmitter::emitPropertyList(ListNode* obj, MutableHandlePlainObject objp, objp.set(nullptr); if (propVal->isKind(PNK_FUNCTION) && - propVal->pn_funbox->needsHomeObject()) + propVal->as<CodeNode>().funbox()->needsHomeObject()) { - MOZ_ASSERT(propVal->pn_funbox->function()->allowSuperProperty()); - bool isAsync = propVal->pn_funbox->isAsync(); + FunctionBox* funbox = propVal->as<CodeNode>().funbox(); + MOZ_ASSERT(funbox->function()->allowSuperProperty()); + bool isAsync = funbox->isAsync(); if (isAsync) { if (!emit1(JSOP_SWAP)) return false; @@ -7836,14 +7858,14 @@ BytecodeEmitter::emitPropertyList(ListNode* obj, MutableHandlePlainObject objp, MOZ_ASSERT(key->isKind(PNK_OBJECT_PROPERTY_NAME) || key->isKind(PNK_STRING)); uint32_t index; - if (!makeAtomIndex(key->pn_atom, &index)) + if (!makeAtomIndex(key->as<NameNode>().atom(), &index)) return false; if (objp) { MOZ_ASSERT(type == ObjectLiteral); MOZ_ASSERT(!IsHiddenInitOp(op)); MOZ_ASSERT(!objp->inDictionaryMode()); - Rooted<jsid> id(cx, AtomToId(key->pn_atom)); + Rooted<jsid> id(cx, AtomToId(key->as<NameNode>().atom())); if (!NativeDefineProperty(cx, objp, id, UndefinedHandleValue, nullptr, nullptr, JSPROP_ENUMERATE)) { @@ -7854,7 +7876,7 @@ BytecodeEmitter::emitPropertyList(ListNode* obj, MutableHandlePlainObject objp, } if (propVal->isDirectRHSAnonFunction()) { - RootedAtom keyName(cx, key->pn_atom); + RootedAtom keyName(cx, key->as<NameNode>().atom()); if (!setOrEmitSetFunName(propVal, keyName, prefixKind)) return false; } @@ -8484,13 +8506,13 @@ BytecodeEmitter::emitClass(ClassNode* classNode) ParseNode* heritageExpression = classNode->heritage(); ListNode* classMethods = classNode->methodList(); - ParseNode* constructor = nullptr; + CodeNode* constructor = nullptr; for (ParseNode* mn : classMethods->contents()) { ClassMethod& method = mn->as<ClassMethod>(); ParseNode& methodName = method.name(); if (!method.isStatic() && (methodName.isKind(PNK_OBJECT_PROPERTY_NAME) || methodName.isKind(PNK_STRING)) && - methodName.pn_atom == cx->names().constructor) + methodName.as<NameNode>().atom() == cx->names().constructor) { constructor = &method.method(); break; @@ -8533,7 +8555,7 @@ BytecodeEmitter::emitClass(ClassNode* classNode) if (constructor) { if (!emitFunction(constructor, !!heritageExpression)) return false; - if (constructor->pn_funbox->needsHomeObject()) { + if (constructor->funbox()->needsHomeObject()) { if (!emit2(JSOP_INITHOMEOBJECT, 0)) return false; } @@ -8547,7 +8569,7 @@ BytecodeEmitter::emitClass(ClassNode* classNode) if (!newSrcNote3(SRC_CLASS_SPAN, classStart, classEnd)) return false; - JSAtom *name = names ? names->innerBinding()->pn_atom : cx->names().empty; + JSAtom *name = names ? names->innerBinding()->as<NameNode>().atom() : cx->names().empty; if (heritageExpression) { if (!emitAtomOp(name, JSOP_DERIVEDCONSTRUCTOR)) return false; @@ -8618,7 +8640,7 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage:: switch (pn->getKind()) { case PNK_FUNCTION: - if (!emitFunction(pn)) + if (!emitFunction(&pn->as<CodeNode>())) return false; break; @@ -8879,7 +8901,7 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage:: return false; } } - if (!poe.emitGet(prop->key().pn_atom)) { // PROP + if (!poe.emitGet(prop->key().atom())) { // PROP return false; } break; @@ -9004,12 +9026,12 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage:: case PNK_TEMPLATE_STRING: case PNK_STRING: - if (!emitAtomOp(pn->pn_atom, JSOP_STRING)) + if (!emitAtomOp(pn->as<NameNode>().atom(), JSOP_STRING)) return false; break; case PNK_NUMBER: - if (!emitNumberOp(pn->pn_dval)) + if (!emitNumberOp(pn->as<NumericLiteral>().value())) return false; break; @@ -9281,7 +9303,7 @@ BytecodeEmitter::emitOptionalDotExpression( } } - if (!poe.emitGet(prop->key().pn_atom)) { + if (!poe.emitGet(prop->key().atom())) { // [stack] PROP return false; } diff --git a/js/src/frontend/BytecodeEmitter.h b/js/src/frontend/BytecodeEmitter.h index 3fd95b60bd..1d2628131c 100644 --- a/js/src/frontend/BytecodeEmitter.h +++ b/js/src/frontend/BytecodeEmitter.h @@ -416,7 +416,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter MOZ_MUST_USE bool emitScript(ParseNode* body); // Emit function code for the tree rooted at body. - MOZ_MUST_USE bool emitFunctionScript(ParseNode* body); + MOZ_MUST_USE bool emitFunctionScript(CodeNode* funNode); // If op is JOF_TYPESET (see the type barriers comment in TypeInference.h), // reserve a type set to store its result. @@ -508,7 +508,7 @@ struct MOZ_STACK_CLASS BytecodeEmitter MOZ_MUST_USE bool emitObjectPairOp(ObjectBox* objbox1, ObjectBox* objbox2, JSOp op); MOZ_MUST_USE bool emitRegExp(uint32_t index); - MOZ_NEVER_INLINE MOZ_MUST_USE bool emitFunction(ParseNode* pn, bool needsProto = false); + MOZ_NEVER_INLINE MOZ_MUST_USE bool emitFunction(CodeNode* funNode, bool needsProto = false); MOZ_NEVER_INLINE MOZ_MUST_USE bool emitObject(ListNode* objNode); MOZ_MUST_USE bool replaceNewInitWithNewObject(JSObject* obj, ptrdiff_t offset); diff --git a/js/src/frontend/FoldConstants.cpp b/js/src/frontend/FoldConstants.cpp index fedec39598..fcc94c34fa 100644 --- a/js/src/frontend/FoldConstants.cpp +++ b/js/src/frontend/FoldConstants.cpp @@ -91,7 +91,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result) // that we preserve an unreachable function declaration node against // dead-code removal. case PNK_FUNCTION: - MOZ_ASSERT(node->isArity(PN_CODE)); + MOZ_ASSERT(node->is<CodeNode>()); *result = false; return true; @@ -151,7 +151,7 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result) return ContainsHoistedDeclaration(cx, node->as<BinaryNode>().right(), result); case PNK_LABEL: - return ContainsHoistedDeclaration(cx, node->pn_expr, result); + return ContainsHoistedDeclaration(cx, node->as<LabeledStatement>().statement(), result); // Statements with more complicated structures. @@ -283,13 +283,13 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result) case PNK_LEXICALSCOPE: { MOZ_ASSERT(node->isArity(PN_SCOPE)); - ParseNode* expr = node->pn_expr; + ParseNode* expr = node->scopeBody(); if (expr->isKind(PNK_FOR) || expr->isKind(PNK_FUNCTION)) return ContainsHoistedDeclaration(cx, expr, result); MOZ_ASSERT(expr->isKind(PNK_STATEMENTLIST)); - return ListContainsHoistedDeclaration(cx, &node->pn_expr->as<ListNode>(), result); + return ListContainsHoistedDeclaration(cx, &node->scopeBody()->as<ListNode>(), result); } // List nodes with all non-null children. @@ -426,21 +426,24 @@ FoldType(ExclusiveContext* cx, ParseNode* pn, ParseNodeKind kind) case PNK_NUMBER: if (pn->isKind(PNK_STRING)) { double d; - if (!StringToNumber(cx, pn->pn_atom, &d)) + if (!StringToNumber(cx, pn->as<NameNode>().atom(), &d)) return false; - pn->pn_dval = d; pn->setKind(PNK_NUMBER); + pn->setArity(PN_NUMBER); pn->setOp(JSOP_DOUBLE); + pn->as<NumericLiteral>().setValue(d); } break; case PNK_STRING: if (pn->isKind(PNK_NUMBER)) { - pn->pn_atom = NumberToAtom(cx, pn->pn_dval); - if (!pn->pn_atom) + JSAtom* atom = NumberToAtom(cx, pn->as<NumericLiteral>().value()); + if (!atom) return false; pn->setKind(PNK_STRING); + pn->setArity(PN_NAME); pn->setOp(JSOP_STRING); + pn->as<NameNode>().setAtom(atom); } break; @@ -485,13 +488,13 @@ Boolish(ParseNode* pn, bool isNullish = false) { switch (pn->getKind()) { case PNK_NUMBER: { - bool isNonZeroNumber = (pn->pn_dval != 0 && !IsNaN(pn->pn_dval)); + bool isNonZeroNumber = (pn->as<NumericLiteral>().value() != 0 && !IsNaN(pn->as<NumericLiteral>().value())); return (isNullish || isNonZeroNumber) ? Truthy : Falsy; } case PNK_STRING: case PNK_TEMPLATE_STRING: { - bool isNonZeroLengthString = (pn->pn_atom->length() > 0); + bool isNonZeroLengthString = (pn->as<NameNode>().atom()->length() > 0); return (isNullish || isNonZeroLengthString) ? Truthy : Falsy; } @@ -588,9 +591,9 @@ FoldTypeOfExpr(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser.prepareNodeForMutation(node); node->setKind(PNK_STRING); - node->setArity(PN_NULLARY); + node->setArity(PN_NAME); node->setOp(JSOP_NOP); - node->pn_atom = result; + node->as<NameNode>().setAtom(result); } return true; @@ -676,7 +679,7 @@ FoldNot(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandler>& parser, ParseNode* expr = node->kid(); if (expr->isKind(PNK_NUMBER)) { - double d = expr->pn_dval; + double d = expr->as<NumericLiteral>().value(); parser.prepareNodeForMutation(node); if (d == 0 || IsNaN(d)) { @@ -713,7 +716,7 @@ FoldUnaryArithmetic(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandl if (expr->isKind(PNK_NUMBER) || expr->isKind(PNK_TRUE) || expr->isKind(PNK_FALSE)) { double d = expr->isKind(PNK_NUMBER) - ? expr->pn_dval + ? expr->as<NumericLiteral>().value() : double(expr->isKind(PNK_TRUE)); if (node->isKind(PNK_BITNOT)) @@ -725,9 +728,9 @@ FoldUnaryArithmetic(ExclusiveContext* cx, UnaryNode* node, Parser<FullParseHandl parser.prepareNodeForMutation(node); node->setKind(PNK_NUMBER); + node->setArity(PN_NUMBER); node->setOp(JSOP_DOUBLE); - node->setArity(PN_NULLARY); - node->pn_dval = d; + node->as<NumericLiteral>().setValue(d); } return true; @@ -1011,20 +1014,19 @@ FoldIf(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& pars } static bool -FoldFunction(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser, +FoldFunction(ExclusiveContext* cx, CodeNode* node, Parser<FullParseHandler>& parser, bool inGenexpLambda) { MOZ_ASSERT(node->isKind(PNK_FUNCTION)); - MOZ_ASSERT(node->isArity(PN_CODE)); // Don't constant-fold inside "use asm" code, as this could create a parse // tree that doesn't type-check as asm.js. - if (node->pn_funbox->useAsmOrInsideUseAsm()) + if (node->funbox()->useAsmOrInsideUseAsm()) return true; // Note: pn_body is null for lazily-parsed functions. - if (ParseNode*& functionBody = node->pn_body) { - if (!Fold(cx, &functionBody, parser, node->pn_funbox->isGenexpLambda)) + if (node->body()) { + if (!Fold(cx, node->unsafeBodyReference(), parser, node->funbox()->isGenexpLambda)) return false; } @@ -1074,14 +1076,11 @@ ComputeBinary(ParseNodeKind kind, double left, double right) } static bool -FoldModule(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser) +FoldModule(ExclusiveContext* cx, CodeNode* node, Parser<FullParseHandler>& parser) { MOZ_ASSERT(node->isKind(PNK_MODULE)); - MOZ_ASSERT(node->isArity(PN_CODE)); - - ParseNode*& moduleBody = node->pn_body; - MOZ_ASSERT(moduleBody); - return Fold(cx, &moduleBody, parser, false); + MOZ_ASSERT(node->body()); + return Fold(cx, node->unsafeBodyReference(), parser, false); } static bool @@ -1122,7 +1121,7 @@ FoldBinaryArithmetic(ExclusiveContext* cx, ListNode* node, Parser<FullParseHandl if (!next || !next->isKind(PNK_NUMBER)) break; - double d = ComputeBinary(kind, elem->pn_dval, next->pn_dval); + double d = ComputeBinary(kind, elem->as<NumericLiteral>().value(), next->as<NumericLiteral>().value()); ParseNode* afterNext = next->pn_next; parser.freeTree(next); @@ -1130,9 +1129,9 @@ FoldBinaryArithmetic(ExclusiveContext* cx, ListNode* node, Parser<FullParseHandl elem->pn_next = next; elem->setKind(PNK_NUMBER); + elem->setArity(PN_NUMBER); elem->setOp(JSOP_DOUBLE); - elem->setArity(PN_NULLARY); - elem->pn_dval = d; + elem->as<NumericLiteral>().setValue(d); node->unsafeDecrementCount(); } @@ -1141,11 +1140,11 @@ FoldBinaryArithmetic(ExclusiveContext* cx, ListNode* node, Parser<FullParseHandl MOZ_ASSERT(node->head() == elem); MOZ_ASSERT(elem->isKind(PNK_NUMBER)); - double d = elem->pn_dval; + double d = elem->as<NumericLiteral>().value(); node->setKind(PNK_NUMBER); - node->setArity(PN_NULLARY); + node->setArity(PN_NUMBER); node->setOp(JSOP_DOUBLE); - node->pn_dval = d; + node->as<NumericLiteral>().setValue(d); parser.freeTree(elem); } @@ -1186,13 +1185,14 @@ FoldExponentiation(ExclusiveContext* cx, ListNode* node, Parser<FullParseHandler if (!base->isKind(PNK_NUMBER) || !exponent->isKind(PNK_NUMBER)) return true; - double d1 = base->pn_dval, d2 = exponent->pn_dval; + double d1 = base->as<NumericLiteral>().value(); + double d2 = exponent->as<NumericLiteral>().value(); parser.prepareNodeForMutation(node); node->setKind(PNK_NUMBER); - node->setArity(PN_NULLARY); + node->setArity(PN_NUMBER); node->setOp(JSOP_DOUBLE); - node->pn_dval = ecmaPow(d1, d2); + node->as<NumericLiteral>().setValue(ecmaPow(d1, d2)); return true; } @@ -1312,20 +1312,21 @@ FoldElement(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& ParseNode* key = &elem->key(); PropertyName* name = nullptr; if (key->isKind(PNK_STRING)) { - JSAtom* atom = key->pn_atom; + JSAtom* atom = key->as<NameNode>().atom(); uint32_t index; if (atom->isIndex(&index)) { // Optimization 1: We have something like expr["100"]. This is // equivalent to expr[100] which is faster. key->setKind(PNK_NUMBER); + key->setArity(PN_NUMBER); key->setOp(JSOP_DOUBLE); - key->pn_dval = index; + key->as<NumericLiteral>().setValue(index); } else { name = atom->asPropertyName(); } } else if (key->isKind(PNK_NUMBER)) { - double number = key->pn_dval; + double number = key->as<NumericLiteral>().value(); if (number != ToUint32(number)) { // Optimization 2: We have something like expr[3.14]. The number // isn't an array index, so it converts to a string ("3.14"), @@ -1343,7 +1344,7 @@ FoldElement(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& // Optimization 3: We have expr["foo"] where foo is not an index. Convert // to a property access (like expr.foo) that optimizes better downstream. - ParseNode* nameNode = parser.handler.newPropertyName(name, key->pn_pos); + NameNode* nameNode = parser.handler.newPropertyName(name, key->pn_pos); if (!nameNode) return false; ParseNode* dottedAccess; @@ -1397,7 +1398,9 @@ FoldAdd(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& par if (!next->isKind(PNK_NUMBER)) break; - current->pn_dval += next->pn_dval; + NumericLiteral* num = ¤t->as<NumericLiteral>(); + + num->setValue(num->value() + next->as<NumericLiteral>().value()); current->pn_next = next->pn_next; parser.freeTree(next); next = current->pn_next; @@ -1442,7 +1445,7 @@ FoldAdd(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& par // and replace them all with that fresh string. MOZ_ASSERT(current->isKind(PNK_STRING)); - combination = current->pn_atom; + combination = current->as<NameNode>().atom(); do { // Try folding the next operand to a string. @@ -1454,7 +1457,7 @@ FoldAdd(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& par break; // Add this string to the combination and remove the node. - tmp = next->pn_atom; + tmp = next->as<NameNode>().atom(); combination = ConcatStrings<CanGC>(cx, combination, tmp); if (!combination) return false; @@ -1471,7 +1474,7 @@ FoldAdd(ExclusiveContext* cx, ParseNode** nodePtr, Parser<FullParseHandler>& par combination = AtomizeString(cx, combination); if (!combination) return false; - current->pn_atom = &combination->asAtom(); + current->as<NameNode>().setAtom(&combination->asAtom()); // If we're out of nodes, we're done. @@ -1624,16 +1627,15 @@ FoldDottedProperty(ExclusiveContext* cx, PropertyAccessBase* prop, Parser<FullPa } static bool -FoldName(ExclusiveContext* cx, ParseNode* node, Parser<FullParseHandler>& parser, +FoldName(ExclusiveContext* cx, NameNode* nameNode, Parser<FullParseHandler>& parser, bool inGenexpLambda) { - MOZ_ASSERT(node->isKind(PNK_NAME)); - MOZ_ASSERT(node->isArity(PN_NAME)); + MOZ_ASSERT(nameNode->isKind(PNK_NAME)); - if (!node->pn_expr) + if (!nameNode->initializer()) return true; - return Fold(cx, &node->pn_expr, parser, inGenexpLambda); + return Fold(cx, nameNode->unsafeInitializerReference(), parser, inGenexpLambda); } bool @@ -1648,31 +1650,41 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo switch (pn->getKind()) { case PNK_NOP: - case PNK_REGEXP: - case PNK_STRING: case PNK_TRUE: case PNK_FALSE: case PNK_NULL: case PNK_RAW_UNDEFINED: case PNK_ELISION: - case PNK_NUMBER: case PNK_DEBUGGER: case PNK_BREAK: case PNK_CONTINUE: - case PNK_TEMPLATE_STRING: case PNK_GENERATOR: case PNK_EXPORT_BATCH_SPEC: - case PNK_OBJECT_PROPERTY_NAME: case PNK_POSHOLDER: MOZ_ASSERT(pn->isArity(PN_NULLARY)); return true; + case PNK_OBJECT_PROPERTY_NAME: + case PNK_STRING: + case PNK_TEMPLATE_STRING: + MOZ_ASSERT(pn->is<NameNode>()); + return true; + + case PNK_REGEXP: + MOZ_ASSERT(pn->is<RegExpLiteral>()); + return true; + + case PNK_NUMBER: + MOZ_ASSERT(pn->is<NumericLiteral>()); + return true; + case PNK_SUPERBASE: case PNK_TYPEOFNAME: { #ifdef DEBUG UnaryNode* node = &pn->as<UnaryNode>(); - MOZ_ASSERT(node->kid()->isKind(PNK_NAME)); - MOZ_ASSERT(!node->kid()->expr()); + NameNode* nameNode = &node->kid()->as<NameNode>(); + MOZ_ASSERT(nameNode->isKind(PNK_NAME)); + MOZ_ASSERT(!nameNode->initializer()); #endif return true; } @@ -1747,10 +1759,10 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo return FoldLogical(cx, pnp, parser, inGenexpLambda); case PNK_FUNCTION: - return FoldFunction(cx, pn, parser, inGenexpLambda); + return FoldFunction(cx, &pn->as<CodeNode>(), parser, inGenexpLambda); case PNK_MODULE: - return FoldModule(cx, pn, parser); + return FoldModule(cx, &pn->as<CodeNode>(), parser); case PNK_SUB: case PNK_STAR: @@ -1932,8 +1944,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo return FoldForHead(cx, &pn->as<TernaryNode>(), parser, inGenexpLambda); case PNK_LABEL: - MOZ_ASSERT(pn->isArity(PN_NAME)); - return Fold(cx, &pn->pn_expr, parser, inGenexpLambda); + return Fold(cx, pn->as<LabeledStatement>().unsafeStatementReference(), parser, inGenexpLambda); case PNK_PROPERTYNAME: MOZ_CRASH("unreachable, handled by ::Dot"); @@ -1949,7 +1960,7 @@ Fold(ExclusiveContext* cx, ParseNode** pnp, Parser<FullParseHandler>& parser, bo return Fold(cx, &pn->pn_u.scope.body, parser, inGenexpLambda); case PNK_NAME: - return FoldName(cx, pn, parser, inGenexpLambda); + return FoldName(cx, &pn->as<NameNode>(), parser, inGenexpLambda); case PNK_LIMIT: // invalid sentinel value MOZ_CRASH("invalid node kind"); diff --git a/js/src/frontend/FullParseHandler.h b/js/src/frontend/FullParseHandler.h index af4900402a..dca7a69cf2 100644 --- a/js/src/frontend/FullParseHandler.h +++ b/js/src/frontend/FullParseHandler.h @@ -133,7 +133,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) void prepareNodeForMutation(ParseNode* pn) { return allocator.prepareNodeForMutation(pn); } const Token& currentToken() { return tokenStream.currentToken(); } - ParseNode* newName(PropertyName* name, const TokenPos& pos, ExclusiveContext* cx) + NameNodeType newName(PropertyName* name, const TokenPos& pos, ExclusiveContext* cx) { return new_<NameNode>(PNK_NAME, JSOP_GETNAME, name, pos); } @@ -143,28 +143,24 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) return new_<UnaryNode>(PNK_COMPUTED_NAME, JSOP_NOP, pos, expr); } - ParseNode* newObjectLiteralPropertyName(JSAtom* atom, const TokenPos& pos) { - return new_<NullaryNode>(PNK_OBJECT_PROPERTY_NAME, JSOP_NOP, pos, atom); + NameNodeType newObjectLiteralPropertyName(JSAtom* atom, const TokenPos& pos) { + return new_<NameNode>(PNK_OBJECT_PROPERTY_NAME, JSOP_NOP, atom, pos); } - ParseNode* newNumber(double value, DecimalPoint decimalPoint, const TokenPos& pos) { - ParseNode* pn = new_<NullaryNode>(PNK_NUMBER, pos); - if (!pn) - return nullptr; - pn->initNumber(value, decimalPoint); - return pn; + NumericLiteralType newNumber(double value, DecimalPoint decimalPoint, const TokenPos& pos) { + return new_<NumericLiteral>(value, decimalPoint, pos); } ParseNode* newBooleanLiteral(bool cond, const TokenPos& pos) { return new_<BooleanLiteral>(cond, pos); } - ParseNode* newStringLiteral(JSAtom* atom, const TokenPos& pos) { - return new_<NullaryNode>(PNK_STRING, JSOP_NOP, pos, atom); + NameNodeType newStringLiteral(JSAtom* atom, const TokenPos& pos) { + return new_<NameNode>(PNK_STRING, JSOP_NOP, atom, pos); } - ParseNode* newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) { - return new_<NullaryNode>(PNK_TEMPLATE_STRING, JSOP_NOP, pos, atom); + NameNodeType newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) { + return new_<NameNode>(PNK_TEMPLATE_STRING, JSOP_NOP, atom, pos); } CallSiteNodeType newCallSiteObject(uint32_t begin) { @@ -211,7 +207,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) // Specifically, a Boxer has a .newObjectBox(T) method that accepts a // Rooted<RegExpObject*> argument and returns an ObjectBox*. template <class Boxer> - ParseNode* newRegExp(RegExpObject* reobj, const TokenPos& pos, Boxer& boxer) { + RegExpLiteralType newRegExp(RegExpObject* reobj, const TokenPos& pos, Boxer& boxer) { ObjectBox* objbox = boxer.newObjectBox(reobj); if (!objbox) return null(); @@ -421,11 +417,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) return true; } - MOZ_MUST_USE bool addShorthand(ListNodeType literal, ParseNode* name, ParseNode* expr) { + MOZ_MUST_USE bool addShorthand(ListNodeType literal, NameNodeType name, NameNodeType expr) { MOZ_ASSERT(literal->isKind(PNK_OBJECT)); MOZ_ASSERT(name->isKind(PNK_OBJECT_PROPERTY_NAME)); MOZ_ASSERT(expr->isKind(PNK_NAME)); - MOZ_ASSERT(name->pn_atom == expr->pn_atom); + MOZ_ASSERT(name->atom() == expr->atom()); literal->setHasNonConstInitializer(); BinaryNode* propdef = newBinary(PNK_SHORTHAND, name, expr, JSOP_INITPROP); @@ -446,7 +442,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) return true; } - MOZ_MUST_USE bool addObjectMethodDefinition(ListNodeType literal, Node key, Node fn, + MOZ_MUST_USE bool addObjectMethodDefinition(ListNodeType literal, Node key, CodeNodeType funNode, JSOp op) { MOZ_ASSERT(key->isKind(PNK_NUMBER) || @@ -455,14 +451,14 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) key->isKind(PNK_COMPUTED_NAME)); literal->setHasNonConstInitializer(); - ParseNode* propdef = newBinary(PNK_COLON, key, fn, op); + ParseNode* propdef = newBinary(PNK_COLON, key, funNode, op); if (!propdef) return false; literal->append(propdef); return true; } - MOZ_MUST_USE bool addClassMethodDefinition(ListNodeType methodList, Node key, Node fn, + MOZ_MUST_USE bool addClassMethodDefinition(ListNodeType methodList, Node key, CodeNodeType funNode, JSOp op, bool isStatic) { MOZ_ASSERT(methodList->isKind(PNK_CLASSMETHODLIST)); @@ -471,7 +467,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) key->isKind(PNK_STRING) || key->isKind(PNK_COMPUTED_NAME)); - ClassMethod* classMethod = new_<ClassMethod>(key, fn, op, isStatic); + ClassMethod* classMethod = new_<ClassMethod>(key, funNode, op, isStatic); if (!classMethod) return false; methodList->append(classMethod); @@ -679,7 +675,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) expr, body); } - ParseNode* newLabeledStatement(PropertyName* label, ParseNode* stmt, uint32_t begin) { + LabeledStatementType newLabeledStatement(PropertyName* label, Node stmt, uint32_t begin) { return new_<LabeledStatement>(label, stmt, begin); } @@ -698,11 +694,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) return new_<DebuggerStatement>(pos); } - ParseNode* newPropertyName(PropertyName* name, const TokenPos& pos) { + NameNodeType newPropertyName(PropertyName* name, const TokenPos& pos) { return new_<NameNode>(PNK_PROPERTYNAME, JSOP_NOP, name, pos); } - PropertyAccessType newPropertyAccess(Node expr, Node key) { + PropertyAccessType newPropertyAccess(Node expr, NameNodeType key) { return new_<PropertyAccess>(expr, key, expr->pn_pos.begin, key->pn_pos.end); } @@ -710,7 +706,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) return new_<PropertyByValue>(lhs, index, lhs->pn_pos.begin, end); } - ParseNode* newOptionalPropertyAccess(ParseNode* expr, ParseNode* key) { + ParseNode* newOptionalPropertyAccess(Node expr, NameNodeType key) { return new_<OptionalPropertyAccess>(expr, key, expr->pn_pos.begin, key->pn_pos.end); } @@ -722,8 +718,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) ParseNode* catchBinding, ParseNode* catchGuard, ParseNode* catchBody); - inline MOZ_MUST_USE bool setLastFunctionFormalParameterDefault(ParseNode* funcpn, - ParseNode* pn); + inline MOZ_MUST_USE bool setLastFunctionFormalParameterDefault(CodeNodeType funNode, + Node defaultValue); inline void setLastFunctionFormalParameterDestructuring(ParseNode* funcpn, ParseNode* pn); void checkAndSetIsDirectRHSAnonFunction(ParseNode* pn) { @@ -731,44 +727,44 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) pn->setDirectRHSAnonFunction(true); } - ParseNode* newFunctionStatement() { + CodeNodeType newFunctionStatement() { return new_<CodeNode>(PNK_FUNCTION, JSOP_NOP, pos()); } - ParseNode* newFunctionExpression() { + CodeNodeType newFunctionExpression() { return new_<CodeNode>(PNK_FUNCTION, JSOP_LAMBDA, pos()); } - ParseNode* newArrowFunction() { + CodeNodeType newArrowFunction() { return new_<CodeNode>(PNK_FUNCTION, JSOP_LAMBDA_ARROW, pos()); } - bool setComprehensionLambdaBody(ParseNode* pn, ParseNode* body) { + bool setComprehensionLambdaBody(CodeNodeType funNode, ListNodeType body) { MOZ_ASSERT(body->isKind(PNK_STATEMENTLIST)); - ParseNode* paramsBody = newList(PNK_PARAMSBODY, body); + ListNode* paramsBody = newList(PNK_PARAMSBODY, body); if (!paramsBody) return false; - setFunctionFormalParametersAndBody(pn, paramsBody); + setFunctionFormalParametersAndBody(funNode, paramsBody); return true; } - void setFunctionFormalParametersAndBody(ParseNode* pn, ParseNode* kid) { - MOZ_ASSERT_IF(kid, kid->isKind(PNK_PARAMSBODY)); - pn->pn_body = kid; + void setFunctionFormalParametersAndBody(CodeNodeType funNode, ListNodeType paramsBody) { + MOZ_ASSERT_IF(paramsBody, paramsBody->isKind(PNK_PARAMSBODY)); + funNode->setBody(paramsBody); } - void setFunctionBox(ParseNode* pn, FunctionBox* funbox) { - MOZ_ASSERT(pn->isKind(PNK_FUNCTION)); - pn->pn_funbox = funbox; - funbox->functionNode = pn; + void setFunctionBox(CodeNodeType funNode, FunctionBox* funbox) { + MOZ_ASSERT(funNode->isKind(PNK_FUNCTION)); + funNode->setFunbox(funbox); + funbox->functionNode = funNode; } - void addFunctionFormalParameter(ParseNode* pn, ParseNode* argpn) { - addList(/* list = */ &pn->pn_body->as<ListNode>(), /* child = */ argpn); + void addFunctionFormalParameter(CodeNodeType funNode, Node argpn) { + addList(/* list = */ funNode->body(), /* child = */ argpn); } - void setFunctionBody(ParseNode* fn, ParseNode* body) { - MOZ_ASSERT(fn->pn_body->isKind(PNK_PARAMSBODY)); - addList(/* list = */ &fn->pn_body->as<ListNode>(), /* child = */ body); + void setFunctionBody(CodeNodeType funNode, Node body) { + MOZ_ASSERT(funNode->body()->isKind(PNK_PARAMSBODY)); + addList(/* list = */ funNode->body(), /* child = */ body); } - ParseNode* newModule() { + CodeNodeType newModule() { return new_<CodeNode>(PNK_MODULE, JSOP_NOP, pos()); } @@ -827,7 +823,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) return node->isKind(PNK_SUPERBASE); } - inline MOZ_MUST_USE bool finishInitializerAssignment(ParseNode* pn, ParseNode* init); + inline MOZ_MUST_USE bool finishInitializerAssignment(NameNodeType nameNode, Node init); void setBeginPosition(ParseNode* pn, ParseNode* oth) { setBeginPosition(pn, oth->pn_pos.begin); @@ -909,12 +905,14 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) void setListHasNonConstInitializer(ListNodeType literal) { literal->setHasNonConstInitializer(); } - MOZ_MUST_USE ParseNode* parenthesize(ParseNode* pn) { - pn->setInParens(true); - return pn; + template <typename NodeType> + MOZ_MUST_USE NodeType parenthesize(NodeType node) { + node->setInParens(true); + return node; } - MOZ_MUST_USE ParseNode* setLikelyIIFE(ParseNode* pn) { - return parenthesize(pn); + template <typename NodeType> + MOZ_MUST_USE NodeType setLikelyIIFE(NodeType node) { + return parenthesize(node); } void setInDirectivePrologue(UnaryNodeType exprStmt) { exprStmt->setIsDirectivePrologueMember(); @@ -933,11 +931,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) } bool isArgumentsAnyParentheses(ParseNode* node, ExclusiveContext* cx) { - return node->isKind(PNK_NAME) && node->pn_atom == cx->names().arguments; + return node->isKind(PNK_NAME) && node->as<NameNode>().atom() == cx->names().arguments; } bool isEvalAnyParentheses(ParseNode* node, ExclusiveContext* cx) { - return node->isKind(PNK_NAME) && node->pn_atom == cx->names().eval; + return node->isKind(PNK_NAME) && node->as<NameNode>().atom() == cx->names().eval; } const char* nameIsArgumentsEvalAnyParentheses(ParseNode* node, ExclusiveContext* cx) { @@ -954,7 +952,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) bool isAsyncKeyword(ParseNode* node, ExclusiveContext* cx) { return node->isKind(PNK_NAME) && node->pn_pos.begin + strlen("async") == node->pn_pos.end && - node->pn_atom == cx->names().async; + node->as<NameNode>().atom() == cx->names().async; } bool isCall(ParseNode* pn) { @@ -1016,9 +1014,10 @@ FullParseHandler::addCatchBlock(ListNodeType catchList, ParseNode* lexicalScope, } inline bool -FullParseHandler::setLastFunctionFormalParameterDefault(ParseNode* funcpn, ParseNode* defaultValue) +FullParseHandler::setLastFunctionFormalParameterDefault(CodeNodeType funNode, Node defaultValue) { - ListNode* body = &funcpn->pn_body->as<ListNode>(); + MOZ_ASSERT(funNode->isKind(PNK_FUNCTION)); + ListNode* body = funNode->body(); ParseNode* arg = body->last(); ParseNode* pn = newBinary(PNK_ASSIGN, arg, defaultValue, JSOP_NOP); if (!pn) @@ -1032,13 +1031,16 @@ FullParseHandler::setLastFunctionFormalParameterDefault(ParseNode* funcpn, Parse } inline bool -FullParseHandler::finishInitializerAssignment(ParseNode* pn, ParseNode* init) +FullParseHandler::finishInitializerAssignment(NameNodeType nameNode, Node init) { - pn->pn_expr = init; - pn->setOp(JSOP_SETNAME); + MOZ_ASSERT(nameNode->isKind(PNK_NAME)); + MOZ_ASSERT(!nameNode->isInParens()); + + nameNode->setInitializer(init); + nameNode->setOp(JSOP_SETNAME); /* The declarator's position must include the initializer. */ - pn->pn_pos.end = init->pn_pos.end; + nameNode->pn_pos.end = init->pn_pos.end; return true; } diff --git a/js/src/frontend/NameFunctions.cpp b/js/src/frontend/NameFunctions.cpp index 9dbfb441f0..92a97ae8b7 100644 --- a/js/src/frontend/NameFunctions.cpp +++ b/js/src/frontend/NameFunctions.cpp @@ -79,12 +79,12 @@ class NameResolver return false; if (!*foundName) return true; - return appendPropertyReference(prop->right()->pn_atom); + return appendPropertyReference(prop->right()->as<NameNode>().atom()); } case PNK_NAME: *foundName = true; - return buf->append(n->pn_atom); + return buf->append(n->as<NameNode>().atom()); case PNK_THIS: *foundName = true; @@ -105,7 +105,7 @@ class NameResolver case PNK_NUMBER: *foundName = true; - return appendNumber(n->pn_dval); + return appendNumber(n->as<NumericLiteral>().value()); default: /* We're confused as to what to call this function. */ @@ -190,11 +190,10 @@ class NameResolver * listed, then it is skipped. Otherwise an intelligent name is guessed to * assign to the function's displayAtom field. */ - bool resolveFun(ParseNode* pn, HandleAtom prefix, MutableHandleAtom retAtom) { - MOZ_ASSERT(pn != nullptr); - MOZ_ASSERT(pn->isKind(PNK_FUNCTION)); - MOZ_ASSERT(pn->isArity(PN_CODE)); - RootedFunction fun(cx, pn->pn_funbox->function()); + bool resolveFun(CodeNode* funNode, HandleAtom prefix, MutableHandleAtom retAtom) { + MOZ_ASSERT(funNode != nullptr); + MOZ_ASSERT(funNode->isKind(PNK_FUNCTION)); + RootedFunction fun(cx, funNode->funbox()->function()); StringBuffer buf(cx); this->buf = &buf; @@ -246,10 +245,10 @@ class NameResolver if (node->isKind(PNK_COLON) || node->isKind(PNK_SHORTHAND)) { ParseNode* left = node->as<BinaryNode>().left(); if (left->isKind(PNK_OBJECT_PROPERTY_NAME) || left->isKind(PNK_STRING)) { - if (!appendPropertyReference(left->pn_atom)) + if (!appendPropertyReference(left->as<NameNode>().atom())) return false; } else if (left->isKind(PNK_NUMBER)) { - if (!appendNumericPropertyReference(left->pn_dval)) + if (!appendNumericPropertyReference(left->as<NumericLiteral>().value())) return false; } else { MOZ_ASSERT(left->isKind(PNK_COMPUTED_NAME)); @@ -360,10 +359,10 @@ class NameResolver if (cur == nullptr) return true; - MOZ_ASSERT((cur->isKind(PNK_FUNCTION) || cur->isKind(PNK_MODULE)) == cur->isArity(PN_CODE)); + MOZ_ASSERT((cur->isKind(PNK_FUNCTION) || cur->isKind(PNK_MODULE)) == cur->is<CodeNode>()); if (cur->isKind(PNK_FUNCTION)) { RootedAtom prefix2(cx); - if (!resolveFun(cur, prefix, &prefix2)) + if (!resolveFun(&cur->as<CodeNode>(), prefix, &prefix2)) return false; /* @@ -383,29 +382,39 @@ class NameResolver // Nodes with no children that might require name resolution need no // further work. case PNK_NOP: - case PNK_STRING: - case PNK_TEMPLATE_STRING: - case PNK_REGEXP: case PNK_TRUE: case PNK_FALSE: case PNK_NULL: case PNK_RAW_UNDEFINED: case PNK_ELISION: case PNK_GENERATOR: - case PNK_NUMBER: case PNK_BREAK: case PNK_CONTINUE: case PNK_DEBUGGER: case PNK_EXPORT_BATCH_SPEC: - case PNK_OBJECT_PROPERTY_NAME: case PNK_POSHOLDER: MOZ_ASSERT(cur->isArity(PN_NULLARY)); break; + case PNK_OBJECT_PROPERTY_NAME: + case PNK_STRING: + case PNK_TEMPLATE_STRING: + MOZ_ASSERT(cur->is<NameNode>()); + break; + + case PNK_REGEXP: + MOZ_ASSERT(cur->is<RegExpLiteral>()); + break; + + case PNK_NUMBER: + MOZ_ASSERT(cur->is<NumericLiteral>()); + break; + + case PNK_TYPEOFNAME: case PNK_SUPERBASE: MOZ_ASSERT(cur->as<UnaryNode>().kid()->isKind(PNK_NAME)); - MOZ_ASSERT(!cur->as<UnaryNode>().kid()->expr()); + MOZ_ASSERT(!cur->as<UnaryNode>().kid()->as<NameNode>().initializer()); break; case PNK_NEWTARGET: { @@ -612,14 +621,14 @@ class NameResolver #ifdef DEBUG if (classNode->names()) { ClassNames* names = classNode->names(); - if (ParseNode* outerBinding = names->outerBinding()) { + if (NameNode* outerBinding = names->outerBinding()) { MOZ_ASSERT(outerBinding->isKind(PNK_NAME)); - MOZ_ASSERT(!outerBinding->expr()); + MOZ_ASSERT(!outerBinding->initializer()); } - ParseNode* innerBinding = names->innerBinding(); + NameNode* innerBinding = names->innerBinding(); MOZ_ASSERT(innerBinding->isKind(PNK_NAME)); - MOZ_ASSERT(!innerBinding->expr()); + MOZ_ASSERT(!innerBinding->initializer()); } #endif if (ParseNode* heritage = classNode->heritage()) { @@ -799,9 +808,9 @@ class NameResolver BinaryNode* spec = &item->as<BinaryNode>(); MOZ_ASSERT(spec->isKind(isImport ? PNK_IMPORT_SPEC : PNK_EXPORT_SPEC)); MOZ_ASSERT(spec->left()->isKind(PNK_NAME)); - MOZ_ASSERT(!spec->left()->expr()); + MOZ_ASSERT(!spec->left()->as<NameNode>().initializer()); MOZ_ASSERT(spec->right()->isKind(PNK_NAME)); - MOZ_ASSERT(!spec->right()->expr()); + MOZ_ASSERT(!spec->right()->as<NameNode>().initializer()); } #endif break; @@ -832,15 +841,15 @@ class NameResolver } case PNK_LABEL: - MOZ_ASSERT(cur->isArity(PN_NAME)); - if (!resolve(cur->expr(), prefix)) + if (!resolve(cur->as<LabeledStatement>().statement(), prefix)) return false; break; case PNK_NAME: - MOZ_ASSERT(cur->isArity(PN_NAME)); - if (!resolve(cur->expr(), prefix)) - return false; + if (ParseNode* init = cur->as<NameNode>().initializer()) { + if (!resolve(init, prefix)) + return false; + } break; case PNK_LEXICALSCOPE: @@ -851,9 +860,10 @@ class NameResolver case PNK_FUNCTION: case PNK_MODULE: - MOZ_ASSERT(cur->isArity(PN_CODE)); - if (!resolve(cur->pn_body, prefix)) - return false; + if (ParseNode* body = cur->as<CodeNode>().body()) { + if (!resolve(body, prefix)) + return false; + } break; // Kinds that should be handled by parent node resolution. diff --git a/js/src/frontend/ParseNode-inl.h b/js/src/frontend/ParseNode-inl.h index f10920e9a5..0b8c87f929 100644 --- a/js/src/frontend/ParseNode-inl.h +++ b/js/src/frontend/ParseNode-inl.h @@ -17,17 +17,12 @@ inline PropertyName* ParseNode::name() const { MOZ_ASSERT(isKind(PNK_FUNCTION) || isKind(PNK_NAME)); - JSAtom* atom = isKind(PNK_FUNCTION) ? pn_funbox->function()->explicitName() : pn_atom; + JSAtom* atom = isKind(PNK_FUNCTION) + ? as<CodeNode>().funbox()->function()->explicitName() + : as<NameNode>().atom(); return atom->asPropertyName(); } -inline JSAtom* -ParseNode::atom() const -{ - MOZ_ASSERT(isKind(PNK_STRING)); - return pn_atom; -} - } /* namespace frontend */ } /* namespace js */ diff --git a/js/src/frontend/ParseNode.cpp b/js/src/frontend/ParseNode.cpp index 4cdf6bde05..5b1a838c47 100644 --- a/js/src/frontend/ParseNode.cpp +++ b/js/src/frontend/ParseNode.cpp @@ -94,7 +94,7 @@ class NodeStack { enum class PushResult { Recyclable, CleanUpLater }; static PushResult -PushCodeNodeChildren(ParseNode* node, NodeStack* stack) +PushCodeNodeChildren(CodeNode* node, NodeStack* stack) { MOZ_ASSERT(node->isArity(PN_CODE)); @@ -108,29 +108,27 @@ PushCodeNodeChildren(ParseNode* node, NodeStack* stack) * * In fact, we can't recycle the parse node yet, either: it may appear * on a method list, and reusing the node would corrupt that. Instead, - * we clear its pn_funbox pointer to mark it as deleted; + * we clear its funbox pointer to mark it as deleted; * CleanFunctionList recycles it as well. * * We do recycle the nodes around it, though, so we must clear pointers * to them to avoid leaving dangling references where someone can find * them. */ - node->pn_funbox = nullptr; - if (node->pn_body) - stack->push(node->pn_body); - node->pn_body = nullptr; + node->setFunbox(nullptr); + if (node->body()) + stack->push(node->body()); + node->setBody(nullptr); return PushResult::CleanUpLater; } static PushResult -PushNameNodeChildren(ParseNode* node, NodeStack* stack) +PushNameNodeChildren(NameNode* node, NodeStack* stack) { - MOZ_ASSERT(node->isArity(PN_NAME)); - - if (node->pn_expr) - stack->push(node->pn_expr); - node->pn_expr = nullptr; + if (node->initializer()) + stack->push(node->initializer()); + node->setInitializer(nullptr); return PushResult::Recyclable; } @@ -179,25 +177,34 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack) // Trivial nodes that refer to no nodes, are referred to by nothing // but their parents, are never used, and are never a definition. case PNK_NOP: - case PNK_STRING: - case PNK_TEMPLATE_STRING: - case PNK_REGEXP: case PNK_TRUE: case PNK_FALSE: case PNK_NULL: case PNK_RAW_UNDEFINED: case PNK_ELISION: case PNK_GENERATOR: - case PNK_NUMBER: case PNK_BREAK: case PNK_CONTINUE: case PNK_DEBUGGER: case PNK_EXPORT_BATCH_SPEC: - case PNK_OBJECT_PROPERTY_NAME: case PNK_POSHOLDER: MOZ_ASSERT(pn->isArity(PN_NULLARY)); return PushResult::Recyclable; + case PNK_OBJECT_PROPERTY_NAME: + case PNK_STRING: + case PNK_TEMPLATE_STRING: + MOZ_ASSERT(pn->is<NameNode>()); + return PushResult::Recyclable; + + case PNK_REGEXP: + MOZ_ASSERT(pn->is<RegExpLiteral>()); + return PushResult::Recyclable; + + case PNK_NUMBER: + MOZ_ASSERT(pn->is<NumericLiteral>()); + return PushResult::Recyclable; + // Nodes with a single non-null child. case PNK_TYPEOFNAME: case PNK_TYPEOFEXPR: @@ -489,14 +496,14 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack) case PNK_LABEL: case PNK_NAME: case PNK_PROPERTYNAME: - return PushNameNodeChildren(pn, stack); + return PushNameNodeChildren(&pn->as<NameNode>(), stack); case PNK_LEXICALSCOPE: return PushScopeNodeChildren(pn, stack); case PNK_FUNCTION: case PNK_MODULE: - return PushCodeNodeChildren(pn, stack); + return PushCodeNodeChildren(&pn->as<CodeNode>(), stack); case PNK_LIMIT: // invalid sentinel value MOZ_CRASH("invalid node kind"); @@ -656,33 +663,37 @@ ParseNode::dump(int indent) switch (pn_arity) { case PN_NULLARY: ((NullaryNode*) this)->dump(); - break; + return; case PN_UNARY: as<UnaryNode>().dump(indent); - break; + return; case PN_BINARY: as<BinaryNode>().dump(indent); - break; + return; case PN_TERNARY: as<TernaryNode>().dump(indent); - break; + return; case PN_CODE: - ((CodeNode*) this)->dump(indent); - break; + as<CodeNode>().dump(indent); + return; case PN_LIST: as<ListNode>().dump(indent); - break; + return; case PN_NAME: - ((NameNode*) this)->dump(indent); - break; + as<NameNode>().dump(indent); + return; + case PN_NUMBER: + as<NumericLiteral>().dump(indent); + return; + case PN_REGEXP: + as<RegExpLiteral>().dump(indent); + return; case PN_SCOPE: ((LexicalScopeNode*) this)->dump(indent); - break; - default: - fprintf(stderr, "#<BAD NODE %p, kind=%u, arity=%u>", - (void*) this, unsigned(getKind()), unsigned(pn_arity)); - break; + return; } + fprintf(stderr, "#<BAD NODE %p, kind=%u, arity=%u>", + (void*) this, unsigned(getKind()), unsigned(pn_arity)); } void @@ -694,28 +705,33 @@ NullaryNode::dump() case PNK_NULL: fprintf(stderr, "#null"); break; case PNK_RAW_UNDEFINED: fprintf(stderr, "#undefined"); break; - case PNK_NUMBER: { - ToCStringBuf cbuf; - const char* cstr = NumberToCString(nullptr, &cbuf, pn_dval); - if (!IsFinite(pn_dval)) - fputc('#', stderr); - if (cstr) - fprintf(stderr, "%s", cstr); - else - fprintf(stderr, "%g", pn_dval); - break; - } - - case PNK_STRING: - pn_atom->dumpCharsNoNewline(); - break; - default: fprintf(stderr, "(%s)", parseNodeNames[getKind()]); } } void +NumericLiteral::dump(int indent) +{ + ToCStringBuf cbuf; + const char* cstr = NumberToCString(nullptr, &cbuf, value()); + if (!IsFinite(value())) { + fprintf(stderr, "#"); + } + if (cstr) { + fprintf(stderr, "%s", cstr); + } else { + fprintf(stderr, "%g", value()); + } +} + +void +RegExpLiteral::dump(int indent) +{ + fprintf(stderr, "(%s)", parseNodeNames[size_t(getKind())]); +} + +void UnaryNode::dump(int indent) { const char* name = parseNodeNames[getKind()]; @@ -772,7 +788,7 @@ CodeNode::dump(int indent) const char* name = parseNodeNames[getKind()]; fprintf(stderr, "(%s ", name); indent += strlen(name) + 2; - DumpParseTree(pn_body, indent); + DumpParseTree(body(), indent); fprintf(stderr, ")"); } @@ -813,29 +829,53 @@ DumpName(const CharT* s, size_t len) void NameNode::dump(int indent) { - if (isKind(PNK_NAME) || isKind(PNK_PROPERTYNAME)) { - if (!pn_atom) { + switch (getKind()) { + case PNK_STRING: + case PNK_TEMPLATE_STRING: + case PNK_OBJECT_PROPERTY_NAME: { + atom()->dumpCharsNoNewline(); + return; + } + + case PNK_NAME: + case PNK_PROPERTYNAME: { + if (!atom()) { fprintf(stderr, "#<null name>"); - } else if (getOp() == JSOP_GETARG && pn_atom->length() == 0) { + } else if (getOp() == JSOP_GETARG && atom()->length() == 0) { // Dump destructuring parameter. - fprintf(stderr, "(#<zero-length name> "); - DumpParseTree(expr(), indent + 21); + static const char ZeroLengthPrefix[] = "(#<zero-length name> "; + fprintf(stderr, ZeroLengthPrefix); + DumpParseTree(initializer(), indent + strlen(ZeroLengthPrefix)); fputc(')', stderr); } else { JS::AutoCheckCannotGC nogc; - if (pn_atom->hasLatin1Chars()) - DumpName(pn_atom->latin1Chars(nogc), pn_atom->length()); + if (atom()->hasLatin1Chars()) + DumpName(atom()->latin1Chars(nogc), atom()->length()); else - DumpName(pn_atom->twoByteChars(nogc), pn_atom->length()); + DumpName(atom()->twoByteChars(nogc), atom()->length()); } return; - } + } - const char* name = parseNodeNames[getKind()]; - fprintf(stderr, "(%s ", name); - indent += strlen(name) + 2; - DumpParseTree(expr(), indent); - fprintf(stderr, ")"); + case PNK_LABEL: { + const char* name = parseNodeNames[getKind()]; + fprintf(stderr, "(%s ", name); + atom()->dumpCharsNoNewline(); + indent += strlen(name) + atom()->length() + 2; + DumpParseTree(initializer(), indent); + fprintf(stderr, ")"); + return; + } + + default: { + const char* name = parseNodeNames[getKind()]; + fprintf(stderr, "(%s ", name); + indent += strlen(name) + 2; + DumpParseTree(initializer(), indent); + fprintf(stderr, ")"); + return; + } + } } void @@ -920,7 +960,8 @@ js::frontend::IsAnonymousFunctionDefinition(ParseNode* pn) // 14.1.12 (FunctionExpression). // 14.4.8 (GeneratorExpression). // 14.6.8 (AsyncFunctionExpression) - if (pn->isKind(PNK_FUNCTION) && !pn->pn_funbox->function()->explicitName()) + if (pn->isKind(PNK_FUNCTION) && + !pn->as<CodeNode>().funbox()->function()->explicitName()) return true; // 14.5.8 (ClassExpression) diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h index d21c4c6c20..f00e370e6f 100644 --- a/js/src/frontend/ParseNode.h +++ b/js/src/frontend/ParseNode.h @@ -221,21 +221,21 @@ IsTypeofKind(ParseNodeKind kind) /* * <Definitions> - * PNK_FUNCTION name pn_funbox: ptr to js::FunctionBox holding function - * object containing arg and var properties. We - * create the function object at parse (not emit) - * time to specialize arg and var bytecodes early. - * pn_body: PNK_PARAMSBODY, ordinarily; - * PNK_LEXICALSCOPE for implicit function in genexpr + * PNK_FUNCTION (CodeNode) + * funbox: ptr to js::FunctionBox holding function object containing arg and + * var properties. We create the function object at parse (not emit) + * time to specialize arg and var bytecodes early. + * body: PNK_PARAMSBODY or null for lazily-parsed function, ordinarily; + * PNK_LEXICALSCOPE for implicit function in genexpr * PNK_PARAMSBODY (ListNode) * head: list of formal parameters with * * Name node with non-empty name for SingleNameBinding without * Initializer * * Assign node for SingleNameBinding with Initializer * * Name node with empty name for destructuring - * pn_expr: Array or Object for BindingPattern without - * Initializer, Assign for BindingPattern with - * Initializer + * expr: Array or Object for BindingPattern without + * Initializer, Assign for BindingPattern with + * Initializer * followed by either: * * StatementList node for function body statements * * Return for expression closure @@ -259,6 +259,9 @@ IsTypeofKind(ParseNodeKind kind) * PNK_CLASSMETHOD (ClassMethod) * name: propertyName * method: methodDefinition + * PNK_MODULE (CodeNode) + * funbox: ? + * body: ? * * <Statements> * PNK_STATEMENTLIST (ListNode) @@ -310,31 +313,29 @@ IsTypeofKind(ParseNodeKind kind) * kid2: null or PNK_CATCHLIST list * kid3: null or finally block * PNK_CATCHLIST list pn_head: list of PNK_LEXICALSCOPE nodes, one per - * catch-block, each with pn_expr pointing + * catch-block, each with scopeBody pointing * to a PNK_CATCH node * PNK_CATCH (TernaryNode) * kid1: PNK_NAME, PNK_ARRAY, or PNK_OBJECT catch binding node (PNK_ARRAY or PNK_OBJECT if destructuring) or null if optional catch binding * kid2: null or the catch guard expression * kid3: catch block statements - * PNK_BREAK name pn_atom: label or null - * PNK_CONTINUE name pn_atom: label or null + * PNK_BREAK (BreakStatement) + * atom: label or null + * PNK_CONTINUE (ContinueStatement) + * atom: label or null * PNK_WITH (BinaryNode) * left: head expr * right: body * PNK_VAR, PNK_LET, PNK_CONST (ListNode) * head: list of N Name or Assign nodes * each name node has either - * pn_used: false - * pn_atom: variable name - * pn_expr: initializer or null + * atom: variable name + * expr: initializer or null * or - * pn_used: true - * pn_atom: variable name - * pn_lexdef: def node + * atom: variable name * each assignment node has - * left: Name with pn_used true and - * pn_lexdef (NOT pn_expr) set + * left: pattern * right: initializer * count: N > 0 * PNK_RETURN (UnaryNode) @@ -343,7 +344,11 @@ IsTypeofKind(ParseNodeKind kind) * kid: expr * prologue: true if Directive Prologue member in original source, not * introduced via constant folding or other tree rewriting - * PNK_LABEL name pn_atom: label, pn_expr: labeled statement + * PNK_NOP (NullaryNode) + * (no fields) + * PNK_LABEL (LabeledStatement) + * atom: label + * expr: labeled statement * PNK_IMPORT (BinaryNode) * left: PNK_IMPORT_SPEC_LIST import specifiers * right: PNK_STRING module specifier @@ -434,7 +439,8 @@ IsTypeofKind(ParseNodeKind kind) * contains are nullish. An optional chain can also * contain nodes such as PNK_DOT, PNK_ELEM, PNK_NAME, * PNK_CALL, etc. These are evaluated normally. - * PNK_PROPERTYNAME name pn_atom: property being accessed + * PNK_PROPERTYNAME (NameNode) + * atom: property name being accessed * PNK_DOT, PNK_OPTDOT (PropertyAccess) short circuits back to PNK_OPTCHAIN if nullish. * left: MEMBER expr to left of '.' * right: PropertyName to right of '.' @@ -472,17 +478,20 @@ IsTypeofKind(ParseNodeKind kind) * ES6 ComputedPropertyName. * kid: the AssignmentExpression inside the square brackets * pn_kid: the AssignmentExpression inside the square brackets - * PNK_NAME, name pn_atom: name, string, or object atom - * PNK_STRING pn_op: JSOP_GETNAME, JSOP_STRING, or JSOP_OBJECT - * If JSOP_GETNAME, pn_op may be JSOP_*ARG or JSOP_*VAR - * telling const-ness and static analysis results + * PNK_NAME (NameNode) + * atom: name, or object atom + * pn_op: JSOP_GETNAME, JSOP_STRING, or JSOP_OBJECT + * If JSOP_GETNAME, pn_op may be JSOP_*ARG or JSOP_*VAR telling + * const-ness and static analysis results + * PNK_STRING (NameNode) + * atom: string * PNK_TEMPLATE_STRING_LIST (ListNode) * head: list of alternating expr and template strings * TemplateString [, expression, TemplateString]+ * there's at least one expression. If the template literal contains * no ${}-delimited expression, it's parsed as a single TemplateString - * PNK_TEMPLATE_STRING pn_atom: template string atom - nullary pn_op: JSOP_NOP + * PNK_TEMPLATE_STRING (NameNode) + * atom: template string atom * PNK_TAGGED_TEMPLATE (BinaryNode) * left: tag expression * right: Arguments, with the first being the call site object, then @@ -493,8 +502,10 @@ IsTypeofKind(ParseNodeKind kind) * Array [, cooked TemplateString]+ * where the Array is * [raw TemplateString]+ - * PNK_REGEXP nullary pn_objbox: RegExp model object - * PNK_NUMBER dval pn_dval: double value of numeric literal + * PNK_REGEXP (RegExpLiteral) + * regexp: RegExp model object + * PNK_NUMBER (NumericLiteral) + * value: double value of numeric literal * PNK_TRUE, nullary pn_op: JSOp bytecode * PNK_FALSE, * PNK_NULL, @@ -528,13 +539,15 @@ IsTypeofKind(ParseNodeKind kind) */ enum ParseNodeArity { - PN_NULLARY, /* 0 kids, only pn_atom/pn_dval/etc. */ + PN_NULLARY, /* 0 kids */ PN_UNARY, /* one kid, plus a couple of scalars */ PN_BINARY, /* two kids, plus a couple of scalars */ PN_TERNARY, /* three kids */ PN_CODE, /* module or function definition node */ PN_LIST, /* generic singly linked list */ - PN_NAME, /* name, label, or regexp */ + PN_NAME, /* name, label, string */ + PN_NUMBER, /* numeric literal */ + PN_REGEXP, /* regexp literal */ PN_SCOPE /* lexical scope */ }; @@ -549,9 +562,18 @@ enum ParseNodeArity macro(PropertyByValue, PropertyByValueType, asPropertyByValue) \ macro(SwitchStatement, SwitchStatementType, asSwitchStatement) \ \ + macro(CodeNode, CodeNodeType, asCode) \ + \ macro(ListNode, ListNodeType, asList) \ macro(CallSiteNode, CallSiteNodeType, asCallSite) \ \ + macro(NameNode, NameNodeType, asName) \ + macro(LabeledStatement, LabeledStatementType, asLabeledStatement) \ + \ + macro(NumericLiteral, NumericLiteralType, asNumericLiteral) \ + \ + macro(RegExpLiteral, RegExpLiteralType, asRegExpLiteral) \ + \ macro(TernaryNode, TernaryNodeType, asTernary) \ macro(ClassNode, ClassNodeType, asClass) \ macro(ConditionalExpression, ConditionalExpressionType, asConditionalExpression) \ @@ -683,19 +705,30 @@ class ParseNode bool prologue; /* directive prologue member */ } unary; struct { /* name, labeled statement, etc. */ - union { - JSAtom* atom; /* lexical name or label atom */ - ObjectBox* objbox; /* regexp object */ - FunctionBox* funbox; /* function object */ - }; - ParseNode* expr; /* module or function body, var - initializer, or argument default */ + private: + friend class NameNode; + JSAtom* atom; /* lexical name or label atom */ + ParseNode* initOrStmt; /* var initializer, argument default, + * or label statement target */ } name; struct { + private: + friend class RegExpLiteral; + ObjectBox* objbox; + } regexp; + struct { + private: + friend class CodeNode; + FunctionBox* funbox; /* function object */ + ParseNode* body; /* module or function body */ + } code; + struct { LexicalScope::Data* bindings; ParseNode* body; } scope; struct { + private: + friend class NumericLiteral; double value; /* aligned numeric literal value */ DecimalPoint decimalPoint; /* Whether the number has a decimal point */ } number; @@ -705,15 +738,6 @@ class ParseNode } loopControl; } pn_u; -#define pn_objbox pn_u.name.objbox -#define pn_funbox pn_u.name.funbox -#define pn_body pn_u.name.expr -#define pn_atom pn_u.name.atom -#define pn_objbox pn_u.name.objbox -#define pn_expr pn_u.name.expr -#define pn_dval pn_u.number.value - - public: /* * If |left| is a list of the given kind/left-associative op, append @@ -724,12 +748,6 @@ class ParseNode FullParseHandler* handler, ParseContext* pc); inline PropertyName* name() const; - inline JSAtom* atom() const; - - ParseNode* expr() const { - MOZ_ASSERT(pn_arity == PN_NAME || pn_arity == PN_CODE); - return pn_expr; - } bool isEmptyScope() const { MOZ_ASSERT(pn_arity == PN_SCOPE); @@ -753,18 +771,6 @@ class ParseNode pn_u.scope.body = body; } - bool functionIsHoisted() const { - MOZ_ASSERT(pn_arity == PN_CODE && getKind() == PNK_FUNCTION); - MOZ_ASSERT(isOp(JSOP_LAMBDA) || // lambda, genexpr - isOp(JSOP_LAMBDA_ARROW) || // arrow function - isOp(JSOP_DEFFUN) || // non-body-level function statement - isOp(JSOP_NOP) || // body-level function stmt in global code - isOp(JSOP_GETLOCAL) || // body-level function stmt in function code - isOp(JSOP_GETARG) || // body-level function redeclaring formal - isOp(JSOP_INITLEXICAL)); // block-level function stmt - return !isOp(JSOP_LAMBDA) && !isOp(JSOP_LAMBDA_ARROW) && !isOp(JSOP_DEFFUN); - } - /* True if pn is a parsenode representing a literal constant. */ bool isLiteral() const { return isKind(PNK_NUMBER) || @@ -778,13 +784,6 @@ class ParseNode // True iff this is a for-in/of loop variable declaration (var/let/const). bool isForLoopDeclaration() const; - void initNumber(double value, DecimalPoint decimalPoint) { - MOZ_ASSERT(pn_arity == PN_NULLARY); - MOZ_ASSERT(getKind() == PNK_NUMBER); - pn_u.number.value = value; - pn_u.number.decimalPoint = decimalPoint; - } - enum AllowConstantObjects { DontAllowObjects = 0, AllowObjects, @@ -827,18 +826,57 @@ struct NullaryNode : public ParseNode NullaryNode(ParseNodeKind kind, JSOp op, const TokenPos& pos) : ParseNode(kind, op, PN_NULLARY, pos) {} - // This constructor is for a few mad uses in the emitter. It populates - // the pn_atom field even though that field belongs to a branch in pn_u - // that nullary nodes shouldn't use -- bogus. - NullaryNode(ParseNodeKind kind, JSOp op, const TokenPos& pos, JSAtom* atom) - : ParseNode(kind, op, PN_NULLARY, pos) +#ifdef DEBUG + void dump(); +#endif +}; + +class NameNode : public ParseNode +{ + protected: + NameNode(ParseNodeKind kind, JSOp op, JSAtom* atom, ParseNode* initOrStmt, const TokenPos& pos) + : ParseNode(kind, op, PN_NAME, pos) + { + pn_u.name.atom = atom; + pn_u.name.initOrStmt = initOrStmt; + } + + public: + NameNode(ParseNodeKind kind, JSOp op, JSAtom* atom, const TokenPos& pos) + : ParseNode(kind, op, PN_NAME, pos) { - pn_atom = atom; + pn_u.name.atom = atom; + pn_u.name.initOrStmt = nullptr; + } + + static bool test(const ParseNode& node) { + return node.isArity(PN_NAME); } #ifdef DEBUG - void dump(); + void dump(int indent); #endif + + JSAtom* atom() const { + return pn_u.name.atom; + } + + ParseNode* initializer() const { + return pn_u.name.initOrStmt; + } + + void setAtom(JSAtom* atom) { + pn_u.name.atom = atom; + } + + void setInitializer(ParseNode* init) { + pn_u.name.initOrStmt = init; + } + + // Methods used by FoldConstants.cpp. + ParseNode** unsafeInitializerReference() { + return &pn_u.name.initOrStmt; + } }; class UnaryNode : public ParseNode @@ -889,7 +927,7 @@ class UnaryNode : public ParseNode if (isKind(PNK_SEMI)) { ParseNode* expr = kid(); if (expr && expr->isKind(PNK_STRING) && !expr->isInParens()) { - return expr->pn_atom; + return kid()->as<NameNode>().atom(); } } return nullptr; @@ -1378,8 +1416,9 @@ ParseNode::isForLoopDeclaration() const return false; } -struct CodeNode : public ParseNode +class CodeNode : public ParseNode { + public: CodeNode(ParseNodeKind kind, JSOp op, const TokenPos& pos) : ParseNode(kind, op, PN_CODE, pos) { @@ -1388,32 +1427,85 @@ struct CodeNode : public ParseNode MOZ_ASSERT(op == JSOP_NOP || // statement, module op == JSOP_LAMBDA_ARROW || // arrow function op == JSOP_LAMBDA); // expression, method, comprehension, accessor, &c. - MOZ_ASSERT(!pn_body); - MOZ_ASSERT(!pn_objbox); + MOZ_ASSERT(!pn_u.code.body); + MOZ_ASSERT(!pn_u.code.funbox); + } + + static bool test(const ParseNode& node) { + bool match = node.isKind(PNK_FUNCTION) || node.isKind(PNK_MODULE); + MOZ_ASSERT_IF(match, node.isArity(PN_CODE)); + return match; } - public: #ifdef DEBUG void dump(int indent); #endif + + FunctionBox* funbox() const { + return pn_u.code.funbox; + } + + ListNode* body() const { + return pn_u.code.body ? &pn_u.code.body->as<ListNode>() : nullptr; + } + + void setFunbox(FunctionBox* funbox) { + pn_u.code.funbox = funbox; + } + + void setBody(ListNode* body) { + pn_u.code.body = body; + } + + // Methods used by FoldConstants.cpp. + ParseNode** unsafeBodyReference() { + return &pn_u.code.body; + } + + bool functionIsHoisted() const { + MOZ_ASSERT(isKind(PNK_FUNCTION)); + MOZ_ASSERT(isOp(JSOP_LAMBDA) || // lambda + isOp(JSOP_LAMBDA_ARROW) || // arrow function + isOp(JSOP_DEFFUN) || // non-body-level function statement + isOp(JSOP_NOP) || // body-level function stmt in global code + isOp(JSOP_GETLOCAL) || // body-level function stmt in function code + isOp(JSOP_GETARG) || // body-level function redeclaring formal + isOp(JSOP_INITLEXICAL)); // block-level function stmt + return !isOp(JSOP_LAMBDA) && !isOp(JSOP_LAMBDA_ARROW) && !isOp(JSOP_DEFFUN); + } }; -struct NameNode : public ParseNode +class NumericLiteral : public ParseNode { - NameNode(ParseNodeKind kind, JSOp op, JSAtom* atom, const TokenPos& pos) - : ParseNode(kind, op, PN_NAME, pos) + public: + NumericLiteral(double value, DecimalPoint decimalPoint, const TokenPos& pos) + : ParseNode(PNK_NUMBER, JSOP_NOP, PN_NUMBER, pos) { - pn_atom = atom; - pn_expr = nullptr; + pn_u.number.value = value; + pn_u.number.decimalPoint = decimalPoint; } static bool test(const ParseNode& node) { - return node.isArity(PN_NAME); + bool match = node.isKind(PNK_NUMBER); + MOZ_ASSERT_IF(match, node.isArity(PN_NUMBER)); + return match; } #ifdef DEBUG void dump(int indent); #endif + + double value() const { + return pn_u.number.value; + } + + DecimalPoint decimalPoint() const { + return pn_u.number.decimalPoint; + } + + void setValue(double v) { + pn_u.number.value = v; + } }; struct LexicalScopeNode : public ParseNode @@ -1434,22 +1526,19 @@ struct LexicalScopeNode : public ParseNode #endif }; -class LabeledStatement : public ParseNode +class LabeledStatement : public NameNode { public: LabeledStatement(PropertyName* label, ParseNode* stmt, uint32_t begin) - : ParseNode(PNK_LABEL, JSOP_NOP, PN_NAME, TokenPos(begin, stmt->pn_pos.end)) - { - pn_atom = label; - pn_expr = stmt; - } + : NameNode(PNK_LABEL, JSOP_NOP, label, stmt, TokenPos(begin, stmt->pn_pos.end)) + { } PropertyName* label() const { - return pn_atom->asPropertyName(); + return atom()->asPropertyName(); } ParseNode* statement() const { - return pn_expr; + return initializer(); } static bool test(const ParseNode& node) { @@ -1458,6 +1547,11 @@ class LabeledStatement : public ParseNode MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP)); return match; } + + // Methods used by FoldConstants.cpp. + ParseNode** unsafeStatementReference() { + return unsafeInitializerReference(); + } }; // Inside a switch statement, a CaseClause is a case-label and the subsequent @@ -1597,44 +1691,52 @@ class ThisLiteral : public UnaryNode } }; -class NullLiteral : public ParseNode +class NullLiteral : public NullaryNode { public: - explicit NullLiteral(const TokenPos& pos) : ParseNode(PNK_NULL, JSOP_NULL, PN_NULLARY, pos) { } + explicit NullLiteral(const TokenPos& pos) + : NullaryNode(PNK_NULL, JSOP_NULL, pos) + { } }; // This is only used internally, currently just for tagged templates. // It represents the value 'undefined' (aka `void 0`), like NullLiteral // represents the value 'null'. -class RawUndefinedLiteral : public ParseNode +class RawUndefinedLiteral : public NullaryNode { public: explicit RawUndefinedLiteral(const TokenPos& pos) - : ParseNode(PNK_RAW_UNDEFINED, JSOP_UNDEFINED, PN_NULLARY, pos) { } + : NullaryNode(PNK_RAW_UNDEFINED, JSOP_UNDEFINED, pos) { } }; -class BooleanLiteral : public ParseNode +class BooleanLiteral : public NullaryNode { public: BooleanLiteral(bool b, const TokenPos& pos) - : ParseNode(b ? PNK_TRUE : PNK_FALSE, b ? JSOP_TRUE : JSOP_FALSE, PN_NULLARY, pos) + : NullaryNode(b ? PNK_TRUE : PNK_FALSE, b ? JSOP_TRUE : JSOP_FALSE, pos) { } }; -class RegExpLiteral : public NullaryNode +class RegExpLiteral : public ParseNode { public: RegExpLiteral(ObjectBox* reobj, const TokenPos& pos) - : NullaryNode(PNK_REGEXP, JSOP_REGEXP, pos) + : ParseNode(PNK_REGEXP, JSOP_REGEXP, PN_REGEXP, pos) { - pn_objbox = reobj; + pn_u.regexp.objbox = reobj; } - ObjectBox* objbox() const { return pn_objbox; } + ObjectBox* objbox() const { + return pn_u.regexp.objbox; + } + +#ifdef DEBUG + void dump(int indent); +#endif static bool test(const ParseNode& node) { bool match = node.isKind(PNK_REGEXP); - MOZ_ASSERT_IF(match, node.isArity(PN_NULLARY)); + MOZ_ASSERT_IF(match, node.isArity(PN_REGEXP)); MOZ_ASSERT_IF(match, node.isOp(JSOP_REGEXP)); return match; } @@ -1647,11 +1749,11 @@ class PropertyAccessBase : public BinaryNode * PropertyAccess nodes can have any expression/'super' as left-hand * side, but the name must be a PNK_PROPERTYNAME node. */ - PropertyAccessBase(ParseNodeKind kind, ParseNode* lhs, ParseNode* name, uint32_t begin, uint32_t end) + PropertyAccessBase(ParseNodeKind kind, ParseNode* lhs, NameNode* name, uint32_t begin, uint32_t end) : BinaryNode(kind, JSOP_NOP, TokenPos(begin, end), lhs, name) { - MOZ_ASSERT(lhs != nullptr); - MOZ_ASSERT(name != nullptr); + MOZ_ASSERT(lhs); + MOZ_ASSERT(name); } static bool test(const ParseNode& node) { @@ -1666,8 +1768,8 @@ class PropertyAccessBase : public BinaryNode return *left(); } - ParseNode& key() const { - return *right(); + NameNode& key() const { + return right()->as<NameNode>(); } // Method used by BytecodeEmitter::emitPropLHS for optimization. @@ -1682,7 +1784,7 @@ class PropertyAccessBase : public BinaryNode } PropertyName& name() const { - return *right()->pn_atom->asPropertyName(); + return *right()->as<NameNode>().atom()->asPropertyName(); } bool isSuper() const { @@ -1694,7 +1796,7 @@ class PropertyAccessBase : public BinaryNode class PropertyAccess : public PropertyAccessBase { public: - PropertyAccess(ParseNode* lhs, ParseNode* name, uint32_t begin, uint32_t end) + PropertyAccess(ParseNode* lhs, NameNode* name, uint32_t begin, uint32_t end) : PropertyAccessBase(PNK_DOT, lhs, name, begin, end) { MOZ_ASSERT(lhs != nullptr); @@ -1712,7 +1814,7 @@ class PropertyAccess : public PropertyAccessBase class OptionalPropertyAccess : public PropertyAccessBase { public: - OptionalPropertyAccess(ParseNode* lhs, ParseNode* name, uint32_t begin, uint32_t end) + OptionalPropertyAccess(ParseNode* lhs, NameNode* name, uint32_t begin, uint32_t end) : PropertyAccessBase(PNK_OPTDOT, lhs, name, begin, end) { MOZ_ASSERT(lhs != nullptr); @@ -1827,8 +1929,8 @@ class ClassMethod : public BinaryNode ParseNode& name() const { return *left(); } - ParseNode& method() const { - return *right(); + CodeNode& method() const { + return right()->as<CodeNode>(); } bool isStatic() const { return pn_u.binary.isStatic; @@ -1887,7 +1989,8 @@ class ClassNames : public BinaryNode { MOZ_ASSERT_IF(outerBinding, outerBinding->isKind(PNK_NAME)); MOZ_ASSERT(innerBinding->isKind(PNK_NAME)); - MOZ_ASSERT_IF(outerBinding, innerBinding->pn_atom == outerBinding->pn_atom); + MOZ_ASSERT_IF(outerBinding, + innerBinding->as<NameNode>().atom() == outerBinding->as<NameNode>().atom()); } static bool test(const ParseNode& node) { @@ -1904,11 +2007,14 @@ class ClassNames : public BinaryNode * giving the methods access to the static members of the class even if * the outer binding has been overwritten. */ - ParseNode* outerBinding() const { - return left(); + NameNode* outerBinding() const { + if (ParseNode* binding = left()) { + return &binding->as<NameNode>(); + } + return nullptr; } - ParseNode* innerBinding() const { - return right(); + NameNode* innerBinding() const { + return &right()->as<NameNode>(); } }; @@ -2068,7 +2174,7 @@ static inline ParseNode* FunctionFormalParametersList(ParseNode* fn, unsigned* numFormals) { MOZ_ASSERT(fn->isKind(PNK_FUNCTION)); - ListNode* argsBody = &fn->pn_body->as<ListNode>(); + ListNode* argsBody = fn->as<CodeNode>().body(); MOZ_ASSERT(argsBody->isKind(PNK_PARAMSBODY)); *numFormals = argsBody->count(); if (*numFormals > 0 && diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 86a9fcc7a0..974cbae36c 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -907,7 +907,7 @@ Parser<ParseHandler>::newObjectBox(JSObject* obj) template <typename ParseHandler> FunctionBox* -Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun, uint32_t toStringStart, +Parser<ParseHandler>::newFunctionBox(CodeNodeType funNode, JSFunction* fun, uint32_t toStringStart, Directives inheritedDirectives, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB) @@ -932,8 +932,8 @@ Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun, uint32_t toString } traceListHead = funbox; - if (fn) - handler.setFunctionBox(fn, funbox); + if (funNode) + handler.setFunctionBox(funNode, funbox); if (tryAnnexB && !pc->addInnerFunctionBoxForAnnexB(funbox)) return nullptr; @@ -1124,7 +1124,7 @@ Parser<ParseHandler>::reportRedeclaration(HandlePropertyName name, DeclarationKi // forbid duplicates.) template <typename ParseHandler> bool -Parser<ParseHandler>::notePositionalFormalParameter(Node fn, HandlePropertyName name, +Parser<ParseHandler>::notePositionalFormalParameter(CodeNodeType funNode, HandlePropertyName name, uint32_t beginPos, bool disallowDuplicateParams, bool* duplicatedParam) @@ -1159,17 +1159,17 @@ Parser<ParseHandler>::notePositionalFormalParameter(Node fn, HandlePropertyName return false; } - Node paramNode = newName(name); + NameNodeType paramNode = newName(name); if (!paramNode) return false; - handler.addFunctionFormalParameter(fn, paramNode); + handler.addFunctionFormalParameter(funNode, paramNode); return true; } template <typename ParseHandler> bool -Parser<ParseHandler>::noteDestructuredPositionalFormalParameter(Node fn, Node destruct) +Parser<ParseHandler>::noteDestructuredPositionalFormalParameter(CodeNodeType funNode, Node destruct) { // Append an empty name to the positional formals vector to keep track of // argument slots when making FunctionScope::Data. @@ -1178,7 +1178,7 @@ Parser<ParseHandler>::noteDestructuredPositionalFormalParameter(Node fn, Node de return false; } - handler.addFunctionFormalParameter(fn, destruct); + handler.addFunctionFormalParameter(funNode, destruct); return true; } @@ -2215,7 +2215,7 @@ Parser<FullParseHandler>::globalBody(GlobalSharedContext* globalsc) } template <> -ParseNode* +CodeNode* Parser<FullParseHandler>::moduleBody(ModuleSharedContext* modulesc) { MOZ_ASSERT(checkOptionsCalled); @@ -2228,8 +2228,8 @@ Parser<FullParseHandler>::moduleBody(ModuleSharedContext* modulesc) if (!varScope.init(pc)) return nullptr; - Node mn = handler.newModule(); - if (!mn) + CodeNodeType moduleNode = handler.newModule(); + if (!moduleNode) return null(); AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, true); @@ -2239,7 +2239,7 @@ Parser<FullParseHandler>::moduleBody(ModuleSharedContext* modulesc) } MOZ_ASSERT(stmtList->isKind(PNK_STATEMENTLIST)); - mn->pn_body = stmtList; + moduleNode->setBody(&stmtList->as<ListNode>()); TokenKind tt; if (!tokenStream.getToken(&tt, TokenStream::Operand)) @@ -2285,11 +2285,11 @@ Parser<FullParseHandler>::moduleBody(ModuleSharedContext* modulesc) return nullptr; modulesc->bindings = *bindings; - return mn; + return moduleNode; } template <> -SyntaxParseHandler::Node +SyntaxParseHandler::CodeNodeType Parser<SyntaxParseHandler>::moduleBody(ModuleSharedContext* modulesc) { MOZ_ALWAYS_FALSE(abortIfSyntaxParser()); @@ -2340,10 +2340,10 @@ Parser<ParseHandler>::declareFunctionThis() } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::NameNodeType Parser<ParseHandler>::newInternalDotName(HandlePropertyName name) { - Node nameNode = newName(name); + NameNodeType nameNode = newName(name); if (!nameNode) return null(); if (!noteUsedName(name)) @@ -2352,14 +2352,14 @@ Parser<ParseHandler>::newInternalDotName(HandlePropertyName name) } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::NameNodeType Parser<ParseHandler>::newThisName() { return newInternalDotName(context->names().dotThis); } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::NameNodeType Parser<ParseHandler>::newDotGeneratorName() { return newInternalDotName(context->names().dotGenerator); @@ -2505,7 +2505,7 @@ GetYieldHandling(GeneratorKind generatorKind) } template <> -ParseNode* +CodeNode* Parser<FullParseHandler>::standaloneFunction(HandleFunction fun, HandleScope enclosingScope, Maybe<uint32_t> parameterListEnd, @@ -2542,16 +2542,16 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun, tokenStream.ungetToken(); } - Node fn = handler.newFunctionStatement(); - if (!fn) + CodeNodeType funNode = handler.newFunctionStatement(); + if (!funNode) return null(); ListNodeType argsbody = handler.newList(PNK_PARAMSBODY); if (!argsbody) return null(); - fn->pn_body = argsbody; + funNode->setBody(argsbody); - FunctionBox* funbox = newFunctionBox(fn, fun, /* toStringStart = */ 0, inheritedDirectives, + FunctionBox* funbox = newFunctionBox(funNode, fun, /* toStringStart = */ 0, inheritedDirectives, generatorKind, asyncKind, /* tryAnnexB = */ false); if (!funbox) return null(); @@ -2564,7 +2564,7 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun, YieldHandling yieldHandling = GetYieldHandling(generatorKind); AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, asyncKind == AsyncFunction); - if (!functionFormalParametersAndBody(InAllowed, yieldHandling, fn, Statement, + if (!functionFormalParametersAndBody(InAllowed, yieldHandling, funNode, Statement, parameterListEnd, /* isStandaloneFunction = */ true)) { return null(); @@ -2577,10 +2577,12 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun, return null(); } - if (!FoldConstants(context, &fn, this)) + ParseNode* node = funNode; + if (!FoldConstants(context, &node, this)) return null(); + funNode = &node->as<CodeNode>(); - return fn; + return funNode; } template <typename ParseHandler> @@ -2745,7 +2747,7 @@ Parser<ParseHandler>::functionBody(InHandling inHandling, YieldHandling yieldHan MOZ_ASSERT_IF(!pc->isAsync(), type == StatementListBody); if (!declareDotGeneratorName()) return null(); - Node generator = newDotGeneratorName(); + NameNodeType generator = newDotGeneratorName(); if (!generator) return null(); if (!handler.prependInitialYield(handler.asList(body), generator)) @@ -2953,7 +2955,7 @@ Parser<ParseHandler>::prefixAccessorName(PropertyType propType, HandleAtom propA template <typename ParseHandler> bool Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind, - Node funcpn) + CodeNodeType funNode) { FunctionBox* funbox = pc->functionBox(); @@ -3013,7 +3015,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn ListNodeType argsbody = handler.newList(PNK_PARAMSBODY); if (!argsbody) return false; - handler.setFunctionFormalParametersAndBody(funcpn, argsbody); + handler.setFunctionFormalParametersAndBody(funNode, argsbody); bool hasArguments = false; if (parenFreeArrow) { @@ -3092,7 +3094,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn if (!destruct) return false; - if (!noteDestructuredPositionalFormalParameter(funcpn, destruct)) + if (!noteDestructuredPositionalFormalParameter(funNode, destruct)) return false; break; @@ -3111,7 +3113,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn if (!name) return false; - if (!notePositionalFormalParameter(funcpn, name, pos().begin, + if (!notePositionalFormalParameter(funNode, name, pos().begin, disallowDuplicateParams, &duplicatedParam)) { return false; @@ -3160,7 +3162,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn Node def_expr = assignExprWithoutYieldOrAwait(yieldHandling); if (!def_expr) return false; - if (!handler.setLastFunctionFormalParameterDefault(funcpn, def_expr)) + if (!handler.setLastFunctionFormalParameterDefault(funNode, def_expr)) return false; } @@ -3214,7 +3216,7 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn template <> bool -Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, uint32_t toStringStart, +Parser<FullParseHandler>::skipLazyInnerFunction(CodeNode* funNode, uint32_t toStringStart, FunctionSyntaxKind kind, bool tryAnnexB) { // When a lazily-parsed function is called, we only fully parse (and emit) @@ -3224,7 +3226,7 @@ Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, uint32_t toString RootedFunction fun(context, handler.nextLazyInnerFunction()); MOZ_ASSERT(!fun->isLegacyGenerator()); - FunctionBox* funbox = newFunctionBox(pn, fun, toStringStart, Directives(/* strict = */ false), + FunctionBox* funbox = newFunctionBox(funNode, fun, toStringStart, Directives(/* strict = */ false), fun->generatorKind(), fun->asyncKind(), tryAnnexB); if (!funbox) return false; @@ -3261,7 +3263,7 @@ Parser<FullParseHandler>::skipLazyInnerFunction(ParseNode* pn, uint32_t toString template <> bool -Parser<SyntaxParseHandler>::skipLazyInnerFunction(Node pn, uint32_t toStringStart, +Parser<SyntaxParseHandler>::skipLazyInnerFunction(CodeNodeType funNode, uint32_t toStringStart, FunctionSyntaxKind kind, bool tryAnnexB) { MOZ_CRASH("Cannot skip lazy inner functions when syntax parsing"); @@ -3314,11 +3316,11 @@ template <typename ParseHandler> typename ParseHandler::ListNodeType Parser<ParseHandler>::templateLiteral(YieldHandling yieldHandling) { - Node pn = noSubstitutionUntaggedTemplate(); - if (!pn) + NameNodeType literal = noSubstitutionUntaggedTemplate(); + if (!literal) return null(); - ListNodeType nodeList = handler.newList(PNK_TEMPLATE_STRING_LIST, pn); + ListNodeType nodeList = handler.newList(PNK_TEMPLATE_STRING_LIST, literal); if (!nodeList) return null(); @@ -3327,18 +3329,18 @@ Parser<ParseHandler>::templateLiteral(YieldHandling yieldHandling) if (!addExprAndGetNextTemplStrToken(yieldHandling, nodeList, &tt)) return null(); - pn = noSubstitutionUntaggedTemplate(); - if (!pn) + literal = noSubstitutionUntaggedTemplate(); + if (!literal) return null(); - handler.addList(nodeList, pn); + handler.addList(nodeList, literal); } while (tt == TOK_TEMPLATE_HEAD); return nodeList; } template <typename ParseHandler> -typename ParseHandler::Node -Parser<ParseHandler>::functionDefinition(uint32_t toStringStart, Node pn, InHandling inHandling, +typename ParseHandler::CodeNodeType +Parser<ParseHandler>::functionDefinition(uint32_t toStringStart, CodeNodeType funNode, InHandling inHandling, YieldHandling yieldHandling, HandleAtom funName, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, @@ -3350,9 +3352,10 @@ Parser<ParseHandler>::functionDefinition(uint32_t toStringStart, Node pn, InHand // functions, which are also lazy. Instead, their free variables and // source extents are recorded and may be skipped. if (handler.canSkipLazyInnerFunctions()) { - if (!skipLazyInnerFunction(pn, toStringStart, kind, tryAnnexB)) + if (!skipLazyInnerFunction(funNode, toStringStart, kind, tryAnnexB)) return null(); - return pn; + + return funNode; } RootedObject proto(context); @@ -3383,8 +3386,8 @@ Parser<ParseHandler>::functionDefinition(uint32_t toStringStart, Node pn, InHand // reparse a function due to failed syntax parsing and encountering new // "use foo" directives. while (true) { - if (trySyntaxParseInnerFunction(pn, fun, toStringStart, inHandling, yieldHandling, kind, - generatorKind, asyncKind, tryAnnexB, directives, + if (trySyntaxParseInnerFunction(funNode, fun, toStringStart, inHandling, yieldHandling, + kind, generatorKind, asyncKind, tryAnnexB, directives, &newDirectives)) { break; @@ -3402,16 +3405,16 @@ Parser<ParseHandler>::functionDefinition(uint32_t toStringStart, Node pn, InHand tokenStream.seek(start); - // functionFormalParametersAndBody may have already set pn->pn_body before failing. - handler.setFunctionFormalParametersAndBody(pn, null()); + // functionFormalParametersAndBody may have already set body before failing. + handler.setFunctionFormalParametersAndBody(funNode, null()); } - return pn; + return funNode; } template <> bool -Parser<FullParseHandler>::trySyntaxParseInnerFunction(ParseNode* pn, HandleFunction fun, +Parser<FullParseHandler>::trySyntaxParseInnerFunction(CodeNode* funNode, HandleFunction fun, uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, @@ -3428,7 +3431,7 @@ Parser<FullParseHandler>::trySyntaxParseInnerFunction(ParseNode* pn, HandleFunct // parse to avoid the overhead of a lazy syntax-only parse. Although // the prediction may be incorrect, IIFEs are common enough that it // pays off for lots of code. - if (pn->isLikelyIIFE() && generatorKind == NotGenerator && asyncKind == SyncFunction) + if (funNode->isLikelyIIFE() && generatorKind == NotGenerator && asyncKind == SyncFunction) break; Parser<SyntaxParseHandler>* parser = handler.syntaxParser; @@ -3443,10 +3446,10 @@ Parser<FullParseHandler>::trySyntaxParseInnerFunction(ParseNode* pn, HandleFunct if (!parser->tokenStream.seek(position, tokenStream)) return false; - // Make a FunctionBox before we enter the syntax parser, because |pn| + // Make a FunctionBox before we enter the syntax parser, because |funNode| // still expects a FunctionBox to be attached to it during BCE, and // the syntax parser cannot attach one to it. - FunctionBox* funbox = newFunctionBox(pn, fun, toStringStart, inheritedDirectives, + FunctionBox* funbox = newFunctionBox(funNode, fun, toStringStart, inheritedDirectives, generatorKind, asyncKind, tryAnnexB); if (!funbox) return false; @@ -3475,18 +3478,18 @@ Parser<FullParseHandler>::trySyntaxParseInnerFunction(ParseNode* pn, HandleFunct return false; // Update the end position of the parse node. - pn->pn_pos.end = tokenStream.currentToken().pos.end; + funNode->pn_pos.end = tokenStream.currentToken().pos.end; return true; } while (false); // We failed to do a syntax parse above, so do the full parse. - return innerFunction(pn, pc, fun, toStringStart, inHandling, yieldHandling, kind, + return innerFunction(funNode, pc, fun, toStringStart, inHandling, yieldHandling, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives, newDirectives); } template <> bool -Parser<SyntaxParseHandler>::trySyntaxParseInnerFunction(Node pn, HandleFunction fun, +Parser<SyntaxParseHandler>::trySyntaxParseInnerFunction(CodeNodeType funNode, HandleFunction fun, uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, @@ -3498,13 +3501,13 @@ Parser<SyntaxParseHandler>::trySyntaxParseInnerFunction(Node pn, HandleFunction Directives* newDirectives) { // This is already a syntax parser, so just parse the inner function. - return innerFunction(pn, pc, fun, toStringStart, inHandling, yieldHandling, kind, + return innerFunction(funNode, pc, fun, toStringStart, inHandling, yieldHandling, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives, newDirectives); } template <typename ParseHandler> bool -Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, FunctionBox* funbox, +Parser<ParseHandler>::innerFunction(CodeNodeType funNode, ParseContext* outerpc, FunctionBox* funbox, uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind, Directives inheritedDirectives, @@ -3520,7 +3523,7 @@ Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, FunctionBox* if (!funpc.init()) return false; - if (!functionFormalParametersAndBody(inHandling, yieldHandling, pn, kind)) + if (!functionFormalParametersAndBody(inHandling, yieldHandling, funNode, kind)) return false; return leaveInnerFunction(outerpc); @@ -3528,7 +3531,7 @@ Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, FunctionBox* template <typename ParseHandler> bool -Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun, +Parser<ParseHandler>::innerFunction(CodeNodeType funNode, ParseContext* outerpc, HandleFunction fun, uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind, @@ -3541,13 +3544,13 @@ Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, HandleFuncti // parser. In that case, outerpc is a ParseContext from the full parser // instead of the current top of the stack of the syntax parser. - FunctionBox* funbox = newFunctionBox(pn, fun, toStringStart, inheritedDirectives, + FunctionBox* funbox = newFunctionBox(funNode, fun, toStringStart, inheritedDirectives, generatorKind, asyncKind, tryAnnexB); if (!funbox) return false; funbox->initWithEnclosingParseContext(outerpc, kind); - return innerFunction(pn, outerpc, funbox, toStringStart, inHandling, yieldHandling, kind, + return innerFunction(funNode, outerpc, funbox, toStringStart, inHandling, yieldHandling, kind, inheritedDirectives, newDirectives); } @@ -3562,7 +3565,7 @@ Parser<ParseHandler>::appendToCallSiteObj(CallSiteNodeType callSiteObj) JSAtom* atom = tokenStream.getRawTemplateStringAtom(); if (!atom) return false; - Node rawNode = handler.newTemplateStringLiteral(atom, pos()); + NameNodeType rawNode = handler.newTemplateStringLiteral(atom, pos()); if (!rawNode) return false; @@ -3571,19 +3574,19 @@ Parser<ParseHandler>::appendToCallSiteObj(CallSiteNodeType callSiteObj) } template <> -ParseNode* +CodeNode* Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict, GeneratorKind generatorKind, FunctionAsyncKind asyncKind) { MOZ_ASSERT(checkOptionsCalled); - Node pn = handler.newFunctionStatement(); - if (!pn) + CodeNodeType funNode = handler.newFunctionStatement(); + if (!funNode) return null(); Directives directives(strict); - FunctionBox* funbox = newFunctionBox(pn, fun, /* toStringStart = */ 0, directives, + FunctionBox* funbox = newFunctionBox(funNode, fun, /* toStringStart = */ 0, directives, generatorKind, asyncKind, /* tryAnnexB = */ false); if (!funbox) return null(); @@ -3594,14 +3597,14 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict if (!funpc.init()) return null(); - // Our tokenStream has no current token, so pn's position is garbage. + // Our tokenStream has no current token, so funNode's position is garbage. // Substitute the position of the first token in our source. If the function // is a not-async arrow, use TokenStream::Operand to keep // verifyConsistentModifier from complaining (we will use // TokenStream::Operand in functionArguments). TokenStream::Modifier modifier = (fun->isArrow() && asyncKind == SyncFunction) ? TokenStream::Operand : TokenStream::None; - if (!tokenStream.peekTokenPos(&pn->pn_pos, modifier)) + if (!tokenStream.peekTokenPos(&funNode->pn_pos, modifier)) return null(); YieldHandling yieldHandling = GetYieldHandling(generatorKind); @@ -3617,22 +3620,24 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict else if (fun->isArrow()) syntaxKind = Arrow; - if (!functionFormalParametersAndBody(InAllowed, yieldHandling, pn, syntaxKind)) { + if (!functionFormalParametersAndBody(InAllowed, yieldHandling, funNode, syntaxKind)) { MOZ_ASSERT(directives == newDirectives); return null(); } - if (!FoldConstants(context, &pn, this)) + ParseNode* node = funNode; + if (!FoldConstants(context, &node, this)) return null(); + funNode = &node->as<CodeNode>(); - return pn; + return funNode; } template <typename ParseHandler> bool Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling, YieldHandling yieldHandling, - Node pn, FunctionSyntaxKind kind, + CodeNodeType funNode, FunctionSyntaxKind kind, Maybe<uint32_t> parameterListEnd /* = Nothing() */, bool isStandaloneFunction /* = false */) { @@ -3648,7 +3653,7 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling, { bool asyncOrArrowInAsync = funbox->isAsync() || (kind == Arrow && awaitIsKeyword()); AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, asyncOrArrowInAsync); - if (!functionArguments(yieldHandling, kind, pn)) + if (!functionArguments(yieldHandling, kind, funNode)) return false; } @@ -3740,7 +3745,7 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling, // We already use the correct await-handling at this point, therefore // we don't need call AutoAwaitIsKeyword here. - if (!checkBindingIdentifier(propertyName, handler.getPosition(pn).begin, + if (!checkBindingIdentifier(propertyName, handler.getPosition(funNode).begin, nameYieldHandling)) { return false; @@ -3771,14 +3776,14 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling, return false; handler.setEndPosition(body, pos().begin); - handler.setEndPosition(pn, pos().end); - handler.setFunctionBody(pn, body); + handler.setEndPosition(funNode, pos().end); + handler.setFunctionBody(funNode, body); return true; } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::CodeNodeType Parser<ParseHandler>::functionStmt(uint32_t toStringStart, YieldHandling yieldHandling, DefaultHandling defaultHandling, FunctionAsyncKind asyncKind) { @@ -3854,17 +3859,17 @@ Parser<ParseHandler>::functionStmt(uint32_t toStringStart, YieldHandling yieldHa return null(); } - Node pn = handler.newFunctionStatement(); - if (!pn) + CodeNodeType funNode = handler.newFunctionStatement(); + if (!funNode) return null(); YieldHandling newYieldHandling = GetYieldHandling(generatorKind); - return functionDefinition(toStringStart, pn, InAllowed, newYieldHandling, - name, Statement, generatorKind, asyncKind, tryAnnexB); + return functionDefinition(toStringStart, funNode, InAllowed, newYieldHandling, + name, Statement, generatorKind, asyncKind, tryAnnexB); } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::CodeNodeType Parser<ParseHandler>::functionExpr(uint32_t toStringStart, InvokedPrediction invoked, FunctionAsyncKind asyncKind) { @@ -3893,14 +3898,14 @@ Parser<ParseHandler>::functionExpr(uint32_t toStringStart, InvokedPrediction inv tokenStream.ungetToken(); } - Node pn = handler.newFunctionExpression(); - if (!pn) + CodeNodeType funNode = handler.newFunctionExpression(); + if (!funNode) return null(); if (invoked) - pn = handler.setLikelyIIFE(pn); + funNode = handler.setLikelyIIFE(funNode); - return functionDefinition(toStringStart, pn, InAllowed, yieldHandling, name, Expression, + return functionDefinition(toStringStart, funNode, InAllowed, yieldHandling, name, Expression, generatorKind, asyncKind); } @@ -4338,14 +4343,14 @@ Parser<ParseHandler>::bindingInitializer(Node lhs, DeclarationKind kind, } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::NameNodeType Parser<ParseHandler>::bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling) { RootedPropertyName name(context, bindingIdentifier(yieldHandling)); if (!name) return null(); - Node binding = newName(name); + NameNodeType binding = newName(name); if (!binding || !noteDeclaredName(name, kind, pos())) return null(); @@ -4442,18 +4447,18 @@ Parser<ParseHandler>::objectBindingPattern(DeclarationKind kind, YieldHandling y // for |var {x: x, y: y} = o|. MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt)); - Node binding = bindingIdentifier(kind, yieldHandling); + NameNodeType binding = bindingIdentifier(kind, yieldHandling); if (!binding) return null(); - if (!handler.addShorthand(literal, propName, binding)) + if (!handler.addShorthand(literal, handler.asName(propName), binding)) return null(); } else if (propType == PropertyType::CoverInitializedName) { // Handle e.g., |var {x=1, y=2} = o| as destructuring // shorthand with default values. MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt)); - Node binding = bindingIdentifier(kind, yieldHandling); + NameNodeType binding = bindingIdentifier(kind, yieldHandling); if (!binding) return null(); @@ -4717,7 +4722,7 @@ Parser<ParseHandler>::declarationPattern(Node decl, DeclarationKind declKind, To template <typename ParseHandler> bool -Parser<ParseHandler>::initializerInNameDeclaration(Node decl, Node binding, +Parser<ParseHandler>::initializerInNameDeclaration(Node decl, NameNodeType binding, Handle<PropertyName*> name, DeclarationKind declKind, bool initialDeclaration, @@ -4803,7 +4808,7 @@ Parser<ParseHandler>::initializerInNameDeclaration(Node decl, Node binding, } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::NameNodeType Parser<ParseHandler>::declarationName(Node decl, DeclarationKind declKind, TokenKind tt, bool initialDeclaration, YieldHandling yieldHandling, ParseNodeKind* forHeadKind, Node* forInOrOfExpression) @@ -4819,7 +4824,7 @@ Parser<ParseHandler>::declarationName(Node decl, DeclarationKind declKind, Token if (!name) return null(); - Node binding = newName(name); + NameNodeType binding = newName(name); if (!binding) return null(); @@ -5025,13 +5030,13 @@ Parser<FullParseHandler>::namedImportsOrNamespaceImport(TokenKind tt, ListNodeTy if (!bindingAtom) return false; - Node bindingName = newName(bindingAtom); + NameNodeType bindingName = newName(bindingAtom); if (!bindingName) return false; if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) return false; - Node importNameNode = newName(importName, importNamePos); + NameNodeType importNameNode = newName(importName, importNamePos); if (!importNameNode) return false; @@ -5060,7 +5065,7 @@ Parser<FullParseHandler>::namedImportsOrNamespaceImport(TokenKind tt, ListNodeTy MUST_MATCH_TOKEN_FUNC_OR(TokenKindIsPossibleIdentifierName, JSMSG_NO_BINDING_NAME, false); - Node importName = newName(context->names().star); + NameNodeType importName = newName(context->names().star); if (!importName) return false; @@ -5071,7 +5076,7 @@ Parser<FullParseHandler>::namedImportsOrNamespaceImport(TokenKind tt, ListNodeTy RootedPropertyName bindingName(context, importedBinding()); if (!bindingName) return false; - Node bindingNameNode = newName(bindingName); + NameNodeType bindingNameNode = newName(bindingName); if (!bindingNameNode) return false; if (!noteDeclaredName(bindingName, DeclarationKind::Const, pos())) @@ -5171,7 +5176,7 @@ Parser<FullParseHandler>::importDeclaration() MUST_MATCH_TOKEN(TOK_STRING, JSMSG_MODULE_SPEC_AFTER_FROM); } - Node moduleSpec = stringLiteral(); + NameNodeType moduleSpec = stringLiteral(); if (!moduleSpec) return null(); @@ -5295,7 +5300,7 @@ bool Parser<FullParseHandler>::checkExportedNamesForDeclaration(ParseNode* node) { if (node->isKind(PNK_NAME)) { - if (!checkExportedName(node->pn_atom)) + if (!checkExportedName(node->as<NameNode>().atom())) return false; } else if (node->isKind(PNK_ARRAY)) { if (!checkExportedNamesForArrayBinding(&node->as<ListNode>())) @@ -5344,14 +5349,14 @@ Parser<SyntaxParseHandler>::checkExportedNamesForDeclarationList(ListNodeType no template<> bool -Parser<FullParseHandler>::checkExportedNameForClause(ParseNode* node) +Parser<FullParseHandler>::checkExportedNameForClause(NameNodeType nameNode) { - return checkExportedName(node->pn_atom); + return checkExportedName(nameNode->atom()); } template<> bool -Parser<SyntaxParseHandler>::checkExportedNameForClause(Node node) +Parser<SyntaxParseHandler>::checkExportedNameForClause(NameNodeType nameNode) { MOZ_ALWAYS_FALSE(abortIfSyntaxParser()); return false; @@ -5359,14 +5364,14 @@ Parser<SyntaxParseHandler>::checkExportedNameForClause(Node node) template<> bool -Parser<FullParseHandler>::checkExportedNameForFunction(ParseNode* node) +Parser<FullParseHandler>::checkExportedNameForFunction(CodeNodeType funNode) { - return checkExportedName(node->pn_funbox->function()->explicitName()); + return checkExportedName(funNode->funbox()->function()->explicitName()); } template<> bool -Parser<SyntaxParseHandler>::checkExportedNameForFunction(Node node) +Parser<SyntaxParseHandler>::checkExportedNameForFunction(CodeNodeType funNode) { MOZ_ALWAYS_FALSE(abortIfSyntaxParser()); return false; @@ -5377,7 +5382,7 @@ bool Parser<FullParseHandler>::checkExportedNameForClass(ClassNode* classNode) { MOZ_ASSERT(classNode->names()); - return checkExportedName(classNode->names()->innerBinding()->pn_atom); + return checkExportedName(classNode->names()->innerBinding()->atom()); } template<> @@ -5432,7 +5437,7 @@ Parser<ParseHandler>::exportFrom(uint32_t begin, Node specList) MUST_MATCH_TOKEN(TOK_STRING, JSMSG_MODULE_SPEC_AFTER_FROM); - Node moduleSpec = stringLiteral(); + NameNodeType moduleSpec = stringLiteral(); if (!moduleSpec) return null(); @@ -5484,7 +5489,7 @@ Parser<FullParseHandler>::checkLocalExportNames(ListNode* node) ParseNode* name = next->as<BinaryNode>().left(); MOZ_ASSERT(name->isKind(PNK_NAME)); - RootedPropertyName ident(context, name->pn_atom->asPropertyName()); + RootedPropertyName ident(context, name->as<NameNode>().atom()->asPropertyName()); if (!checkLocalExportName(ident, name->pn_pos.begin)) return false; } @@ -5528,7 +5533,7 @@ Parser<ParseHandler>::exportClause(uint32_t begin) return null(); } - Node bindingName = newName(tokenStream.currentName()); + NameNodeType bindingName = newName(tokenStream.currentName()); if (!bindingName) return null(); @@ -5538,7 +5543,7 @@ Parser<ParseHandler>::exportClause(uint32_t begin) if (foundAs) MUST_MATCH_TOKEN_FUNC(TokenKindIsPossibleIdentifierName, JSMSG_NO_EXPORT_NAME); - Node exportName = newName(tokenStream.currentName()); + NameNodeType exportName = newName(tokenStream.currentName()); if (!exportName) return null(); @@ -5640,7 +5645,7 @@ Parser<ParseHandler>::exportFunctionDeclaration(uint32_t begin) if (!kid) return null(); - if (!checkExportedNameForFunction(kid)) + if (!checkExportedNameForFunction(handler.asCode(kid))) return null(); UnaryNodeType node = handler.newExportDeclaration(kid, TokenPos(begin, pos().end)); @@ -5762,7 +5767,7 @@ Parser<ParseHandler>::exportDefaultAssignExpr(uint32_t begin) return null(); RootedPropertyName name(context, context->names().starDefaultStar); - Node nameNode = newName(name); + NameNodeType nameNode = newName(name); if (!nameNode) return null(); if (!noteDeclaredName(name, DeclarationKind::Const, pos())) @@ -6894,7 +6899,7 @@ Parser<ParseHandler>::labeledItem(YieldHandling yieldHandling) } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::LabeledStatementType Parser<ParseHandler>::labeledStatement(YieldHandling yieldHandling) { RootedPropertyName label(context, labelIdentifier(yieldHandling)); @@ -7390,15 +7395,15 @@ Parser<ParseHandler>::classDefinition(YieldHandling yieldHandling, // Calling toString on constructors need to return the source text for // the entire class. The end offset is unknown at this point in // parsing and will be amended when class parsing finishes below. - Node fn = methodDefinition(isConstructor ? classStartOffset : nameOffset, - propType, funName); - if (!fn) + CodeNodeType funNode = methodDefinition(isConstructor ? classStartOffset : nameOffset, + propType, funName); + if (!funNode) return null(); - handler.checkAndSetIsDirectRHSAnonFunction(fn); + handler.checkAndSetIsDirectRHSAnonFunction(funNode); JSOp op = JSOpFromPropertyType(propType); - if (!handler.addClassMethodDefinition(classMethods, propName, fn, op, isStatic)) + if (!handler.addClassMethodDefinition(classMethods, propName, funNode, op, isStatic)) return null(); } @@ -7418,7 +7423,7 @@ Parser<ParseHandler>::classDefinition(YieldHandling yieldHandling, if (!noteDeclaredName(name, DeclarationKind::Const, namePos)) return null(); - Node innerName = newName(name, namePos); + NameNodeType innerName = newName(name, namePos); if (!innerName) return null(); @@ -7432,7 +7437,7 @@ Parser<ParseHandler>::classDefinition(YieldHandling yieldHandling, innerScope.reset(); innerScopeStmt.reset(); - Node outerName = null(); + NameNodeType outerName = null(); if (classContext == ClassStatement) { // The outer name is mutable. if (!noteDeclaredName(name, DeclarationKind::Let, namePos)) @@ -8387,11 +8392,11 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl } } - Node pn = handler.newArrowFunction(); - if (!pn) + CodeNodeType funNode = handler.newArrowFunction(); + if (!funNode) return null(); - Node arrowFunc = functionDefinition(toStringStart, pn, inHandling, yieldHandling, nullptr, + Node arrowFunc = functionDefinition(toStringStart, funNode, inHandling, yieldHandling, nullptr, Arrow, NotGenerator, asyncKind); if (!arrowFunc) return null(); @@ -8784,7 +8789,7 @@ template <typename ParseHandler> typename ParseHandler::Node Parser<ParseHandler>::generatorComprehensionLambda(unsigned begin) { - Node genfn = handler.newFunctionExpression(); + CodeNodeType genfn = handler.newFunctionExpression(); if (!genfn) return null(); @@ -9235,7 +9240,7 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling handler.setOp(lhs, JSOP_SPREADNEW); } } else if (tt == TOK_SUPER) { - Node thisName = newThisName(); + NameNodeType thisName = newThisName(); if (!thisName) return null(); lhs = handler.newSuperBase(thisName, pos()); @@ -9301,7 +9306,7 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling if (isSpread) handler.setOp(nextMember, JSOP_SPREADSUPERCALL); - Node thisName = newThisName(); + NameNodeType thisName = newThisName(); if (!thisName) return null(); @@ -9336,14 +9341,14 @@ Parser<ParseHandler>::memberExpr(YieldHandling yieldHandling, TripledotHandling } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::NameNodeType Parser<ParseHandler>::newName(PropertyName* name) { return newName(name, pos()); } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::NameNodeType Parser<ParseHandler>::newName(PropertyName* name, TokenPos pos) { return handler.newName(name, pos, context); @@ -9360,7 +9365,7 @@ Parser<ParseHandler>::memberPropertyAccess( error(JSMSG_BAD_SUPERPROP, "property"); return null(); } - Node name = handler.newPropertyName(field, pos()); + NameNodeType name = handler.newPropertyName(field, pos()); if (!name) return null(); if (optionalKind == OptionalKind::Optional) { @@ -9624,21 +9629,21 @@ Parser<ParseHandler>::bindingIdentifier(YieldHandling yieldHandling) } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::NameNodeType Parser<ParseHandler>::identifierReference(Handle<PropertyName*> name) { - Node pn = newName(name); - if (!pn) + NameNodeType id = newName(name); + if (!id) return null(); if (!noteUsedName(name)) return null(); - return pn; + return id; } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::NameNodeType Parser<ParseHandler>::stringLiteral() { return handler.newStringLiteral(stopStringCompression(), pos()); @@ -9657,7 +9662,7 @@ Parser<ParseHandler>::noSubstitutionTaggedTemplate() } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::NameNodeType Parser<ParseHandler>::noSubstitutionUntaggedTemplate() { if (!tokenStream.checkForInvalidTemplateEscapeError()) @@ -9680,7 +9685,7 @@ JSAtom * Parser<ParseHandler>::stopStringCompression() { } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::RegExpLiteralType Parser<ParseHandler>::newRegExp() { MOZ_ASSERT(!options().selfHostingMode); @@ -9700,7 +9705,7 @@ Parser<ParseHandler>::newRegExp() template <typename ParseHandler> void Parser<ParseHandler>::checkDestructuringAssignmentTarget(Node expr, TokenPos exprPos, - PossibleError* possibleError) + PossibleError* possibleError) { // Return early if a pending destructuring error is already present. if (possibleError->hasPendingDestructuringError()) @@ -10193,14 +10198,14 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling, PossibleError* if (!name) return null(); - Node nameExpr = identifierReference(name); + NameNodeType nameExpr = identifierReference(name); if (!nameExpr) return null(); if (possibleError) checkDestructuringAssignmentTarget(nameExpr, namePos, possibleError); - if (!handler.addShorthand(literal, propName, nameExpr)) + if (!handler.addShorthand(literal, handler.asName(propName), nameExpr)) return null(); } else if (propType == PropertyType::CoverInitializedName) { /* @@ -10269,14 +10274,14 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling, PossibleError* } } - Node fn = methodDefinition(namePos.begin, propType, funName); - if (!fn) + CodeNodeType funNode = methodDefinition(namePos.begin, propType, funName); + if (!funNode) return null(); - handler.checkAndSetIsDirectRHSAnonFunction(fn); + handler.checkAndSetIsDirectRHSAnonFunction(funNode); JSOp op = JSOpFromPropertyType(propType); - if (!handler.addObjectMethodDefinition(literal, propName, fn, op)) + if (!handler.addObjectMethodDefinition(literal, propName, funNode, op)) return null(); if (possibleError) { @@ -10304,7 +10309,7 @@ Parser<ParseHandler>::objectLiteral(YieldHandling yieldHandling, PossibleError* } template <typename ParseHandler> -typename ParseHandler::Node +typename ParseHandler::CodeNodeType Parser<ParseHandler>::methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName) { @@ -10357,11 +10362,11 @@ Parser<ParseHandler>::methodDefinition(uint32_t toStringStart, PropertyType prop YieldHandling yieldHandling = GetYieldHandling(generatorKind); - Node pn = handler.newFunctionExpression(); - if (!pn) + CodeNodeType funNode = handler.newFunctionExpression(); + if (!funNode) return null(); - return functionDefinition(toStringStart, pn, InAllowed, yieldHandling, funName, + return functionDefinition(toStringStart, funNode, InAllowed, yieldHandling, funName, kind, generatorKind, asyncKind); } @@ -10515,7 +10520,7 @@ Parser<ParseHandler>::primaryExpr(YieldHandling yieldHandling, TripledotHandling case TOK_THIS: { if (pc->isFunctionBox()) pc->functionBox()->usesThis = true; - Node thisName = null(); + NameNodeType thisName = null(); if (pc->sc()->thisBinding() == ThisBinding::Function) { thisName = newThisName(); if (!thisName) diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h index 332956716c..0ab23ef578 100644 --- a/js/src/frontend/Parser.h +++ b/js/src/frontend/Parser.h @@ -1085,7 +1085,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) * cx->tempLifoAlloc. */ ObjectBox* newObjectBox(JSObject* obj); - FunctionBox* newFunctionBox(Node fn, JSFunction* fun, uint32_t toStringStart, + FunctionBox* newFunctionBox(CodeNodeType funNode, JSFunction* fun, uint32_t toStringStart, Directives directives, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB); @@ -1105,9 +1105,9 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) JSAtom* stopStringCompression(); - Node stringLiteral(); + NameNodeType stringLiteral(); Node noSubstitutionTaggedTemplate(); - Node noSubstitutionUntaggedTemplate(); + NameNodeType noSubstitutionUntaggedTemplate(); ListNodeType templateLiteral(YieldHandling yieldHandling); bool taggedTemplate(YieldHandling yieldHandling, ListNodeType tagArgsList, TokenKind tt); bool appendToCallSiteObj(CallSiteNodeType callSiteObj); @@ -1115,8 +1115,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) TokenKind* ttp); bool checkStatementsEOF(); - inline Node newName(PropertyName* name); - inline Node newName(PropertyName* name, TokenPos pos); + inline NameNodeType newName(PropertyName* name); + inline NameNodeType newName(PropertyName* name, TokenPos pos); inline bool abortIfSyntaxParser(); @@ -1138,23 +1138,23 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) ListNodeType globalBody(GlobalSharedContext* globalsc); // Parse a module. - Node moduleBody(ModuleSharedContext* modulesc); + CodeNodeType moduleBody(ModuleSharedContext* modulesc); // Parse a function, used for the Function, GeneratorFunction, and // AsyncFunction constructors. - Node standaloneFunction(HandleFunction fun, HandleScope enclosingScope, - mozilla::Maybe<uint32_t> parameterListEnd, - GeneratorKind generatorKind, FunctionAsyncKind asyncKind, - Directives inheritedDirectives, Directives* newDirectives); + CodeNodeType standaloneFunction(HandleFunction fun, HandleScope enclosingScope, + mozilla::Maybe<uint32_t> parameterListEnd, + GeneratorKind generatorKind, FunctionAsyncKind asyncKind, + Directives inheritedDirectives, Directives* newDirectives); // Parse a function, given only its arguments and body. Used for lazily // parsed functions. - Node standaloneLazyFunction(HandleFunction fun, bool strict, - GeneratorKind generatorKind, FunctionAsyncKind asyncKind); + CodeNodeType standaloneLazyFunction(HandleFunction fun, bool strict, + GeneratorKind generatorKind, FunctionAsyncKind asyncKind); // Parse an inner function given an enclosing ParseContext and a // FunctionBox for the inner function. - bool innerFunction(Node pn, ParseContext* outerpc, FunctionBox* funbox, uint32_t toStringStart, + bool innerFunction(CodeNodeType funNode, ParseContext* outerpc, FunctionBox* funbox, uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind, Directives inheritedDirectives, Directives* newDirectives); @@ -1162,7 +1162,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) // Parse a function's formal parameters and its body assuming its function // ParseContext is already on the stack. bool functionFormalParametersAndBody(InHandling inHandling, YieldHandling yieldHandling, - Node pn, FunctionSyntaxKind kind, + CodeNodeType funNode, FunctionSyntaxKind kind, mozilla::Maybe<uint32_t> parameterListEnd = mozilla::Nothing(), bool isStandaloneFunction = false); @@ -1188,11 +1188,11 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) * Some parsers have two versions: an always-inlined version (with an 'i' * suffix) and a never-inlined version (with an 'n' suffix). */ - Node functionStmt(uint32_t toStringStart, - YieldHandling yieldHandling, DefaultHandling defaultHandling, - FunctionAsyncKind asyncKind = SyncFunction); - Node functionExpr(uint32_t toStringStart, InvokedPrediction invoked = PredictUninvoked, - FunctionAsyncKind asyncKind = SyncFunction); + CodeNodeType functionStmt(uint32_t toStringStart, + YieldHandling yieldHandling, DefaultHandling defaultHandling, + FunctionAsyncKind asyncKind = SyncFunction); + CodeNodeType functionExpr(uint32_t toStringStart, InvokedPrediction invoked = PredictUninvoked, + FunctionAsyncKind asyncKind = SyncFunction); ListNodeType statementList(YieldHandling yieldHandling); @@ -1222,7 +1222,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) Node variableStatement(YieldHandling yieldHandling); - Node labeledStatement(YieldHandling yieldHandling); + LabeledStatementType labeledStatement(YieldHandling yieldHandling); Node labeledItem(YieldHandling yieldHandling); TernaryNodeType ifStatement(YieldHandling yieldHandling); @@ -1295,16 +1295,16 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) Node declarationPattern(Node decl, DeclarationKind declKind, TokenKind tt, bool initialDeclaration, YieldHandling yieldHandling, ParseNodeKind* forHeadKind, Node* forInOrOfExpression); - Node declarationName(Node decl, DeclarationKind declKind, TokenKind tt, - bool initialDeclaration, YieldHandling yieldHandling, - ParseNodeKind* forHeadKind, Node* forInOrOfExpression); + NameNodeType declarationName(Node decl, 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(Node decl, Node binding, Handle<PropertyName*> name, + bool initializerInNameDeclaration(Node decl, NameNodeType binding, Handle<PropertyName*> name, DeclarationKind declKind, bool initialDeclaration, YieldHandling yieldHandling, ParseNodeKind* forHeadKind, Node* forInOrOfExpression); @@ -1346,19 +1346,19 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) bool tryNewTarget(BinaryNodeType* newTarget); bool checkAndMarkSuperScope(); - Node methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName); + CodeNodeType methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName); /* * Additional JS parsers. */ bool functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind, - Node funcpn); + CodeNodeType funNode); - Node functionDefinition(uint32_t toStringStart, Node pn, - InHandling inHandling, YieldHandling yieldHandling, HandleAtom name, - FunctionSyntaxKind kind, - GeneratorKind generatorKind, FunctionAsyncKind asyncKind, - bool tryAnnexB = false); + CodeNodeType functionDefinition(uint32_t toStringStart, CodeNodeType funNode, + InHandling inHandling, YieldHandling yieldHandling, HandleAtom name, + FunctionSyntaxKind kind, + GeneratorKind generatorKind, FunctionAsyncKind asyncKind, + bool tryAnnexB = false); // Parse a function body. Pass StatementListBody if the body is a list of // statements; pass ExpressionBody if the body is a single expression. @@ -1393,8 +1393,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) bool checkExportedNamesForDeclaration(Node node); bool checkExportedNamesForDeclarationList(ListNodeType node); - bool checkExportedNameForClause(Node node); - bool checkExportedNameForFunction(Node node); + bool checkExportedNameForClause(NameNodeType funNode); + bool checkExportedNameForFunction(CodeNodeType funNode); bool checkExportedNameForClass(ClassNodeType classNode); enum ClassContext { ClassStatement, ClassExpression }; @@ -1427,7 +1427,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) return bindingIdentifier(YieldIsName); } - Node identifierReference(Handle<PropertyName*> name); + NameNodeType identifierReference(Handle<PropertyName*> name); bool matchLabel(YieldHandling yieldHandling, MutableHandle<PropertyName*> label); @@ -1444,19 +1444,19 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) bool hasUsedFunctionSpecialName(HandlePropertyName name); bool declareFunctionArgumentsObject(); bool declareFunctionThis(); - Node newInternalDotName(HandlePropertyName name); - Node newThisName(); - Node newDotGeneratorName(); + NameNodeType newInternalDotName(HandlePropertyName name); + NameNodeType newThisName(); + NameNodeType newDotGeneratorName(); bool declareDotGeneratorName(); - bool skipLazyInnerFunction(Node pn, uint32_t toStringStart, FunctionSyntaxKind kind, + bool skipLazyInnerFunction(CodeNodeType funNode, uint32_t toStringStart, FunctionSyntaxKind kind, bool tryAnnexB); - bool innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun, uint32_t toStringStart, + bool innerFunction(CodeNodeType funNode, ParseContext* outerpc, HandleFunction fun, uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives, Directives* newDirectives); - bool trySyntaxParseInnerFunction(Node pn, HandleFunction fun, uint32_t toStringStart, + bool trySyntaxParseInnerFunction(CodeNodeType funNode, HandleFunction fun, uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, @@ -1489,9 +1489,9 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) void reportRedeclaration(HandlePropertyName name, DeclarationKind prevKind, TokenPos pos, uint32_t prevPos); - bool notePositionalFormalParameter(Node fn, HandlePropertyName name, uint32_t beginPos, + bool notePositionalFormalParameter(CodeNodeType funNode, HandlePropertyName name, uint32_t beginPos, bool disallowDuplicateParams, bool* duplicatedParam); - bool noteDestructuredPositionalFormalParameter(Node fn, Node destruct); + bool noteDestructuredPositionalFormalParameter(CodeNodeType funNode, Node destruct); mozilla::Maybe<DeclarationKind> isVarRedeclaredInEval(HandlePropertyName name, DeclarationKind kind); bool tryDeclareVar(HandlePropertyName name, DeclarationKind kind, uint32_t beginPos, @@ -1522,12 +1522,12 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) UnaryNodeType computedPropertyName(YieldHandling yieldHandling, const mozilla::Maybe<DeclarationKind>& maybeDecl, ListNodeType literal); ListNodeType arrayInitializer(YieldHandling yieldHandling, PossibleError* possibleError); - Node newRegExp(); + RegExpLiteralType newRegExp(); ListNodeType objectLiteral(YieldHandling yieldHandling, PossibleError* possibleError); BinaryNodeType bindingInitializer(Node lhs, DeclarationKind kind, YieldHandling yieldHandling); - Node bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling); + NameNodeType bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling); Node bindingIdentifierOrPattern(DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt); ListNodeType objectBindingPattern(DeclarationKind kind, YieldHandling yieldHandling); @@ -1538,7 +1538,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE) void checkDestructuringAssignmentElement(Node expr, TokenPos exprPos, PossibleError* possibleError); - Node newNumber(const Token& tok) { + NumericLiteralType newNumber(const Token& tok) { return handler.newNumber(tok.number(), tok.decimalPoint(), tok.pos); } diff --git a/js/src/frontend/SharedContext.h b/js/src/frontend/SharedContext.h index ab90953194..41e5e707a1 100644 --- a/js/src/frontend/SharedContext.h +++ b/js/src/frontend/SharedContext.h @@ -395,7 +395,7 @@ class FunctionBox : public ObjectBox, public SharedContext void initWithEnclosingScope(Scope* enclosingScope); public: - ParseNode* functionNode; /* back pointer used by asm.js for error messages */ + CodeNode* functionNode; /* back pointer used by asm.js for error messages */ uint32_t bufStart; uint32_t bufEnd; uint32_t startLine; diff --git a/js/src/frontend/SyntaxParseHandler.h b/js/src/frontend/SyntaxParseHandler.h index bb382447c6..fd7753c581 100644 --- a/js/src/frontend/SyntaxParseHandler.h +++ b/js/src/frontend/SyntaxParseHandler.h @@ -204,7 +204,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) void trace(JSTracer* trc) {} - Node newName(PropertyName* name, const TokenPos& pos, ExclusiveContext* cx) { + NameNodeType newName(PropertyName* name, const TokenPos& pos, ExclusiveContext* cx) { lastAtom = name; if (name == cx->names().arguments) return NodeUnparenthesizedArgumentsName; @@ -219,20 +219,20 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) return NodeGeneric; } - Node newObjectLiteralPropertyName(JSAtom* atom, const TokenPos& pos) { + NameNodeType newObjectLiteralPropertyName(JSAtom* atom, const TokenPos& pos) { return NodeUnparenthesizedName; } - Node newNumber(double value, DecimalPoint decimalPoint, const TokenPos& pos) { return NodeGeneric; } + NumericLiteralType newNumber(double value, DecimalPoint decimalPoint, const TokenPos& pos) { return NodeGeneric; } Node newBooleanLiteral(bool cond, const TokenPos& pos) { return NodeGeneric; } - Node newStringLiteral(JSAtom* atom, const TokenPos& pos) { + NameNodeType newStringLiteral(JSAtom* atom, const TokenPos& pos) { lastAtom = atom; lastStringPos = pos; return NodeUnparenthesizedString; } - Node newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) { + NameNodeType newTemplateStringLiteral(JSAtom* atom, const TokenPos& pos) { return NodeGeneric; } @@ -247,7 +247,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) Node newRawUndefinedLiteral(const TokenPos& pos) { return NodeGeneric; } template <class Boxer> - Node newRegExp(RegExpObject* reobj, const TokenPos& pos, Boxer& boxer) { return NodeGeneric; } + RegExpLiteralType newRegExp(RegExpObject* reobj, const TokenPos& pos, Boxer& boxer) { return NodeGeneric; } ConditionalExpressionType newConditional(Node cond, Node thenExpr, Node elseExpr) { return NodeGeneric; @@ -322,10 +322,10 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) MOZ_MUST_USE bool addPrototypeMutation(ListNodeType literal, uint32_t begin, Node expr) { return true; } MOZ_MUST_USE bool addPropertyDefinition(ListNodeType literal, Node name, Node expr) { return true; } - MOZ_MUST_USE bool addShorthand(ListNodeType literal, Node name, Node expr) { return true; } + MOZ_MUST_USE bool addShorthand(ListNodeType literal, NameNodeType name, NameNodeType expr) { return true; } MOZ_MUST_USE bool addSpreadProperty(ListNodeType literal, uint32_t begin, Node inner) { return true; } - MOZ_MUST_USE bool addObjectMethodDefinition(ListNodeType literal, Node name, Node fn, JSOp op) { return true; } - MOZ_MUST_USE bool addClassMethodDefinition(ListNodeType literal, Node name, Node fn, JSOp op, bool isStatic) { return true; } + MOZ_MUST_USE bool addObjectMethodDefinition(ListNodeType literal, Node name, CodeNodeType funNode, JSOp op) { return true; } + MOZ_MUST_USE bool addClassMethodDefinition(ListNodeType literal, Node name, CodeNodeType funNode, JSOp op, bool isStatic) { return true; } UnaryNodeType newYieldExpression(uint32_t begin, Node value) { return NodeGeneric; } UnaryNodeType newYieldStarExpression(uint32_t begin, Node value) { return NodeGeneric; } UnaryNodeType newAwaitExpression(uint32_t begin, Node value) { return NodeGeneric; } @@ -370,7 +370,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) UnaryNodeType newReturnStatement(Node expr, const TokenPos& pos) { return NodeReturn; } BinaryNodeType newWithStatement(uint32_t begin, Node expr, Node body) { return NodeGeneric; } - Node newLabeledStatement(PropertyName* label, Node stmt, uint32_t begin) { + LabeledStatementType newLabeledStatement(PropertyName* label, Node stmt, uint32_t begin) { return NodeGeneric; } @@ -380,16 +380,16 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) } Node newDebuggerStatement(const TokenPos& pos) { return NodeGeneric; } - Node newPropertyName(PropertyName* name, const TokenPos& pos) { + NameNodeType newPropertyName(PropertyName* name, const TokenPos& pos) { lastAtom = name; return NodeGeneric; } - PropertyAccessType newPropertyAccess(Node expr, Node key) { + PropertyAccessType newPropertyAccess(Node expr, NameNodeType key) { return NodeDottedProperty; } - Node newOptionalPropertyAccess(Node expr, Node key) { + Node newOptionalPropertyAccess(Node expr, NameNodeType key) { return NodeOptionalDottedProperty; } @@ -400,19 +400,19 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) MOZ_MUST_USE bool addCatchBlock(ListNodeType catchList, Node letBlock, Node catchBinding, Node catchGuard, Node catchBody) { return true; } - MOZ_MUST_USE bool setLastFunctionFormalParameterDefault(Node funcpn, Node pn) { return true; } + MOZ_MUST_USE bool setLastFunctionFormalParameterDefault(CodeNodeType funNode, Node pn) { return true; } void checkAndSetIsDirectRHSAnonFunction(Node pn) {} - Node newFunctionStatement() { return NodeFunctionDefinition; } - Node newFunctionExpression() { return NodeFunctionDefinition; } - Node newArrowFunction() { return NodeFunctionDefinition; } + CodeNodeType newFunctionStatement() { return NodeFunctionDefinition; } + CodeNodeType newFunctionExpression() { return NodeFunctionDefinition; } + CodeNodeType newArrowFunction() { return NodeFunctionDefinition; } - bool setComprehensionLambdaBody(Node pn, Node body) { return true; } - void setFunctionFormalParametersAndBody(Node pn, Node kid) {} - void setFunctionBody(Node pn, Node kid) {} - void setFunctionBox(Node pn, FunctionBox* funbox) {} - void addFunctionFormalParameter(Node pn, Node argpn) {} + bool setComprehensionLambdaBody(CodeNodeType funNode, ListNodeType body) { return true; } + void setFunctionFormalParametersAndBody(CodeNodeType funNode, ListNodeType paramsBody) {} + void setFunctionBody(CodeNodeType funNode, Node body) {} + void setFunctionBox(CodeNodeType funNode, FunctionBox* funbox) {} + void addFunctionFormalParameter(CodeNodeType funNode, Node argpn) {} ForNodeType newForStatement(uint32_t begin, TernaryNodeType forHead, Node body, unsigned iflags) { return NodeGeneric; @@ -438,7 +438,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) return NodeGeneric; } - MOZ_MUST_USE bool finishInitializerAssignment(Node pn, Node init) { return true; } + MOZ_MUST_USE bool finishInitializerAssignment(NameNodeType nameNode, Node init) { return true; } void setBeginPosition(Node pn, Node oth) {} void setBeginPosition(Node pn, uint32_t begin) {} @@ -587,8 +587,9 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) // to the unparenthesized form: return |node| unchanged. return node; } - MOZ_MUST_USE Node setLikelyIIFE(Node pn) { - return pn; // Remain in syntax-parse mode. + template <typename NodeType> + MOZ_MUST_USE NodeType setLikelyIIFE(NodeType node) { + return node; // Remain in syntax-parse mode. } void setInDirectivePrologue(UnaryNodeType exprStmt) {} |