diff --git a/js/src/frontend/BinAST.yaml b/js/src/frontend/BinAST.yaml index 7558cbf063bb..8a93490d1906 100644 --- a/js/src/frontend/BinAST.yaml +++ b/js/src/frontend/BinAST.yaml @@ -118,6 +118,7 @@ hpp: using AutoList = typename Tokenizer::AutoList; using AutoTaggedTuple = typename Tokenizer::AutoTaggedTuple; using Chars = typename Tokenizer::Chars; + using Context = typename BinASTTokenReaderBase::Context; public: // Auto-generated types. @@ -297,6 +298,8 @@ hpp: #include + #include "jstypes.h" + /** * Definition of Binary AST tokens. * @@ -625,7 +628,7 @@ BreakStatement: block: replace: | RootedAtom label(cx_); - MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom()); + MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom(fieldContext)); build: | if (label) { @@ -769,7 +772,7 @@ ContinueStatement: block: replace: | RootedAtom label(cx_); - MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom()); + MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom(fieldContext)); build: | if (label) { @@ -1282,7 +1285,7 @@ LiteralRegExpExpression: block: replace: | Chars flags(cx_); - MOZ_TRY(tokenizer_->readChars(flags)); + MOZ_TRY(tokenizer_->readChars(flags, fieldContext)); build: | RegExpFlags reflags = RegExpFlag::NoFlags; for (auto c : flags) { diff --git a/js/src/frontend/BinASTParser.cpp b/js/src/frontend/BinASTParser.cpp index ac508a5cfd96..227da371c98c 100644 --- a/js/src/frontend/BinASTParser.cpp +++ b/js/src/frontend/BinASTParser.cpp @@ -24,7 +24,7 @@ #include "frontend/ParseNode.h" #include "frontend/Parser.h" #include "frontend/SharedContext.h" -#include "js/RegExpFlags.h" // JS::RegExpFlag, JS::RegExpFlags +#include "js/RegExpFlags.h" // JS::RegExpFlag, JS::RegExpFlags #include "vm/RegExpObject.h" #include "frontend/ParseContext-inl.h" @@ -52,17 +52,17 @@ AssertedMaybePositionalParameterName ::= AssertedParameterName template JS::Result BinASTParser::parseAssertedMaybePositionalParameterName( AssertedScopeKind scopeKind, - MutableHandle> positionalParams) { + MutableHandle> positionalParams, const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL(result, - parseSumAssertedMaybePositionalParameterName( - start, kind, fields, scopeKind, positionalParams)); + BINJS_MOZ_TRY_DECL( + result, parseSumAssertedMaybePositionalParameterName( + start, kind, fields, scopeKind, positionalParams, context)); MOZ_TRY(guard.done()); return result; @@ -72,7 +72,7 @@ template JS::Result BinASTParser::parseSumAssertedMaybePositionalParameterName( const size_t start, const BinASTKind kind, const BinASTFields& fields, AssertedScopeKind scopeKind, - MutableHandle> positionalParams) { + MutableHandle> positionalParams, const Context& context) { Ok result; switch (kind) { case BinASTKind::AssertedParameterName: @@ -80,9 +80,9 @@ JS::Result BinASTParser::parseSumAssertedMaybePositionalParameterName( "FIXME: Not implemented yet in this preview release " "(AssertedParameterName)"); case BinASTKind::AssertedPositionalParameterName: - MOZ_TRY_VAR(result, - parseInterfaceAssertedPositionalParameterName( - start, kind, fields, scopeKind, positionalParams)); + MOZ_TRY_VAR(result, parseInterfaceAssertedPositionalParameterName( + start, kind, fields, scopeKind, positionalParams, + context)); break; case BinASTKind::AssertedRestParameterName: return raiseError( @@ -102,15 +102,17 @@ AssignmentTarget ::= ArrayAssignmentTarget StaticMemberAssignmentTarget */ template -JS::Result BinASTParser::parseAssignmentTarget() { +JS::Result BinASTParser::parseAssignmentTarget( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL(result, parseSumAssignmentTarget(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, + parseSumAssignmentTarget(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -118,28 +120,29 @@ JS::Result BinASTParser::parseAssignmentTarget() { template JS::Result BinASTParser::parseSumAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::ArrayAssignmentTarget: - MOZ_TRY_VAR(result, - parseInterfaceArrayAssignmentTarget(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceArrayAssignmentTarget(start, kind, + fields, context)); break; case BinASTKind::AssignmentTargetIdentifier: - MOZ_TRY_VAR(result, parseInterfaceAssignmentTargetIdentifier(start, kind, - fields)); + MOZ_TRY_VAR(result, parseInterfaceAssignmentTargetIdentifier( + start, kind, fields, context)); break; case BinASTKind::ComputedMemberAssignmentTarget: MOZ_TRY_VAR(result, parseInterfaceComputedMemberAssignmentTarget( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::ObjectAssignmentTarget: - MOZ_TRY_VAR(result, - parseInterfaceObjectAssignmentTarget(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceObjectAssignmentTarget( + start, kind, fields, context)); break; case BinASTKind::StaticMemberAssignmentTarget: MOZ_TRY_VAR(result, parseInterfaceStaticMemberAssignmentTarget( - start, kind, fields)); + start, kind, fields, context)); break; default: return raiseInvalidKind("AssignmentTarget", kind); @@ -153,15 +156,15 @@ Binding ::= ArrayBinding ObjectBinding */ template -JS::Result BinASTParser::parseBinding() { +JS::Result BinASTParser::parseBinding(const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL(result, parseSumBinding(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, parseSumBinding(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -169,17 +172,21 @@ JS::Result BinASTParser::parseBinding() { template JS::Result BinASTParser::parseSumBinding( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::ArrayBinding: - MOZ_TRY_VAR(result, parseInterfaceArrayBinding(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceArrayBinding(start, kind, fields, context)); break; case BinASTKind::BindingIdentifier: - MOZ_TRY_VAR(result, parseInterfaceBindingIdentifier(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceBindingIdentifier(start, kind, fields, + context)); break; case BinASTKind::ObjectBinding: - MOZ_TRY_VAR(result, parseInterfaceObjectBinding(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceObjectBinding(start, kind, fields, context)); break; default: return raiseInvalidKind("Binding", kind); @@ -222,15 +229,16 @@ Expression ::= ArrayExpression YieldStarExpression */ template -JS::Result BinASTParser::parseExpression() { +JS::Result BinASTParser::parseExpression( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL(result, parseSumExpression(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, parseSumExpression(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -238,125 +246,137 @@ JS::Result BinASTParser::parseExpression() { template JS::Result BinASTParser::parseSumExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::ArrayExpression: - MOZ_TRY_VAR(result, parseInterfaceArrayExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceArrayExpression(start, kind, fields, context)); break; case BinASTKind::AssignmentExpression: - MOZ_TRY_VAR(result, - parseInterfaceAssignmentExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression(start, kind, + fields, context)); break; case BinASTKind::AwaitExpression: - MOZ_TRY_VAR(result, parseInterfaceAwaitExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceAwaitExpression(start, kind, fields, context)); break; case BinASTKind::BinaryExpression: - MOZ_TRY_VAR(result, parseInterfaceBinaryExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceBinaryExpression(start, kind, fields, context)); break; case BinASTKind::CallExpression: - MOZ_TRY_VAR(result, parseInterfaceCallExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceCallExpression(start, kind, fields, context)); break; case BinASTKind::ClassExpression: - MOZ_TRY_VAR(result, parseInterfaceClassExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceClassExpression(start, kind, fields, context)); break; case BinASTKind::CompoundAssignmentExpression: MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::ComputedMemberExpression: - MOZ_TRY_VAR(result, - parseInterfaceComputedMemberExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression( + start, kind, fields, context)); break; case BinASTKind::ConditionalExpression: - MOZ_TRY_VAR(result, - parseInterfaceConditionalExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceConditionalExpression(start, kind, + fields, context)); break; case BinASTKind::EagerArrowExpressionWithExpression: MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithExpression( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::EagerArrowExpressionWithFunctionBody: MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithFunctionBody( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::EagerFunctionExpression: - MOZ_TRY_VAR(result, - parseInterfaceEagerFunctionExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression( + start, kind, fields, context)); break; case BinASTKind::IdentifierExpression: - MOZ_TRY_VAR(result, - parseInterfaceIdentifierExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression(start, kind, + fields, context)); break; case BinASTKind::LazyArrowExpressionWithExpression: MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithExpression( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::LazyArrowExpressionWithFunctionBody: MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithFunctionBody( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::LazyFunctionExpression: - MOZ_TRY_VAR(result, - parseInterfaceLazyFunctionExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLazyFunctionExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralBooleanExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralBooleanExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralInfinityExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralInfinityExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralInfinityExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralNullExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralNullExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralNullExpression(start, kind, + fields, context)); break; case BinASTKind::LiteralNumericExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralNumericExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralNumericExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralRegExpExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralRegExpExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralRegExpExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralStringExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralStringExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralStringExpression( + start, kind, fields, context)); break; case BinASTKind::NewExpression: - MOZ_TRY_VAR(result, parseInterfaceNewExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceNewExpression(start, kind, fields, context)); break; case BinASTKind::NewTargetExpression: - MOZ_TRY_VAR(result, - parseInterfaceNewTargetExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression(start, kind, fields, + context)); break; case BinASTKind::ObjectExpression: - MOZ_TRY_VAR(result, parseInterfaceObjectExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceObjectExpression(start, kind, fields, context)); break; case BinASTKind::StaticMemberExpression: - MOZ_TRY_VAR(result, - parseInterfaceStaticMemberExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression( + start, kind, fields, context)); break; case BinASTKind::TemplateExpression: - MOZ_TRY_VAR(result, - parseInterfaceTemplateExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceTemplateExpression(start, kind, fields, + context)); break; case BinASTKind::ThisExpression: - MOZ_TRY_VAR(result, parseInterfaceThisExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceThisExpression(start, kind, fields, context)); break; case BinASTKind::UnaryExpression: - MOZ_TRY_VAR(result, parseInterfaceUnaryExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceUnaryExpression(start, kind, fields, context)); break; case BinASTKind::UpdateExpression: - MOZ_TRY_VAR(result, parseInterfaceUpdateExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceUpdateExpression(start, kind, fields, context)); break; case BinASTKind::YieldExpression: - MOZ_TRY_VAR(result, parseInterfaceYieldExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceYieldExpression(start, kind, fields, context)); break; case BinASTKind::YieldStarExpression: - MOZ_TRY_VAR(result, - parseInterfaceYieldStarExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceYieldStarExpression(start, kind, fields, + context)); break; default: return raiseInvalidKind("Expression", kind); @@ -400,15 +420,17 @@ ExpressionOrSuper ::= ArrayExpression YieldStarExpression */ template -JS::Result BinASTParser::parseExpressionOrSuper() { +JS::Result BinASTParser::parseExpressionOrSuper( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL(result, parseSumExpressionOrSuper(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, + parseSumExpressionOrSuper(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -416,128 +438,140 @@ JS::Result BinASTParser::parseExpressionOrSuper() { template JS::Result BinASTParser::parseSumExpressionOrSuper( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::ArrayExpression: - MOZ_TRY_VAR(result, parseInterfaceArrayExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceArrayExpression(start, kind, fields, context)); break; case BinASTKind::AssignmentExpression: - MOZ_TRY_VAR(result, - parseInterfaceAssignmentExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression(start, kind, + fields, context)); break; case BinASTKind::AwaitExpression: - MOZ_TRY_VAR(result, parseInterfaceAwaitExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceAwaitExpression(start, kind, fields, context)); break; case BinASTKind::BinaryExpression: - MOZ_TRY_VAR(result, parseInterfaceBinaryExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceBinaryExpression(start, kind, fields, context)); break; case BinASTKind::CallExpression: - MOZ_TRY_VAR(result, parseInterfaceCallExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceCallExpression(start, kind, fields, context)); break; case BinASTKind::ClassExpression: - MOZ_TRY_VAR(result, parseInterfaceClassExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceClassExpression(start, kind, fields, context)); break; case BinASTKind::CompoundAssignmentExpression: MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::ComputedMemberExpression: - MOZ_TRY_VAR(result, - parseInterfaceComputedMemberExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression( + start, kind, fields, context)); break; case BinASTKind::ConditionalExpression: - MOZ_TRY_VAR(result, - parseInterfaceConditionalExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceConditionalExpression(start, kind, + fields, context)); break; case BinASTKind::EagerArrowExpressionWithExpression: MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithExpression( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::EagerArrowExpressionWithFunctionBody: MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithFunctionBody( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::EagerFunctionExpression: - MOZ_TRY_VAR(result, - parseInterfaceEagerFunctionExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression( + start, kind, fields, context)); break; case BinASTKind::IdentifierExpression: - MOZ_TRY_VAR(result, - parseInterfaceIdentifierExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression(start, kind, + fields, context)); break; case BinASTKind::LazyArrowExpressionWithExpression: MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithExpression( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::LazyArrowExpressionWithFunctionBody: MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithFunctionBody( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::LazyFunctionExpression: - MOZ_TRY_VAR(result, - parseInterfaceLazyFunctionExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLazyFunctionExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralBooleanExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralBooleanExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralInfinityExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralInfinityExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralInfinityExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralNullExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralNullExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralNullExpression(start, kind, + fields, context)); break; case BinASTKind::LiteralNumericExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralNumericExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralNumericExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralRegExpExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralRegExpExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralRegExpExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralStringExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralStringExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralStringExpression( + start, kind, fields, context)); break; case BinASTKind::NewExpression: - MOZ_TRY_VAR(result, parseInterfaceNewExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceNewExpression(start, kind, fields, context)); break; case BinASTKind::NewTargetExpression: - MOZ_TRY_VAR(result, - parseInterfaceNewTargetExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression(start, kind, fields, + context)); break; case BinASTKind::ObjectExpression: - MOZ_TRY_VAR(result, parseInterfaceObjectExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceObjectExpression(start, kind, fields, context)); break; case BinASTKind::StaticMemberExpression: - MOZ_TRY_VAR(result, - parseInterfaceStaticMemberExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression( + start, kind, fields, context)); break; case BinASTKind::Super: - MOZ_TRY_VAR(result, parseInterfaceSuper(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceSuper(start, kind, fields, context)); break; case BinASTKind::TemplateExpression: - MOZ_TRY_VAR(result, - parseInterfaceTemplateExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceTemplateExpression(start, kind, fields, + context)); break; case BinASTKind::ThisExpression: - MOZ_TRY_VAR(result, parseInterfaceThisExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceThisExpression(start, kind, fields, context)); break; case BinASTKind::UnaryExpression: - MOZ_TRY_VAR(result, parseInterfaceUnaryExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceUnaryExpression(start, kind, fields, context)); break; case BinASTKind::UpdateExpression: - MOZ_TRY_VAR(result, parseInterfaceUpdateExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceUpdateExpression(start, kind, fields, context)); break; case BinASTKind::YieldExpression: - MOZ_TRY_VAR(result, parseInterfaceYieldExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceYieldExpression(start, kind, fields, context)); break; case BinASTKind::YieldStarExpression: - MOZ_TRY_VAR(result, - parseInterfaceYieldStarExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceYieldStarExpression(start, kind, fields, + context)); break; default: return raiseInvalidKind("ExpressionOrSuper", kind); @@ -554,17 +588,17 @@ ForInOfBindingOrAssignmentTarget ::= ArrayAssignmentTarget StaticMemberAssignmentTarget */ template -JS::Result -BinASTParser::parseForInOfBindingOrAssignmentTarget() { +JS::Result BinASTParser::parseForInOfBindingOrAssignmentTarget( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL( - result, parseSumForInOfBindingOrAssignmentTarget(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, parseSumForInOfBindingOrAssignmentTarget( + start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -573,31 +607,33 @@ BinASTParser::parseForInOfBindingOrAssignmentTarget() { template JS::Result BinASTParser::parseSumForInOfBindingOrAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::ArrayAssignmentTarget: - MOZ_TRY_VAR(result, - parseInterfaceArrayAssignmentTarget(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceArrayAssignmentTarget(start, kind, + fields, context)); break; case BinASTKind::AssignmentTargetIdentifier: - MOZ_TRY_VAR(result, parseInterfaceAssignmentTargetIdentifier(start, kind, - fields)); + MOZ_TRY_VAR(result, parseInterfaceAssignmentTargetIdentifier( + start, kind, fields, context)); break; case BinASTKind::ComputedMemberAssignmentTarget: MOZ_TRY_VAR(result, parseInterfaceComputedMemberAssignmentTarget( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::ForInOfBinding: - MOZ_TRY_VAR(result, parseInterfaceForInOfBinding(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceForInOfBinding(start, kind, fields, context)); break; case BinASTKind::ObjectAssignmentTarget: - MOZ_TRY_VAR(result, - parseInterfaceObjectAssignmentTarget(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceObjectAssignmentTarget( + start, kind, fields, context)); break; case BinASTKind::StaticMemberAssignmentTarget: MOZ_TRY_VAR(result, parseInterfaceStaticMemberAssignmentTarget( - start, kind, fields)); + start, kind, fields, context)); break; default: return raiseInvalidKind("ForInOfBindingOrAssignmentTarget", kind); @@ -616,15 +652,17 @@ ObjectProperty ::= DataProperty ShorthandProperty */ template -JS::Result BinASTParser::parseObjectProperty() { +JS::Result BinASTParser::parseObjectProperty( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL(result, parseSumObjectProperty(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, + parseSumObjectProperty(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -632,32 +670,41 @@ JS::Result BinASTParser::parseObjectProperty() { template JS::Result BinASTParser::parseSumObjectProperty( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::DataProperty: - MOZ_TRY_VAR(result, parseInterfaceDataProperty(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceDataProperty(start, kind, fields, context)); break; case BinASTKind::EagerGetter: - MOZ_TRY_VAR(result, parseInterfaceEagerGetter(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceEagerGetter(start, kind, fields, context)); break; case BinASTKind::EagerMethod: - MOZ_TRY_VAR(result, parseInterfaceEagerMethod(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceEagerMethod(start, kind, fields, context)); break; case BinASTKind::EagerSetter: - MOZ_TRY_VAR(result, parseInterfaceEagerSetter(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceEagerSetter(start, kind, fields, context)); break; case BinASTKind::LazyGetter: - MOZ_TRY_VAR(result, parseInterfaceLazyGetter(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceLazyGetter(start, kind, fields, context)); break; case BinASTKind::LazyMethod: - MOZ_TRY_VAR(result, parseInterfaceLazyMethod(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceLazyMethod(start, kind, fields, context)); break; case BinASTKind::LazySetter: - MOZ_TRY_VAR(result, parseInterfaceLazySetter(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceLazySetter(start, kind, fields, context)); break; case BinASTKind::ShorthandProperty: - MOZ_TRY_VAR(result, parseInterfaceShorthandProperty(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceShorthandProperty(start, kind, fields, + context)); break; default: return raiseInvalidKind("ObjectProperty", kind); @@ -672,15 +719,16 @@ Parameter ::= ArrayBinding ObjectBinding */ template -JS::Result BinASTParser::parseParameter() { +JS::Result BinASTParser::parseParameter( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL(result, parseSumParameter(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, parseSumParameter(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -688,14 +736,17 @@ JS::Result BinASTParser::parseParameter() { template JS::Result BinASTParser::parseSumParameter( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::ArrayBinding: - MOZ_TRY_VAR(result, parseInterfaceArrayBinding(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceArrayBinding(start, kind, fields, context)); break; case BinASTKind::BindingIdentifier: - MOZ_TRY_VAR(result, parseInterfaceBindingIdentifier(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceBindingIdentifier(start, kind, fields, + context)); if (!pc_->positionalFormalParameterNames().append( result->template as().atom())) { return raiseOOM(); @@ -705,11 +756,12 @@ JS::Result BinASTParser::parseSumParameter( } break; case BinASTKind::BindingWithInitializer: - MOZ_TRY_VAR(result, - parseInterfaceBindingWithInitializer(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceBindingWithInitializer( + start, kind, fields, context)); break; case BinASTKind::ObjectBinding: - MOZ_TRY_VAR(result, parseInterfaceObjectBinding(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceObjectBinding(start, kind, fields, context)); break; default: return raiseInvalidKind("Parameter", kind); @@ -722,15 +774,15 @@ Program ::= Module Script */ template -JS::Result BinASTParser::parseProgram() { +JS::Result BinASTParser::parseProgram(const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL(result, parseSumProgram(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, parseSumProgram(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -738,14 +790,15 @@ JS::Result BinASTParser::parseProgram() { template JS::Result BinASTParser::parseSumProgram( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::Module: - MOZ_TRY_VAR(result, parseInterfaceModule(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceModule(start, kind, fields, context)); break; case BinASTKind::Script: - MOZ_TRY_VAR(result, parseInterfaceScript(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceScript(start, kind, fields, context)); break; default: return raiseInvalidKind("Program", kind); @@ -758,15 +811,17 @@ PropertyName ::= ComputedPropertyName LiteralPropertyName */ template -JS::Result BinASTParser::parsePropertyName() { +JS::Result BinASTParser::parsePropertyName( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL(result, parseSumPropertyName(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, + parseSumPropertyName(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -774,16 +829,17 @@ JS::Result BinASTParser::parsePropertyName() { template JS::Result BinASTParser::parseSumPropertyName( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::ComputedPropertyName: - MOZ_TRY_VAR(result, - parseInterfaceComputedPropertyName(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceComputedPropertyName(start, kind, + fields, context)); break; case BinASTKind::LiteralPropertyName: - MOZ_TRY_VAR(result, - parseInterfaceLiteralPropertyName(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralPropertyName(start, kind, fields, + context)); break; default: return raiseInvalidKind("PropertyName", kind); @@ -797,16 +853,17 @@ SimpleAssignmentTarget ::= AssignmentTargetIdentifier StaticMemberAssignmentTarget */ template -JS::Result BinASTParser::parseSimpleAssignmentTarget() { +JS::Result BinASTParser::parseSimpleAssignmentTarget( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL(result, - parseSumSimpleAssignmentTarget(start, kind, fields)); + BINJS_MOZ_TRY_DECL( + result, parseSumSimpleAssignmentTarget(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -814,20 +871,21 @@ JS::Result BinASTParser::parseSimpleAssignmentTarget() { template JS::Result BinASTParser::parseSumSimpleAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::AssignmentTargetIdentifier: - MOZ_TRY_VAR(result, parseInterfaceAssignmentTargetIdentifier(start, kind, - fields)); + MOZ_TRY_VAR(result, parseInterfaceAssignmentTargetIdentifier( + start, kind, fields, context)); break; case BinASTKind::ComputedMemberAssignmentTarget: MOZ_TRY_VAR(result, parseInterfaceComputedMemberAssignmentTarget( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::StaticMemberAssignmentTarget: MOZ_TRY_VAR(result, parseInterfaceStaticMemberAssignmentTarget( - start, kind, fields)); + start, kind, fields, context)); break; default: return raiseInvalidKind("SimpleAssignmentTarget", kind); @@ -871,16 +929,17 @@ SpreadElementOrExpression ::= ArrayExpression YieldStarExpression */ template -JS::Result BinASTParser::parseSpreadElementOrExpression() { +JS::Result BinASTParser::parseSpreadElementOrExpression( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL(result, - parseSumSpreadElementOrExpression(start, kind, fields)); + BINJS_MOZ_TRY_DECL( + result, parseSumSpreadElementOrExpression(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -888,128 +947,141 @@ JS::Result BinASTParser::parseSpreadElementOrExpression() { template JS::Result BinASTParser::parseSumSpreadElementOrExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::ArrayExpression: - MOZ_TRY_VAR(result, parseInterfaceArrayExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceArrayExpression(start, kind, fields, context)); break; case BinASTKind::AssignmentExpression: - MOZ_TRY_VAR(result, - parseInterfaceAssignmentExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression(start, kind, + fields, context)); break; case BinASTKind::AwaitExpression: - MOZ_TRY_VAR(result, parseInterfaceAwaitExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceAwaitExpression(start, kind, fields, context)); break; case BinASTKind::BinaryExpression: - MOZ_TRY_VAR(result, parseInterfaceBinaryExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceBinaryExpression(start, kind, fields, context)); break; case BinASTKind::CallExpression: - MOZ_TRY_VAR(result, parseInterfaceCallExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceCallExpression(start, kind, fields, context)); break; case BinASTKind::ClassExpression: - MOZ_TRY_VAR(result, parseInterfaceClassExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceClassExpression(start, kind, fields, context)); break; case BinASTKind::CompoundAssignmentExpression: MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::ComputedMemberExpression: - MOZ_TRY_VAR(result, - parseInterfaceComputedMemberExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression( + start, kind, fields, context)); break; case BinASTKind::ConditionalExpression: - MOZ_TRY_VAR(result, - parseInterfaceConditionalExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceConditionalExpression(start, kind, + fields, context)); break; case BinASTKind::EagerArrowExpressionWithExpression: MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithExpression( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::EagerArrowExpressionWithFunctionBody: MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithFunctionBody( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::EagerFunctionExpression: - MOZ_TRY_VAR(result, - parseInterfaceEagerFunctionExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression( + start, kind, fields, context)); break; case BinASTKind::IdentifierExpression: - MOZ_TRY_VAR(result, - parseInterfaceIdentifierExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression(start, kind, + fields, context)); break; case BinASTKind::LazyArrowExpressionWithExpression: MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithExpression( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::LazyArrowExpressionWithFunctionBody: MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithFunctionBody( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::LazyFunctionExpression: - MOZ_TRY_VAR(result, - parseInterfaceLazyFunctionExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLazyFunctionExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralBooleanExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralBooleanExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralInfinityExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralInfinityExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralInfinityExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralNullExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralNullExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralNullExpression(start, kind, + fields, context)); break; case BinASTKind::LiteralNumericExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralNumericExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralNumericExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralRegExpExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralRegExpExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralRegExpExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralStringExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralStringExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralStringExpression( + start, kind, fields, context)); break; case BinASTKind::NewExpression: - MOZ_TRY_VAR(result, parseInterfaceNewExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceNewExpression(start, kind, fields, context)); break; case BinASTKind::NewTargetExpression: - MOZ_TRY_VAR(result, - parseInterfaceNewTargetExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression(start, kind, fields, + context)); break; case BinASTKind::ObjectExpression: - MOZ_TRY_VAR(result, parseInterfaceObjectExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceObjectExpression(start, kind, fields, context)); break; case BinASTKind::SpreadElement: - MOZ_TRY_VAR(result, parseInterfaceSpreadElement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceSpreadElement(start, kind, fields, context)); break; case BinASTKind::StaticMemberExpression: - MOZ_TRY_VAR(result, - parseInterfaceStaticMemberExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression( + start, kind, fields, context)); break; case BinASTKind::TemplateExpression: - MOZ_TRY_VAR(result, - parseInterfaceTemplateExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceTemplateExpression(start, kind, fields, + context)); break; case BinASTKind::ThisExpression: - MOZ_TRY_VAR(result, parseInterfaceThisExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceThisExpression(start, kind, fields, context)); break; case BinASTKind::UnaryExpression: - MOZ_TRY_VAR(result, parseInterfaceUnaryExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceUnaryExpression(start, kind, fields, context)); break; case BinASTKind::UpdateExpression: - MOZ_TRY_VAR(result, parseInterfaceUpdateExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceUpdateExpression(start, kind, fields, context)); break; case BinASTKind::YieldExpression: - MOZ_TRY_VAR(result, parseInterfaceYieldExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceYieldExpression(start, kind, fields, context)); break; case BinASTKind::YieldStarExpression: - MOZ_TRY_VAR(result, - parseInterfaceYieldStarExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceYieldStarExpression(start, kind, fields, + context)); break; default: return raiseInvalidKind("SpreadElementOrExpression", kind); @@ -1044,15 +1116,16 @@ Statement ::= Block WithStatement */ template -JS::Result BinASTParser::parseStatement() { +JS::Result BinASTParser::parseStatement( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); - BINJS_MOZ_TRY_DECL(result, parseSumStatement(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, parseSumStatement(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -1060,86 +1133,104 @@ JS::Result BinASTParser::parseStatement() { template JS::Result BinASTParser::parseSumStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::Block: - MOZ_TRY_VAR(result, parseInterfaceBlock(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceBlock(start, kind, fields, context)); break; case BinASTKind::BreakStatement: - MOZ_TRY_VAR(result, parseInterfaceBreakStatement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceBreakStatement(start, kind, fields, context)); break; case BinASTKind::ClassDeclaration: - MOZ_TRY_VAR(result, parseInterfaceClassDeclaration(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceClassDeclaration(start, kind, fields, context)); break; case BinASTKind::ContinueStatement: - MOZ_TRY_VAR(result, parseInterfaceContinueStatement(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceContinueStatement(start, kind, fields, + context)); break; case BinASTKind::DebuggerStatement: - MOZ_TRY_VAR(result, parseInterfaceDebuggerStatement(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceDebuggerStatement(start, kind, fields, + context)); break; case BinASTKind::DoWhileStatement: - MOZ_TRY_VAR(result, parseInterfaceDoWhileStatement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceDoWhileStatement(start, kind, fields, context)); break; case BinASTKind::EagerFunctionDeclaration: - MOZ_TRY_VAR(result, - parseInterfaceEagerFunctionDeclaration(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionDeclaration( + start, kind, fields, context)); break; case BinASTKind::EmptyStatement: - MOZ_TRY_VAR(result, parseInterfaceEmptyStatement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceEmptyStatement(start, kind, fields, context)); break; case BinASTKind::ExpressionStatement: - MOZ_TRY_VAR(result, - parseInterfaceExpressionStatement(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceExpressionStatement(start, kind, fields, + context)); break; case BinASTKind::ForInStatement: - MOZ_TRY_VAR(result, parseInterfaceForInStatement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceForInStatement(start, kind, fields, context)); break; case BinASTKind::ForOfStatement: - MOZ_TRY_VAR(result, parseInterfaceForOfStatement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceForOfStatement(start, kind, fields, context)); break; case BinASTKind::ForStatement: - MOZ_TRY_VAR(result, parseInterfaceForStatement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceForStatement(start, kind, fields, context)); break; case BinASTKind::IfStatement: - MOZ_TRY_VAR(result, parseInterfaceIfStatement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceIfStatement(start, kind, fields, context)); break; case BinASTKind::LabelledStatement: - MOZ_TRY_VAR(result, parseInterfaceLabelledStatement(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLabelledStatement(start, kind, fields, + context)); break; case BinASTKind::LazyFunctionDeclaration: - MOZ_TRY_VAR(result, - parseInterfaceLazyFunctionDeclaration(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLazyFunctionDeclaration( + start, kind, fields, context)); break; case BinASTKind::ReturnStatement: - MOZ_TRY_VAR(result, parseInterfaceReturnStatement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceReturnStatement(start, kind, fields, context)); break; case BinASTKind::SwitchStatement: - MOZ_TRY_VAR(result, parseInterfaceSwitchStatement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceSwitchStatement(start, kind, fields, context)); break; case BinASTKind::SwitchStatementWithDefault: - MOZ_TRY_VAR(result, parseInterfaceSwitchStatementWithDefault(start, kind, - fields)); + MOZ_TRY_VAR(result, parseInterfaceSwitchStatementWithDefault( + start, kind, fields, context)); break; case BinASTKind::ThrowStatement: - MOZ_TRY_VAR(result, parseInterfaceThrowStatement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceThrowStatement(start, kind, fields, context)); break; case BinASTKind::TryCatchStatement: - MOZ_TRY_VAR(result, parseInterfaceTryCatchStatement(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceTryCatchStatement(start, kind, fields, + context)); break; case BinASTKind::TryFinallyStatement: - MOZ_TRY_VAR(result, - parseInterfaceTryFinallyStatement(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceTryFinallyStatement(start, kind, fields, + context)); break; case BinASTKind::VariableDeclaration: - MOZ_TRY_VAR(result, - parseInterfaceVariableDeclaration(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceVariableDeclaration(start, kind, fields, + context)); break; case BinASTKind::WhileStatement: - MOZ_TRY_VAR(result, parseInterfaceWhileStatement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceWhileStatement(start, kind, fields, context)); break; case BinASTKind::WithStatement: - MOZ_TRY_VAR(result, parseInterfaceWithStatement(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceWithStatement(start, kind, fields, context)); break; default: return raiseInvalidKind("Statement", kind); @@ -1150,129 +1241,141 @@ JS::Result BinASTParser::parseSumStatement( template JS::Result BinASTParser::parseSumVariableDeclarationOrExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { ParseNode* result; switch (kind) { case BinASTKind::ArrayExpression: - MOZ_TRY_VAR(result, parseInterfaceArrayExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceArrayExpression(start, kind, fields, context)); break; case BinASTKind::AssignmentExpression: - MOZ_TRY_VAR(result, - parseInterfaceAssignmentExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression(start, kind, + fields, context)); break; case BinASTKind::AwaitExpression: - MOZ_TRY_VAR(result, parseInterfaceAwaitExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceAwaitExpression(start, kind, fields, context)); break; case BinASTKind::BinaryExpression: - MOZ_TRY_VAR(result, parseInterfaceBinaryExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceBinaryExpression(start, kind, fields, context)); break; case BinASTKind::CallExpression: - MOZ_TRY_VAR(result, parseInterfaceCallExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceCallExpression(start, kind, fields, context)); break; case BinASTKind::ClassExpression: - MOZ_TRY_VAR(result, parseInterfaceClassExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceClassExpression(start, kind, fields, context)); break; case BinASTKind::CompoundAssignmentExpression: MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::ComputedMemberExpression: - MOZ_TRY_VAR(result, - parseInterfaceComputedMemberExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression( + start, kind, fields, context)); break; case BinASTKind::ConditionalExpression: - MOZ_TRY_VAR(result, - parseInterfaceConditionalExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceConditionalExpression(start, kind, + fields, context)); break; case BinASTKind::EagerArrowExpressionWithExpression: MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithExpression( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::EagerArrowExpressionWithFunctionBody: MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpressionWithFunctionBody( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::EagerFunctionExpression: - MOZ_TRY_VAR(result, - parseInterfaceEagerFunctionExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression( + start, kind, fields, context)); break; case BinASTKind::IdentifierExpression: - MOZ_TRY_VAR(result, - parseInterfaceIdentifierExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression(start, kind, + fields, context)); break; case BinASTKind::LazyArrowExpressionWithExpression: MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithExpression( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::LazyArrowExpressionWithFunctionBody: MOZ_TRY_VAR(result, parseInterfaceLazyArrowExpressionWithFunctionBody( - start, kind, fields)); + start, kind, fields, context)); break; case BinASTKind::LazyFunctionExpression: - MOZ_TRY_VAR(result, - parseInterfaceLazyFunctionExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLazyFunctionExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralBooleanExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralBooleanExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralInfinityExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralInfinityExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralInfinityExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralNullExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralNullExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralNullExpression(start, kind, + fields, context)); break; case BinASTKind::LiteralNumericExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralNumericExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralNumericExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralRegExpExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralRegExpExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralRegExpExpression( + start, kind, fields, context)); break; case BinASTKind::LiteralStringExpression: - MOZ_TRY_VAR(result, - parseInterfaceLiteralStringExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceLiteralStringExpression( + start, kind, fields, context)); break; case BinASTKind::NewExpression: - MOZ_TRY_VAR(result, parseInterfaceNewExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceNewExpression(start, kind, fields, context)); break; case BinASTKind::NewTargetExpression: - MOZ_TRY_VAR(result, - parseInterfaceNewTargetExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression(start, kind, fields, + context)); break; case BinASTKind::ObjectExpression: - MOZ_TRY_VAR(result, parseInterfaceObjectExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceObjectExpression(start, kind, fields, context)); break; case BinASTKind::StaticMemberExpression: - MOZ_TRY_VAR(result, - parseInterfaceStaticMemberExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression( + start, kind, fields, context)); break; case BinASTKind::TemplateExpression: - MOZ_TRY_VAR(result, - parseInterfaceTemplateExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceTemplateExpression(start, kind, fields, + context)); break; case BinASTKind::ThisExpression: - MOZ_TRY_VAR(result, parseInterfaceThisExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceThisExpression(start, kind, fields, context)); break; case BinASTKind::UnaryExpression: - MOZ_TRY_VAR(result, parseInterfaceUnaryExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceUnaryExpression(start, kind, fields, context)); break; case BinASTKind::UpdateExpression: - MOZ_TRY_VAR(result, parseInterfaceUpdateExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceUpdateExpression(start, kind, fields, context)); break; case BinASTKind::VariableDeclaration: - MOZ_TRY_VAR(result, - parseInterfaceVariableDeclaration(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceVariableDeclaration(start, kind, fields, + context)); break; case BinASTKind::YieldExpression: - MOZ_TRY_VAR(result, parseInterfaceYieldExpression(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceYieldExpression(start, kind, fields, context)); break; case BinASTKind::YieldStarExpression: - MOZ_TRY_VAR(result, - parseInterfaceYieldStarExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseInterfaceYieldStarExpression(start, kind, fields, + context)); break; default: return raiseInvalidKind("VariableDeclarationOrExpression", kind); @@ -1285,7 +1388,8 @@ BinASTParser::parseSumVariableDeclarationOrExpression( // delegated to another parser. template JS::Result BinASTParser::parseInterfaceArrayAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release " "(ArrayAssignmentTarget)"); @@ -1293,23 +1397,27 @@ JS::Result BinASTParser::parseInterfaceArrayAssignmentTarget( template JS::Result BinASTParser::parseInterfaceArrayBinding( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (ArrayBinding)"); } template JS::Result BinASTParser::parseInterfaceArrayExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ArrayExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Elements}; MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(elements, parseListOfOptionalSpreadElementOrExpression()); + BINJS_MOZ_TRY_DECL( + elements, parseListOfOptionalSpreadElementOrExpression(fieldContext++)); if (elements->empty()) { elements->setHasNonConstInitializer(); @@ -1325,18 +1433,19 @@ JS::Result BinASTParser::parseInterfaceArrayExpression( } */ template -JS::Result BinASTParser::parseAssertedBlockScope() { +JS::Result BinASTParser::parseAssertedBlockScope( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::AssertedBlockScope) { return raiseInvalidKind("AssertedBlockScope", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceAssertedBlockScope(start, kind, fields)); + BINJS_MOZ_TRY_DECL( + result, parseInterfaceAssertedBlockScope(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -1344,9 +1453,11 @@ JS::Result BinASTParser::parseAssertedBlockScope() { template JS::Result BinASTParser::parseInterfaceAssertedBlockScope( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::AssertedBlockScope); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::DeclaredNames, @@ -1355,9 +1466,9 @@ JS::Result BinASTParser::parseInterfaceAssertedBlockScope( #endif // defined(DEBUG) const auto scopeKind = AssertedScopeKind::Block; - MOZ_TRY(parseListOfAssertedDeclaredName(scopeKind)); + MOZ_TRY(parseListOfAssertedDeclaredName(scopeKind, fieldContext++)); - BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool(fieldContext++)); if (hasDirectEval) { pc_->sc()->setHasDirectEval(); pc_->sc()->setBindingsAccessedDynamically(); @@ -1379,18 +1490,18 @@ JS::Result BinASTParser::parseInterfaceAssertedBlockScope( */ template JS::Result BinASTParser::parseAssertedBoundName( - AssertedScopeKind scopeKind) { + AssertedScopeKind scopeKind, const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::AssertedBoundName) { return raiseInvalidKind("AssertedBoundName", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL( - result, parseInterfaceAssertedBoundName(start, kind, fields, scopeKind)); + BINJS_MOZ_TRY_DECL(result, parseInterfaceAssertedBoundName( + start, kind, fields, scopeKind, context)); MOZ_TRY(guard.done()); return result; @@ -1399,9 +1510,10 @@ JS::Result BinASTParser::parseAssertedBoundName( template JS::Result BinASTParser::parseInterfaceAssertedBoundName( const size_t start, const BinASTKind kind, const BinASTFields& fields, - AssertedScopeKind scopeKind) { + AssertedScopeKind scopeKind, const Context& context) { MOZ_ASSERT(kind == BinASTKind::AssertedBoundName); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Name, @@ -1411,9 +1523,9 @@ JS::Result BinASTParser::parseInterfaceAssertedBoundName( const bool allowDuplicateName = false; RootedAtom name(cx_); - MOZ_TRY_VAR(name, tokenizer_->readIdentifierName()); + MOZ_TRY_VAR(name, tokenizer_->readIdentifierName(fieldContext++)); - BINJS_MOZ_TRY_DECL(isCaptured, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isCaptured, tokenizer_->readBool(fieldContext++)); ParseContext::Scope* scope; DeclarationKind declKind; MOZ_TRY(getBoundScope(scopeKind, scope, declKind)); @@ -1430,18 +1542,19 @@ JS::Result BinASTParser::parseInterfaceAssertedBoundName( } */ template -JS::Result BinASTParser::parseAssertedBoundNamesScope() { +JS::Result BinASTParser::parseAssertedBoundNamesScope( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::AssertedBoundNamesScope) { return raiseInvalidKind("AssertedBoundNamesScope", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL( - result, parseInterfaceAssertedBoundNamesScope(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, parseInterfaceAssertedBoundNamesScope( + start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -1449,9 +1562,11 @@ JS::Result BinASTParser::parseAssertedBoundNamesScope() { template JS::Result BinASTParser::parseInterfaceAssertedBoundNamesScope( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::AssertedBoundNamesScope); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::BoundNames, @@ -1460,9 +1575,9 @@ JS::Result BinASTParser::parseInterfaceAssertedBoundNamesScope( #endif // defined(DEBUG) const auto scopeKind = AssertedScopeKind::Catch; - MOZ_TRY(parseListOfAssertedBoundName(scopeKind)); + MOZ_TRY(parseListOfAssertedBoundName(scopeKind, fieldContext++)); - BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool(fieldContext++)); if (hasDirectEval) { pc_->sc()->setHasDirectEval(); pc_->sc()->setBindingsAccessedDynamically(); @@ -1485,18 +1600,18 @@ JS::Result BinASTParser::parseInterfaceAssertedBoundNamesScope( */ template JS::Result BinASTParser::parseAssertedDeclaredName( - AssertedScopeKind scopeKind) { + AssertedScopeKind scopeKind, const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::AssertedDeclaredName) { return raiseInvalidKind("AssertedDeclaredName", kind); } const auto start = tokenizer_->offset(); BINJS_MOZ_TRY_DECL(result, parseInterfaceAssertedDeclaredName( - start, kind, fields, scopeKind)); + start, kind, fields, scopeKind, context)); MOZ_TRY(guard.done()); return result; @@ -1505,9 +1620,10 @@ JS::Result BinASTParser::parseAssertedDeclaredName( template JS::Result BinASTParser::parseInterfaceAssertedDeclaredName( const size_t start, const BinASTKind kind, const BinASTFields& fields, - AssertedScopeKind scopeKind) { + AssertedScopeKind scopeKind, const Context& context) { MOZ_ASSERT(kind == BinASTKind::AssertedDeclaredName); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = {BinASTField::Name, BinASTField::Kind, @@ -1517,16 +1633,16 @@ JS::Result BinASTParser::parseInterfaceAssertedDeclaredName( const bool allowDuplicateName = false; RootedAtom name(cx_); - MOZ_TRY_VAR(name, tokenizer_->readIdentifierName()); + MOZ_TRY_VAR(name, tokenizer_->readIdentifierName(fieldContext++)); - BINJS_MOZ_TRY_DECL(kind_, parseAssertedDeclaredKind()); + BINJS_MOZ_TRY_DECL(kind_, parseAssertedDeclaredKind(fieldContext++)); if (kind_ == AssertedDeclaredKind::NonConstLexical) { return raiseError("Let is not supported in this preview release"); } if (kind_ == AssertedDeclaredKind::ConstLexical) { return raiseError("Const is not supported in this preview release"); } - BINJS_MOZ_TRY_DECL(isCaptured, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isCaptured, tokenizer_->readBool(fieldContext++)); ParseContext::Scope* scope; DeclarationKind declKind; MOZ_TRY(getDeclaredScope(scopeKind, kind_, scope, declKind)); @@ -1545,18 +1661,19 @@ JS::Result BinASTParser::parseInterfaceAssertedDeclaredName( */ template JS::Result BinASTParser::parseAssertedParameterScope( - MutableHandle> positionalParams) { + MutableHandle> positionalParams, const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::AssertedParameterScope) { return raiseInvalidKind("AssertedParameterScope", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceAssertedParameterScope( - start, kind, fields, positionalParams)); + BINJS_MOZ_TRY_DECL( + result, parseInterfaceAssertedParameterScope(start, kind, fields, + positionalParams, context)); MOZ_TRY(guard.done()); return result; @@ -1565,9 +1682,10 @@ JS::Result BinASTParser::parseAssertedParameterScope( template JS::Result BinASTParser::parseInterfaceAssertedParameterScope( const size_t start, const BinASTKind kind, const BinASTFields& fields, - MutableHandle> positionalParams) { + MutableHandle> positionalParams, const Context& context) { MOZ_ASSERT(kind == BinASTKind::AssertedParameterScope); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = {BinASTField::ParamNames, @@ -1577,15 +1695,16 @@ JS::Result BinASTParser::parseInterfaceAssertedParameterScope( #endif // defined(DEBUG) const auto scopeKind = AssertedScopeKind::Parameter; - MOZ_TRY(parseListOfAssertedMaybePositionalParameterName(scopeKind, - positionalParams)); + MOZ_TRY(parseListOfAssertedMaybePositionalParameterName( + scopeKind, positionalParams, fieldContext++)); - BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool(fieldContext++)); if (hasDirectEval) { pc_->sc()->setHasDirectEval(); pc_->sc()->setBindingsAccessedDynamically(); } - BINJS_MOZ_TRY_DECL(isSimpleParameterList, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isSimpleParameterList, + tokenizer_->readBool(fieldContext++)); (void)isSimpleParameterList; if (hasDirectEval && pc_->isFunctionBox() && !pc_->sc()->strict()) { // In non-strict mode code, direct calls to eval can @@ -1600,9 +1719,10 @@ template JS::Result BinASTParser::parseInterfaceAssertedPositionalParameterName( const size_t start, const BinASTKind kind, const BinASTFields& fields, AssertedScopeKind scopeKind, - MutableHandle> positionalParams) { + MutableHandle> positionalParams, const Context& context) { MOZ_ASSERT(kind == BinASTKind::AssertedPositionalParameterName); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = {BinASTField::Index, BinASTField::Name, @@ -1611,10 +1731,10 @@ JS::Result BinASTParser::parseInterfaceAssertedPositionalParameterName( #endif // defined(DEBUG) bool allowDuplicateName = !pc_->sc()->strict(); - BINJS_MOZ_TRY_DECL(index, tokenizer_->readUnsignedLong()); + BINJS_MOZ_TRY_DECL(index, tokenizer_->readUnsignedLong(fieldContext++)); RootedAtom name(cx_); - MOZ_TRY_VAR(name, tokenizer_->readIdentifierName()); + MOZ_TRY_VAR(name, tokenizer_->readIdentifierName(fieldContext++)); // `positionalParams` vector can be shorter than the actual // parameter length. Resize on demand. // (see also ListOfAssertedMaybePositionalParameterName) @@ -1637,7 +1757,7 @@ JS::Result BinASTParser::parseInterfaceAssertedPositionalParameterName( "index"); } positionalParams.get()[index] = name; - BINJS_MOZ_TRY_DECL(isCaptured, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isCaptured, tokenizer_->readBool(fieldContext++)); ParseContext::Scope* scope; DeclarationKind declKind; MOZ_TRY(getBoundScope(scopeKind, scope, declKind)); @@ -1654,18 +1774,19 @@ JS::Result BinASTParser::parseInterfaceAssertedPositionalParameterName( } */ template -JS::Result BinASTParser::parseAssertedScriptGlobalScope() { +JS::Result BinASTParser::parseAssertedScriptGlobalScope( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::AssertedScriptGlobalScope) { return raiseInvalidKind("AssertedScriptGlobalScope", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL( - result, parseInterfaceAssertedScriptGlobalScope(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, parseInterfaceAssertedScriptGlobalScope( + start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -1673,9 +1794,11 @@ JS::Result BinASTParser::parseAssertedScriptGlobalScope() { template JS::Result BinASTParser::parseInterfaceAssertedScriptGlobalScope( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::AssertedScriptGlobalScope); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::DeclaredNames, @@ -1684,9 +1807,9 @@ JS::Result BinASTParser::parseInterfaceAssertedScriptGlobalScope( #endif // defined(DEBUG) const auto scopeKind = AssertedScopeKind::Global; - MOZ_TRY(parseListOfAssertedDeclaredName(scopeKind)); + MOZ_TRY(parseListOfAssertedDeclaredName(scopeKind, fieldContext++)); - BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool(fieldContext++)); if (hasDirectEval) { pc_->sc()->setHasDirectEval(); pc_->sc()->setBindingsAccessedDynamically(); @@ -1707,18 +1830,19 @@ JS::Result BinASTParser::parseInterfaceAssertedScriptGlobalScope( } */ template -JS::Result BinASTParser::parseAssertedVarScope() { +JS::Result BinASTParser::parseAssertedVarScope( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::AssertedVarScope) { return raiseInvalidKind("AssertedVarScope", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceAssertedVarScope(start, kind, fields)); + BINJS_MOZ_TRY_DECL( + result, parseInterfaceAssertedVarScope(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -1726,9 +1850,11 @@ JS::Result BinASTParser::parseAssertedVarScope() { template JS::Result BinASTParser::parseInterfaceAssertedVarScope( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::AssertedVarScope); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::DeclaredNames, @@ -1737,9 +1863,9 @@ JS::Result BinASTParser::parseInterfaceAssertedVarScope( #endif // defined(DEBUG) const auto scopeKind = AssertedScopeKind::Var; - MOZ_TRY(parseListOfAssertedDeclaredName(scopeKind)); + MOZ_TRY(parseListOfAssertedDeclaredName(scopeKind, fieldContext++)); - BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool(fieldContext++)); if (hasDirectEval) { pc_->sc()->setHasDirectEval(); pc_->sc()->setBindingsAccessedDynamically(); @@ -1755,9 +1881,11 @@ JS::Result BinASTParser::parseInterfaceAssertedVarScope( template JS::Result BinASTParser::parseInterfaceAssignmentExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::AssignmentExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Binding, @@ -1765,9 +1893,9 @@ JS::Result BinASTParser::parseInterfaceAssignmentExpression( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(binding, parseAssignmentTarget()); + BINJS_MOZ_TRY_DECL(binding, parseAssignmentTarget(fieldContext++)); - BINJS_MOZ_TRY_DECL(expression, parseExpression()); + BINJS_MOZ_TRY_DECL(expression, parseExpression(fieldContext++)); BINJS_TRY_DECL(result, handler_.newAssignment(ParseNodeKind::AssignExpr, binding, expression)); @@ -1777,9 +1905,11 @@ JS::Result BinASTParser::parseInterfaceAssignmentExpression( template JS::Result BinASTParser::parseInterfaceAssignmentTargetIdentifier( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::AssignmentTargetIdentifier); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Name}; @@ -1787,7 +1917,7 @@ BinASTParser::parseInterfaceAssignmentTargetIdentifier( #endif // defined(DEBUG) RootedAtom name(cx_); - MOZ_TRY_VAR(name, tokenizer_->readIdentifierName()); + MOZ_TRY_VAR(name, tokenizer_->readIdentifierName(fieldContext++)); BINJS_TRY(usedNames_.noteUse(cx_, name, pc_->scriptId(), pc_->innermostScope()->id())); @@ -1798,16 +1928,19 @@ BinASTParser::parseInterfaceAssignmentTargetIdentifier( template JS::Result BinASTParser::parseInterfaceAwaitExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (AwaitExpression)"); } template JS::Result BinASTParser::parseInterfaceBinaryExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::BinaryExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = { @@ -1815,11 +1948,11 @@ JS::Result BinASTParser::parseInterfaceBinaryExpression( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(operator_, parseBinaryOperator()); + BINJS_MOZ_TRY_DECL(operator_, parseBinaryOperator(fieldContext++)); - BINJS_MOZ_TRY_DECL(left, parseExpression()); + BINJS_MOZ_TRY_DECL(left, parseExpression(fieldContext++)); - BINJS_MOZ_TRY_DECL(right, parseExpression()); + BINJS_MOZ_TRY_DECL(right, parseExpression(fieldContext++)); ParseNodeKind pnk; switch (operator_) { @@ -1922,18 +2055,19 @@ JS::Result BinASTParser::parseInterfaceBinaryExpression( } */ template -JS::Result BinASTParser::parseBindingIdentifier() { +JS::Result BinASTParser::parseBindingIdentifier( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::BindingIdentifier) { return raiseInvalidKind("BindingIdentifier", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceBindingIdentifier(start, kind, fields)); + BINJS_MOZ_TRY_DECL( + result, parseInterfaceBindingIdentifier(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -1941,9 +2075,11 @@ JS::Result BinASTParser::parseBindingIdentifier() { template JS::Result BinASTParser::parseInterfaceBindingIdentifier( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::BindingIdentifier); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Name}; @@ -1951,7 +2087,7 @@ JS::Result BinASTParser::parseInterfaceBindingIdentifier( #endif // defined(DEBUG) RootedAtom name(cx_); - MOZ_TRY_VAR(name, tokenizer_->readIdentifierName()); + MOZ_TRY_VAR(name, tokenizer_->readIdentifierName(fieldContext++)); BINJS_TRY_DECL(result, handler_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_)); @@ -1960,7 +2096,8 @@ JS::Result BinASTParser::parseInterfaceBindingIdentifier( template JS::Result BinASTParser::parseInterfaceBindingWithInitializer( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release " "(BindingWithInitializer)"); @@ -1973,17 +2110,17 @@ JS::Result BinASTParser::parseInterfaceBindingWithInitializer( } */ template -JS::Result BinASTParser::parseBlock() { +JS::Result BinASTParser::parseBlock(const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::Block) { return raiseInvalidKind("Block", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceBlock(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, parseInterfaceBlock(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -1991,9 +2128,11 @@ JS::Result BinASTParser::parseBlock() { template JS::Result BinASTParser::parseInterfaceBlock( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::Block); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Scope, @@ -2004,9 +2143,9 @@ JS::Result BinASTParser::parseInterfaceBlock( ParseContext::Scope currentScope(cx_, pc_, usedNames_); BINJS_TRY(currentScope.init(pc_)); - MOZ_TRY(parseAssertedBlockScope()); + MOZ_TRY(parseAssertedBlockScope(fieldContext++)); - BINJS_MOZ_TRY_DECL(statements, parseListOfStatement()); + BINJS_MOZ_TRY_DECL(statements, parseListOfStatement(fieldContext++)); MOZ_TRY(checkClosedVars(currentScope)); BINJS_TRY_DECL(bindings, NewLexicalScopeData(cx_, currentScope, alloc_, pc_)); @@ -2016,16 +2155,18 @@ JS::Result BinASTParser::parseInterfaceBlock( template JS::Result BinASTParser::parseInterfaceBreakStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::BreakStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Label}; MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) RootedAtom label(cx_); - MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom()); + MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom(fieldContext)); if (label) { if (!IsIdentifier(label)) { @@ -2054,9 +2195,11 @@ JS::Result BinASTParser::parseInterfaceBreakStatement( template JS::Result BinASTParser::parseInterfaceCallExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::CallExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Callee, @@ -2064,9 +2207,9 @@ JS::Result BinASTParser::parseInterfaceCallExpression( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(callee, parseExpressionOrSuper()); + BINJS_MOZ_TRY_DECL(callee, parseExpressionOrSuper(fieldContext++)); - BINJS_MOZ_TRY_DECL(arguments, parseArguments()); + BINJS_MOZ_TRY_DECL(arguments, parseArguments(fieldContext++)); auto op = JSOP_CALL; @@ -2107,17 +2250,19 @@ JS::Result BinASTParser::parseInterfaceCallExpression( } */ template -JS::Result BinASTParser::parseCatchClause() { +JS::Result BinASTParser::parseCatchClause( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::CatchClause) { return raiseInvalidKind("CatchClause", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceCatchClause(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, + parseInterfaceCatchClause(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -2125,9 +2270,11 @@ JS::Result BinASTParser::parseCatchClause() { template JS::Result BinASTParser::parseInterfaceCatchClause( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::CatchClause); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = { @@ -2138,14 +2285,14 @@ JS::Result BinASTParser::parseInterfaceCatchClause( ParseContext::Scope currentScope(cx_, pc_, usedNames_); BINJS_TRY(currentScope.init(pc_)); - MOZ_TRY(parseAssertedBoundNamesScope()); + MOZ_TRY(parseAssertedBoundNamesScope(fieldContext++)); - BINJS_MOZ_TRY_DECL(binding, parseBinding()); + BINJS_MOZ_TRY_DECL(binding, parseBinding(fieldContext++)); if (!currentScope.lookupDeclaredName( binding->template as().atom())) { return raiseError("Missing catch variable in scope"); } - BINJS_MOZ_TRY_DECL(body, parseBlock()); + BINJS_MOZ_TRY_DECL(body, parseBlock(fieldContext++)); MOZ_TRY(checkClosedVars(currentScope)); BINJS_TRY_DECL(bindings, NewLexicalScopeData(cx_, currentScope, alloc_, pc_)); @@ -2156,14 +2303,16 @@ JS::Result BinASTParser::parseInterfaceCatchClause( template JS::Result BinASTParser::parseInterfaceClassDeclaration( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (ClassDeclaration)"); } template JS::Result BinASTParser::parseInterfaceClassExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (ClassExpression)"); } @@ -2171,9 +2320,11 @@ JS::Result BinASTParser::parseInterfaceClassExpression( template JS::Result BinASTParser::parseInterfaceCompoundAssignmentExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::CompoundAssignmentExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = { @@ -2181,11 +2332,12 @@ BinASTParser::parseInterfaceCompoundAssignmentExpression( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(operator_, parseCompoundAssignmentOperator()); + BINJS_MOZ_TRY_DECL(operator_, + parseCompoundAssignmentOperator(fieldContext++)); - BINJS_MOZ_TRY_DECL(binding, parseSimpleAssignmentTarget()); + BINJS_MOZ_TRY_DECL(binding, parseSimpleAssignmentTarget(fieldContext++)); - BINJS_MOZ_TRY_DECL(expression, parseExpression()); + BINJS_MOZ_TRY_DECL(expression, parseExpression(fieldContext++)); ParseNodeKind pnk; switch (operator_) { @@ -2233,9 +2385,11 @@ BinASTParser::parseInterfaceCompoundAssignmentExpression( template JS::Result BinASTParser::parseInterfaceComputedMemberAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ComputedMemberAssignmentTarget); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Object, @@ -2243,9 +2397,9 @@ BinASTParser::parseInterfaceComputedMemberAssignmentTarget( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper()); + BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper(fieldContext++)); - BINJS_MOZ_TRY_DECL(expression, parseExpression()); + BINJS_MOZ_TRY_DECL(expression, parseExpression(fieldContext++)); BINJS_TRY_DECL(result, handler_.newPropertyByValue(object, expression, tokenizer_->offset())); @@ -2255,9 +2409,11 @@ BinASTParser::parseInterfaceComputedMemberAssignmentTarget( template JS::Result BinASTParser::parseInterfaceComputedMemberExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ComputedMemberExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Object, @@ -2265,9 +2421,9 @@ BinASTParser::parseInterfaceComputedMemberExpression( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper()); + BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper(fieldContext++)); - BINJS_MOZ_TRY_DECL(expression, parseExpression()); + BINJS_MOZ_TRY_DECL(expression, parseExpression(fieldContext++)); BINJS_TRY_DECL(result, handler_.newPropertyByValue(object, expression, tokenizer_->offset())); @@ -2276,7 +2432,8 @@ BinASTParser::parseInterfaceComputedMemberExpression( template JS::Result BinASTParser::parseInterfaceComputedPropertyName( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release " "(ComputedPropertyName)"); @@ -2284,9 +2441,11 @@ JS::Result BinASTParser::parseInterfaceComputedPropertyName( template JS::Result BinASTParser::parseInterfaceConditionalExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ConditionalExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = { @@ -2294,11 +2453,11 @@ JS::Result BinASTParser::parseInterfaceConditionalExpression( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(test, parseExpression()); + BINJS_MOZ_TRY_DECL(test, parseExpression(fieldContext++)); - BINJS_MOZ_TRY_DECL(consequent, parseExpression()); + BINJS_MOZ_TRY_DECL(consequent, parseExpression(fieldContext++)); - BINJS_MOZ_TRY_DECL(alternate, parseExpression()); + BINJS_MOZ_TRY_DECL(alternate, parseExpression(fieldContext++)); BINJS_TRY_DECL(result, handler_.newConditional(test, consequent, alternate)); return result; @@ -2306,16 +2465,18 @@ JS::Result BinASTParser::parseInterfaceConditionalExpression( template JS::Result BinASTParser::parseInterfaceContinueStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ContinueStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Label}; MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) RootedAtom label(cx_); - MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom()); + MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom(fieldContext)); if (label) { if (!IsIdentifier(label)) { @@ -2344,9 +2505,11 @@ JS::Result BinASTParser::parseInterfaceContinueStatement( template JS::Result BinASTParser::parseInterfaceDataProperty( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::DataProperty); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Name, @@ -2354,9 +2517,9 @@ JS::Result BinASTParser::parseInterfaceDataProperty( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(name, parsePropertyName()); + BINJS_MOZ_TRY_DECL(name, parsePropertyName(fieldContext++)); - BINJS_MOZ_TRY_DECL(expression, parseExpression()); + BINJS_MOZ_TRY_DECL(expression, parseExpression(fieldContext++)); if (!handler_.isUsableAsObjectPropertyName(name)) { return raiseError("DataProperty key kind"); @@ -2376,7 +2539,8 @@ JS::Result BinASTParser::parseInterfaceDataProperty( template JS::Result BinASTParser::parseInterfaceDebuggerStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (DebuggerStatement)"); } @@ -2387,17 +2551,19 @@ JS::Result BinASTParser::parseInterfaceDebuggerStatement( } */ template -JS::Result BinASTParser::parseDirective() { +JS::Result BinASTParser::parseDirective( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::Directive) { return raiseInvalidKind("Directive", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceDirective(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, + parseInterfaceDirective(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -2405,9 +2571,11 @@ JS::Result BinASTParser::parseDirective() { template JS::Result BinASTParser::parseInterfaceDirective( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::Directive); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::RawValue}; @@ -2415,7 +2583,7 @@ JS::Result BinASTParser::parseInterfaceDirective( #endif // defined(DEBUG) RootedAtom rawValue(cx_); - MOZ_TRY_VAR(rawValue, tokenizer_->readAtom()); + MOZ_TRY_VAR(rawValue, tokenizer_->readAtom(fieldContext++)); TokenPos pos = tokenizer_->pos(start); BINJS_TRY_DECL(result, handler_.newStringLiteral(rawValue, pos)); @@ -2424,9 +2592,11 @@ JS::Result BinASTParser::parseInterfaceDirective( template JS::Result BinASTParser::parseInterfaceDoWhileStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::DoWhileStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Test, BinASTField::Body}; @@ -2434,9 +2604,9 @@ JS::Result BinASTParser::parseInterfaceDoWhileStatement( #endif // defined(DEBUG) ParseContext::Statement stmt(pc_, StatementKind::DoLoop); - BINJS_MOZ_TRY_DECL(test, parseExpression()); + BINJS_MOZ_TRY_DECL(test, parseExpression(fieldContext++)); - BINJS_MOZ_TRY_DECL(body, parseStatement()); + BINJS_MOZ_TRY_DECL(body, parseStatement(fieldContext++)); BINJS_TRY_DECL( result, handler_.newDoWhileStatement(body, test, tokenizer_->pos(start))); @@ -2446,7 +2616,8 @@ JS::Result BinASTParser::parseInterfaceDoWhileStatement( template JS::Result BinASTParser::parseInterfaceEagerArrowExpressionWithExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release " "(EagerArrowExpressionWithExpression)"); @@ -2455,7 +2626,8 @@ BinASTParser::parseInterfaceEagerArrowExpressionWithExpression( template JS::Result BinASTParser::parseInterfaceEagerArrowExpressionWithFunctionBody( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release " "(EagerArrowExpressionWithFunctionBody)"); @@ -2464,9 +2636,11 @@ BinASTParser::parseInterfaceEagerArrowExpressionWithFunctionBody( template JS::Result BinASTParser::parseInterfaceEagerFunctionDeclaration( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::EagerFunctionDeclaration); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[6] = { @@ -2476,20 +2650,20 @@ BinASTParser::parseInterfaceEagerFunctionDeclaration( #endif // defined(DEBUG) const auto syntax = FunctionSyntaxKind::Statement; - BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool(fieldContext++)); if (isAsync) { return raiseError( "Async function is not supported in this preview release"); } - BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool(fieldContext++)); if (isGenerator) { return raiseError("Generator is not supported in this preview release"); } - BINJS_MOZ_TRY_DECL(name, parseBindingIdentifier()); + BINJS_MOZ_TRY_DECL(name, parseBindingIdentifier(fieldContext++)); - BINJS_MOZ_TRY_DECL(length, tokenizer_->readUnsignedLong()); + BINJS_MOZ_TRY_DECL(length, tokenizer_->readUnsignedLong(fieldContext++)); - BINJS_MOZ_TRY_DECL(directives, parseListOfDirective()); + BINJS_MOZ_TRY_DECL(directives, parseListOfDirective(fieldContext++)); BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(isGenerator ? GeneratorKind::Generator @@ -2515,7 +2689,8 @@ BinASTParser::parseInterfaceEagerFunctionDeclaration( BINJS_TRY(lexicalScope.init(pc_)); ListNode* params; ListNode* body; - MOZ_TRY(parseFunctionOrMethodContents(length, ¶ms, &body)); + MOZ_TRY( + parseFunctionOrMethodContents(length, ¶ms, &body, fieldContext++)); MOZ_TRY(prependDirectivesToBody(body, directives)); BINJS_TRY_DECL(lexicalScopeData, NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); @@ -2527,9 +2702,11 @@ BinASTParser::parseInterfaceEagerFunctionDeclaration( template JS::Result BinASTParser::parseInterfaceEagerFunctionExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::EagerFunctionExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[6] = { @@ -2539,20 +2716,20 @@ JS::Result BinASTParser::parseInterfaceEagerFunctionExpression( #endif // defined(DEBUG) const auto syntax = FunctionSyntaxKind::Expression; - BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool(fieldContext++)); if (isAsync) { return raiseError( "Async function is not supported in this preview release"); } - BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool(fieldContext++)); if (isGenerator) { return raiseError("Generator is not supported in this preview release"); } - BINJS_MOZ_TRY_DECL(name, parseOptionalBindingIdentifier()); + BINJS_MOZ_TRY_DECL(name, parseOptionalBindingIdentifier(fieldContext++)); - BINJS_MOZ_TRY_DECL(length, tokenizer_->readUnsignedLong()); + BINJS_MOZ_TRY_DECL(length, tokenizer_->readUnsignedLong(fieldContext++)); - BINJS_MOZ_TRY_DECL(directives, parseListOfDirective()); + BINJS_MOZ_TRY_DECL(directives, parseListOfDirective(fieldContext++)); BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(isGenerator ? GeneratorKind::Generator @@ -2578,7 +2755,8 @@ JS::Result BinASTParser::parseInterfaceEagerFunctionExpression( BINJS_TRY(lexicalScope.init(pc_)); ListNode* params; ListNode* body; - MOZ_TRY(parseFunctionExpressionContents(length, ¶ms, &body)); + MOZ_TRY( + parseFunctionExpressionContents(length, ¶ms, &body, fieldContext++)); MOZ_TRY(prependDirectivesToBody(body, directives)); BINJS_TRY_DECL(lexicalScopeData, NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); @@ -2590,9 +2768,11 @@ JS::Result BinASTParser::parseInterfaceEagerFunctionExpression( template JS::Result BinASTParser::parseInterfaceEagerGetter( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::EagerGetter); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = { @@ -2605,9 +2785,9 @@ JS::Result BinASTParser::parseInterfaceEagerGetter( const auto accessorType = AccessorType::Getter; const uint32_t length = 0; - BINJS_MOZ_TRY_DECL(name, parsePropertyName()); + BINJS_MOZ_TRY_DECL(name, parsePropertyName(fieldContext++)); - BINJS_MOZ_TRY_DECL(directives, parseListOfDirective()); + BINJS_MOZ_TRY_DECL(directives, parseListOfDirective(fieldContext++)); BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(isGenerator ? GeneratorKind::Generator @@ -2633,7 +2813,7 @@ JS::Result BinASTParser::parseInterfaceEagerGetter( BINJS_TRY(lexicalScope.init(pc_)); ListNode* params; ListNode* body; - MOZ_TRY(parseGetterContents(length, ¶ms, &body)); + MOZ_TRY(parseGetterContents(length, ¶ms, &body, fieldContext++)); MOZ_TRY(prependDirectivesToBody(body, directives)); BINJS_TRY_DECL(lexicalScopeData, NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); @@ -2647,9 +2827,11 @@ JS::Result BinASTParser::parseInterfaceEagerGetter( template JS::Result BinASTParser::parseInterfaceEagerMethod( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::EagerMethod); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[6] = { @@ -2660,20 +2842,20 @@ JS::Result BinASTParser::parseInterfaceEagerMethod( const auto syntax = FunctionSyntaxKind::Method; const auto accessorType = AccessorType::None; - BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool(fieldContext++)); if (isAsync) { return raiseError( "Async function is not supported in this preview release"); } - BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool(fieldContext++)); if (isGenerator) { return raiseError("Generator is not supported in this preview release"); } - BINJS_MOZ_TRY_DECL(name, parsePropertyName()); + BINJS_MOZ_TRY_DECL(name, parsePropertyName(fieldContext++)); - BINJS_MOZ_TRY_DECL(length, tokenizer_->readUnsignedLong()); + BINJS_MOZ_TRY_DECL(length, tokenizer_->readUnsignedLong(fieldContext++)); - BINJS_MOZ_TRY_DECL(directives, parseListOfDirective()); + BINJS_MOZ_TRY_DECL(directives, parseListOfDirective(fieldContext++)); BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(isGenerator ? GeneratorKind::Generator @@ -2699,7 +2881,8 @@ JS::Result BinASTParser::parseInterfaceEagerMethod( BINJS_TRY(lexicalScope.init(pc_)); ListNode* params; ListNode* body; - MOZ_TRY(parseFunctionOrMethodContents(length, ¶ms, &body)); + MOZ_TRY( + parseFunctionOrMethodContents(length, ¶ms, &body, fieldContext++)); MOZ_TRY(prependDirectivesToBody(body, directives)); BINJS_TRY_DECL(lexicalScopeData, NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); @@ -2713,9 +2896,11 @@ JS::Result BinASTParser::parseInterfaceEagerMethod( template JS::Result BinASTParser::parseInterfaceEagerSetter( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::EagerSetter); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[4] = { @@ -2728,11 +2913,11 @@ JS::Result BinASTParser::parseInterfaceEagerSetter( const bool isAsync = false; const auto accessorType = AccessorType::Setter; - BINJS_MOZ_TRY_DECL(name, parsePropertyName()); + BINJS_MOZ_TRY_DECL(name, parsePropertyName(fieldContext++)); - BINJS_MOZ_TRY_DECL(length, tokenizer_->readUnsignedLong()); + BINJS_MOZ_TRY_DECL(length, tokenizer_->readUnsignedLong(fieldContext++)); - BINJS_MOZ_TRY_DECL(directives, parseListOfDirective()); + BINJS_MOZ_TRY_DECL(directives, parseListOfDirective(fieldContext++)); BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(isGenerator ? GeneratorKind::Generator @@ -2758,7 +2943,7 @@ JS::Result BinASTParser::parseInterfaceEagerSetter( BINJS_TRY(lexicalScope.init(pc_)); ListNode* params; ListNode* body; - MOZ_TRY(parseSetterContents(length, ¶ms, &body)); + MOZ_TRY(parseSetterContents(length, ¶ms, &body, fieldContext++)); MOZ_TRY(prependDirectivesToBody(body, directives)); BINJS_TRY_DECL(lexicalScopeData, NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); @@ -2772,7 +2957,8 @@ JS::Result BinASTParser::parseInterfaceEagerSetter( template JS::Result BinASTParser::parseInterfaceEmptyStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::EmptyStatement); BINJS_TRY(CheckRecursionLimit(cx_)); MOZ_TRY(tokenizer_->checkFields0(kind, fields)); @@ -2783,16 +2969,18 @@ JS::Result BinASTParser::parseInterfaceEmptyStatement( template JS::Result BinASTParser::parseInterfaceExpressionStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ExpressionStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Expression}; MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(expression, parseExpression()); + BINJS_MOZ_TRY_DECL(expression, parseExpression(fieldContext++)); BINJS_TRY_DECL(result, handler_.newExprStatement(expression, tokenizer_->offset())); @@ -2801,9 +2989,11 @@ JS::Result BinASTParser::parseInterfaceExpressionStatement( template JS::Result BinASTParser::parseInterfaceForInOfBinding( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ForInOfBinding); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Kind, @@ -2812,9 +3002,9 @@ JS::Result BinASTParser::parseInterfaceForInOfBinding( #endif // defined(DEBUG) AutoVariableDeclarationKind kindGuard(this); - BINJS_MOZ_TRY_DECL(kind_, parseVariableDeclarationKind()); + BINJS_MOZ_TRY_DECL(kind_, parseVariableDeclarationKind(fieldContext++)); - BINJS_MOZ_TRY_DECL(binding, parseBinding()); + BINJS_MOZ_TRY_DECL(binding, parseBinding(fieldContext++)); // Restored by `kindGuard`. variableDeclarationKind_ = kind_; @@ -2838,9 +3028,11 @@ JS::Result BinASTParser::parseInterfaceForInOfBinding( template JS::Result BinASTParser::parseInterfaceForInStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ForInStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = {BinASTField::Left, BinASTField::Right, @@ -2855,11 +3047,12 @@ JS::Result BinASTParser::parseInterfaceForInStatement( ParseContext::Scope scope(cx_, pc_, usedNames_); BINJS_TRY(scope.init(pc_)); - BINJS_MOZ_TRY_DECL(left, parseForInOfBindingOrAssignmentTarget()); + BINJS_MOZ_TRY_DECL(left, + parseForInOfBindingOrAssignmentTarget(fieldContext++)); - BINJS_MOZ_TRY_DECL(right, parseExpression()); + BINJS_MOZ_TRY_DECL(right, parseExpression(fieldContext++)); - BINJS_MOZ_TRY_DECL(body, parseStatement()); + BINJS_MOZ_TRY_DECL(body, parseStatement(fieldContext++)); BINJS_TRY_DECL(forHead, handler_.newForInOrOfHead(ParseNodeKind::ForIn, left, right, @@ -2877,16 +3070,19 @@ JS::Result BinASTParser::parseInterfaceForInStatement( template JS::Result BinASTParser::parseInterfaceForOfStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (ForOfStatement)"); } template JS::Result BinASTParser::parseInterfaceForStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ForStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[4] = {BinASTField::Init, BinASTField::Test, @@ -2902,13 +3098,14 @@ JS::Result BinASTParser::parseInterfaceForStatement( ParseContext::Scope scope(cx_, pc_, usedNames_); BINJS_TRY(scope.init(pc_)); - BINJS_MOZ_TRY_DECL(init, parseOptionalVariableDeclarationOrExpression()); + BINJS_MOZ_TRY_DECL( + init, parseOptionalVariableDeclarationOrExpression(fieldContext++)); - BINJS_MOZ_TRY_DECL(test, parseOptionalExpression()); + BINJS_MOZ_TRY_DECL(test, parseOptionalExpression(fieldContext++)); - BINJS_MOZ_TRY_DECL(update, parseOptionalExpression()); + BINJS_MOZ_TRY_DECL(update, parseOptionalExpression(fieldContext++)); - BINJS_MOZ_TRY_DECL(body, parseStatement()); + BINJS_MOZ_TRY_DECL(body, parseStatement(fieldContext++)); BINJS_TRY_DECL( forHead, handler_.newForHead(init, test, update, tokenizer_->pos(start))); @@ -2930,18 +3127,19 @@ JS::Result BinASTParser::parseInterfaceForStatement( } */ template -JS::Result BinASTParser::parseFormalParameters() { +JS::Result BinASTParser::parseFormalParameters( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::FormalParameters) { return raiseInvalidKind("FormalParameters", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceFormalParameters(start, kind, fields)); + BINJS_MOZ_TRY_DECL( + result, parseInterfaceFormalParameters(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -2949,9 +3147,11 @@ JS::Result BinASTParser::parseFormalParameters() { template JS::Result BinASTParser::parseInterfaceFormalParameters( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::FormalParameters); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Items, @@ -2959,9 +3159,9 @@ JS::Result BinASTParser::parseInterfaceFormalParameters( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(items, parseListOfParameter()); + BINJS_MOZ_TRY_DECL(items, parseListOfParameter(fieldContext++)); - BINJS_MOZ_TRY_DECL(rest, parseOptionalBinding()); + BINJS_MOZ_TRY_DECL(rest, parseOptionalBinding(fieldContext++)); auto result = items; if (rest) { @@ -2983,19 +3183,20 @@ JS::Result BinASTParser::parseInterfaceFormalParameters( */ template JS::Result BinASTParser::parseFunctionExpressionContents( - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut) { + uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::FunctionExpressionContents) { return raiseInvalidKind("FunctionExpressionContents", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceFunctionExpressionContents( - start, kind, fields, funLength, paramsOut, bodyOut)); + BINJS_MOZ_TRY_DECL( + result, parseInterfaceFunctionExpressionContents( + start, kind, fields, funLength, paramsOut, bodyOut, context)); MOZ_TRY(guard.done()); return result; @@ -3004,9 +3205,11 @@ JS::Result BinASTParser::parseFunctionExpressionContents( template JS::Result BinASTParser::parseInterfaceFunctionExpressionContents( const size_t start, const BinASTKind kind, const BinASTFields& fields, - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut) { + uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::FunctionExpressionContents); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[6] = {BinASTField::IsFunctionNameCaptured, @@ -3018,7 +3221,8 @@ JS::Result BinASTParser::parseInterfaceFunctionExpressionContents( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(isFunctionNameCaptured, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isFunctionNameCaptured, + tokenizer_->readBool(fieldContext++)); // Per spec, isFunctionNameCaptured can be true for anonymous // function. Check isFunctionNameCaptured only for named // function. @@ -3026,18 +3230,18 @@ JS::Result BinASTParser::parseInterfaceFunctionExpressionContents( isFunctionNameCaptured) { captureFunctionName(); } - BINJS_MOZ_TRY_DECL(isThisCaptured, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isThisCaptured, tokenizer_->readBool(fieldContext++)); // TODO: Use this in BinASTParser::buildFunction. (void)isThisCaptured; Rooted> positionalParams(cx_, GCVector(cx_)); - MOZ_TRY(parseAssertedParameterScope(&positionalParams)); + MOZ_TRY(parseAssertedParameterScope(&positionalParams, fieldContext++)); - BINJS_MOZ_TRY_DECL(params, parseFormalParameters()); + BINJS_MOZ_TRY_DECL(params, parseFormalParameters(fieldContext++)); MOZ_TRY(checkFunctionLength(funLength)); MOZ_TRY(checkPositionalParameterIndices(positionalParams, params)); - MOZ_TRY(parseAssertedVarScope()); + MOZ_TRY(parseAssertedVarScope(fieldContext++)); - BINJS_MOZ_TRY_DECL(body, parseFunctionBody()); + BINJS_MOZ_TRY_DECL(body, parseFunctionBody(fieldContext++)); *paramsOut = params; *bodyOut = body; @@ -3056,19 +3260,20 @@ JS::Result BinASTParser::parseInterfaceFunctionExpressionContents( */ template JS::Result BinASTParser::parseFunctionOrMethodContents( - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut) { + uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::FunctionOrMethodContents) { return raiseInvalidKind("FunctionOrMethodContents", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceFunctionOrMethodContents( - start, kind, fields, funLength, paramsOut, bodyOut)); + BINJS_MOZ_TRY_DECL( + result, parseInterfaceFunctionOrMethodContents( + start, kind, fields, funLength, paramsOut, bodyOut, context)); MOZ_TRY(guard.done()); return result; @@ -3077,9 +3282,11 @@ JS::Result BinASTParser::parseFunctionOrMethodContents( template JS::Result BinASTParser::parseInterfaceFunctionOrMethodContents( const size_t start, const BinASTKind kind, const BinASTFields& fields, - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut) { + uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::FunctionOrMethodContents); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[5] = { @@ -3088,18 +3295,18 @@ JS::Result BinASTParser::parseInterfaceFunctionOrMethodContents( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(isThisCaptured, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isThisCaptured, tokenizer_->readBool(fieldContext++)); // TODO: Use this in BinASTParser::buildFunction. (void)isThisCaptured; Rooted> positionalParams(cx_, GCVector(cx_)); - MOZ_TRY(parseAssertedParameterScope(&positionalParams)); + MOZ_TRY(parseAssertedParameterScope(&positionalParams, fieldContext++)); - BINJS_MOZ_TRY_DECL(params, parseFormalParameters()); + BINJS_MOZ_TRY_DECL(params, parseFormalParameters(fieldContext++)); MOZ_TRY(checkFunctionLength(funLength)); MOZ_TRY(checkPositionalParameterIndices(positionalParams, params)); - MOZ_TRY(parseAssertedVarScope()); + MOZ_TRY(parseAssertedVarScope(fieldContext++)); - BINJS_MOZ_TRY_DECL(body, parseFunctionBody()); + BINJS_MOZ_TRY_DECL(body, parseFunctionBody(fieldContext++)); *paramsOut = params; *bodyOut = body; @@ -3117,19 +3324,20 @@ JS::Result BinASTParser::parseInterfaceFunctionOrMethodContents( template JS::Result BinASTParser::parseGetterContents(uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut) { + ListNode** bodyOut, + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::GetterContents) { return raiseInvalidKind("GetterContents", kind); } const auto start = tokenizer_->offset(); BINJS_MOZ_TRY_DECL( result, parseInterfaceGetterContents(start, kind, fields, funLength, - paramsOut, bodyOut)); + paramsOut, bodyOut, context)); MOZ_TRY(guard.done()); return result; @@ -3138,9 +3346,11 @@ JS::Result BinASTParser::parseGetterContents(uint32_t funLength, template JS::Result BinASTParser::parseInterfaceGetterContents( const size_t start, const BinASTKind kind, const BinASTFields& fields, - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut) { + uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::GetterContents); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = { @@ -3148,13 +3358,13 @@ JS::Result BinASTParser::parseInterfaceGetterContents( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(isThisCaptured, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isThisCaptured, tokenizer_->readBool(fieldContext++)); // TODO: Use this in BinASTParser::buildFunction. (void)isThisCaptured; - MOZ_TRY(parseAssertedVarScope()); + MOZ_TRY(parseAssertedVarScope(fieldContext++)); BINJS_TRY_DECL(params, handler_.newParamsBody(tokenizer_->pos(start))); - BINJS_MOZ_TRY_DECL(body, parseFunctionBody()); + BINJS_MOZ_TRY_DECL(body, parseFunctionBody(fieldContext++)); *paramsOut = params; *bodyOut = body; @@ -3168,18 +3378,19 @@ JS::Result BinASTParser::parseInterfaceGetterContents( } */ template -JS::Result BinASTParser::parseIdentifierExpression() { +JS::Result BinASTParser::parseIdentifierExpression( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::IdentifierExpression) { return raiseInvalidKind("IdentifierExpression", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceIdentifierExpression(start, kind, fields)); + BINJS_MOZ_TRY_DECL( + result, parseInterfaceIdentifierExpression(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -3187,9 +3398,11 @@ JS::Result BinASTParser::parseIdentifierExpression() { template JS::Result BinASTParser::parseInterfaceIdentifierExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::IdentifierExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Name}; @@ -3197,7 +3410,7 @@ JS::Result BinASTParser::parseInterfaceIdentifierExpression( #endif // defined(DEBUG) RootedAtom name(cx_); - MOZ_TRY_VAR(name, tokenizer_->readIdentifierName()); + MOZ_TRY_VAR(name, tokenizer_->readIdentifierName(fieldContext++)); BINJS_TRY(usedNames_.noteUse(cx_, name, pc_->scriptId(), pc_->innermostScope()->id())); @@ -3208,9 +3421,11 @@ JS::Result BinASTParser::parseInterfaceIdentifierExpression( template JS::Result BinASTParser::parseInterfaceIfStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::IfStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = { @@ -3218,11 +3433,11 @@ JS::Result BinASTParser::parseInterfaceIfStatement( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(test, parseExpression()); + BINJS_MOZ_TRY_DECL(test, parseExpression(fieldContext++)); - BINJS_MOZ_TRY_DECL(consequent, parseStatement()); + BINJS_MOZ_TRY_DECL(consequent, parseStatement(fieldContext++)); - BINJS_MOZ_TRY_DECL(alternate, parseOptionalStatement()); + BINJS_MOZ_TRY_DECL(alternate, parseOptionalStatement(fieldContext++)); BINJS_TRY_DECL(result, handler_.newIfStatement(start, test, consequent, alternate)); @@ -3231,9 +3446,11 @@ JS::Result BinASTParser::parseInterfaceIfStatement( template JS::Result BinASTParser::parseInterfaceLabelledStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::LabelledStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Label, @@ -3242,12 +3459,12 @@ JS::Result BinASTParser::parseInterfaceLabelledStatement( #endif // defined(DEBUG) RootedAtom label(cx_); - MOZ_TRY_VAR(label, tokenizer_->readAtom()); + MOZ_TRY_VAR(label, tokenizer_->readAtom(fieldContext++)); if (!IsIdentifier(label)) { return raiseError("Invalid identifier"); } ParseContext::LabelStatement stmt(pc_, label); - BINJS_MOZ_TRY_DECL(body, parseStatement()); + BINJS_MOZ_TRY_DECL(body, parseStatement(fieldContext++)); BINJS_TRY_DECL(result, handler_.newLabeledStatement(label->asPropertyName(), body, start)); @@ -3257,7 +3474,8 @@ JS::Result BinASTParser::parseInterfaceLabelledStatement( template JS::Result BinASTParser::parseInterfaceLazyArrowExpressionWithExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release " "(LazyArrowExpressionWithExpression)"); @@ -3266,7 +3484,8 @@ BinASTParser::parseInterfaceLazyArrowExpressionWithExpression( template JS::Result BinASTParser::parseInterfaceLazyArrowExpressionWithFunctionBody( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release " "(LazyArrowExpressionWithFunctionBody)"); @@ -3274,9 +3493,11 @@ BinASTParser::parseInterfaceLazyArrowExpressionWithFunctionBody( template JS::Result BinASTParser::parseInterfaceLazyFunctionDeclaration( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::LazyFunctionDeclaration); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[7] = { @@ -3287,22 +3508,23 @@ JS::Result BinASTParser::parseInterfaceLazyFunctionDeclaration( #endif // defined(DEBUG) const auto syntax = FunctionSyntaxKind::Statement; - BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool(fieldContext++)); if (isAsync) { return raiseError( "Async function is not supported in this preview release"); } - BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool(fieldContext++)); if (isGenerator) { return raiseError("Generator is not supported in this preview release"); } - BINJS_MOZ_TRY_DECL(name, parseBindingIdentifier()); + BINJS_MOZ_TRY_DECL(name, parseBindingIdentifier(fieldContext++)); - BINJS_MOZ_TRY_DECL(length, tokenizer_->readUnsignedLong()); + BINJS_MOZ_TRY_DECL(length, tokenizer_->readUnsignedLong(fieldContext++)); - BINJS_MOZ_TRY_DECL(directives, parseListOfDirective()); + BINJS_MOZ_TRY_DECL(directives, parseListOfDirective(fieldContext++)); - BINJS_MOZ_TRY_DECL(contentsSkip, tokenizer_->readSkippableSubTree()); + BINJS_MOZ_TRY_DECL(contentsSkip, + tokenizer_->readSkippableSubTree(fieldContext++)); // Don't parse the contents until we delazify. BINJS_MOZ_TRY_DECL(funbox, @@ -3339,9 +3561,11 @@ JS::Result BinASTParser::parseInterfaceLazyFunctionDeclaration( template JS::Result BinASTParser::parseInterfaceLazyFunctionExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::LazyFunctionExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[7] = { @@ -3352,22 +3576,23 @@ JS::Result BinASTParser::parseInterfaceLazyFunctionExpression( #endif // defined(DEBUG) const auto syntax = FunctionSyntaxKind::Expression; - BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool(fieldContext++)); if (isAsync) { return raiseError( "Async function is not supported in this preview release"); } - BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool(fieldContext++)); if (isGenerator) { return raiseError("Generator is not supported in this preview release"); } - BINJS_MOZ_TRY_DECL(name, parseOptionalBindingIdentifier()); + BINJS_MOZ_TRY_DECL(name, parseOptionalBindingIdentifier(fieldContext++)); - BINJS_MOZ_TRY_DECL(length, tokenizer_->readUnsignedLong()); + BINJS_MOZ_TRY_DECL(length, tokenizer_->readUnsignedLong(fieldContext++)); - BINJS_MOZ_TRY_DECL(directives, parseListOfDirective()); + BINJS_MOZ_TRY_DECL(directives, parseListOfDirective(fieldContext++)); - BINJS_MOZ_TRY_DECL(contentsSkip, tokenizer_->readSkippableSubTree()); + BINJS_MOZ_TRY_DECL(contentsSkip, + tokenizer_->readSkippableSubTree(fieldContext++)); // Don't parse the contents until we delazify. BINJS_MOZ_TRY_DECL(funbox, @@ -3404,21 +3629,24 @@ JS::Result BinASTParser::parseInterfaceLazyFunctionExpression( template JS::Result BinASTParser::parseInterfaceLazyGetter( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (LazyGetter)"); } template JS::Result BinASTParser::parseInterfaceLazyMethod( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (LazyMethod)"); } template JS::Result BinASTParser::parseInterfaceLazySetter( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (LazySetter)"); } @@ -3426,16 +3654,18 @@ JS::Result BinASTParser::parseInterfaceLazySetter( template JS::Result BinASTParser::parseInterfaceLiteralBooleanExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::LiteralBooleanExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Value}; MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(value, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(value, tokenizer_->readBool(fieldContext++)); BINJS_TRY_DECL(result, handler_.newBooleanLiteral(value, tokenizer_->pos(start))); @@ -3445,7 +3675,8 @@ BinASTParser::parseInterfaceLiteralBooleanExpression( template JS::Result BinASTParser::parseInterfaceLiteralInfinityExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release " "(LiteralInfinityExpression)"); @@ -3453,7 +3684,8 @@ BinASTParser::parseInterfaceLiteralInfinityExpression( template JS::Result BinASTParser::parseInterfaceLiteralNullExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::LiteralNullExpression); BINJS_TRY(CheckRecursionLimit(cx_)); MOZ_TRY(tokenizer_->checkFields0(kind, fields)); @@ -3465,16 +3697,18 @@ JS::Result BinASTParser::parseInterfaceLiteralNullExpression( template JS::Result BinASTParser::parseInterfaceLiteralNumericExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::LiteralNumericExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Value}; MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(value, tokenizer_->readDouble()); + BINJS_MOZ_TRY_DECL(value, tokenizer_->readDouble(fieldContext++)); BINJS_TRY_DECL(result, handler_.newNumber(value, DecimalPoint::HasDecimal, tokenizer_->pos(start))); @@ -3483,9 +3717,11 @@ BinASTParser::parseInterfaceLiteralNumericExpression( template JS::Result BinASTParser::parseInterfaceLiteralPropertyName( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::LiteralPropertyName); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Value}; @@ -3493,7 +3729,7 @@ JS::Result BinASTParser::parseInterfaceLiteralPropertyName( #endif // defined(DEBUG) RootedAtom value(cx_); - MOZ_TRY_VAR(value, tokenizer_->readAtom()); + MOZ_TRY_VAR(value, tokenizer_->readAtom(fieldContext++)); ParseNode* result; uint32_t index; @@ -3510,9 +3746,11 @@ JS::Result BinASTParser::parseInterfaceLiteralPropertyName( template JS::Result BinASTParser::parseInterfaceLiteralRegExpExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::LiteralRegExpExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Pattern, @@ -3521,9 +3759,9 @@ JS::Result BinASTParser::parseInterfaceLiteralRegExpExpression( #endif // defined(DEBUG) RootedAtom pattern(cx_); - MOZ_TRY_VAR(pattern, tokenizer_->readAtom()); + MOZ_TRY_VAR(pattern, tokenizer_->readAtom(fieldContext++)); Chars flags(cx_); - MOZ_TRY(tokenizer_->readChars(flags)); + MOZ_TRY(tokenizer_->readChars(flags, fieldContext)); RegExpFlags reflags = RegExpFlag::NoFlags; for (auto c : flags) { @@ -3553,9 +3791,11 @@ JS::Result BinASTParser::parseInterfaceLiteralRegExpExpression( template JS::Result BinASTParser::parseInterfaceLiteralStringExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::LiteralStringExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Value}; @@ -3563,7 +3803,7 @@ JS::Result BinASTParser::parseInterfaceLiteralStringExpression( #endif // defined(DEBUG) RootedAtom value(cx_); - MOZ_TRY_VAR(value, tokenizer_->readAtom()); + MOZ_TRY_VAR(value, tokenizer_->readAtom(fieldContext++)); BINJS_TRY_DECL(result, handler_.newStringLiteral(value, tokenizer_->pos(start))); @@ -3572,16 +3812,19 @@ JS::Result BinASTParser::parseInterfaceLiteralStringExpression( template JS::Result BinASTParser::parseInterfaceModule( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (Module)"); } template JS::Result BinASTParser::parseInterfaceNewExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::NewExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Callee, @@ -3589,9 +3832,9 @@ JS::Result BinASTParser::parseInterfaceNewExpression( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(callee, parseExpression()); + BINJS_MOZ_TRY_DECL(callee, parseExpression(fieldContext++)); - BINJS_MOZ_TRY_DECL(arguments, parseArguments()); + BINJS_MOZ_TRY_DECL(arguments, parseArguments(fieldContext++)); BINJS_TRY_DECL(result, handler_.newNewExpression(tokenizer_->pos(start).begin, callee, @@ -3601,7 +3844,8 @@ JS::Result BinASTParser::parseInterfaceNewExpression( template JS::Result BinASTParser::parseInterfaceNewTargetExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release " "(NewTargetExpression)"); @@ -3609,7 +3853,8 @@ JS::Result BinASTParser::parseInterfaceNewTargetExpression( template JS::Result BinASTParser::parseInterfaceObjectAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release " "(ObjectAssignmentTarget)"); @@ -3617,23 +3862,26 @@ JS::Result BinASTParser::parseInterfaceObjectAssignmentTarget( template JS::Result BinASTParser::parseInterfaceObjectBinding( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (ObjectBinding)"); } template JS::Result BinASTParser::parseInterfaceObjectExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ObjectExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Properties}; MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(properties, parseListOfObjectProperty()); + BINJS_MOZ_TRY_DECL(properties, parseListOfObjectProperty(fieldContext++)); auto result = properties; return result; @@ -3641,9 +3889,11 @@ JS::Result BinASTParser::parseInterfaceObjectExpression( template JS::Result BinASTParser::parseInterfaceReturnStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ReturnStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Expression}; @@ -3656,7 +3906,7 @@ JS::Result BinASTParser::parseInterfaceReturnStatement( pc_->functionBox()->usesReturn = true; - BINJS_MOZ_TRY_DECL(expression, parseOptionalExpression()); + BINJS_MOZ_TRY_DECL(expression, parseOptionalExpression(fieldContext++)); BINJS_TRY_DECL( result, handler_.newReturnStatement(expression, tokenizer_->pos(start))); @@ -3665,9 +3915,11 @@ JS::Result BinASTParser::parseInterfaceReturnStatement( template JS::Result BinASTParser::parseInterfaceScript( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::Script); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = { @@ -3675,11 +3927,11 @@ JS::Result BinASTParser::parseInterfaceScript( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - MOZ_TRY(parseAssertedScriptGlobalScope()); + MOZ_TRY(parseAssertedScriptGlobalScope(fieldContext++)); - BINJS_MOZ_TRY_DECL(directives, parseListOfDirective()); + BINJS_MOZ_TRY_DECL(directives, parseListOfDirective(fieldContext++)); forceStrictIfNecessary(pc_->sc(), directives); - BINJS_MOZ_TRY_DECL(statements, parseListOfStatement()); + BINJS_MOZ_TRY_DECL(statements, parseListOfStatement(fieldContext++)); MOZ_TRY(checkClosedVars(pc_->varScope())); MOZ_TRY(prependDirectivesToBody(/* body = */ statements, directives)); @@ -3699,19 +3951,20 @@ JS::Result BinASTParser::parseInterfaceScript( template JS::Result BinASTParser::parseSetterContents(uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut) { + ListNode** bodyOut, + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::SetterContents) { return raiseInvalidKind("SetterContents", kind); } const auto start = tokenizer_->offset(); BINJS_MOZ_TRY_DECL( result, parseInterfaceSetterContents(start, kind, fields, funLength, - paramsOut, bodyOut)); + paramsOut, bodyOut, context)); MOZ_TRY(guard.done()); return result; @@ -3720,9 +3973,11 @@ JS::Result BinASTParser::parseSetterContents(uint32_t funLength, template JS::Result BinASTParser::parseInterfaceSetterContents( const size_t start, const BinASTKind kind, const BinASTFields& fields, - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut) { + uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::SetterContents); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[5] = { @@ -3731,19 +3986,19 @@ JS::Result BinASTParser::parseInterfaceSetterContents( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(isThisCaptured, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isThisCaptured, tokenizer_->readBool(fieldContext++)); // TODO: Use this in BinASTParser::buildFunction. (void)isThisCaptured; Rooted> positionalParams(cx_, GCVector(cx_)); - MOZ_TRY(parseAssertedParameterScope(&positionalParams)); + MOZ_TRY(parseAssertedParameterScope(&positionalParams, fieldContext++)); - BINJS_MOZ_TRY_DECL(param, parseParameter()); + BINJS_MOZ_TRY_DECL(param, parseParameter(fieldContext++)); BINJS_TRY_DECL(params, handler_.newParamsBody(param->pn_pos)); handler_.addList(params, param); MOZ_TRY(checkPositionalParameterIndices(positionalParams, params)); - MOZ_TRY(parseAssertedVarScope()); + MOZ_TRY(parseAssertedVarScope(fieldContext++)); - BINJS_MOZ_TRY_DECL(body, parseFunctionBody()); + BINJS_MOZ_TRY_DECL(body, parseFunctionBody(fieldContext++)); *paramsOut = params; *bodyOut = body; @@ -3753,16 +4008,18 @@ JS::Result BinASTParser::parseInterfaceSetterContents( template JS::Result BinASTParser::parseInterfaceShorthandProperty( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ShorthandProperty); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Name}; MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(name, parseIdentifierExpression()); + BINJS_MOZ_TRY_DECL(name, parseIdentifierExpression(fieldContext++)); MOZ_ASSERT(name->isKind(ParseNodeKind::Name)); MOZ_ASSERT(!handler_.isUsableAsObjectPropertyName(name)); @@ -3777,7 +4034,8 @@ JS::Result BinASTParser::parseInterfaceShorthandProperty( template JS::Result BinASTParser::parseInterfaceSpreadElement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (SpreadElement)"); } @@ -3785,9 +4043,11 @@ JS::Result BinASTParser::parseInterfaceSpreadElement( template JS::Result BinASTParser::parseInterfaceStaticMemberAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::StaticMemberAssignmentTarget); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Object, @@ -3796,11 +4056,12 @@ BinASTParser::parseInterfaceStaticMemberAssignmentTarget( #endif // defined(DEBUG) size_t nameStart; - BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper()); + BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper(fieldContext++)); + RootedAtom property(cx_); { nameStart = tokenizer_->offset(); - MOZ_TRY_VAR(property, tokenizer_->readPropertyKey()); + MOZ_TRY_VAR(property, tokenizer_->readPropertyKey(fieldContext++)); } BINJS_TRY_DECL(name, handler_.newPropertyName(property->asPropertyName(), @@ -3811,9 +4072,11 @@ BinASTParser::parseInterfaceStaticMemberAssignmentTarget( template JS::Result BinASTParser::parseInterfaceStaticMemberExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::StaticMemberExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Object, @@ -3822,11 +4085,12 @@ JS::Result BinASTParser::parseInterfaceStaticMemberExpression( #endif // defined(DEBUG) size_t nameStart; - BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper()); + BINJS_MOZ_TRY_DECL(object, parseExpressionOrSuper(fieldContext++)); + RootedAtom property(cx_); { nameStart = tokenizer_->offset(); - MOZ_TRY_VAR(property, tokenizer_->readPropertyKey()); + MOZ_TRY_VAR(property, tokenizer_->readPropertyKey(fieldContext++)); } BINJS_TRY_DECL(name, handler_.newPropertyName(property->asPropertyName(), @@ -3837,7 +4101,8 @@ JS::Result BinASTParser::parseInterfaceStaticMemberExpression( template JS::Result BinASTParser::parseInterfaceSuper( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (Super)"); } @@ -3849,17 +4114,19 @@ JS::Result BinASTParser::parseInterfaceSuper( } */ template -JS::Result BinASTParser::parseSwitchCase() { +JS::Result BinASTParser::parseSwitchCase( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::SwitchCase) { return raiseInvalidKind("SwitchCase", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceSwitchCase(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, + parseInterfaceSwitchCase(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -3867,9 +4134,11 @@ JS::Result BinASTParser::parseSwitchCase() { template JS::Result BinASTParser::parseInterfaceSwitchCase( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::SwitchCase); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Test, @@ -3877,9 +4146,9 @@ JS::Result BinASTParser::parseInterfaceSwitchCase( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(test, parseExpression()); + BINJS_MOZ_TRY_DECL(test, parseExpression(fieldContext++)); - BINJS_MOZ_TRY_DECL(consequent, parseListOfStatement()); + BINJS_MOZ_TRY_DECL(consequent, parseListOfStatement(fieldContext++)); BINJS_TRY_DECL(result, handler_.newCaseOrDefault(start, test, consequent)); return result; @@ -3891,17 +4160,19 @@ JS::Result BinASTParser::parseInterfaceSwitchCase( } */ template -JS::Result BinASTParser::parseSwitchDefault() { +JS::Result BinASTParser::parseSwitchDefault( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::SwitchDefault) { return raiseInvalidKind("SwitchDefault", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, parseInterfaceSwitchDefault(start, kind, fields)); + BINJS_MOZ_TRY_DECL(result, + parseInterfaceSwitchDefault(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -3909,16 +4180,18 @@ JS::Result BinASTParser::parseSwitchDefault() { template JS::Result BinASTParser::parseInterfaceSwitchDefault( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::SwitchDefault); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Consequent}; MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(consequent, parseListOfStatement()); + BINJS_MOZ_TRY_DECL(consequent, parseListOfStatement(fieldContext++)); BINJS_TRY_DECL(result, handler_.newCaseOrDefault(start, nullptr, consequent)); return result; @@ -3926,9 +4199,11 @@ JS::Result BinASTParser::parseInterfaceSwitchDefault( template JS::Result BinASTParser::parseInterfaceSwitchStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::SwitchStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Discriminant, @@ -3936,9 +4211,9 @@ JS::Result BinASTParser::parseInterfaceSwitchStatement( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(discriminant, parseExpression()); + BINJS_MOZ_TRY_DECL(discriminant, parseExpression(fieldContext++)); ParseContext::Statement stmt(pc_, StatementKind::Switch); - BINJS_MOZ_TRY_DECL(cases, parseListOfSwitchCase()); + BINJS_MOZ_TRY_DECL(cases, parseListOfSwitchCase(fieldContext++)); BINJS_TRY_DECL(scope, handler_.newLexicalScope(nullptr, cases)); BINJS_TRY_DECL(result, handler_.newSwitchStatement(start, discriminant, scope, @@ -3949,9 +4224,11 @@ JS::Result BinASTParser::parseInterfaceSwitchStatement( template JS::Result BinASTParser::parseInterfaceSwitchStatementWithDefault( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::SwitchStatementWithDefault); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[4] = { @@ -3960,13 +4237,13 @@ BinASTParser::parseInterfaceSwitchStatementWithDefault( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(discriminant, parseExpression()); + BINJS_MOZ_TRY_DECL(discriminant, parseExpression(fieldContext++)); ParseContext::Statement stmt(pc_, StatementKind::Switch); - BINJS_MOZ_TRY_DECL(preDefaultCases, parseListOfSwitchCase()); + BINJS_MOZ_TRY_DECL(preDefaultCases, parseListOfSwitchCase(fieldContext++)); - BINJS_MOZ_TRY_DECL(defaultCase, parseSwitchDefault()); + BINJS_MOZ_TRY_DECL(defaultCase, parseSwitchDefault(fieldContext++)); - BINJS_MOZ_TRY_DECL(postDefaultCases, parseListOfSwitchCase()); + BINJS_MOZ_TRY_DECL(postDefaultCases, parseListOfSwitchCase(fieldContext++)); // Concatenate `preDefaultCase`, `defaultCase`, `postDefaultCase` auto cases = preDefaultCases; @@ -3985,7 +4262,8 @@ BinASTParser::parseInterfaceSwitchStatementWithDefault( template JS::Result BinASTParser::parseInterfaceTemplateExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release " "(TemplateExpression)"); @@ -3993,7 +4271,8 @@ JS::Result BinASTParser::parseInterfaceTemplateExpression( template JS::Result BinASTParser::parseInterfaceThisExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ThisExpression); BINJS_TRY(CheckRecursionLimit(cx_)); MOZ_TRY(tokenizer_->checkFields0(kind, fields)); @@ -4017,16 +4296,18 @@ JS::Result BinASTParser::parseInterfaceThisExpression( template JS::Result BinASTParser::parseInterfaceThrowStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::ThrowStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[1] = {BinASTField::Expression}; MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(expression, parseExpression()); + BINJS_MOZ_TRY_DECL(expression, parseExpression(fieldContext++)); BINJS_TRY_DECL( result, handler_.newThrowStatement(expression, tokenizer_->pos(start))); @@ -4035,24 +4316,27 @@ JS::Result BinASTParser::parseInterfaceThrowStatement( template JS::Result BinASTParser::parseInterfaceTryCatchStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::TryCatchStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Body, BinASTField::CatchClause}; MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) + ParseNode* body; { ParseContext::Statement stmt(pc_, StatementKind::Try); ParseContext::Scope scope(cx_, pc_, usedNames_); BINJS_TRY(scope.init(pc_)); - MOZ_TRY_VAR(body, parseBlock()); + MOZ_TRY_VAR(body, parseBlock(fieldContext++)); } - BINJS_MOZ_TRY_DECL(catchClause, parseCatchClause()); + BINJS_MOZ_TRY_DECL(catchClause, parseCatchClause(fieldContext++)); BINJS_TRY_DECL(result, handler_.newTryStatement(start, body, catchClause, @@ -4062,30 +4346,34 @@ JS::Result BinASTParser::parseInterfaceTryCatchStatement( template JS::Result BinASTParser::parseInterfaceTryFinallyStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::TryFinallyStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = { BinASTField::Body, BinASTField::CatchClause, BinASTField::Finalizer}; MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) + ParseNode* body; { ParseContext::Statement stmt(pc_, StatementKind::Try); ParseContext::Scope scope(cx_, pc_, usedNames_); BINJS_TRY(scope.init(pc_)); - MOZ_TRY_VAR(body, parseBlock()); + MOZ_TRY_VAR(body, parseBlock(fieldContext++)); } - BINJS_MOZ_TRY_DECL(catchClause, parseOptionalCatchClause()); + BINJS_MOZ_TRY_DECL(catchClause, parseOptionalCatchClause(fieldContext++)); + ParseNode* finalizer; { ParseContext::Statement stmt(pc_, StatementKind::Finally); ParseContext::Scope scope(cx_, pc_, usedNames_); BINJS_TRY(scope.init(pc_)); - MOZ_TRY_VAR(finalizer, parseBlock()); + MOZ_TRY_VAR(finalizer, parseBlock(fieldContext++)); } BINJS_TRY_DECL(result, @@ -4095,9 +4383,11 @@ JS::Result BinASTParser::parseInterfaceTryFinallyStatement( template JS::Result BinASTParser::parseInterfaceUnaryExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::UnaryExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Operator, @@ -4105,9 +4395,9 @@ JS::Result BinASTParser::parseInterfaceUnaryExpression( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(operator_, parseUnaryOperator()); + BINJS_MOZ_TRY_DECL(operator_, parseUnaryOperator(fieldContext++)); - BINJS_MOZ_TRY_DECL(operand, parseExpression()); + BINJS_MOZ_TRY_DECL(operand, parseExpression(fieldContext++)); ParseNodeKind pnk; switch (operator_) { @@ -4159,9 +4449,11 @@ JS::Result BinASTParser::parseInterfaceUnaryExpression( template JS::Result BinASTParser::parseInterfaceUpdateExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::UpdateExpression); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[3] = { @@ -4169,11 +4461,11 @@ JS::Result BinASTParser::parseInterfaceUpdateExpression( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(isPrefix, tokenizer_->readBool()); + BINJS_MOZ_TRY_DECL(isPrefix, tokenizer_->readBool(fieldContext++)); - BINJS_MOZ_TRY_DECL(operator_, parseUpdateOperator()); + BINJS_MOZ_TRY_DECL(operator_, parseUpdateOperator(fieldContext++)); - BINJS_MOZ_TRY_DECL(operand, parseSimpleAssignmentTarget()); + BINJS_MOZ_TRY_DECL(operand, parseSimpleAssignmentTarget(fieldContext++)); ParseNodeKind pnk; switch (operator_) { @@ -4192,9 +4484,11 @@ JS::Result BinASTParser::parseInterfaceUpdateExpression( template JS::Result BinASTParser::parseInterfaceVariableDeclaration( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::VariableDeclaration); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Kind, @@ -4203,7 +4497,7 @@ JS::Result BinASTParser::parseInterfaceVariableDeclaration( #endif // defined(DEBUG) AutoVariableDeclarationKind kindGuard(this); - BINJS_MOZ_TRY_DECL(kind_, parseVariableDeclarationKind()); + BINJS_MOZ_TRY_DECL(kind_, parseVariableDeclarationKind(fieldContext++)); // Restored by `kindGuard`. variableDeclarationKind_ = kind_; ParseNodeKind declarationListKind; @@ -4216,8 +4510,8 @@ JS::Result BinASTParser::parseInterfaceVariableDeclaration( case VariableDeclarationKind::Const: return raiseError("Const is not supported in this preview release"); } - BINJS_MOZ_TRY_DECL(declarators, - parseListOfVariableDeclarator(declarationListKind)); + BINJS_MOZ_TRY_DECL(declarators, parseListOfVariableDeclarator( + declarationListKind, fieldContext++)); // By specification, the list may not be empty. if (declarators->empty()) { @@ -4235,18 +4529,19 @@ JS::Result BinASTParser::parseInterfaceVariableDeclaration( } */ template -JS::Result BinASTParser::parseVariableDeclarator() { +JS::Result BinASTParser::parseVariableDeclarator( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::VariableDeclarator) { return raiseInvalidKind("VariableDeclarator", kind); } const auto start = tokenizer_->offset(); - BINJS_MOZ_TRY_DECL(result, - parseInterfaceVariableDeclarator(start, kind, fields)); + BINJS_MOZ_TRY_DECL( + result, parseInterfaceVariableDeclarator(start, kind, fields, context)); MOZ_TRY(guard.done()); return result; @@ -4254,9 +4549,11 @@ JS::Result BinASTParser::parseVariableDeclarator() { template JS::Result BinASTParser::parseInterfaceVariableDeclarator( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::VariableDeclarator); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Binding, @@ -4264,9 +4561,9 @@ JS::Result BinASTParser::parseInterfaceVariableDeclarator( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(binding, parseBinding()); + BINJS_MOZ_TRY_DECL(binding, parseBinding(fieldContext++)); - BINJS_MOZ_TRY_DECL(init, parseOptionalExpression()); + BINJS_MOZ_TRY_DECL(init, parseOptionalExpression(fieldContext++)); ParseNode* result; if (binding->isKind(ParseNodeKind::Name)) { @@ -4298,9 +4595,11 @@ JS::Result BinASTParser::parseInterfaceVariableDeclarator( template JS::Result BinASTParser::parseInterfaceWhileStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::WhileStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Test, BinASTField::Body}; @@ -4308,9 +4607,9 @@ JS::Result BinASTParser::parseInterfaceWhileStatement( #endif // defined(DEBUG) ParseContext::Statement stmt(pc_, StatementKind::WhileLoop); - BINJS_MOZ_TRY_DECL(test, parseExpression()); + BINJS_MOZ_TRY_DECL(test, parseExpression(fieldContext++)); - BINJS_MOZ_TRY_DECL(body, parseStatement()); + BINJS_MOZ_TRY_DECL(body, parseStatement(fieldContext++)); BINJS_TRY_DECL(result, handler_.newWhileStatement(start, test, body)); return result; @@ -4318,9 +4617,11 @@ JS::Result BinASTParser::parseInterfaceWhileStatement( template JS::Result BinASTParser::parseInterfaceWithStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { MOZ_ASSERT(kind == BinASTKind::WithStatement); BINJS_TRY(CheckRecursionLimit(cx_)); + Context fieldContext = Context::firstField(kind); #if defined(DEBUG) const BinASTField expected_fields[2] = {BinASTField::Object, @@ -4328,10 +4629,10 @@ JS::Result BinASTParser::parseInterfaceWithStatement( MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); #endif // defined(DEBUG) - BINJS_MOZ_TRY_DECL(object, parseExpression()); + BINJS_MOZ_TRY_DECL(object, parseExpression(fieldContext++)); ParseContext::Statement stmt(pc_, StatementKind::With); - BINJS_MOZ_TRY_DECL(body, parseStatement()); + BINJS_MOZ_TRY_DECL(body, parseStatement(fieldContext++)); pc_->sc()->setBindingsAccessedDynamically(); BINJS_TRY_DECL(result, handler_.newWithStatement(start, object, body)); @@ -4340,14 +4641,16 @@ JS::Result BinASTParser::parseInterfaceWithStatement( template JS::Result BinASTParser::parseInterfaceYieldExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release (YieldExpression)"); } template JS::Result BinASTParser::parseInterfaceYieldStarExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields) { + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context) { return raiseError( "FIXME: Not implemented yet in this preview release " "(YieldStarExpression)"); @@ -4363,8 +4666,8 @@ enum AssertedDeclaredKind { */ template JS::Result::AssertedDeclaredKind> -BinASTParser::parseAssertedDeclaredKind() { - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant()); +BinASTParser::parseAssertedDeclaredKind(const Context& context) { + BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); switch (variant) { case BinASTVariant::AssertedDeclaredKindOrVariableDeclarationKindVar: @@ -4409,8 +4712,8 @@ enum BinaryOperator { */ template JS::Result::BinaryOperator> -BinASTParser::parseBinaryOperator() { - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant()); +BinASTParser::parseBinaryOperator(const Context& context) { + BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); switch (variant) { case BinASTVariant::BinaryOperatorComma: @@ -4486,8 +4789,8 @@ enum CompoundAssignmentOperator { */ template JS::Result::CompoundAssignmentOperator> -BinASTParser::parseCompoundAssignmentOperator() { - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant()); +BinASTParser::parseCompoundAssignmentOperator(const Context& context) { + BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); switch (variant) { case BinASTVariant::CompoundAssignmentOperatorPlusAssign: @@ -4532,8 +4835,8 @@ enum UnaryOperator { */ template JS::Result::UnaryOperator> -BinASTParser::parseUnaryOperator() { - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant()); +BinASTParser::parseUnaryOperator(const Context& context) { + BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); switch (variant) { case BinASTVariant::BinaryOperatorOrUnaryOperatorPlus: @@ -4563,8 +4866,8 @@ enum UpdateOperator { */ template JS::Result::UpdateOperator> -BinASTParser::parseUpdateOperator() { - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant()); +BinASTParser::parseUpdateOperator(const Context& context) { + BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); switch (variant) { case BinASTVariant::UpdateOperatorIncr: @@ -4585,8 +4888,8 @@ enum VariableDeclarationKind { */ template JS::Result::VariableDeclarationKind> -BinASTParser::parseVariableDeclarationKind() { - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant()); +BinASTParser::parseVariableDeclarationKind(const Context& context) { + BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); switch (variant) { case BinASTVariant::AssertedDeclaredKindOrVariableDeclarationKindVar: @@ -4603,17 +4906,19 @@ BinASTParser::parseVariableDeclarationKind() { // ----- Lists (autogenerated, by lexicographical order) template -JS::Result BinASTParser::parseArguments() { +JS::Result BinASTParser::parseArguments( + const Context& context) { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, context, guard)); BINJS_TRY_DECL(result, handler_.newList(ParseNodeKind::Arguments, tokenizer_->pos(start))); - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseSpreadElementOrExpression()); + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) { + BINJS_MOZ_TRY_DECL(item, parseSpreadElementOrExpression(childContext)); handler_.addList(/* list = */ result, /* kid = */ item); } @@ -4622,16 +4927,18 @@ JS::Result BinASTParser::parseArguments() { } template -JS::Result BinASTParser::parseFunctionBody() { +JS::Result BinASTParser::parseFunctionBody( + const Context& context) { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, context, guard)); BINJS_TRY_DECL(result, handler_.newStatementList(tokenizer_->pos(start))); - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseStatement()); + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) { + BINJS_MOZ_TRY_DECL(item, parseStatement(childContext)); handler_.addStatementToList(result, item); } @@ -4641,17 +4948,18 @@ JS::Result BinASTParser::parseFunctionBody() { template JS::Result BinASTParser::parseListOfAssertedBoundName( - AssertedScopeKind scopeKind) { + AssertedScopeKind scopeKind, const Context& context) { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, context, guard)); (void)start; auto result = Ok(); - for (uint32_t i = 0; i < length; ++i) { - MOZ_TRY(parseAssertedBoundName(scopeKind)); + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) { + MOZ_TRY(parseAssertedBoundName(scopeKind, childContext)); // Nothing to do here. } @@ -4661,17 +4969,18 @@ JS::Result BinASTParser::parseListOfAssertedBoundName( template JS::Result BinASTParser::parseListOfAssertedDeclaredName( - AssertedScopeKind scopeKind) { + AssertedScopeKind scopeKind, const Context& context) { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, context, guard)); (void)start; auto result = Ok(); - for (uint32_t i = 0; i < length; ++i) { - MOZ_TRY(parseAssertedDeclaredName(scopeKind)); + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) { + MOZ_TRY(parseAssertedDeclaredName(scopeKind, childContext)); // Nothing to do here. } @@ -4683,12 +4992,12 @@ template JS::Result BinASTParser::parseListOfAssertedMaybePositionalParameterName( AssertedScopeKind scopeKind, - MutableHandle> positionalParams) { + MutableHandle> positionalParams, const Context& context) { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, context, guard)); (void)start; auto result = Ok(); // This list contains also destructuring parameters, and the number of @@ -4700,9 +5009,10 @@ BinASTParser::parseListOfAssertedMaybePositionalParameterName( // We resize `positionalParams` vector on demand, to keep the vector // length match to the known maximum positional parameter index + 1. - for (uint32_t i = 0; i < length; ++i) { - MOZ_TRY( - parseAssertedMaybePositionalParameterName(scopeKind, positionalParams)); + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) { + MOZ_TRY(parseAssertedMaybePositionalParameterName( + scopeKind, positionalParams, childContext)); // Nothing to do here. } @@ -4711,16 +5021,18 @@ BinASTParser::parseListOfAssertedMaybePositionalParameterName( } template -JS::Result BinASTParser::parseListOfDirective() { +JS::Result BinASTParser::parseListOfDirective( + const Context& context) { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, context, guard)); BINJS_TRY_DECL(result, handler_.newStatementList(tokenizer_->pos(start))); - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseDirective()); + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) { + BINJS_MOZ_TRY_DECL(item, parseDirective(childContext)); handler_.addStatementToList(result, item); } @@ -4729,16 +5041,18 @@ JS::Result BinASTParser::parseListOfDirective() { } template -JS::Result BinASTParser::parseListOfObjectProperty() { +JS::Result BinASTParser::parseListOfObjectProperty( + const Context& context) { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, context, guard)); BINJS_TRY_DECL(result, handler_.newObjectLiteral(start)); - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseObjectProperty()); + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) { + BINJS_MOZ_TRY_DECL(item, parseObjectProperty(childContext)); if (!item->isConstant()) result->setHasNonConstInitializer(); result->appendWithoutOrderAssumption(item); } @@ -4749,16 +5063,19 @@ JS::Result BinASTParser::parseListOfObjectProperty() { template JS::Result -BinASTParser::parseListOfOptionalSpreadElementOrExpression() { +BinASTParser::parseListOfOptionalSpreadElementOrExpression( + const Context& context) { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, context, guard)); BINJS_TRY_DECL(result, handler_.newArrayLiteral(start)); - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseOptionalSpreadElementOrExpression()); + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) { + BINJS_MOZ_TRY_DECL(item, + parseOptionalSpreadElementOrExpression(childContext)); if (item) { handler_.addArrayElement(result, item); // Infallible. } else { @@ -4771,16 +5088,18 @@ BinASTParser::parseListOfOptionalSpreadElementOrExpression() { } template -JS::Result BinASTParser::parseListOfParameter() { +JS::Result BinASTParser::parseListOfParameter( + const Context& context) { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, context, guard)); BINJS_TRY_DECL(result, handler_.newParamsBody(tokenizer_->pos(start))); - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseParameter()); + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) { + BINJS_MOZ_TRY_DECL(item, parseParameter(childContext)); handler_.addList(/* list = */ result, /* kid = */ item); } @@ -4789,16 +5108,18 @@ JS::Result BinASTParser::parseListOfParameter() { } template -JS::Result BinASTParser::parseListOfStatement() { +JS::Result BinASTParser::parseListOfStatement( + const Context& context) { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, context, guard)); BINJS_TRY_DECL(result, handler_.newStatementList(tokenizer_->pos(start))); - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseStatement()); + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) { + BINJS_MOZ_TRY_DECL(item, parseStatement(childContext)); handler_.addStatementToList(result, item); } @@ -4807,16 +5128,18 @@ JS::Result BinASTParser::parseListOfStatement() { } template -JS::Result BinASTParser::parseListOfSwitchCase() { +JS::Result BinASTParser::parseListOfSwitchCase( + const Context& context) { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, context, guard)); BINJS_TRY_DECL(result, handler_.newStatementList(tokenizer_->pos(start))); - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseSwitchCase()); + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) { + BINJS_MOZ_TRY_DECL(item, parseSwitchCase(childContext)); handler_.addCaseStatementToList(result, item); } @@ -4826,17 +5149,18 @@ JS::Result BinASTParser::parseListOfSwitchCase() { template JS::Result BinASTParser::parseListOfVariableDeclarator( - ParseNodeKind declarationListKind) { + ParseNodeKind declarationListKind, const Context& context) { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, context, guard)); BINJS_TRY_DECL(result, handler_.newDeclarationList(declarationListKind, tokenizer_->pos(start))); - for (uint32_t i = 0; i < length; ++i) { - BINJS_MOZ_TRY_DECL(item, parseVariableDeclarator()); + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) { + BINJS_MOZ_TRY_DECL(item, parseVariableDeclarator(childContext)); result->appendWithoutOrderAssumption(item); } @@ -4846,18 +5170,19 @@ JS::Result BinASTParser::parseListOfVariableDeclarator( // ----- Default values (by lexicographical order) template -JS::Result BinASTParser::parseOptionalBinding() { +JS::Result BinASTParser::parseOptionalBinding( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); ParseNode* result; if (kind == BinASTKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, parseSumBinding(start, kind, fields)); + MOZ_TRY_VAR(result, parseSumBinding(start, kind, fields, context)); } MOZ_TRY(guard.done()); @@ -4865,18 +5190,20 @@ JS::Result BinASTParser::parseOptionalBinding() { } template -JS::Result BinASTParser::parseOptionalBindingIdentifier() { +JS::Result BinASTParser::parseOptionalBindingIdentifier( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); ParseNode* result; if (kind == BinASTKind::_Null) { result = nullptr; } else if (kind == BinASTKind::BindingIdentifier) { const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, parseInterfaceBindingIdentifier(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceBindingIdentifier(start, kind, fields, context)); } else { return raiseInvalidKind("BindingIdentifier", kind); } @@ -4886,18 +5213,20 @@ JS::Result BinASTParser::parseOptionalBindingIdentifier() { } template -JS::Result BinASTParser::parseOptionalCatchClause() { +JS::Result BinASTParser::parseOptionalCatchClause( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); LexicalScopeNode* result; if (kind == BinASTKind::_Null) { result = nullptr; } else if (kind == BinASTKind::CatchClause) { const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, parseInterfaceCatchClause(start, kind, fields)); + MOZ_TRY_VAR(result, + parseInterfaceCatchClause(start, kind, fields, context)); } else { return raiseInvalidKind("CatchClause", kind); } @@ -4907,18 +5236,19 @@ JS::Result BinASTParser::parseOptionalCatchClause() { } template -JS::Result BinASTParser::parseOptionalExpression() { +JS::Result BinASTParser::parseOptionalExpression( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); ParseNode* result; if (kind == BinASTKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, parseSumExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseSumExpression(start, kind, fields, context)); } MOZ_TRY(guard.done()); @@ -4927,18 +5257,20 @@ JS::Result BinASTParser::parseOptionalExpression() { template JS::Result -BinASTParser::parseOptionalSpreadElementOrExpression() { +BinASTParser::parseOptionalSpreadElementOrExpression( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); ParseNode* result; if (kind == BinASTKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, parseSumSpreadElementOrExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseSumSpreadElementOrExpression(start, kind, fields, + context)); } MOZ_TRY(guard.done()); @@ -4946,18 +5278,19 @@ BinASTParser::parseOptionalSpreadElementOrExpression() { } template -JS::Result BinASTParser::parseOptionalStatement() { +JS::Result BinASTParser::parseOptionalStatement( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); ParseNode* result; if (kind == BinASTKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, parseSumStatement(start, kind, fields)); + MOZ_TRY_VAR(result, parseSumStatement(start, kind, fields, context)); } MOZ_TRY(guard.done()); @@ -4966,19 +5299,20 @@ JS::Result BinASTParser::parseOptionalStatement() { template JS::Result -BinASTParser::parseOptionalVariableDeclarationOrExpression() { +BinASTParser::parseOptionalVariableDeclarationOrExpression( + const Context& context) { BinASTKind kind; BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); ParseNode* result; if (kind == BinASTKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, - parseSumVariableDeclarationOrExpression(start, kind, fields)); + MOZ_TRY_VAR(result, parseSumVariableDeclarationOrExpression( + start, kind, fields, context)); } MOZ_TRY(guard.done()); diff --git a/js/src/frontend/BinASTParser.h b/js/src/frontend/BinASTParser.h index ee6b6322fe41..e3453f0a0e9c 100644 --- a/js/src/frontend/BinASTParser.h +++ b/js/src/frontend/BinASTParser.h @@ -42,6 +42,7 @@ class BinASTParser : public BinASTParserPerTokenizer { using AutoList = typename Tokenizer::AutoList; using AutoTaggedTuple = typename Tokenizer::AutoTaggedTuple; using Chars = typename Tokenizer::Chars; + using Context = typename BinASTTokenReaderBase::Context; public: // Auto-generated types. @@ -121,349 +122,486 @@ class BinASTParser : public BinASTParserPerTokenizer { // `ParseNode*` may never be nullptr JS::Result parseAssertedMaybePositionalParameterName( AssertedScopeKind scopeKind, - MutableHandle> positionalParams); - JS::Result parseAssignmentTarget(); - JS::Result parseBinding(); - JS::Result parseExpression(); - JS::Result parseExpressionOrSuper(); - JS::Result parseForInOfBindingOrAssignmentTarget(); - JS::Result parseObjectProperty(); - JS::Result parseParameter(); - JS::Result parseProgram(); - JS::Result parsePropertyName(); - JS::Result parseSimpleAssignmentTarget(); - JS::Result parseSpreadElementOrExpression(); - JS::Result parseStatement(); + MutableHandle> positionalParams, + const Context& context); + JS::Result parseAssignmentTarget(const Context& context); + JS::Result parseBinding(const Context& context); + JS::Result parseExpression(const Context& context); + JS::Result parseExpressionOrSuper(const Context& context); + JS::Result parseForInOfBindingOrAssignmentTarget( + const Context& context); + JS::Result parseObjectProperty(const Context& context); + JS::Result parseParameter(const Context& context); + JS::Result parseProgram(const Context& context); + JS::Result parsePropertyName(const Context& context); + JS::Result parseSimpleAssignmentTarget(const Context& context); + JS::Result parseSpreadElementOrExpression(const Context& context); + JS::Result parseStatement(const Context& context); JS::Result parseSumAssertedMaybePositionalParameterName( const size_t start, const BinASTKind kind, const BinASTFields& fields, AssertedScopeKind scopeKind, - MutableHandle> positionalParams); + MutableHandle> positionalParams, + const Context& context); JS::Result parseSumAssignmentTarget(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseSumBinding(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseSumExpression(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseSumExpressionOrSuper(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseSumForInOfBindingOrAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseSumObjectProperty(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseSumParameter(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseSumProgram(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseSumPropertyName(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseSumSimpleAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseSumSpreadElementOrExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseSumStatement(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseSumVariableDeclarationOrExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); // ----- Interfaces (by lexicographical order) // `ParseNode*` may never be nullptr - JS::Result parseAssertedBlockScope(); - JS::Result parseAssertedBoundName(AssertedScopeKind scopeKind); - JS::Result parseAssertedBoundNamesScope(); - JS::Result parseAssertedDeclaredName(AssertedScopeKind scopeKind); + JS::Result parseAssertedBlockScope(const Context& context); + JS::Result parseAssertedBoundName(AssertedScopeKind scopeKind, + const Context& context); + JS::Result parseAssertedBoundNamesScope(const Context& context); + JS::Result parseAssertedDeclaredName(AssertedScopeKind scopeKind, + const Context& context); JS::Result parseAssertedParameterScope( - MutableHandle> positionalParams); - JS::Result parseAssertedScriptGlobalScope(); - JS::Result parseAssertedVarScope(); - JS::Result parseBindingIdentifier(); - JS::Result parseBlock(); - JS::Result parseCatchClause(); - JS::Result parseDirective(); - JS::Result parseFormalParameters(); + MutableHandle> positionalParams, + const Context& context); + JS::Result parseAssertedScriptGlobalScope(const Context& context); + JS::Result parseAssertedVarScope(const Context& context); + JS::Result parseBindingIdentifier(const Context& context); + JS::Result parseBlock(const Context& context); + JS::Result parseCatchClause(const Context& context); + JS::Result parseDirective(const Context& context); + JS::Result parseFormalParameters(const Context& context); JS::Result parseFunctionExpressionContents(uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut); + ListNode** bodyOut, + const Context& context); JS::Result parseFunctionOrMethodContents(uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut); + ListNode** bodyOut, + const Context& context); JS::Result parseGetterContents(uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut); - JS::Result parseIdentifierExpression(); + ListNode** bodyOut, + const Context& context); + JS::Result parseIdentifierExpression(const Context& context); JS::Result parseSetterContents(uint32_t funLength, ListNode** paramsOut, - ListNode** bodyOut); - JS::Result parseSwitchCase(); - JS::Result parseSwitchDefault(); - JS::Result parseVariableDeclarator(); + ListNode** bodyOut, + const Context& context); + JS::Result parseSwitchCase(const Context& context); + JS::Result parseSwitchDefault(const Context& context); + JS::Result parseVariableDeclarator(const Context& context); JS::Result parseInterfaceArrayAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceArrayBinding(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceArrayExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceAssertedBlockScope(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceAssertedBoundName(const size_t start, const BinASTKind kind, const BinASTFields& fields, - AssertedScopeKind scopeKind); + AssertedScopeKind scopeKind, + const Context& context); JS::Result parseInterfaceAssertedBoundNamesScope( - const size_t start, const BinASTKind kind, const BinASTFields& fields); - JS::Result parseInterfaceAssertedDeclaredName( const size_t start, const BinASTKind kind, const BinASTFields& fields, - AssertedScopeKind scopeKind); + const Context& context); + JS::Result parseInterfaceAssertedDeclaredName(const size_t start, + const BinASTKind kind, + const BinASTFields& fields, + AssertedScopeKind scopeKind, + const Context& context); JS::Result parseInterfaceAssertedParameterScope( const size_t start, const BinASTKind kind, const BinASTFields& fields, - MutableHandle> positionalParams); + MutableHandle> positionalParams, + const Context& context); JS::Result parseInterfaceAssertedPositionalParameterName( const size_t start, const BinASTKind kind, const BinASTFields& fields, AssertedScopeKind scopeKind, - MutableHandle> positionalParams); + MutableHandle> positionalParams, + const Context& context); JS::Result parseInterfaceAssertedScriptGlobalScope( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceAssertedVarScope(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceAssignmentExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceAssignmentTargetIdentifier( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceAwaitExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceBinaryExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceBindingIdentifier( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceBindingWithInitializer( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceBlock(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceBreakStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceCallExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceCatchClause( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceClassDeclaration( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceClassExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceCompoundAssignmentExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceComputedMemberAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceComputedMemberExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceComputedPropertyName( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceConditionalExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceContinueStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceDataProperty(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceDebuggerStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceDirective(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceDoWhileStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceEagerArrowExpressionWithExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceEagerArrowExpressionWithFunctionBody( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceEagerFunctionDeclaration( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceEagerFunctionExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceEagerGetter(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceEagerMethod(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceEagerSetter(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceEmptyStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceExpressionStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceForInOfBinding( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceForInStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceForOfStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceForStatement(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceFormalParameters( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceFunctionExpressionContents( const size_t start, const BinASTKind kind, const BinASTFields& fields, - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut); + uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, + const Context& context); JS::Result parseInterfaceFunctionOrMethodContents( const size_t start, const BinASTKind kind, const BinASTFields& fields, - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut); + uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, + const Context& context); JS::Result parseInterfaceGetterContents( const size_t start, const BinASTKind kind, const BinASTFields& fields, - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut); + uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, + const Context& context); JS::Result parseInterfaceIdentifierExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceIfStatement(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLabelledStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLazyArrowExpressionWithExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLazyArrowExpressionWithFunctionBody( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLazyFunctionDeclaration( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLazyFunctionExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLazyGetter(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLazyMethod(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLazySetter(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLiteralBooleanExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLiteralInfinityExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLiteralNullExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLiteralNumericExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLiteralPropertyName( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLiteralRegExpExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceLiteralStringExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceModule(const size_t start, const BinASTKind kind, - const BinASTFields& fields); - JS::Result parseInterfaceNewExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); + JS::Result parseInterfaceNewExpression(const size_t start, + const BinASTKind kind, + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceNewTargetExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceObjectAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields); - JS::Result parseInterfaceObjectBinding( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); + JS::Result parseInterfaceObjectBinding(const size_t start, + const BinASTKind kind, + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceObjectExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceReturnStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceScript(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceSetterContents( const size_t start, const BinASTKind kind, const BinASTFields& fields, - uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut); + uint32_t funLength, ListNode** paramsOut, ListNode** bodyOut, + const Context& context); JS::Result parseInterfaceShorthandProperty( - const size_t start, const BinASTKind kind, const BinASTFields& fields); - JS::Result parseInterfaceSpreadElement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); + JS::Result parseInterfaceSpreadElement(const size_t start, + const BinASTKind kind, + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceStaticMemberAssignmentTarget( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceStaticMemberExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceSuper(const size_t start, const BinASTKind kind, - const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceSwitchCase(const size_t start, const BinASTKind kind, - const BinASTFields& fields); - JS::Result parseInterfaceSwitchDefault( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const BinASTFields& fields, + const Context& context); + JS::Result parseInterfaceSwitchDefault(const size_t start, + const BinASTKind kind, + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceSwitchStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceSwitchStatementWithDefault( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceTemplateExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceThisExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceThrowStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceTryCatchStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceTryFinallyStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceUnaryExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceUpdateExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceVariableDeclaration( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceVariableDeclarator( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceWhileStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); - JS::Result parseInterfaceWithStatement( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); + JS::Result parseInterfaceWithStatement(const size_t start, + const BinASTKind kind, + const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceYieldExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); JS::Result parseInterfaceYieldStarExpression( - const size_t start, const BinASTKind kind, const BinASTFields& fields); + const size_t start, const BinASTKind kind, const BinASTFields& fields, + const Context& context); // ----- String enums (by lexicographical order) JS::Result::AssertedDeclaredKind> - parseAssertedDeclaredKind(); - JS::Result::BinaryOperator> parseBinaryOperator(); + parseAssertedDeclaredKind(const Context& context); + JS::Result::BinaryOperator> parseBinaryOperator( + const Context& context); JS::Result::CompoundAssignmentOperator> - parseCompoundAssignmentOperator(); - JS::Result::UnaryOperator> parseUnaryOperator(); - JS::Result::UpdateOperator> parseUpdateOperator(); + parseCompoundAssignmentOperator(const Context& context); + JS::Result::UnaryOperator> parseUnaryOperator( + const Context& context); + JS::Result::UpdateOperator> parseUpdateOperator( + const Context& context); JS::Result::VariableDeclarationKind> - parseVariableDeclarationKind(); + parseVariableDeclarationKind(const Context& context); // ----- Lists (by lexicographical order) - JS::Result parseArguments(); - JS::Result parseFunctionBody(); - JS::Result parseListOfAssertedBoundName(AssertedScopeKind scopeKind); - JS::Result parseListOfAssertedDeclaredName(AssertedScopeKind scopeKind); + JS::Result parseArguments(const Context& context); + JS::Result parseFunctionBody(const Context& context); + JS::Result parseListOfAssertedBoundName(AssertedScopeKind scopeKind, + const Context& context); + JS::Result parseListOfAssertedDeclaredName(AssertedScopeKind scopeKind, + const Context& context); JS::Result parseListOfAssertedMaybePositionalParameterName( AssertedScopeKind scopeKind, - MutableHandle> positionalParams); - JS::Result parseListOfDirective(); - JS::Result parseListOfObjectProperty(); - JS::Result parseListOfOptionalSpreadElementOrExpression(); - JS::Result parseListOfParameter(); - JS::Result parseListOfStatement(); - JS::Result parseListOfSwitchCase(); + MutableHandle> positionalParams, + const Context& context); + JS::Result parseListOfDirective(const Context& context); + JS::Result parseListOfObjectProperty(const Context& context); + JS::Result parseListOfOptionalSpreadElementOrExpression( + const Context& context); + JS::Result parseListOfParameter(const Context& context); + JS::Result parseListOfStatement(const Context& context); + JS::Result parseListOfSwitchCase(const Context& context); JS::Result parseListOfVariableDeclarator( - ParseNodeKind declarationListKind); + ParseNodeKind declarationListKind, const Context& context); // ----- Default values (by lexicographical order) - JS::Result parseOptionalBinding(); - JS::Result parseOptionalBindingIdentifier(); - JS::Result parseOptionalCatchClause(); - JS::Result parseOptionalExpression(); - JS::Result parseOptionalSpreadElementOrExpression(); - JS::Result parseOptionalStatement(); - JS::Result parseOptionalVariableDeclarationOrExpression(); + JS::Result parseOptionalBinding(const Context& context); + JS::Result parseOptionalBindingIdentifier(const Context& context); + JS::Result parseOptionalCatchClause( + const Context& context); + JS::Result parseOptionalExpression(const Context& context); + JS::Result parseOptionalSpreadElementOrExpression( + const Context& context); + JS::Result parseOptionalStatement(const Context& context); + JS::Result parseOptionalVariableDeclarationOrExpression( + const Context& context); }; extern template class BinASTParser; diff --git a/js/src/frontend/BinASTParserPerTokenizer.cpp b/js/src/frontend/BinASTParserPerTokenizer.cpp index 36ec93bc60ee..cfead1dfed0e 100644 --- a/js/src/frontend/BinASTParserPerTokenizer.cpp +++ b/js/src/frontend/BinASTParserPerTokenizer.cpp @@ -132,7 +132,8 @@ JS::Result BinASTParserPerTokenizer::parseAux( MOZ_TRY(tokenizer_->readHeader()); ParseNode* result(nullptr); - MOZ_TRY_VAR(result, asFinalParser()->parseProgram()); + const Context topContext(Context::topLevel()); + MOZ_TRY_VAR(result, asFinalParser()->parseProgram(topContext)); mozilla::Maybe bindings = NewGlobalScopeData(cx_, varScope, alloc_, pc_); @@ -191,7 +192,12 @@ JS::Result BinASTParserPerTokenizer::parseLazyFunction( ListNode* tmpBody; auto parseFunc = isExpr ? &FinalParser::parseFunctionExpressionContents : &FinalParser::parseFunctionOrMethodContents; - MOZ_TRY((asFinalParser()->*parseFunc)(func->nargs(), ¶ms, &tmpBody)); + + // Inject a toplevel context (i.e. no parent) to parse the lazy content. + // In the future, we may move this to a more specific context. + const Context context(Context::topLevel()); + MOZ_TRY( + (asFinalParser()->*parseFunc)(func->nargs(), ¶ms, &tmpBody, context)); BINJS_TRY_DECL(lexicalScopeData, NewLexicalScopeData(cx_, lexicalScope, alloc_, pc_)); diff --git a/js/src/frontend/BinASTParserPerTokenizer.h b/js/src/frontend/BinASTParserPerTokenizer.h index 02db3332c0e8..6cf3220eacc1 100644 --- a/js/src/frontend/BinASTParserPerTokenizer.h +++ b/js/src/frontend/BinASTParserPerTokenizer.h @@ -56,6 +56,7 @@ class BinASTParserPerTokenizer : public BinASTParserBase, using AutoTaggedTuple = typename Tokenizer::AutoTaggedTuple; using BinASTFields = typename Tokenizer::BinASTFields; using Chars = typename Tokenizer::Chars; + using Context = BinASTTokenReaderBase::Context; public: // Auto-generated types. diff --git a/js/src/frontend/BinASTToken.h b/js/src/frontend/BinASTToken.h index 2c71cb8f15e8..ad043cb40d88 100644 --- a/js/src/frontend/BinASTToken.h +++ b/js/src/frontend/BinASTToken.h @@ -14,6 +14,8 @@ #include +#include "jstypes.h" + /** * Definition of Binary AST tokens. * @@ -185,7 +187,7 @@ namespace frontend { F(YieldExpression, "YieldExpression") \ F(YieldStarExpression, "YieldStarExpression") -enum class BinASTKind { +enum class BinASTKind : uint16_t { #define EMIT_ENUM(name, _) name, FOR_EACH_BIN_KIND(EMIT_ENUM) #undef EMIT_ENUM @@ -278,7 +280,7 @@ const size_t BINASTKIND_LIMIT = 120; F(Update, "update") \ F(Value, "value") -enum class BinASTField { +enum class BinASTField : uint16_t { #define EMIT_ENUM(name, _) name, FOR_EACH_BIN_FIELD(EMIT_ENUM) #undef EMIT_ENUM @@ -354,7 +356,7 @@ const size_t BINASTFIELD_LIMIT = 69; F(VariableDeclarationKindConst, "const") \ F(VariableDeclarationKindLet, "let") -enum class BinASTVariant { +enum class BinASTVariant : uint16_t { #define EMIT_ENUM(name, _) name, FOR_EACH_BIN_VARIANT(EMIT_ENUM) #undef EMIT_ENUM diff --git a/js/src/frontend/BinASTTokenReaderBase.h b/js/src/frontend/BinASTTokenReaderBase.h index 8708e38d02d0..30fcc7d2f29b 100644 --- a/js/src/frontend/BinASTTokenReaderBase.h +++ b/js/src/frontend/BinASTTokenReaderBase.h @@ -25,6 +25,53 @@ class MOZ_STACK_CLASS BinASTTokenReaderBase { template using ErrorResult = mozilla::GenericErrorResult; + // The context in which we read a token. + struct Context { + // Construct a context for a root node. + constexpr static Context topLevel() { + return Context(BinASTKind::_Null, 0, ElementOf::TaggedTuple); + } + + Context arrayElement() const { + return Context(kind, fieldIndex, ElementOf::Array); + } + + // Construct a context for a field of a tagged tuple. + constexpr static Context firstField(BinASTKind kind) { + return Context(kind, 0, ElementOf::TaggedTuple); + } + + const Context operator++(int) { + MOZ_ASSERT(elementOf == ElementOf::TaggedTuple); + Context result = *this; + fieldIndex++; + return result; + } + + // The kind of the tagged tuple containing the token. + // + // If the parent is the root, use `BinASTKind::_Null`. + BinASTKind kind; + + // The index of the token as a field of the parent. + uint8_t fieldIndex; + + enum class ElementOf { + // This token is an element of an array. + Array, + + // This token is a field of a tagged tuple. + TaggedTuple, + }; + ElementOf elementOf; + + Context() = delete; + + private: + constexpr Context(BinASTKind kind, uint8_t fieldIndex, ElementOf elementOf) + : kind(kind), fieldIndex(fieldIndex), elementOf(elementOf) {} + }; + // The information needed to skip a subtree. class SkippableSubTree { public: diff --git a/js/src/frontend/BinASTTokenReaderMultipart.cpp b/js/src/frontend/BinASTTokenReaderMultipart.cpp index bf1e1d06d383..d31361041be9 100644 --- a/js/src/frontend/BinASTTokenReaderMultipart.cpp +++ b/js/src/frontend/BinASTTokenReaderMultipart.cpp @@ -221,7 +221,7 @@ void BinASTTokenReaderMultipart::traceMetadata(JSTracer* trc) { } } -JS::Result BinASTTokenReaderMultipart::readBool() { +JS::Result BinASTTokenReaderMultipart::readBool(const Context&) { updateLatestKnownGood(); BINJS_MOZ_TRY_DECL(byte, readByte()); @@ -241,7 +241,7 @@ JS::Result BinASTTokenReaderMultipart::readBool() { // // NULL_FLOAT_REPRESENTATION (signaling NaN) => null // anything other 64 bit sequence => IEEE-764 64-bit floating point number -JS::Result BinASTTokenReaderMultipart::readDouble() { +JS::Result BinASTTokenReaderMultipart::readDouble(const Context&) { updateLatestKnownGood(); uint8_t bytes[8]; @@ -262,7 +262,7 @@ JS::Result BinASTTokenReaderMultipart::readDouble() { } // A single atom is represented as an index into the table of strings. -JS::Result BinASTTokenReaderMultipart::readMaybeAtom() { +JS::Result BinASTTokenReaderMultipart::readMaybeAtom(const Context&) { updateLatestKnownGood(); BINJS_MOZ_TRY_DECL(index, readInternalUint32()); @@ -272,8 +272,9 @@ JS::Result BinASTTokenReaderMultipart::readMaybeAtom() { return metadata_->getAtom(index); } -JS::Result BinASTTokenReaderMultipart::readAtom() { - BINJS_MOZ_TRY_DECL(maybe, readMaybeAtom()); +JS::Result BinASTTokenReaderMultipart::readAtom( + const Context& context) { + BINJS_MOZ_TRY_DECL(maybe, readMaybeAtom(context)); if (!maybe) { return raiseError("Empty string"); @@ -282,8 +283,9 @@ JS::Result BinASTTokenReaderMultipart::readAtom() { return maybe; } -JS::Result BinASTTokenReaderMultipart::readMaybeIdentifierName() { - BINJS_MOZ_TRY_DECL(result, readMaybeAtom()); +JS::Result BinASTTokenReaderMultipart::readMaybeIdentifierName( + const Context& context) { + BINJS_MOZ_TRY_DECL(result, readMaybeAtom(context)); if (result) { if (!IsIdentifier(result)) { return raiseError("Invalid identifier"); @@ -292,19 +294,22 @@ JS::Result BinASTTokenReaderMultipart::readMaybeIdentifierName() { return result; } -JS::Result BinASTTokenReaderMultipart::readIdentifierName() { - BINJS_MOZ_TRY_DECL(result, readAtom()); +JS::Result BinASTTokenReaderMultipart::readIdentifierName( + const Context& context) { + BINJS_MOZ_TRY_DECL(result, readAtom(context)); if (!IsIdentifier(result)) { return raiseError("Invalid identifier"); } return result; } -JS::Result BinASTTokenReaderMultipart::readPropertyKey() { - return readAtom(); +JS::Result BinASTTokenReaderMultipart::readPropertyKey( + const Context& context) { + return readAtom(context); } -JS::Result BinASTTokenReaderMultipart::readChars(Chars& out) { +JS::Result BinASTTokenReaderMultipart::readChars(Chars& out, + const Context&) { updateLatestKnownGood(); BINJS_MOZ_TRY_DECL(index, readInternalUint32()); @@ -316,7 +321,8 @@ JS::Result BinASTTokenReaderMultipart::readChars(Chars& out) { return Ok(); } -JS::Result BinASTTokenReaderMultipart::readVariant() { +JS::Result BinASTTokenReaderMultipart::readVariant( + const Context&) { updateLatestKnownGood(); BINJS_MOZ_TRY_DECL(index, readInternalUint32()); @@ -351,7 +357,7 @@ JS::Result BinASTTokenReaderMultipart::readVariant() { } JS::Result -BinASTTokenReaderMultipart::readSkippableSubTree() { +BinASTTokenReaderMultipart::readSkippableSubTree(const Context&) { updateLatestKnownGood(); BINJS_MOZ_TRY_DECL(byteLen, readInternalUint32()); @@ -370,7 +376,7 @@ BinASTTokenReaderMultipart::readSkippableSubTree() { // - uint32_t index in table [grammar]; // - content (specified by the higher-level grammar); JS::Result BinASTTokenReaderMultipart::enterTaggedTuple( - BinASTKind& tag, BinASTTokenReaderMultipart::BinASTFields&, + BinASTKind& tag, BinASTTokenReaderMultipart::BinASTFields&, const Context&, AutoTaggedTuple& guard) { BINJS_MOZ_TRY_DECL(index, readInternalUint32()); if (index >= metadata_->numBinASTKinds()) { @@ -392,6 +398,7 @@ JS::Result BinASTTokenReaderMultipart::enterTaggedTuple( // The total byte length of `number of items` + `contents` must be `byte // length`. JS::Result BinASTTokenReaderMultipart::enterList(uint32_t& items, + const Context&, AutoList& guard) { guard.init(); diff --git a/js/src/frontend/BinASTTokenReaderMultipart.h b/js/src/frontend/BinASTTokenReaderMultipart.h index f716161fbe8e..228e4d7b8922 100644 --- a/js/src/frontend/BinASTTokenReaderMultipart.h +++ b/js/src/frontend/BinASTTokenReaderMultipart.h @@ -37,6 +37,7 @@ class MOZ_STACK_CLASS BinASTTokenReaderMultipart class AutoTaggedTuple; using CharSlice = BinaryASTSupport::CharSlice; + using Context = BinASTTokenReaderBase::Context; // This implementation of `BinASTFields` is effectively `void`, as the format // does not embed field information. @@ -83,44 +84,45 @@ class MOZ_STACK_CLASS BinASTTokenReaderMultipart /** * Read a single `true | false` value. */ - MOZ_MUST_USE JS::Result readBool(); + MOZ_MUST_USE JS::Result readBool(const Context&); /** * Read a single `number` value. */ - MOZ_MUST_USE JS::Result readDouble(); + MOZ_MUST_USE JS::Result readDouble(const Context&); /** * Read a single `string | null` value. * * Fails if that string is not valid UTF-8. */ - MOZ_MUST_USE JS::Result readMaybeAtom(); - MOZ_MUST_USE JS::Result readAtom(); + MOZ_MUST_USE JS::Result readMaybeAtom(const Context&); + MOZ_MUST_USE JS::Result readAtom(const Context&); /** * Read a single IdentifierName value. */ - MOZ_MUST_USE JS::Result readMaybeIdentifierName(); - MOZ_MUST_USE JS::Result readIdentifierName(); + MOZ_MUST_USE JS::Result readMaybeIdentifierName(const Context&); + MOZ_MUST_USE JS::Result readIdentifierName(const Context&); /** * Read a single PropertyKey value. */ - MOZ_MUST_USE JS::Result readPropertyKey(); + MOZ_MUST_USE JS::Result readPropertyKey(const Context&); /** * Read a single `string | null` value. * * MAY check if that string is not valid UTF-8. */ - MOZ_MUST_USE JS::Result readChars(Chars&); + MOZ_MUST_USE JS::Result readChars(Chars&, const Context&); /** * Read a single `BinASTVariant | null` value. */ - MOZ_MUST_USE JS::Result> readMaybeVariant(); - MOZ_MUST_USE JS::Result readVariant(); + MOZ_MUST_USE JS::Result> readMaybeVariant( + const Context&); + MOZ_MUST_USE JS::Result readVariant(const Context&); /** * Read over a single `[Skippable]` subtree value. @@ -129,7 +131,8 @@ class MOZ_STACK_CLASS BinASTTokenReaderMultipart * returned `SkippableSubTree` contains the necessary information * to parse/tokenize the subtree at a later stage */ - MOZ_MUST_USE JS::Result readSkippableSubTree(); + MOZ_MUST_USE JS::Result readSkippableSubTree( + const Context&); // --- Composite values. // @@ -151,7 +154,8 @@ class MOZ_STACK_CLASS BinASTTokenReaderMultipart * If the caller has consumed too few/too many bytes, this will be reported * in the call go `guard.done()`. */ - MOZ_MUST_USE JS::Result enterList(uint32_t& length, AutoList& guard); + MOZ_MUST_USE JS::Result enterList(uint32_t& length, const Context&, + AutoList& guard); /** * Start reading a tagged tuple. @@ -171,12 +175,12 @@ class MOZ_STACK_CLASS BinASTTokenReaderMultipart */ MOZ_MUST_USE JS::Result enterTaggedTuple( BinASTKind& tag, BinASTTokenReaderMultipart::BinASTFields& fields, - AutoTaggedTuple& guard); + const Context&, AutoTaggedTuple& guard); /** * Read a single unsigned long. */ - MOZ_MUST_USE JS::Result readUnsignedLong() { + MOZ_MUST_USE JS::Result readUnsignedLong(const Context&) { return readInternalUint32(); } diff --git a/js/src/frontend/binast/src/main.rs b/js/src/frontend/binast/src/main.rs index 6a5e8337d039..d1e330fe9a8f 100644 --- a/js/src/frontend/binast/src/main.rs +++ b/js/src/frontend/binast/src/main.rs @@ -835,12 +835,18 @@ impl CPPExporter { "".to_string() } }; - format!(" JS::Result<{type_ok}> parse{prefix}{kind}({args}{extra});\n", + format!(" JS::Result<{type_ok}> parse{prefix}{kind}({args}{extra}{before_context}{context});\n", prefix = prefix, type_ok = type_ok, kind = kind, args = args, extra = extra, + before_context = if args.len() > 0 || extra_params.is_some() { + ", " + } else { + "" + }, + context = "const Context& context", ) } @@ -862,7 +868,7 @@ impl CPPExporter { "".to_string() } }; - format!("{parser_class_template}JS::Result<{type_ok}>\n{parser_class_name}::parse{prefix}{kind}({args}{extra})", + format!("{parser_class_template}JS::Result<{type_ok}>\n{parser_class_name}::parse{prefix}{kind}({args}{extra}{before_context}{context})", parser_class_template = self.rules.parser_class_template, prefix = prefix, type_ok = type_ok, @@ -870,12 +876,19 @@ impl CPPExporter { kind = kind, args = args, extra = extra, + before_context = if args.len() > 0 || extra_params.is_some() { + ", " + } else { + "" + }, + context = "const Context& context", ) } fn get_method_call(&self, var_name: &str, name: &NodeName, prefix: &str, args: &str, extra_params: &Option>, + context_name: &str, call_kind: MethodCallKind) -> String { let type_ok_is_ok = match call_kind { MethodCallKind::Decl | MethodCallKind::Var => { @@ -899,11 +912,18 @@ impl CPPExporter { "".to_string() } }; - let call = format!("parse{prefix}{name}({args}{extra})", + let call = format!("parse{prefix}{name}({args}{extra}{before_context}{context})", prefix = prefix, name = name.to_class_cases(), args = args, - extra = extra); + extra = extra, + before_context = if extra_params.is_some() || args.len() > 0 { + ", " + } else { + "" + }, + context = context_name + ); if type_ok_is_ok { // Special case: `Ok` means that we shouldn't bind the return value. @@ -1248,7 +1268,7 @@ impl CPPExporter { AutoTaggedTuple guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); {call} @@ -1259,6 +1279,7 @@ impl CPPExporter { call = self.get_method_call("result", name, "Sum", INTERFACE_ARGS, &extra_args, + "context", MethodCallKind::AlwaysDecl) .reindent(" "), first_line = self.get_method_definition_start(name, "", "", @@ -1293,6 +1314,7 @@ impl CPPExporter { call = self.get_method_call("result", node, "Interface", INTERFACE_ARGS, &extra_args, + "context", MethodCallKind::AlwaysVar) .reindent(" "), variant_name = node.to_cpp_enum_case(), @@ -1378,10 +1400,11 @@ impl CPPExporter { AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard));{empty_check} + MOZ_TRY(tokenizer_->enterList(length, context, guard));{empty_check} {init} - for (uint32_t i = 0; i < length; ++i) {{ + const Context childContext(context.arrayElement()); + for (uint8_t i = 0; i < length; ++i) {{ {call} {append} }} @@ -1403,6 +1426,7 @@ impl CPPExporter { call = self.get_method_call("item", &parser.elements, "", "", &extra_args, + "childContext", MethodCallKind::Decl) .reindent(" "), init = init, @@ -1462,7 +1486,7 @@ impl CPPExporter { BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); {type_ok} result; if (kind == BinASTKind::{null}) {{ {none_block} @@ -1485,6 +1509,7 @@ impl CPPExporter { &parser.elements, "Interface", INTERFACE_ARGS, &extra_args, + "context", MethodCallKind::AlwaysVar) .reindent(" "), before = rules_for_this_node.some_before @@ -1515,7 +1540,7 @@ impl CPPExporter { BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); {type_ok} result; if (kind == BinASTKind::{null}) {{ {none_block} @@ -1534,6 +1559,7 @@ impl CPPExporter { call = self.get_method_call("result", &parser.elements, "Sum", INTERFACE_ARGS, &extra_args, + "context", MethodCallKind::AlwaysVar) .reindent(" "), before = rules_for_this_node.some_before @@ -1571,7 +1597,7 @@ impl CPPExporter { } else { buffer.push_str(&format!("{first_line} {{ - BINJS_MOZ_TRY_DECL(result, tokenizer_->readMaybeAtom()); + BINJS_MOZ_TRY_DECL(result, tokenizer_->readMaybeAtom(context)); {build} @@ -1600,7 +1626,7 @@ impl CPPExporter { } else { buffer.push_str(&format!("{first_line} {{ - BINJS_MOZ_TRY_DECL(result, tokenizer_->readMaybeIdentifierName()); + BINJS_MOZ_TRY_DECL(result, tokenizer_->readMaybeIdentifierName(context)); {build} @@ -1665,7 +1691,7 @@ impl CPPExporter { BinASTFields fields(cx_); AutoTaggedTuple guard(*tokenizer_); - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, context, guard)); if (kind != BinASTKind::{kind}) {{ return raiseInvalidKind(\"{kind}\", kind); }} @@ -1683,6 +1709,7 @@ impl CPPExporter { call = self.get_method_call("result", name, "Interface", INTERFACE_ARGS, &extra_args, + "context", MethodCallKind::AlwaysDecl) .reindent(" ") )); @@ -1707,6 +1734,8 @@ impl CPPExporter { let mut fields_implem = String::new(); for field in interface.contents().fields() { + let context = "fieldContext++"; + let rules_for_this_field = rules_for_this_interface.by_field.get(field.name()) .cloned() .unwrap_or_default(); @@ -1717,37 +1746,53 @@ impl CPPExporter { Some(IsNullable { is_nullable: false, content: Primitive::Number }) => { if needs_block { (Some(format!("double {var_name};", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readDouble());", var_name = var_name))) + Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readDouble({context}));", + var_name = var_name, + context = context))) } else { (None, - Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readDouble());", var_name = var_name))) + Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readDouble({context}));", + var_name = var_name, + context = context))) } } Some(IsNullable { is_nullable: false, content: Primitive::UnsignedLong }) => { if needs_block { (Some(format!("uint32_t {var_name};", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readUnsignedLong());", var_name = var_name))) + Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readUnsignedLong({context}));", + var_name = var_name, + context = context))) } else { (None, - Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readUnsignedLong());", var_name = var_name))) + Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readUnsignedLong({context}));", + var_name = var_name, + context = context))) } } Some(IsNullable { is_nullable: false, content: Primitive::Boolean }) => { if needs_block { (Some(format!("bool {var_name};", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readBool());", var_name = var_name))) + Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readBool({context}));", + var_name = var_name, + context = context))) } else { (None, - Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readBool());", var_name = var_name))) + Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readBool({context}));", + var_name = var_name, + context = context))) } } Some(IsNullable { is_nullable: false, content: Primitive::Offset }) => { if needs_block { (Some(format!("BinASTTokenReaderBase::SkippableSubTree {var_name};", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readSkippableSubTree());", var_name = var_name))) + Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readSkippableSubTree({context}));", + var_name = var_name, + context = context))) } else { (None, - Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readSkippableSubTree());", var_name = var_name))) + Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readSkippableSubTree({context}));", + var_name = var_name, + context = context))) } } Some(IsNullable { content: Primitive::Void, .. }) => { @@ -1757,23 +1802,33 @@ impl CPPExporter { } Some(IsNullable { is_nullable: false, content: Primitive::String }) => { (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readAtom());", var_name = var_name))) + Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readAtom({context}));", + var_name = var_name, + context = context))) } Some(IsNullable { is_nullable: false, content: Primitive::IdentifierName }) => { (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readIdentifierName());", var_name = var_name))) + Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readIdentifierName({context}));", + var_name = var_name, + context = context))) } Some(IsNullable { is_nullable: false, content: Primitive::PropertyKey }) => { (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readPropertyKey());", var_name = var_name))) + Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readPropertyKey({context}));", + var_name = var_name, + context = context))) } Some(IsNullable { is_nullable: true, content: Primitive::String }) => { (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readMaybeAtom());", var_name = var_name))) + Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readMaybeAtom({context}));", + var_name = var_name, + context = context))) } Some(IsNullable { is_nullable: true, content: Primitive::IdentifierName }) => { (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readMaybeIdentifierName());", var_name = var_name))) + Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readMaybeIdentifierName({context}));", + var_name = var_name, + context = context))) } Some(IsNullable { is_nullable: true, content: Primitive::PropertyKey }) => { panic!("PropertyKey shouldn't be optional"); @@ -1797,6 +1852,7 @@ impl CPPExporter { (decl_var, Some(self.get_method_call(var_name.to_str(), &name, "", "", &field_extra_args, + &context, call_kind))) } }; @@ -1823,7 +1879,8 @@ impl CPPExporter { }; if needs_block { let parse_var = parse_var.reindent(" "); - format!("{before_field}{decl_var} {{ + format!(" +{before_field}{decl_var} {{ {block_before_field}{parse_var}{block_after_field} }} {after_field}", @@ -1832,7 +1889,8 @@ impl CPPExporter { block_before_field = rules_for_this_field.block_before_field.reindent(" ").newline_if_not_empty(), parse_var = parse_var.reindent(" ").newline_if_not_empty(), block_after_field = rules_for_this_field.block_after_field.reindent(" "), - after_field = after_field.reindent(" ")) + after_field = after_field.reindent(" "), + ) } else { // We have a before_field and an after_field. This will create newlines // for them. @@ -1878,7 +1936,7 @@ impl CPPExporter { {{ MOZ_ASSERT(kind == BinASTKind::{kind}); BINJS_TRY(CheckRecursionLimit(cx_)); -{check_fields} +{maybe_field_context}{check_fields} {pre}{fields_implem} {post} return result; }} @@ -1890,6 +1948,11 @@ impl CPPExporter { post = build_result.newline_if_not_empty(), kind = name.to_cpp_enum_case(), first_line = first_line, + maybe_field_context = if interface.contents().fields().len() > 0 { + " Context fieldContext = Context::firstField(kind);\n" + } else { + "" + }, )); } } @@ -1967,7 +2030,7 @@ impl CPPExporter { ); buffer.push_str(&format!("{rendered_doc}{first_line} {{ - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant()); + BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); {convert} }}