☠☠ backed out by ac148c181d2b ☠ ☠ | |
author | David Teller <dteller@mozilla.com> |
Thu, 05 Apr 2018 14:31:39 +0200 | |
changeset 414039 | 6e57f703e46d1066d6607f58445c1c9295fe998f |
parent 414038 | e19f06ed8be932735c42db90f7dfe501dd3e6751 |
child 414040 | bb47995e64812293236032bc57d20a7bee183d60 |
push id | 33857 |
push user | ncsoregi@mozilla.com |
push date | Tue, 17 Apr 2018 21:54:38 +0000 |
treeherder | mozilla-central@1a1223d74b7b [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | arai |
bugs | 1439855 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/frontend/BinSource-auto.cpp +++ b/js/src/frontend/BinSource-auto.cpp @@ -12,158 +12,102 @@ #include "mozilla/ArrayUtils.h" #include "mozilla/Casting.h" #include "mozilla/Maybe.h" #include "mozilla/Move.h" #include "mozilla/PodOperations.h" #include "mozilla/Vector.h" #include "frontend/BinSource.h" +#include "frontend/BinSource-macros.h" #include "frontend/BinTokenReaderTester.h" #include "frontend/FullParseHandler.h" #include "frontend/Parser.h" #include "frontend/SharedContext.h" #include "vm/RegExpObject.h" #include "frontend/ParseContext-inl.h" #include "frontend/ParseNode-inl.h" namespace js { namespace frontend { -using AutoList = BinTokenReaderTester::AutoList; -using AutoTaggedTuple = BinTokenReaderTester::AutoTaggedTuple; -using AutoTuple = BinTokenReaderTester::AutoTuple; -using BinFields = BinTokenReaderTester::BinFields; -using Chars = BinTokenReaderTester::Chars; -using NameBag = GCHashSet<JSString*>; -using Names = GCVector<JSString*, 8>; -using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr; - -// Evaluate an expression EXPR, checking that the result is not falsy. -// -// Throw `cx->alreadyReportedError()` if it returns 0/nullptr. -#define TRY(EXPR) \ - do { \ - if (!EXPR) \ - return cx_->alreadyReportedError(); \ - } while(false) - - -// Evaluate an expression EXPR, checking that the result is not falsy. -// In case of success, assign the result to VAR. -// -// Throw `cx->alreadyReportedError()` if it returns 0/nullptr. -#define TRY_VAR(VAR, EXPR) \ - do { \ - VAR = EXPR; \ - if (!VAR) \ - return cx_->alreadyReportedError(); \ - } while (false) - -// Evaluate an expression EXPR, checking that the result is not falsy. -// In case of success, assign the result to a new variable VAR. -// -// Throw `cx->alreadyReportedError()` if it returns 0/nullptr. -#define TRY_DECL(VAR, EXPR) \ - auto VAR = EXPR; \ - if (!VAR) \ - return cx_->alreadyReportedError(); - -// Evaluate an expression EXPR, checking that the result is a success. -// In case of success, unwrap and assign the result to a new variable VAR. -// -// In case of error, propagate the error. -#define MOZ_TRY_DECL(VAR, EXPR) \ - auto _##VAR = EXPR; \ - if (_##VAR.isErr()) \ - return ::mozilla::Err(_##VAR.unwrapErr()); \ - auto VAR = _##VAR.unwrap(); - -// Ensure that we are visiting the right fields. -template<size_t N> -JS::Result<Ok, JS::Error&> -BinASTParser::checkFields(const BinKind kind, const BinFields& actual, const BinField (&expected)[N]) -{ - if (actual.length() != N) - return raiseInvalidNumberOfFields(kind, N, actual.length()); - - for (size_t i = 0; i < N; ++i) { - if (actual[i] != expected[i]) - return raiseInvalidField(describeBinKind(kind), actual[i]); - } - - return Ok(); -} - -// Special case for N=0, as empty arrays are not permitted in C++ -JS::Result<Ok, JS::Error&> -BinASTParser::checkFields0(const BinKind kind, const BinFields& actual) -{ - if (actual.length() != 0) - return raiseInvalidNumberOfFields(kind, 0, actual.length()); - - return Ok(); -} - // Compare a bunch of `uint8_t` values (as returned by the tokenizer_) with // a string literal (and ONLY a string literal). -template<size_t N> -bool operator==(const Chars& left, const char (&right)[N]) { - return BinTokenReaderTester::equals(left, right); -} - -// Helper class: Restore field `variableDeclarationKind_` upon leaving a scope. -class MOZ_RAII AutoVariableDeclarationKind { - public: - explicit AutoVariableDeclarationKind(BinASTParser* parser - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : - parser_(parser), - kind(parser->variableDeclarationKind_) - { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - } - ~AutoVariableDeclarationKind() { - parser_->variableDeclarationKind_ = kind; - } - private: - BinASTParser* parser_; - BinASTParser::VariableDeclarationKind kind; - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; +template<typename Tok, size_t N> +bool operator==(const typename Tok::Chars& left, const char (&right)[N]) { + return Tok::equals(left, right); +} // ----- Sums of interfaces (autogenerated, by lexicographical order) // Sums of sums are flattened. /* +ArrowExpression ::= EagerArrowExpression + SkippableArrowExpression +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseArrowExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + + MOZ_TRY_DECL(result, parseSumArrowExpression(start, kind, fields)); + + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumArrowExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + ParseNode* result; + switch(kind) { + case BinKind::EagerArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpression(start, kind, fields)); + break; + case BinKind::SkippableArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableArrowExpression(start, kind, fields)); + break; + default: + return raiseInvalidKind("ArrowExpression", kind); + } + return result; +} + +/* AssignmentTarget ::= ArrayAssignmentTarget AssignmentTargetIdentifier ComputedMemberAssignmentTarget ObjectAssignmentTarget StaticMemberAssignmentTarget */ -JS::Result<ParseNode*> -BinASTParser::parseAssignmentTarget() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseAssignmentTarget() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumAssignmentTarget(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayAssignmentTarget: MOZ_TRY_VAR(result, parseInterfaceArrayAssignmentTarget(start, kind, fields)); break; case BinKind::AssignmentTargetIdentifier: MOZ_TRY_VAR(result, parseInterfaceAssignmentTargetIdentifier(start, kind, fields)); @@ -186,34 +130,34 @@ BinASTParser::parseSumAssignmentTarget(c /* AssignmentTargetOrAssignmentTargetWithInitializer ::= ArrayAssignmentTarget AssignmentTargetIdentifier AssignmentTargetWithInitializer ComputedMemberAssignmentTarget ObjectAssignmentTarget StaticMemberAssignmentTarget */ -JS::Result<ParseNode*> -BinASTParser::parseAssignmentTargetOrAssignmentTargetWithInitializer() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseAssignmentTargetOrAssignmentTargetWithInitializer() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumAssignmentTargetOrAssignmentTargetWithInitializer(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumAssignmentTargetOrAssignmentTargetWithInitializer(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumAssignmentTargetOrAssignmentTargetWithInitializer(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayAssignmentTarget: MOZ_TRY_VAR(result, parseInterfaceArrayAssignmentTarget(start, kind, fields)); break; case BinKind::AssignmentTargetIdentifier: MOZ_TRY_VAR(result, parseInterfaceAssignmentTargetIdentifier(start, kind, fields)); @@ -235,34 +179,34 @@ BinASTParser::parseSumAssignmentTargetOr } return result; } /* AssignmentTargetPattern ::= ArrayAssignmentTarget ObjectAssignmentTarget */ -JS::Result<ParseNode*> -BinASTParser::parseAssignmentTargetPattern() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseAssignmentTargetPattern() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumAssignmentTargetPattern(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumAssignmentTargetPattern(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumAssignmentTargetPattern(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayAssignmentTarget: MOZ_TRY_VAR(result, parseInterfaceArrayAssignmentTarget(start, kind, fields)); break; case BinKind::ObjectAssignmentTarget: MOZ_TRY_VAR(result, parseInterfaceObjectAssignmentTarget(start, kind, fields)); @@ -272,34 +216,34 @@ BinASTParser::parseSumAssignmentTargetPa } return result; } /* AssignmentTargetProperty ::= AssignmentTargetPropertyIdentifier AssignmentTargetPropertyProperty */ -JS::Result<ParseNode*> -BinASTParser::parseAssignmentTargetProperty() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseAssignmentTargetProperty() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumAssignmentTargetProperty(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumAssignmentTargetProperty(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumAssignmentTargetProperty(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::AssignmentTargetPropertyIdentifier: MOZ_TRY_VAR(result, parseInterfaceAssignmentTargetPropertyIdentifier(start, kind, fields)); break; case BinKind::AssignmentTargetPropertyProperty: MOZ_TRY_VAR(result, parseInterfaceAssignmentTargetPropertyProperty(start, kind, fields)); @@ -310,34 +254,34 @@ BinASTParser::parseSumAssignmentTargetPr return result; } /* Binding ::= ArrayBinding BindingIdentifier ObjectBinding */ -JS::Result<ParseNode*> -BinASTParser::parseBinding() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseBinding() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumBinding(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumBinding(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumBinding(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayBinding: MOZ_TRY_VAR(result, parseInterfaceArrayBinding(start, kind, fields)); break; case BinKind::BindingIdentifier: MOZ_TRY_VAR(result, parseInterfaceBindingIdentifier(start, kind, fields)); @@ -352,34 +296,34 @@ BinASTParser::parseSumBinding(const size } /* BindingOrBindingWithInitializer ::= ArrayBinding BindingIdentifier BindingWithInitializer ObjectBinding */ -JS::Result<ParseNode*> -BinASTParser::parseBindingOrBindingWithInitializer() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseBindingOrBindingWithInitializer() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumBindingOrBindingWithInitializer(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumBindingOrBindingWithInitializer(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumBindingOrBindingWithInitializer(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayBinding: MOZ_TRY_VAR(result, parseInterfaceArrayBinding(start, kind, fields)); break; case BinKind::BindingIdentifier: MOZ_TRY_VAR(result, parseInterfaceBindingIdentifier(start, kind, fields)); @@ -395,34 +339,34 @@ BinASTParser::parseSumBindingOrBindingWi } return result; } /* BindingPattern ::= ArrayBinding ObjectBinding */ -JS::Result<ParseNode*> -BinASTParser::parseBindingPattern() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseBindingPattern() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumBindingPattern(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumBindingPattern(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumBindingPattern(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayBinding: MOZ_TRY_VAR(result, parseInterfaceArrayBinding(start, kind, fields)); break; case BinKind::ObjectBinding: MOZ_TRY_VAR(result, parseInterfaceObjectBinding(start, kind, fields)); @@ -432,34 +376,34 @@ BinASTParser::parseSumBindingPattern(con } return result; } /* BindingProperty ::= BindingPropertyIdentifier BindingPropertyProperty */ -JS::Result<ParseNode*> -BinASTParser::parseBindingProperty() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseBindingProperty() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumBindingProperty(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumBindingProperty(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumBindingProperty(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::BindingPropertyIdentifier: MOZ_TRY_VAR(result, parseInterfaceBindingPropertyIdentifier(start, kind, fields)); break; case BinKind::BindingPropertyProperty: MOZ_TRY_VAR(result, parseInterfaceBindingPropertyProperty(start, kind, fields)); @@ -472,34 +416,34 @@ BinASTParser::parseSumBindingProperty(co /* ExportDeclaration ::= Export ExportAllFrom ExportDefault ExportFrom ExportLocals */ -JS::Result<ParseNode*> -BinASTParser::parseExportDeclaration() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseExportDeclaration() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumExportDeclaration(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumExportDeclaration(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumExportDeclaration(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::Export: MOZ_TRY_VAR(result, parseInterfaceExport(start, kind, fields)); break; case BinKind::ExportAllFrom: MOZ_TRY_VAR(result, parseInterfaceExportAllFrom(start, kind, fields)); @@ -516,71 +460,70 @@ BinASTParser::parseSumExportDeclaration( default: return raiseInvalidKind("ExportDeclaration", kind); } return result; } /* Expression ::= ArrayExpression - ArrowExpression AssignmentExpression AwaitExpression BinaryExpression CallExpression ClassExpression CompoundAssignmentExpression ComputedMemberExpression ConditionalExpression - FunctionExpression + EagerArrowExpression + EagerFunctionExpression IdentifierExpression LiteralBooleanExpression LiteralInfinityExpression LiteralNullExpression LiteralNumericExpression LiteralRegExpExpression LiteralStringExpression NewExpression NewTargetExpression ObjectExpression + SkippableArrowExpression + SkippableFunctionExpression StaticMemberExpression TemplateExpression ThisExpression UnaryExpression UpdateExpression YieldExpression YieldStarExpression */ -JS::Result<ParseNode*> -BinASTParser::parseExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumExpression(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumExpression(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayExpression: MOZ_TRY_VAR(result, parseInterfaceArrayExpression(start, kind, fields)); break; - case BinKind::ArrowExpression: - MOZ_TRY_VAR(result, parseInterfaceArrowExpression(start, kind, fields)); - break; case BinKind::AssignmentExpression: MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression(start, kind, fields)); break; case BinKind::AwaitExpression: MOZ_TRY_VAR(result, parseInterfaceAwaitExpression(start, kind, fields)); break; case BinKind::BinaryExpression: MOZ_TRY_VAR(result, parseInterfaceBinaryExpression(start, kind, fields)); @@ -595,18 +538,21 @@ BinASTParser::parseSumExpression(const s MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression(start, kind, fields)); break; case BinKind::ComputedMemberExpression: MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression(start, kind, fields)); break; case BinKind::ConditionalExpression: MOZ_TRY_VAR(result, parseInterfaceConditionalExpression(start, kind, fields)); break; - case BinKind::FunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceFunctionExpression(start, kind, fields)); + case BinKind::EagerArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpression(start, kind, fields)); + break; + case BinKind::EagerFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression(start, kind, fields)); break; case BinKind::IdentifierExpression: MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression(start, kind, fields)); break; case BinKind::LiteralBooleanExpression: MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression(start, kind, fields)); break; case BinKind::LiteralInfinityExpression: @@ -628,16 +574,22 @@ BinASTParser::parseSumExpression(const s MOZ_TRY_VAR(result, parseInterfaceNewExpression(start, kind, fields)); break; case BinKind::NewTargetExpression: MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression(start, kind, fields)); break; case BinKind::ObjectExpression: MOZ_TRY_VAR(result, parseInterfaceObjectExpression(start, kind, fields)); break; + case BinKind::SkippableArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableArrowExpression(start, kind, fields)); + break; + case BinKind::SkippableFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionExpression(start, kind, fields)); + break; case BinKind::StaticMemberExpression: MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression(start, kind, fields)); break; case BinKind::TemplateExpression: MOZ_TRY_VAR(result, parseInterfaceTemplateExpression(start, kind, fields)); break; case BinKind::ThisExpression: MOZ_TRY_VAR(result, parseInterfaceThisExpression(start, kind, fields)); @@ -657,72 +609,71 @@ BinASTParser::parseSumExpression(const s default: return raiseInvalidKind("Expression", kind); } return result; } /* ExpressionOrSuper ::= ArrayExpression - ArrowExpression AssignmentExpression AwaitExpression BinaryExpression CallExpression ClassExpression CompoundAssignmentExpression ComputedMemberExpression ConditionalExpression - FunctionExpression + EagerArrowExpression + EagerFunctionExpression IdentifierExpression LiteralBooleanExpression LiteralInfinityExpression LiteralNullExpression LiteralNumericExpression LiteralRegExpExpression LiteralStringExpression NewExpression NewTargetExpression ObjectExpression + SkippableArrowExpression + SkippableFunctionExpression StaticMemberExpression Super TemplateExpression ThisExpression UnaryExpression UpdateExpression YieldExpression YieldStarExpression */ -JS::Result<ParseNode*> -BinASTParser::parseExpressionOrSuper() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseExpressionOrSuper() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumExpressionOrSuper(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumExpressionOrSuper(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumExpressionOrSuper(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayExpression: MOZ_TRY_VAR(result, parseInterfaceArrayExpression(start, kind, fields)); break; - case BinKind::ArrowExpression: - MOZ_TRY_VAR(result, parseInterfaceArrowExpression(start, kind, fields)); - break; case BinKind::AssignmentExpression: MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression(start, kind, fields)); break; case BinKind::AwaitExpression: MOZ_TRY_VAR(result, parseInterfaceAwaitExpression(start, kind, fields)); break; case BinKind::BinaryExpression: MOZ_TRY_VAR(result, parseInterfaceBinaryExpression(start, kind, fields)); @@ -737,18 +688,21 @@ BinASTParser::parseSumExpressionOrSuper( MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression(start, kind, fields)); break; case BinKind::ComputedMemberExpression: MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression(start, kind, fields)); break; case BinKind::ConditionalExpression: MOZ_TRY_VAR(result, parseInterfaceConditionalExpression(start, kind, fields)); break; - case BinKind::FunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceFunctionExpression(start, kind, fields)); + case BinKind::EagerArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpression(start, kind, fields)); + break; + case BinKind::EagerFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression(start, kind, fields)); break; case BinKind::IdentifierExpression: MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression(start, kind, fields)); break; case BinKind::LiteralBooleanExpression: MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression(start, kind, fields)); break; case BinKind::LiteralInfinityExpression: @@ -770,16 +724,22 @@ BinASTParser::parseSumExpressionOrSuper( MOZ_TRY_VAR(result, parseInterfaceNewExpression(start, kind, fields)); break; case BinKind::NewTargetExpression: MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression(start, kind, fields)); break; case BinKind::ObjectExpression: MOZ_TRY_VAR(result, parseInterfaceObjectExpression(start, kind, fields)); break; + case BinKind::SkippableArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableArrowExpression(start, kind, fields)); + break; + case BinKind::SkippableFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionExpression(start, kind, fields)); + break; case BinKind::StaticMemberExpression: MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression(start, kind, fields)); break; case BinKind::Super: MOZ_TRY_VAR(result, parseInterfaceSuper(start, kind, fields)); break; case BinKind::TemplateExpression: MOZ_TRY_VAR(result, parseInterfaceTemplateExpression(start, kind, fields)); @@ -802,72 +762,71 @@ BinASTParser::parseSumExpressionOrSuper( default: return raiseInvalidKind("ExpressionOrSuper", kind); } return result; } /* ExpressionOrTemplateElement ::= ArrayExpression - ArrowExpression AssignmentExpression AwaitExpression BinaryExpression CallExpression ClassExpression CompoundAssignmentExpression ComputedMemberExpression ConditionalExpression - FunctionExpression + EagerArrowExpression + EagerFunctionExpression IdentifierExpression LiteralBooleanExpression LiteralInfinityExpression LiteralNullExpression LiteralNumericExpression LiteralRegExpExpression LiteralStringExpression NewExpression NewTargetExpression ObjectExpression + SkippableArrowExpression + SkippableFunctionExpression StaticMemberExpression TemplateElement TemplateExpression ThisExpression UnaryExpression UpdateExpression YieldExpression YieldStarExpression */ -JS::Result<ParseNode*> -BinASTParser::parseExpressionOrTemplateElement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseExpressionOrTemplateElement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumExpressionOrTemplateElement(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumExpressionOrTemplateElement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumExpressionOrTemplateElement(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayExpression: MOZ_TRY_VAR(result, parseInterfaceArrayExpression(start, kind, fields)); break; - case BinKind::ArrowExpression: - MOZ_TRY_VAR(result, parseInterfaceArrowExpression(start, kind, fields)); - break; case BinKind::AssignmentExpression: MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression(start, kind, fields)); break; case BinKind::AwaitExpression: MOZ_TRY_VAR(result, parseInterfaceAwaitExpression(start, kind, fields)); break; case BinKind::BinaryExpression: MOZ_TRY_VAR(result, parseInterfaceBinaryExpression(start, kind, fields)); @@ -882,18 +841,21 @@ BinASTParser::parseSumExpressionOrTempla MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression(start, kind, fields)); break; case BinKind::ComputedMemberExpression: MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression(start, kind, fields)); break; case BinKind::ConditionalExpression: MOZ_TRY_VAR(result, parseInterfaceConditionalExpression(start, kind, fields)); break; - case BinKind::FunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceFunctionExpression(start, kind, fields)); + case BinKind::EagerArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpression(start, kind, fields)); + break; + case BinKind::EagerFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression(start, kind, fields)); break; case BinKind::IdentifierExpression: MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression(start, kind, fields)); break; case BinKind::LiteralBooleanExpression: MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression(start, kind, fields)); break; case BinKind::LiteralInfinityExpression: @@ -915,16 +877,22 @@ BinASTParser::parseSumExpressionOrTempla MOZ_TRY_VAR(result, parseInterfaceNewExpression(start, kind, fields)); break; case BinKind::NewTargetExpression: MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression(start, kind, fields)); break; case BinKind::ObjectExpression: MOZ_TRY_VAR(result, parseInterfaceObjectExpression(start, kind, fields)); break; + case BinKind::SkippableArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableArrowExpression(start, kind, fields)); + break; + case BinKind::SkippableFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionExpression(start, kind, fields)); + break; case BinKind::StaticMemberExpression: MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression(start, kind, fields)); break; case BinKind::TemplateElement: MOZ_TRY_VAR(result, parseInterfaceTemplateElement(start, kind, fields)); break; case BinKind::TemplateExpression: MOZ_TRY_VAR(result, parseInterfaceTemplateExpression(start, kind, fields)); @@ -953,34 +921,34 @@ BinASTParser::parseSumExpressionOrTempla /* ForInOfBindingOrAssignmentTarget ::= ArrayAssignmentTarget AssignmentTargetIdentifier ComputedMemberAssignmentTarget ForInOfBinding ObjectAssignmentTarget StaticMemberAssignmentTarget */ -JS::Result<ParseNode*> -BinASTParser::parseForInOfBindingOrAssignmentTarget() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseForInOfBindingOrAssignmentTarget() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumForInOfBindingOrAssignmentTarget(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumForInOfBindingOrAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumForInOfBindingOrAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayAssignmentTarget: MOZ_TRY_VAR(result, parseInterfaceArrayAssignmentTarget(start, kind, fields)); break; case BinKind::AssignmentTargetIdentifier: MOZ_TRY_VAR(result, parseInterfaceAssignmentTargetIdentifier(start, kind, fields)); @@ -1000,72 +968,71 @@ BinASTParser::parseSumForInOfBindingOrAs default: return raiseInvalidKind("ForInOfBindingOrAssignmentTarget", kind); } return result; } /* FunctionBodyOrExpression ::= ArrayExpression - ArrowExpression AssignmentExpression AwaitExpression BinaryExpression CallExpression ClassExpression CompoundAssignmentExpression ComputedMemberExpression ConditionalExpression + EagerArrowExpression + EagerFunctionExpression FunctionBody - FunctionExpression IdentifierExpression LiteralBooleanExpression LiteralInfinityExpression LiteralNullExpression LiteralNumericExpression LiteralRegExpExpression LiteralStringExpression NewExpression NewTargetExpression ObjectExpression + SkippableArrowExpression + SkippableFunctionExpression StaticMemberExpression TemplateExpression ThisExpression UnaryExpression UpdateExpression YieldExpression YieldStarExpression */ -JS::Result<ParseNode*> -BinASTParser::parseFunctionBodyOrExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseFunctionBodyOrExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumFunctionBodyOrExpression(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumFunctionBodyOrExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumFunctionBodyOrExpression(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayExpression: MOZ_TRY_VAR(result, parseInterfaceArrayExpression(start, kind, fields)); break; - case BinKind::ArrowExpression: - MOZ_TRY_VAR(result, parseInterfaceArrowExpression(start, kind, fields)); - break; case BinKind::AssignmentExpression: MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression(start, kind, fields)); break; case BinKind::AwaitExpression: MOZ_TRY_VAR(result, parseInterfaceAwaitExpression(start, kind, fields)); break; case BinKind::BinaryExpression: MOZ_TRY_VAR(result, parseInterfaceBinaryExpression(start, kind, fields)); @@ -1080,22 +1047,25 @@ BinASTParser::parseSumFunctionBodyOrExpr MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression(start, kind, fields)); break; case BinKind::ComputedMemberExpression: MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression(start, kind, fields)); break; case BinKind::ConditionalExpression: MOZ_TRY_VAR(result, parseInterfaceConditionalExpression(start, kind, fields)); break; + case BinKind::EagerArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpression(start, kind, fields)); + break; + case BinKind::EagerFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression(start, kind, fields)); + break; case BinKind::FunctionBody: MOZ_TRY_VAR(result, parseInterfaceFunctionBody(start, kind, fields)); break; - case BinKind::FunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceFunctionExpression(start, kind, fields)); - break; case BinKind::IdentifierExpression: MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression(start, kind, fields)); break; case BinKind::LiteralBooleanExpression: MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression(start, kind, fields)); break; case BinKind::LiteralInfinityExpression: MOZ_TRY_VAR(result, parseInterfaceLiteralInfinityExpression(start, kind, fields)); @@ -1116,16 +1086,22 @@ BinASTParser::parseSumFunctionBodyOrExpr MOZ_TRY_VAR(result, parseInterfaceNewExpression(start, kind, fields)); break; case BinKind::NewTargetExpression: MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression(start, kind, fields)); break; case BinKind::ObjectExpression: MOZ_TRY_VAR(result, parseInterfaceObjectExpression(start, kind, fields)); break; + case BinKind::SkippableArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableArrowExpression(start, kind, fields)); + break; + case BinKind::SkippableFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionExpression(start, kind, fields)); + break; case BinKind::StaticMemberExpression: MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression(start, kind, fields)); break; case BinKind::TemplateExpression: MOZ_TRY_VAR(result, parseInterfaceTemplateExpression(start, kind, fields)); break; case BinKind::ThisExpression: MOZ_TRY_VAR(result, parseInterfaceThisExpression(start, kind, fields)); @@ -1144,74 +1120,111 @@ BinASTParser::parseSumFunctionBodyOrExpr break; default: return raiseInvalidKind("FunctionBodyOrExpression", kind); } return result; } /* +FunctionDeclaration ::= EagerFunctionDeclaration + SkippableFunctionDeclaration +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseFunctionDeclaration() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + + MOZ_TRY_DECL(result, parseSumFunctionDeclaration(start, kind, fields)); + + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields) +{ + ParseNode* result; + switch(kind) { + case BinKind::EagerFunctionDeclaration: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionDeclaration(start, kind, fields)); + break; + case BinKind::SkippableFunctionDeclaration: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionDeclaration(start, kind, fields)); + break; + default: + return raiseInvalidKind("FunctionDeclaration", kind); + } + return result; +} + +/* FunctionDeclarationOrClassDeclarationOrExpression ::= ArrayExpression - ArrowExpression AssignmentExpression AwaitExpression BinaryExpression CallExpression ClassDeclaration ClassExpression CompoundAssignmentExpression ComputedMemberExpression ConditionalExpression - FunctionDeclaration - FunctionExpression + EagerArrowExpression + EagerFunctionDeclaration + EagerFunctionExpression IdentifierExpression LiteralBooleanExpression LiteralInfinityExpression LiteralNullExpression LiteralNumericExpression LiteralRegExpExpression LiteralStringExpression NewExpression NewTargetExpression ObjectExpression + SkippableArrowExpression + SkippableFunctionDeclaration + SkippableFunctionExpression StaticMemberExpression TemplateExpression ThisExpression UnaryExpression UpdateExpression YieldExpression YieldStarExpression */ -JS::Result<ParseNode*> -BinASTParser::parseFunctionDeclarationOrClassDeclarationOrExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseFunctionDeclarationOrClassDeclarationOrExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumFunctionDeclarationOrClassDeclarationOrExpression(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumFunctionDeclarationOrClassDeclarationOrExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumFunctionDeclarationOrClassDeclarationOrExpression(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayExpression: MOZ_TRY_VAR(result, parseInterfaceArrayExpression(start, kind, fields)); break; - case BinKind::ArrowExpression: - MOZ_TRY_VAR(result, parseInterfaceArrowExpression(start, kind, fields)); - break; case BinKind::AssignmentExpression: MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression(start, kind, fields)); break; case BinKind::AwaitExpression: MOZ_TRY_VAR(result, parseInterfaceAwaitExpression(start, kind, fields)); break; case BinKind::BinaryExpression: MOZ_TRY_VAR(result, parseInterfaceBinaryExpression(start, kind, fields)); @@ -1229,21 +1242,24 @@ BinASTParser::parseSumFunctionDeclaratio MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression(start, kind, fields)); break; case BinKind::ComputedMemberExpression: MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression(start, kind, fields)); break; case BinKind::ConditionalExpression: MOZ_TRY_VAR(result, parseInterfaceConditionalExpression(start, kind, fields)); break; - case BinKind::FunctionDeclaration: - MOZ_TRY_VAR(result, parseInterfaceFunctionDeclaration(start, kind, fields)); - break; - case BinKind::FunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceFunctionExpression(start, kind, fields)); + case BinKind::EagerArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpression(start, kind, fields)); + break; + case BinKind::EagerFunctionDeclaration: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionDeclaration(start, kind, fields)); + break; + case BinKind::EagerFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression(start, kind, fields)); break; case BinKind::IdentifierExpression: MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression(start, kind, fields)); break; case BinKind::LiteralBooleanExpression: MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression(start, kind, fields)); break; case BinKind::LiteralInfinityExpression: @@ -1265,16 +1281,25 @@ BinASTParser::parseSumFunctionDeclaratio MOZ_TRY_VAR(result, parseInterfaceNewExpression(start, kind, fields)); break; case BinKind::NewTargetExpression: MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression(start, kind, fields)); break; case BinKind::ObjectExpression: MOZ_TRY_VAR(result, parseInterfaceObjectExpression(start, kind, fields)); break; + case BinKind::SkippableArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableArrowExpression(start, kind, fields)); + break; + case BinKind::SkippableFunctionDeclaration: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionDeclaration(start, kind, fields)); + break; + case BinKind::SkippableFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionExpression(start, kind, fields)); + break; case BinKind::StaticMemberExpression: MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression(start, kind, fields)); break; case BinKind::TemplateExpression: MOZ_TRY_VAR(result, parseInterfaceTemplateExpression(start, kind, fields)); break; case BinKind::ThisExpression: MOZ_TRY_VAR(result, parseInterfaceThisExpression(start, kind, fields)); @@ -1294,77 +1319,155 @@ BinASTParser::parseSumFunctionDeclaratio default: return raiseInvalidKind("FunctionDeclarationOrClassDeclarationOrExpression", kind); } return result; } /* FunctionDeclarationOrClassDeclarationOrVariableDeclaration ::= ClassDeclaration - FunctionDeclaration + EagerFunctionDeclaration + SkippableFunctionDeclaration VariableDeclaration */ -JS::Result<ParseNode*> -BinASTParser::parseFunctionDeclarationOrClassDeclarationOrVariableDeclaration() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseFunctionDeclarationOrClassDeclarationOrVariableDeclaration() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumFunctionDeclarationOrClassDeclarationOrVariableDeclaration(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumFunctionDeclarationOrClassDeclarationOrVariableDeclaration(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumFunctionDeclarationOrClassDeclarationOrVariableDeclaration(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ClassDeclaration: MOZ_TRY_VAR(result, parseInterfaceClassDeclaration(start, kind, fields)); break; - case BinKind::FunctionDeclaration: - MOZ_TRY_VAR(result, parseInterfaceFunctionDeclaration(start, kind, fields)); + case BinKind::EagerFunctionDeclaration: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionDeclaration(start, kind, fields)); + break; + case BinKind::SkippableFunctionDeclaration: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionDeclaration(start, kind, fields)); break; case BinKind::VariableDeclaration: MOZ_TRY_VAR(result, parseInterfaceVariableDeclaration(start, kind, fields)); break; default: return raiseInvalidKind("FunctionDeclarationOrClassDeclarationOrVariableDeclaration", kind); } return result; } /* +FunctionExpression ::= EagerFunctionExpression + SkippableFunctionExpression +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseFunctionExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + + MOZ_TRY_DECL(result, parseSumFunctionExpression(start, kind, fields)); + + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + ParseNode* result; + switch(kind) { + case BinKind::EagerFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression(start, kind, fields)); + break; + case BinKind::SkippableFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionExpression(start, kind, fields)); + break; + default: + return raiseInvalidKind("FunctionExpression", kind); + } + return result; +} + +/* +Getter ::= EagerGetter + SkippableGetter +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseGetter() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + + MOZ_TRY_DECL(result, parseSumGetter(start, kind, fields)); + + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumGetter(const size_t start, const BinKind kind, const BinFields& fields) +{ + ParseNode* result; + switch(kind) { + case BinKind::EagerGetter: + MOZ_TRY_VAR(result, parseInterfaceEagerGetter(start, kind, fields)); + break; + case BinKind::SkippableGetter: + MOZ_TRY_VAR(result, parseInterfaceSkippableGetter(start, kind, fields)); + break; + default: + return raiseInvalidKind("Getter", kind); + } + return result; +} + +/* ImportDeclaration ::= Import ImportNamespace */ -JS::Result<ParseNode*> -BinASTParser::parseImportDeclaration() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseImportDeclaration() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumImportDeclaration(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumImportDeclaration(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumImportDeclaration(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::Import: MOZ_TRY_VAR(result, parseInterfaceImport(start, kind, fields)); break; case BinKind::ImportNamespace: MOZ_TRY_VAR(result, parseInterfaceImportNamespace(start, kind, fields)); @@ -1377,59 +1480,60 @@ BinASTParser::parseSumImportDeclaration( /* ImportDeclarationOrExportDeclarationOrStatement ::= Block BreakStatement ClassDeclaration ContinueStatement DebuggerStatement DoWhileStatement + EagerFunctionDeclaration EmptyStatement Export ExportAllFrom ExportDefault ExportFrom ExportLocals ExpressionStatement ForInStatement ForOfStatement ForStatement - FunctionDeclaration IfStatement Import ImportNamespace LabelledStatement ReturnStatement + SkippableFunctionDeclaration SwitchStatement SwitchStatementWithDefault ThrowStatement TryCatchStatement TryFinallyStatement VariableDeclaration WhileStatement WithStatement */ -JS::Result<ParseNode*> -BinASTParser::parseImportDeclarationOrExportDeclarationOrStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseImportDeclarationOrExportDeclarationOrStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumImportDeclarationOrExportDeclarationOrStatement(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumImportDeclarationOrExportDeclarationOrStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumImportDeclarationOrExportDeclarationOrStatement(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::Block: MOZ_TRY_VAR(result, parseInterfaceBlock(start, kind, fields)); break; case BinKind::BreakStatement: MOZ_TRY_VAR(result, parseInterfaceBreakStatement(start, kind, fields)); @@ -1441,16 +1545,19 @@ BinASTParser::parseSumImportDeclarationO MOZ_TRY_VAR(result, parseInterfaceContinueStatement(start, kind, fields)); break; case BinKind::DebuggerStatement: MOZ_TRY_VAR(result, parseInterfaceDebuggerStatement(start, kind, fields)); break; case BinKind::DoWhileStatement: MOZ_TRY_VAR(result, parseInterfaceDoWhileStatement(start, kind, fields)); break; + case BinKind::EagerFunctionDeclaration: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionDeclaration(start, kind, fields)); + break; case BinKind::EmptyStatement: MOZ_TRY_VAR(result, parseInterfaceEmptyStatement(start, kind, fields)); break; case BinKind::Export: MOZ_TRY_VAR(result, parseInterfaceExport(start, kind, fields)); break; case BinKind::ExportAllFrom: MOZ_TRY_VAR(result, parseInterfaceExportAllFrom(start, kind, fields)); @@ -1471,34 +1578,34 @@ BinASTParser::parseSumImportDeclarationO MOZ_TRY_VAR(result, parseInterfaceForInStatement(start, kind, fields)); break; case BinKind::ForOfStatement: MOZ_TRY_VAR(result, parseInterfaceForOfStatement(start, kind, fields)); break; case BinKind::ForStatement: MOZ_TRY_VAR(result, parseInterfaceForStatement(start, kind, fields)); break; - case BinKind::FunctionDeclaration: - MOZ_TRY_VAR(result, parseInterfaceFunctionDeclaration(start, kind, fields)); - break; case BinKind::IfStatement: MOZ_TRY_VAR(result, parseInterfaceIfStatement(start, kind, fields)); break; case BinKind::Import: MOZ_TRY_VAR(result, parseInterfaceImport(start, kind, fields)); break; case BinKind::ImportNamespace: MOZ_TRY_VAR(result, parseInterfaceImportNamespace(start, kind, fields)); break; case BinKind::LabelledStatement: MOZ_TRY_VAR(result, parseInterfaceLabelledStatement(start, kind, fields)); break; case BinKind::ReturnStatement: MOZ_TRY_VAR(result, parseInterfaceReturnStatement(start, kind, fields)); break; + case BinKind::SkippableFunctionDeclaration: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionDeclaration(start, kind, fields)); + break; case BinKind::SwitchStatement: MOZ_TRY_VAR(result, parseInterfaceSwitchStatement(start, kind, fields)); break; case BinKind::SwitchStatementWithDefault: MOZ_TRY_VAR(result, parseInterfaceSwitchStatementWithDefault(start, kind, fields)); break; case BinKind::ThrowStatement: MOZ_TRY_VAR(result, parseInterfaceThrowStatement(start, kind, fields)); @@ -1526,34 +1633,34 @@ BinASTParser::parseSumImportDeclarationO /* IterationStatement ::= DoWhileStatement ForInStatement ForOfStatement ForStatement WhileStatement */ -JS::Result<ParseNode*> -BinASTParser::parseIterationStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseIterationStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumIterationStatement(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumIterationStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumIterationStatement(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::DoWhileStatement: MOZ_TRY_VAR(result, parseInterfaceDoWhileStatement(start, kind, fields)); break; case BinKind::ForInStatement: MOZ_TRY_VAR(result, parseInterfaceForInStatement(start, kind, fields)); @@ -1575,34 +1682,34 @@ BinASTParser::parseSumIterationStatement /* Literal ::= LiteralBooleanExpression LiteralInfinityExpression LiteralNullExpression LiteralNumericExpression LiteralStringExpression */ -JS::Result<ParseNode*> -BinASTParser::parseLiteral() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseLiteral() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumLiteral(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumLiteral(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumLiteral(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::LiteralBooleanExpression: MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression(start, kind, fields)); break; case BinKind::LiteralInfinityExpression: MOZ_TRY_VAR(result, parseInterfaceLiteralInfinityExpression(start, kind, fields)); @@ -1618,129 +1725,190 @@ BinASTParser::parseSumLiteral(const size break; default: return raiseInvalidKind("Literal", kind); } return result; } /* -MethodDefinition ::= Getter - Method - Setter -*/ -JS::Result<ParseNode*> -BinASTParser::parseMethodDefinition() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - - MOZ_TRY_DECL(result, parseSumMethodDefinition(start, kind, fields)); - - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumMethodDefinition(const size_t start, const BinKind kind, const BinFields& fields) +Method ::= EagerMethod + SkippableMethod +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseMethod() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + + MOZ_TRY_DECL(result, parseSumMethod(start, kind, fields)); + + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumMethod(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { - case BinKind::Getter: - MOZ_TRY_VAR(result, parseInterfaceGetter(start, kind, fields)); - break; - case BinKind::Method: - MOZ_TRY_VAR(result, parseInterfaceMethod(start, kind, fields)); - break; - case BinKind::Setter: - MOZ_TRY_VAR(result, parseInterfaceSetter(start, kind, fields)); + case BinKind::EagerMethod: + MOZ_TRY_VAR(result, parseInterfaceEagerMethod(start, kind, fields)); + break; + case BinKind::SkippableMethod: + MOZ_TRY_VAR(result, parseInterfaceSkippableMethod(start, kind, fields)); + break; + default: + return raiseInvalidKind("Method", kind); + } + return result; +} + +/* +MethodDefinition ::= EagerGetter + EagerMethod + EagerSetter + SkippableGetter + SkippableMethod + SkippableSetter +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseMethodDefinition() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + + MOZ_TRY_DECL(result, parseSumMethodDefinition(start, kind, fields)); + + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumMethodDefinition(const size_t start, const BinKind kind, const BinFields& fields) +{ + ParseNode* result; + switch(kind) { + case BinKind::EagerGetter: + MOZ_TRY_VAR(result, parseInterfaceEagerGetter(start, kind, fields)); + break; + case BinKind::EagerMethod: + MOZ_TRY_VAR(result, parseInterfaceEagerMethod(start, kind, fields)); + break; + case BinKind::EagerSetter: + MOZ_TRY_VAR(result, parseInterfaceEagerSetter(start, kind, fields)); + break; + case BinKind::SkippableGetter: + MOZ_TRY_VAR(result, parseInterfaceSkippableGetter(start, kind, fields)); + break; + case BinKind::SkippableMethod: + MOZ_TRY_VAR(result, parseInterfaceSkippableMethod(start, kind, fields)); + break; + case BinKind::SkippableSetter: + MOZ_TRY_VAR(result, parseInterfaceSkippableSetter(start, kind, fields)); break; default: return raiseInvalidKind("MethodDefinition", kind); } return result; } /* ObjectProperty ::= DataProperty - Getter - Method - Setter + EagerGetter + EagerMethod + EagerSetter ShorthandProperty -*/ -JS::Result<ParseNode*> -BinASTParser::parseObjectProperty() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + SkippableGetter + SkippableMethod + SkippableSetter +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseObjectProperty() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumObjectProperty(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumObjectProperty(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumObjectProperty(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::DataProperty: MOZ_TRY_VAR(result, parseInterfaceDataProperty(start, kind, fields)); break; - case BinKind::Getter: - MOZ_TRY_VAR(result, parseInterfaceGetter(start, kind, fields)); - break; - case BinKind::Method: - MOZ_TRY_VAR(result, parseInterfaceMethod(start, kind, fields)); - break; - case BinKind::Setter: - MOZ_TRY_VAR(result, parseInterfaceSetter(start, kind, fields)); + case BinKind::EagerGetter: + MOZ_TRY_VAR(result, parseInterfaceEagerGetter(start, kind, fields)); + break; + case BinKind::EagerMethod: + MOZ_TRY_VAR(result, parseInterfaceEagerMethod(start, kind, fields)); + break; + case BinKind::EagerSetter: + MOZ_TRY_VAR(result, parseInterfaceEagerSetter(start, kind, fields)); break; case BinKind::ShorthandProperty: MOZ_TRY_VAR(result, parseInterfaceShorthandProperty(start, kind, fields)); break; + case BinKind::SkippableGetter: + MOZ_TRY_VAR(result, parseInterfaceSkippableGetter(start, kind, fields)); + break; + case BinKind::SkippableMethod: + MOZ_TRY_VAR(result, parseInterfaceSkippableMethod(start, kind, fields)); + break; + case BinKind::SkippableSetter: + MOZ_TRY_VAR(result, parseInterfaceSkippableSetter(start, kind, fields)); + break; default: return raiseInvalidKind("ObjectProperty", kind); } return result; } /* Parameter ::= ArrayBinding BindingIdentifier BindingWithInitializer ObjectBinding */ -JS::Result<ParseNode*> -BinASTParser::parseParameter() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseParameter() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumParameter(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumParameter(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumParameter(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayBinding: MOZ_TRY_VAR(result, parseInterfaceArrayBinding(start, kind, fields)); break; case BinKind::BindingIdentifier: MOZ_TRY_VAR(result, parseInterfaceBindingIdentifier(start, kind, fields)); @@ -1756,34 +1924,34 @@ BinASTParser::parseSumParameter(const si } return result; } /* Program ::= Module Script */ -JS::Result<ParseNode*> -BinASTParser::parseProgram() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseProgram() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumProgram(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumProgram(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumProgram(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::Module: MOZ_TRY_VAR(result, parseInterfaceModule(start, kind, fields)); break; case BinKind::Script: MOZ_TRY_VAR(result, parseInterfaceScript(start, kind, fields)); @@ -1793,72 +1961,109 @@ BinASTParser::parseSumProgram(const size } return result; } /* PropertyName ::= ComputedPropertyName LiteralPropertyName */ -JS::Result<ParseNode*> -BinASTParser::parsePropertyName() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parsePropertyName() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumPropertyName(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumPropertyName(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumPropertyName(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ComputedPropertyName: MOZ_TRY_VAR(result, parseInterfaceComputedPropertyName(start, kind, fields)); break; case BinKind::LiteralPropertyName: MOZ_TRY_VAR(result, parseInterfaceLiteralPropertyName(start, kind, fields)); break; default: return raiseInvalidKind("PropertyName", kind); } return result; } /* +Setter ::= EagerSetter + SkippableSetter +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSetter() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + + MOZ_TRY_DECL(result, parseSumSetter(start, kind, fields)); + + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumSetter(const size_t start, const BinKind kind, const BinFields& fields) +{ + ParseNode* result; + switch(kind) { + case BinKind::EagerSetter: + MOZ_TRY_VAR(result, parseInterfaceEagerSetter(start, kind, fields)); + break; + case BinKind::SkippableSetter: + MOZ_TRY_VAR(result, parseInterfaceSkippableSetter(start, kind, fields)); + break; + default: + return raiseInvalidKind("Setter", kind); + } + return result; +} + +/* SimpleAssignmentTarget ::= AssignmentTargetIdentifier ComputedMemberAssignmentTarget StaticMemberAssignmentTarget */ -JS::Result<ParseNode*> -BinASTParser::parseSimpleAssignmentTarget() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSimpleAssignmentTarget() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumSimpleAssignmentTarget(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumSimpleAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumSimpleAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::AssignmentTargetIdentifier: MOZ_TRY_VAR(result, parseInterfaceAssignmentTargetIdentifier(start, kind, fields)); break; case BinKind::ComputedMemberAssignmentTarget: MOZ_TRY_VAR(result, parseInterfaceComputedMemberAssignmentTarget(start, kind, fields)); @@ -1869,72 +2074,71 @@ BinASTParser::parseSumSimpleAssignmentTa default: return raiseInvalidKind("SimpleAssignmentTarget", kind); } return result; } /* SpreadElementOrExpression ::= ArrayExpression - ArrowExpression AssignmentExpression AwaitExpression BinaryExpression CallExpression ClassExpression CompoundAssignmentExpression ComputedMemberExpression ConditionalExpression - FunctionExpression + EagerArrowExpression + EagerFunctionExpression IdentifierExpression LiteralBooleanExpression LiteralInfinityExpression LiteralNullExpression LiteralNumericExpression LiteralRegExpExpression LiteralStringExpression NewExpression NewTargetExpression ObjectExpression + SkippableArrowExpression + SkippableFunctionExpression SpreadElement StaticMemberExpression TemplateExpression ThisExpression UnaryExpression UpdateExpression YieldExpression YieldStarExpression */ -JS::Result<ParseNode*> -BinASTParser::parseSpreadElementOrExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSpreadElementOrExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumSpreadElementOrExpression(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumSpreadElementOrExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumSpreadElementOrExpression(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayExpression: MOZ_TRY_VAR(result, parseInterfaceArrayExpression(start, kind, fields)); break; - case BinKind::ArrowExpression: - MOZ_TRY_VAR(result, parseInterfaceArrowExpression(start, kind, fields)); - break; case BinKind::AssignmentExpression: MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression(start, kind, fields)); break; case BinKind::AwaitExpression: MOZ_TRY_VAR(result, parseInterfaceAwaitExpression(start, kind, fields)); break; case BinKind::BinaryExpression: MOZ_TRY_VAR(result, parseInterfaceBinaryExpression(start, kind, fields)); @@ -1949,18 +2153,21 @@ BinASTParser::parseSumSpreadElementOrExp MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression(start, kind, fields)); break; case BinKind::ComputedMemberExpression: MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression(start, kind, fields)); break; case BinKind::ConditionalExpression: MOZ_TRY_VAR(result, parseInterfaceConditionalExpression(start, kind, fields)); break; - case BinKind::FunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceFunctionExpression(start, kind, fields)); + case BinKind::EagerArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpression(start, kind, fields)); + break; + case BinKind::EagerFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression(start, kind, fields)); break; case BinKind::IdentifierExpression: MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression(start, kind, fields)); break; case BinKind::LiteralBooleanExpression: MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression(start, kind, fields)); break; case BinKind::LiteralInfinityExpression: @@ -1982,16 +2189,22 @@ BinASTParser::parseSumSpreadElementOrExp MOZ_TRY_VAR(result, parseInterfaceNewExpression(start, kind, fields)); break; case BinKind::NewTargetExpression: MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression(start, kind, fields)); break; case BinKind::ObjectExpression: MOZ_TRY_VAR(result, parseInterfaceObjectExpression(start, kind, fields)); break; + case BinKind::SkippableArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableArrowExpression(start, kind, fields)); + break; + case BinKind::SkippableFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionExpression(start, kind, fields)); + break; case BinKind::SpreadElement: MOZ_TRY_VAR(result, parseInterfaceSpreadElement(start, kind, fields)); break; case BinKind::StaticMemberExpression: MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression(start, kind, fields)); break; case BinKind::TemplateExpression: MOZ_TRY_VAR(result, parseInterfaceTemplateExpression(start, kind, fields)); @@ -2019,52 +2232,53 @@ BinASTParser::parseSumSpreadElementOrExp /* Statement ::= Block BreakStatement ClassDeclaration ContinueStatement DebuggerStatement DoWhileStatement + EagerFunctionDeclaration EmptyStatement ExpressionStatement ForInStatement ForOfStatement ForStatement - FunctionDeclaration IfStatement LabelledStatement ReturnStatement + SkippableFunctionDeclaration SwitchStatement SwitchStatementWithDefault ThrowStatement TryCatchStatement TryFinallyStatement VariableDeclaration WhileStatement WithStatement */ -JS::Result<ParseNode*> -BinASTParser::parseStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumStatement(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumStatement(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::Block: MOZ_TRY_VAR(result, parseInterfaceBlock(start, kind, fields)); break; case BinKind::BreakStatement: MOZ_TRY_VAR(result, parseInterfaceBreakStatement(start, kind, fields)); @@ -2076,43 +2290,46 @@ BinASTParser::parseSumStatement(const si MOZ_TRY_VAR(result, parseInterfaceContinueStatement(start, kind, fields)); break; case BinKind::DebuggerStatement: MOZ_TRY_VAR(result, parseInterfaceDebuggerStatement(start, kind, fields)); break; case BinKind::DoWhileStatement: MOZ_TRY_VAR(result, parseInterfaceDoWhileStatement(start, kind, fields)); break; + case BinKind::EagerFunctionDeclaration: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionDeclaration(start, kind, fields)); + break; case BinKind::EmptyStatement: MOZ_TRY_VAR(result, parseInterfaceEmptyStatement(start, kind, fields)); break; case BinKind::ExpressionStatement: MOZ_TRY_VAR(result, parseInterfaceExpressionStatement(start, kind, fields)); break; case BinKind::ForInStatement: MOZ_TRY_VAR(result, parseInterfaceForInStatement(start, kind, fields)); break; case BinKind::ForOfStatement: MOZ_TRY_VAR(result, parseInterfaceForOfStatement(start, kind, fields)); break; case BinKind::ForStatement: MOZ_TRY_VAR(result, parseInterfaceForStatement(start, kind, fields)); break; - case BinKind::FunctionDeclaration: - MOZ_TRY_VAR(result, parseInterfaceFunctionDeclaration(start, kind, fields)); - break; case BinKind::IfStatement: MOZ_TRY_VAR(result, parseInterfaceIfStatement(start, kind, fields)); break; case BinKind::LabelledStatement: MOZ_TRY_VAR(result, parseInterfaceLabelledStatement(start, kind, fields)); break; case BinKind::ReturnStatement: MOZ_TRY_VAR(result, parseInterfaceReturnStatement(start, kind, fields)); break; + case BinKind::SkippableFunctionDeclaration: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionDeclaration(start, kind, fields)); + break; case BinKind::SwitchStatement: MOZ_TRY_VAR(result, parseInterfaceSwitchStatement(start, kind, fields)); break; case BinKind::SwitchStatementWithDefault: MOZ_TRY_VAR(result, parseInterfaceSwitchStatementWithDefault(start, kind, fields)); break; case BinKind::ThrowStatement: MOZ_TRY_VAR(result, parseInterfaceThrowStatement(start, kind, fields)); @@ -2135,72 +2352,71 @@ BinASTParser::parseSumStatement(const si default: return raiseInvalidKind("Statement", kind); } return result; } /* VariableDeclarationOrExpression ::= ArrayExpression - ArrowExpression AssignmentExpression AwaitExpression BinaryExpression CallExpression ClassExpression CompoundAssignmentExpression ComputedMemberExpression ConditionalExpression - FunctionExpression + EagerArrowExpression + EagerFunctionExpression IdentifierExpression LiteralBooleanExpression LiteralInfinityExpression LiteralNullExpression LiteralNumericExpression LiteralRegExpExpression LiteralStringExpression NewExpression NewTargetExpression ObjectExpression + SkippableArrowExpression + SkippableFunctionExpression StaticMemberExpression TemplateExpression ThisExpression UnaryExpression UpdateExpression VariableDeclaration YieldExpression YieldStarExpression */ -JS::Result<ParseNode*> -BinASTParser::parseVariableDeclarationOrExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseVariableDeclarationOrExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + const auto start = tokenizer_->offset(); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); MOZ_TRY_DECL(result, parseSumVariableDeclarationOrExpression(start, kind, fields)); - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseSumVariableDeclarationOrExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSumVariableDeclarationOrExpression(const size_t start, const BinKind kind, const BinFields& fields) { ParseNode* result; switch(kind) { case BinKind::ArrayExpression: MOZ_TRY_VAR(result, parseInterfaceArrayExpression(start, kind, fields)); break; - case BinKind::ArrowExpression: - MOZ_TRY_VAR(result, parseInterfaceArrowExpression(start, kind, fields)); - break; case BinKind::AssignmentExpression: MOZ_TRY_VAR(result, parseInterfaceAssignmentExpression(start, kind, fields)); break; case BinKind::AwaitExpression: MOZ_TRY_VAR(result, parseInterfaceAwaitExpression(start, kind, fields)); break; case BinKind::BinaryExpression: MOZ_TRY_VAR(result, parseInterfaceBinaryExpression(start, kind, fields)); @@ -2215,18 +2431,21 @@ BinASTParser::parseSumVariableDeclaratio MOZ_TRY_VAR(result, parseInterfaceCompoundAssignmentExpression(start, kind, fields)); break; case BinKind::ComputedMemberExpression: MOZ_TRY_VAR(result, parseInterfaceComputedMemberExpression(start, kind, fields)); break; case BinKind::ConditionalExpression: MOZ_TRY_VAR(result, parseInterfaceConditionalExpression(start, kind, fields)); break; - case BinKind::FunctionExpression: - MOZ_TRY_VAR(result, parseInterfaceFunctionExpression(start, kind, fields)); + case BinKind::EagerArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerArrowExpression(start, kind, fields)); + break; + case BinKind::EagerFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceEagerFunctionExpression(start, kind, fields)); break; case BinKind::IdentifierExpression: MOZ_TRY_VAR(result, parseInterfaceIdentifierExpression(start, kind, fields)); break; case BinKind::LiteralBooleanExpression: MOZ_TRY_VAR(result, parseInterfaceLiteralBooleanExpression(start, kind, fields)); break; case BinKind::LiteralInfinityExpression: @@ -2248,16 +2467,22 @@ BinASTParser::parseSumVariableDeclaratio MOZ_TRY_VAR(result, parseInterfaceNewExpression(start, kind, fields)); break; case BinKind::NewTargetExpression: MOZ_TRY_VAR(result, parseInterfaceNewTargetExpression(start, kind, fields)); break; case BinKind::ObjectExpression: MOZ_TRY_VAR(result, parseInterfaceObjectExpression(start, kind, fields)); break; + case BinKind::SkippableArrowExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableArrowExpression(start, kind, fields)); + break; + case BinKind::SkippableFunctionExpression: + MOZ_TRY_VAR(result, parseInterfaceSkippableFunctionExpression(start, kind, fields)); + break; case BinKind::StaticMemberExpression: MOZ_TRY_VAR(result, parseInterfaceStaticMemberExpression(start, kind, fields)); break; case BinKind::TemplateExpression: MOZ_TRY_VAR(result, parseInterfaceTemplateExpression(start, kind, fields)); break; case BinKind::ThisExpression: MOZ_TRY_VAR(result, parseInterfaceThisExpression(start, kind, fields)); @@ -2284,524 +2509,525 @@ BinASTParser::parseSumVariableDeclaratio } // ----- Interfaces (autogenerated, by lexicographical order) // When fields have a non-trivial type, implementation is deanonymized and delegated to another parser. /* + interface : Node { + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseNull() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceNull(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceNull(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (Null)"); +} + + +/* interface ArrayAssignmentTarget : Node { FrozenArray<(AssignmentTarget or AssignmentTargetWithInitializer)> elements; AssignmentTarget? rest; } */ -JS::Result<ParseNode*> -BinASTParser::parseArrayAssignmentTarget() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseArrayAssignmentTarget() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceArrayAssignmentTarget(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceArrayAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceArrayAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (ArrayAssignmentTarget)"); } /* interface ArrayBinding : Node { FrozenArray<(Binding or BindingWithInitializer)?> elements; Binding? rest; } */ -JS::Result<ParseNode*> -BinASTParser::parseArrayBinding() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseArrayBinding() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceArrayBinding(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceArrayBinding(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceArrayBinding(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (ArrayBinding)"); } /* interface ArrayExpression : Node { FrozenArray<(SpreadElement or Expression)?> elements; } */ -JS::Result<ParseNode*> -BinASTParser::parseArrayExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseArrayExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceArrayExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceArrayExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceArrayExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::ArrayExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Elements })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Elements })); MOZ_TRY_DECL(elements, parseListOfOptionalSpreadElementOrExpression()); - auto result = elements;return result; -} - - -/* - interface ArrowExpression : Node { - bool isAsync; - AssertedParameterScope? parameterScope; - AssertedVarScope? bodyScope; - FormalParameters params; - (FunctionBody or Expression) body; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseArrowExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceArrowExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceArrowExpression(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (ArrowExpression)"); + auto result = elements; + return result; } /* interface AssertedBlockScope : Node { FrozenArray<IdentifierName> lexicallyDeclaredNames; FrozenArray<IdentifierName> capturedNames; bool hasDirectEval; } */ -JS::Result<Ok> -BinASTParser::parseAssertedBlockScope() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<Ok> +BinASTParser<Tok>::parseAssertedBlockScope() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceAssertedBlockScope(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<Ok> -BinASTParser::parseInterfaceAssertedBlockScope(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<Ok> +BinASTParser<Tok>::parseInterfaceAssertedBlockScope(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::AssertedBlockScope); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::LexicallyDeclaredNames, BinField::CapturedNames, BinField::HasDirectEval })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::LexicallyDeclaredNames, BinField::CapturedNames, BinField::HasDirectEval })); MOZ_TRY(parseAndUpdateScopeNames(*parseContext_->innermostScope(), DeclarationKind::Let)); MOZ_TRY(parseAndUpdateCapturedNames()); - MOZ_TRY_DECL(hasDirectEval, readBool()); + MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool()); if (hasDirectEval) { parseContext_->sc()->setHasDirectEval(); parseContext_->sc()->setBindingsAccessedDynamically(); } if (hasDirectEval && parseContext_->isFunctionBox() && !parseContext_->sc()->strict()) { // In non-strict mode code, direct calls to eval can // add variables to the call object. parseContext_->functionBox()->setHasExtensibleScope(); } - auto result = Ok();return result; + auto result = Ok(); + return result; } /* interface AssertedParameterScope : Node { FrozenArray<IdentifierName> parameterNames; FrozenArray<IdentifierName> capturedNames; bool hasDirectEval; } */ -JS::Result<Ok> -BinASTParser::parseAssertedParameterScope() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<Ok> +BinASTParser<Tok>::parseAssertedParameterScope() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceAssertedParameterScope(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<Ok> -BinASTParser::parseInterfaceAssertedParameterScope(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<Ok> +BinASTParser<Tok>::parseInterfaceAssertedParameterScope(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::AssertedParameterScope); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::ParameterNames, BinField::CapturedNames, BinField::HasDirectEval })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::ParameterNames, BinField::CapturedNames, BinField::HasDirectEval })); MOZ_TRY(parseAndUpdateScopeNames(parseContext_->functionScope(), DeclarationKind:: PositionalFormalParameter)); MOZ_TRY(parseAndUpdateCapturedNames()); - MOZ_TRY_DECL(hasDirectEval, readBool()); + MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool()); if (hasDirectEval) { parseContext_->sc()->setHasDirectEval(); parseContext_->sc()->setBindingsAccessedDynamically(); } if (hasDirectEval && parseContext_->isFunctionBox() && !parseContext_->sc()->strict()) { // In non-strict mode code, direct calls to eval can // add variables to the call object. parseContext_->functionBox()->setHasExtensibleScope(); } - auto result = Ok();return result; + auto result = Ok(); + return result; } /* interface AssertedVarScope : Node { FrozenArray<IdentifierName> lexicallyDeclaredNames; FrozenArray<IdentifierName> varDeclaredNames; FrozenArray<IdentifierName> capturedNames; bool hasDirectEval; } */ -JS::Result<Ok> -BinASTParser::parseAssertedVarScope() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<Ok> +BinASTParser<Tok>::parseAssertedVarScope() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceAssertedVarScope(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<Ok> -BinASTParser::parseInterfaceAssertedVarScope(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<Ok> +BinASTParser<Tok>::parseInterfaceAssertedVarScope(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::AssertedVarScope); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::LexicallyDeclaredNames, BinField::VarDeclaredNames, BinField::CapturedNames, BinField::HasDirectEval })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::LexicallyDeclaredNames, BinField::VarDeclaredNames, BinField::CapturedNames, BinField::HasDirectEval })); MOZ_TRY(parseAndUpdateScopeNames(*parseContext_->innermostScope(), DeclarationKind::Let)); MOZ_TRY(parseAndUpdateScopeNames(parseContext_->varScope(), DeclarationKind::Var)); MOZ_TRY(parseAndUpdateCapturedNames()); - MOZ_TRY_DECL(hasDirectEval, readBool()); + MOZ_TRY_DECL(hasDirectEval, tokenizer_->readBool()); if (hasDirectEval) { parseContext_->sc()->setHasDirectEval(); parseContext_->sc()->setBindingsAccessedDynamically(); } if (hasDirectEval && parseContext_->isFunctionBox() && !parseContext_->sc()->strict()) { // In non-strict mode code, direct calls to eval can // add variables to the call object. parseContext_->functionBox()->setHasExtensibleScope(); } - auto result = Ok();return result; + auto result = Ok(); + return result; } /* interface AssignmentExpression : Node { AssignmentTarget binding; Expression expression; } */ -JS::Result<ParseNode*> -BinASTParser::parseAssignmentExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseAssignmentExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceAssignmentExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::AssignmentExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Binding, BinField::Expression })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Binding, BinField::Expression })); MOZ_TRY_DECL(binding, parseAssignmentTarget()); MOZ_TRY_DECL(expression, parseExpression()); - TRY_DECL(result, factory_.newAssignment(ParseNodeKind::Assign, binding, expression));return result; + TRY_DECL(result, factory_.newAssignment(ParseNodeKind::Assign, binding, expression)); + return result; } /* interface AssignmentTargetIdentifier : Node { Identifier name; } */ -JS::Result<ParseNode*> -BinASTParser::parseAssignmentTargetIdentifier() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseAssignmentTargetIdentifier() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceAssignmentTargetIdentifier(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceAssignmentTargetIdentifier(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceAssignmentTargetIdentifier(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::AssignmentTargetIdentifier); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Name })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Name })); RootedAtom name(cx_); - MOZ_TRY(readString(&name)); + MOZ_TRY_VAR(name, tokenizer_->readAtom()); if (!IsIdentifier(name)) return raiseError("Invalid identifier"); - TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_));return result; + TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_)); + return result; } /* interface AssignmentTargetPropertyIdentifier : Node { AssignmentTargetIdentifier binding; Expression? init; } */ -JS::Result<ParseNode*> -BinASTParser::parseAssignmentTargetPropertyIdentifier() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseAssignmentTargetPropertyIdentifier() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceAssignmentTargetPropertyIdentifier(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceAssignmentTargetPropertyIdentifier(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceAssignmentTargetPropertyIdentifier(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (AssignmentTargetPropertyIdentifier)"); } /* interface AssignmentTargetPropertyProperty : Node { PropertyName name; (AssignmentTarget or AssignmentTargetWithInitializer) binding; } */ -JS::Result<ParseNode*> -BinASTParser::parseAssignmentTargetPropertyProperty() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseAssignmentTargetPropertyProperty() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceAssignmentTargetPropertyProperty(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceAssignmentTargetPropertyProperty(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceAssignmentTargetPropertyProperty(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (AssignmentTargetPropertyProperty)"); } /* interface AssignmentTargetWithInitializer : Node { AssignmentTarget binding; Expression init; } */ -JS::Result<ParseNode*> -BinASTParser::parseAssignmentTargetWithInitializer() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseAssignmentTargetWithInitializer() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceAssignmentTargetWithInitializer(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceAssignmentTargetWithInitializer(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceAssignmentTargetWithInitializer(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (AssignmentTargetWithInitializer)"); } /* interface AwaitExpression : Node { Expression expression; } */ -JS::Result<ParseNode*> -BinASTParser::parseAwaitExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseAwaitExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceAwaitExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceAwaitExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceAwaitExpression(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (AwaitExpression)"); } /* interface BinaryExpression : Node { BinaryOperator operator; Expression left; Expression right; } */ -JS::Result<ParseNode*> -BinASTParser::parseBinaryExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseBinaryExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceBinaryExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceBinaryExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceBinaryExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::BinaryExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Operator, BinField::Left, BinField::Right })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Operator, BinField::Left, BinField::Right })); MOZ_TRY_DECL(operator_, parseBinaryOperator()); @@ -2900,171 +3126,173 @@ BinASTParser::parseInterfaceBinaryExpres left->appendWithoutOrderAssumption(right); result = left; } else { TRY_DECL(list, factory_.newList(pnk, tokenizer_->pos(start))); list->appendWithoutOrderAssumption(left); list->appendWithoutOrderAssumption(right); result = list; - }return result; + } + return result; } /* interface BindingIdentifier : Node { Identifier name; } */ -JS::Result<ParseNode*> -BinASTParser::parseBindingIdentifier() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseBindingIdentifier() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceBindingIdentifier(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceBindingIdentifier(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceBindingIdentifier(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::BindingIdentifier); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Name })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Name })); RootedAtom name(cx_); - MOZ_TRY(readString(&name)); + MOZ_TRY_VAR(name, tokenizer_->readAtom()); if (!IsIdentifier(name)) return raiseError("Invalid identifier"); - TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_));return result; + TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_)); + return result; } /* interface BindingPropertyIdentifier : Node { BindingIdentifier binding; Expression? init; } */ -JS::Result<ParseNode*> -BinASTParser::parseBindingPropertyIdentifier() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseBindingPropertyIdentifier() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceBindingPropertyIdentifier(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceBindingPropertyIdentifier(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceBindingPropertyIdentifier(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (BindingPropertyIdentifier)"); } /* interface BindingPropertyProperty : Node { PropertyName name; (Binding or BindingWithInitializer) binding; } */ -JS::Result<ParseNode*> -BinASTParser::parseBindingPropertyProperty() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseBindingPropertyProperty() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceBindingPropertyProperty(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceBindingPropertyProperty(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceBindingPropertyProperty(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (BindingPropertyProperty)"); } /* interface BindingWithInitializer : Node { Binding binding; Expression init; } */ -JS::Result<ParseNode*> -BinASTParser::parseBindingWithInitializer() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseBindingWithInitializer() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceBindingWithInitializer(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceBindingWithInitializer(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceBindingWithInitializer(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (BindingWithInitializer)"); } /* interface Block : Node { AssertedBlockScope? scope; FrozenArray<Statement> statements; } */ -JS::Result<ParseNode*> -BinASTParser::parseBlock() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseBlock() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceBlock(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceBlock(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceBlock(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::Block); CheckRecursionLimit(cx_); MOZ_TRY(checkFields(kind, fields, { BinField::Scope, BinField::Statements })); ParseContext::Statement stmt(parseContext_, StatementKind::Block); ParseContext::Scope currentScope(cx_, parseContext_, usedNames_); TRY(currentScope.init(parseContext_)); @@ -3084,90 +3312,91 @@ BinASTParser::parseInterfaceBlock(const } /* interface BreakStatement : Node { Label? label; } */ -JS::Result<ParseNode*> -BinASTParser::parseBreakStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseBreakStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceBreakStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceBreakStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceBreakStatement(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::BreakStatement); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Label })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Label })); RootedAtom label(cx_); - MOZ_TRY(readMaybeString(&label)); - - if (label && !IsIdentifier(label)) - return raiseError("Invalid identifier"); + MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom()); if (label) { + if (!IsIdentifier(label)) + return raiseError("Invalid identifier"); + auto validity = parseContext_->checkBreakStatement(label->asPropertyName()); if (validity.isErr()) { switch (validity.unwrapErr()) { case ParseContext::BreakStatementError::ToughBreak: return raiseError(kind, "Not in a loop"); case ParseContext::BreakStatementError::LabelNotFound: return raiseError(kind, "Label not found"); } } } - TRY_DECL(result, factory_.newBreakStatement(label ? label->asPropertyName() : nullptr, tokenizer_->pos(start)));return result; + TRY_DECL(result, factory_.newBreakStatement(label ? label->asPropertyName() : nullptr, tokenizer_->pos(start))); + return result; } /* interface CallExpression : Node { (Expression or Super) callee; Arguments arguments; } */ -JS::Result<ParseNode*> -BinASTParser::parseCallExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseCallExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceCallExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceCallExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceCallExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::CallExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Callee, BinField::Arguments })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Callee, BinField::Arguments })); MOZ_TRY_DECL(callee, parseExpressionOrSuper()); @@ -3184,193 +3413,201 @@ BinASTParser::parseInterfaceCallExpressi return raiseMissingDirectEvalInAssertedScope(); op = parseContext_->sc()->strict() ? JSOP_STRICTEVAL : JSOP_EVAL; } } auto result = arguments; result->setKind(ParseNodeKind::Call); result->prepend(callee); - result->setOp(op);return result; + result->setOp(op); + return result; } /* interface CatchClause : Node { + AssertedParameterScope? bindingScope; Binding binding; Block body; } */ -JS::Result<ParseNode*> -BinASTParser::parseCatchClause() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseCatchClause() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceCatchClause(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceCatchClause(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceCatchClause(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::CatchClause); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Binding, BinField::Body })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::BindingScope, BinField::Binding, BinField::Body })); ParseContext::Statement stmt(parseContext_, StatementKind::Catch); ParseContext::Scope currentScope(cx_, parseContext_, usedNames_); TRY(currentScope.init(parseContext_)); + MOZ_TRY(parseOptionalAssertedParameterScope()); + + + + MOZ_TRY_DECL(binding, parseBinding()); MOZ_TRY_DECL(body, parseBlock()); // Export implicit variables to the scope. // FIXME: Handle cases other than Name. MOZ_ASSERT(binding->isKind(ParseNodeKind::Name)); auto ptr = currentScope.lookupDeclaredNameForAdd(binding->name()); TRY(currentScope.addDeclaredName(parseContext_, ptr, binding->name(), DeclarationKind::Let, start)); TRY_DECL(bindings, NewLexicalScopeData(cx_, currentScope, alloc_, parseContext_)); TRY_DECL(result, factory_.newLexicalScope(*bindings, body)); - TRY(factory_.setupCatchScope(result, binding, body));return result; + TRY(factory_.setupCatchScope(result, binding, body)); + return result; } /* interface ClassDeclaration : Node { BindingIdentifier name; Expression? super; FrozenArray<ClassElement> elements; } */ -JS::Result<ParseNode*> -BinASTParser::parseClassDeclaration() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseClassDeclaration() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceClassDeclaration(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceClassDeclaration(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceClassDeclaration(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (ClassDeclaration)"); } /* interface ClassElement : Node { bool isStatic; MethodDefinition method; } */ -JS::Result<ParseNode*> -BinASTParser::parseClassElement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseClassElement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceClassElement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceClassElement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceClassElement(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (ClassElement)"); } /* interface ClassExpression : Node { BindingIdentifier? name; Expression? super; FrozenArray<ClassElement> elements; } */ -JS::Result<ParseNode*> -BinASTParser::parseClassExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseClassExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceClassExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceClassExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceClassExpression(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (ClassExpression)"); } /* interface CompoundAssignmentExpression : Node { CompoundAssignmentOperator operator; SimpleAssignmentTarget binding; Expression expression; } */ -JS::Result<ParseNode*> -BinASTParser::parseCompoundAssignmentExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseCompoundAssignmentExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceCompoundAssignmentExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceCompoundAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceCompoundAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::CompoundAssignmentExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Operator, BinField::Binding, BinField::Expression })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Operator, BinField::Binding, BinField::Expression })); MOZ_TRY_DECL(operator_, parseCompoundAssignmentOperator()); @@ -3416,1098 +3653,510 @@ BinASTParser::parseInterfaceCompoundAssi break; case CompoundAssignmentOperator::BitXorAssign: pnk = ParseNodeKind::BitXorAssign; break; case CompoundAssignmentOperator::BitAndAssign: pnk = ParseNodeKind::BitAndAssign; break; } - TRY_DECL(result, factory_.newAssignment(pnk, binding, expression));return result; + TRY_DECL(result, factory_.newAssignment(pnk, binding, expression)); + return result; } /* interface ComputedMemberAssignmentTarget : Node { (Expression or Super) object; Expression expression; } */ -JS::Result<ParseNode*> -BinASTParser::parseComputedMemberAssignmentTarget() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseComputedMemberAssignmentTarget() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceComputedMemberAssignmentTarget(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceComputedMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceComputedMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::ComputedMemberAssignmentTarget); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Object, BinField::Expression })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Object, BinField::Expression })); MOZ_TRY_DECL(object, parseExpressionOrSuper()); MOZ_TRY_DECL(expression, parseExpression()); - TRY_DECL(result, factory_.newPropertyByValue(object, expression, start));return result; + TRY_DECL(result, factory_.newPropertyByValue(object, expression, start)); + return result; } /* interface ComputedMemberExpression : Node { (Expression or Super) object; Expression expression; } */ -JS::Result<ParseNode*> -BinASTParser::parseComputedMemberExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseComputedMemberExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceComputedMemberExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceComputedMemberExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceComputedMemberExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::ComputedMemberExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Object, BinField::Expression })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Object, BinField::Expression })); MOZ_TRY_DECL(object, parseExpressionOrSuper()); MOZ_TRY_DECL(expression, parseExpression()); - TRY_DECL(result, factory_.newPropertyByValue(object, expression, start));return result; + TRY_DECL(result, factory_.newPropertyByValue(object, expression, start)); + return result; } /* interface ComputedPropertyName : Node { Expression expression; } */ -JS::Result<ParseNode*> -BinASTParser::parseComputedPropertyName() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseComputedPropertyName() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceComputedPropertyName(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceComputedPropertyName(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceComputedPropertyName(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (ComputedPropertyName)"); } /* interface ConditionalExpression : Node { Expression test; Expression consequent; Expression alternate; } */ -JS::Result<ParseNode*> -BinASTParser::parseConditionalExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseConditionalExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceConditionalExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceConditionalExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceConditionalExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::ConditionalExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Test, BinField::Consequent, BinField::Alternate })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Test, BinField::Consequent, BinField::Alternate })); MOZ_TRY_DECL(test, parseExpression()); MOZ_TRY_DECL(consequent, parseExpression()); MOZ_TRY_DECL(alternate, parseExpression()); - TRY_DECL(result, factory_.newConditional(test, consequent, alternate));return result; + TRY_DECL(result, factory_.newConditional(test, consequent, alternate)); + return result; } /* interface ContinueStatement : Node { Label? label; } */ -JS::Result<ParseNode*> -BinASTParser::parseContinueStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseContinueStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceContinueStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceContinueStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceContinueStatement(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::ContinueStatement); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Label })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Label })); RootedAtom label(cx_); - MOZ_TRY(readMaybeString(&label)); - - if (label && !IsIdentifier(label)) - return raiseError("ContinueStatement - Label MUST be an identifier"); + MOZ_TRY_VAR(label, tokenizer_->readMaybeAtom()); if (label) { + if (!IsIdentifier(label)) + return raiseError("ContinueStatement - Label MUST be an identifier"); + auto validity = parseContext_->checkContinueStatement(label ? label->asPropertyName() : nullptr); if (validity.isErr()) { switch (validity.unwrapErr()) { case ParseContext::ContinueStatementError::NotInALoop: return raiseError(kind, "Not in a loop"); case ParseContext::ContinueStatementError::LabelNotFound: return raiseError(kind, "Label not found"); } } } - TRY_DECL(result, factory_.newContinueStatement(label ? label->asPropertyName() : nullptr, tokenizer_->pos(start)));return result; + TRY_DECL(result, factory_.newContinueStatement(label ? label->asPropertyName() : nullptr, tokenizer_->pos(start))); + return result; } /* interface DataProperty : Node { PropertyName name; Expression expression; } */ -JS::Result<ParseNode*> -BinASTParser::parseDataProperty() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseDataProperty() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceDataProperty(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceDataProperty(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceDataProperty(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::DataProperty); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Name, BinField::Expression })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Name, BinField::Expression })); MOZ_TRY_DECL(name, parsePropertyName()); MOZ_TRY_DECL(expression, parseExpression()); if (!factory_.isUsableAsObjectPropertyName(name)) return raiseError("DataProperty key kind"); - TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, expression, AccessorType::None));return result; + TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, expression, AccessorType::None)); + return result; } /* interface DebuggerStatement : Node { } */ -JS::Result<ParseNode*> -BinASTParser::parseDebuggerStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseDebuggerStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceDebuggerStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceDebuggerStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceDebuggerStatement(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (DebuggerStatement)"); } /* interface Directive : Node { string rawValue; } */ -JS::Result<ParseNode*> -BinASTParser::parseDirective() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseDirective() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceDirective(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceDirective(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceDirective(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::Directive); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::RawValue })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::RawValue })); RootedAtom rawValue(cx_); - MOZ_TRY(readString(&rawValue)); + MOZ_TRY_VAR(rawValue, tokenizer_->readAtom()); TokenPos pos = tokenizer_->pos(start); - TRY_DECL(result, factory_.newStringLiteral(rawValue, pos));return result; + TRY_DECL(result, factory_.newStringLiteral(rawValue, pos)); + return result; } /* interface DoWhileStatement : Node { Expression test; Statement body; } */ -JS::Result<ParseNode*> -BinASTParser::parseDoWhileStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseDoWhileStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceDoWhileStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceDoWhileStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceDoWhileStatement(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::DoWhileStatement); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Test, BinField::Body })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Test, BinField::Body })); ParseContext::Statement stmt(parseContext_, StatementKind::DoLoop); MOZ_TRY_DECL(test, parseExpression()); MOZ_TRY_DECL(body, parseStatement()); - TRY_DECL(result, factory_.newDoWhileStatement(body, test, tokenizer_->pos(start)));return result; -} - - -/* - interface EmptyStatement : Node { - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseEmptyStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceEmptyStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceEmptyStatement(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::EmptyStatement); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields0(kind, fields)); - - TRY_DECL(result, factory_.newEmptyStatement(tokenizer_->pos(start)));return result; -} - - -/* - interface Export : Node { - (FunctionDeclaration or ClassDeclaration or VariableDeclaration) declaration; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseExport() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceExport(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceExport(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (Export)"); -} - - -/* - interface ExportAllFrom : Node { - string moduleSpecifier; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseExportAllFrom() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceExportAllFrom(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceExportAllFrom(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (ExportAllFrom)"); -} - - -/* - interface ExportDefault : Node { - (FunctionDeclaration or ClassDeclaration or Expression) body; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseExportDefault() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceExportDefault(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceExportDefault(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (ExportDefault)"); -} - - -/* - interface ExportFrom : Node { - FrozenArray<ExportFromSpecifier> namedExports; - string moduleSpecifier; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseExportFrom() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceExportFrom(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceExportFrom(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (ExportFrom)"); -} - - -/* - interface ExportFromSpecifier : Node { - IdentifierName name; - IdentifierName? exportedName; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseExportFromSpecifier() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceExportFromSpecifier(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceExportFromSpecifier(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (ExportFromSpecifier)"); -} - - -/* - interface ExportLocalSpecifier : Node { - IdentifierExpression name; - IdentifierName? exportedName; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseExportLocalSpecifier() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceExportLocalSpecifier(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceExportLocalSpecifier(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (ExportLocalSpecifier)"); -} - - -/* - interface ExportLocals : Node { - FrozenArray<ExportLocalSpecifier> namedExports; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseExportLocals() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceExportLocals(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceExportLocals(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (ExportLocals)"); -} - - -/* - interface ExpressionStatement : Node { - Expression expression; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseExpressionStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceExpressionStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceExpressionStatement(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::ExpressionStatement); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Expression })); - - - - MOZ_TRY_DECL(expression, parseExpression()); - - - TRY_DECL(result, factory_.newExprStatement(expression, tokenizer_->offset()));return result; -} - - -/* - interface ForInOfBinding : Node { - VariableDeclarationKind kind; - Binding binding; + TRY_DECL(result, factory_.newDoWhileStatement(body, test, tokenizer_->pos(start))); + return result; +} + + +/* + interface EagerArrowExpression : Node { + bool isAsync; + AssertedParameterScope? parameterScope; + AssertedVarScope? bodyScope; + FormalParameters params; + (FunctionBody or Expression) body; } */ -JS::Result<ParseNode*> -BinASTParser::parseForInOfBinding() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceForInOfBinding(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceForInOfBinding(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::ForInOfBinding); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Kind, BinField::Binding })); - AutoVariableDeclarationKind kindGuard(this); - - - MOZ_TRY_DECL(kind_, parseVariableDeclarationKind()); - - - - - MOZ_TRY_DECL(binding, parseBinding()); - - - // Restored by `kindGuard`. - variableDeclarationKind_ = kind_; - MOZ_TRY(checkBinding(binding->pn_atom->asPropertyName())); - auto pnk = - kind_ == VariableDeclarationKind::Let - ? ParseNodeKind::Let - : ParseNodeKind::Var; - TRY_DECL(result, factory_.newDeclarationList(pnk, tokenizer_->pos(start))); - factory_.addList(result, binding);return result; -} - - -/* - interface ForInStatement : Node { - (ForInOfBinding or AssignmentTarget) left; - Expression right; - Statement body; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseForInStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceForInStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceForInStatement(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::ForInStatement); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Left, BinField::Right, BinField::Body })); - ParseContext::Statement stmt(parseContext_, StatementKind::ForInLoop); - - // Implicit scope around the `for`, used to store `for (let x in ...)` - // or `for (const x in ...)`-style declarations. Detail on the - // declaration is stored as part of `scope`. - ParseContext::Scope scope(cx_, parseContext_, usedNames_); - TRY(scope.init(parseContext_)); - - - MOZ_TRY_DECL(left, parseForInOfBindingOrAssignmentTarget()); - - - - - MOZ_TRY_DECL(right, parseExpression()); - - - - - MOZ_TRY_DECL(body, parseStatement()); - - - TRY_DECL(forHead, factory_.newForInOrOfHead(ParseNodeKind::ForIn, left, right, tokenizer_->pos(start))); - TRY_DECL(result, factory_.newForStatement(start, forHead, body, /*flags*/ 0)); - - if (!scope.isEmpty()) { - TRY_DECL(bindings, NewLexicalScopeData(cx_, scope, alloc_, parseContext_)); - TRY_VAR(result, factory_.newLexicalScope(*bindings, result)); - }return result; -} - - -/* - interface ForOfStatement : Node { - (ForInOfBinding or AssignmentTarget) left; - Expression right; - Statement body; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseForOfStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceForOfStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceForOfStatement(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (ForOfStatement)"); -} - - -/* - interface ForStatement : Node { - (VariableDeclaration or Expression)? init; - Expression? test; - Expression? update; - Statement body; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseForStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceForStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceForStatement(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::ForStatement); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Init, BinField::Test, BinField::Update, BinField::Body })); - ParseContext::Statement stmt(parseContext_, StatementKind::ForLoop); - - // Implicit scope around the `for`, used to store `for (let x; ...; ...)` - // or `for (const x; ...; ...)`-style declarations. Detail on the - // declaration is stored as part of `BINJS_Scope`. - ParseContext::Scope scope(cx_, parseContext_, usedNames_); - TRY(scope.init(parseContext_)); - - - MOZ_TRY_DECL(init, parseOptionalVariableDeclarationOrExpression()); - - - - - MOZ_TRY_DECL(test, parseOptionalExpression()); - - - - - MOZ_TRY_DECL(update, parseOptionalExpression()); - - - - - MOZ_TRY_DECL(body, parseStatement()); - - - TRY_DECL(forHead, factory_.newForHead(init, test, update, tokenizer_->pos(start))); - TRY_DECL(result, factory_.newForStatement(start, forHead, body, /* iflags = */ 0)); - - if (!scope.isEmpty()) { - TRY_DECL(bindings, NewLexicalScopeData(cx_, scope, alloc_, parseContext_)); - TRY_VAR(result, factory_.newLexicalScope(*bindings, result)); - }return result; -} - - -/* - interface FormalParameters : Node { - FrozenArray<Parameter> items; - Binding? rest; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseFormalParameters() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceFormalParameters(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceFormalParameters(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::FormalParameters); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Items, BinField::Rest })); - - - - MOZ_TRY_DECL(items, parseListOfParameter()); - - - - - MOZ_TRY_DECL(rest, parseOptionalBinding()); - - - auto result = items; - if (rest) { - TRY_DECL(spread, factory_.newSpread(start, rest)); - factory_.addList(result, spread); - }return result; -} - - -/* - interface FunctionBody : Node { - FrozenArray<Directive> directives; - FrozenArray<Statement> statements; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseFunctionBody() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceFunctionBody(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceFunctionBody(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::FunctionBody); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Directives, BinField::Statements })); - - - - MOZ_TRY_DECL(directives, parseListOfDirective()); - - - - - MOZ_TRY_DECL(statements, parseListOfStatement()); - - - MOZ_TRY_DECL(result, appendDirectivesToBody(/* body = */ statements, /* directives = */ directives));return result; -} - - -/* - interface FunctionDeclaration : Node { +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseEagerArrowExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceEagerArrowExpression(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceEagerArrowExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (EagerArrowExpression)"); +} + + +/* + interface EagerFunctionDeclaration : Node { bool isAsync; bool isGenerator; AssertedParameterScope? parameterScope; AssertedVarScope? bodyScope; BindingIdentifier name; FormalParameters params; FunctionBody body; } */ -JS::Result<ParseNode*> -BinASTParser::parseFunctionDeclaration() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceFunctionDeclaration(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::FunctionDeclaration); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body })); - - - - MOZ_TRY_DECL(isAsync, readBool()); - - - - - MOZ_TRY_DECL(isGenerator, readBool()); - - - MOZ_TRY_DECL(funbox, buildFunctionBox( - isGenerator ? GeneratorKind::Generator - : GeneratorKind::NotGenerator, - isAsync ? FunctionAsyncKind::AsyncFunction - : FunctionAsyncKind::SyncFunction)); - - // Push a new ParseContext. It will be used to parse `scope`, the arguments, the function. - BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr); - TRY(funpc.init()); - parseContext_->functionScope().useAsVarScope(parseContext_); - MOZ_ASSERT(parseContext_->isFunctionBox()); - - ParseContext::Scope lexicalScope(cx_, parseContext_, usedNames_); - TRY(lexicalScope.init(parseContext_)); - - MOZ_TRY(parseOptionalAssertedParameterScope()); - - - - - MOZ_TRY(parseOptionalAssertedVarScope()); - - - - - MOZ_TRY_DECL(name, parseBindingIdentifier()); - - - - - MOZ_TRY_DECL(params, parseFormalParameters()); - - - - - MOZ_TRY_DECL(body, parseFunctionBody()); - - - TRY_DECL(lexicalScopeData, NewLexicalScopeData(cx_, lexicalScope, alloc_, parseContext_)); - TRY_VAR(body, factory_.newLexicalScope(*lexicalScopeData, body)); - MOZ_TRY_DECL(result, buildFunction(start, kind, name, params, body, funbox));return result; -} - - -/* - interface FunctionExpression : Node { +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseEagerFunctionDeclaration() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceEagerFunctionDeclaration(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceEagerFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (EagerFunctionDeclaration)"); +} + + +/* + interface EagerFunctionExpression : Node { bool isAsync; bool isGenerator; AssertedParameterScope? parameterScope; AssertedVarScope? bodyScope; BindingIdentifier? name; FormalParameters params; FunctionBody body; } */ -JS::Result<ParseNode*> -BinASTParser::parseFunctionExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceFunctionExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::FunctionExpression); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseEagerFunctionExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceEagerFunctionExpression(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceEagerFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::EagerFunctionExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body })); - - - - MOZ_TRY_DECL(isAsync, readBool()); - - - - - MOZ_TRY_DECL(isGenerator, readBool()); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body })); + + + + MOZ_TRY_DECL(isAsync, tokenizer_->readBool()); + + + + + MOZ_TRY_DECL(isGenerator, tokenizer_->readBool()); MOZ_TRY_DECL(funbox, buildFunctionBox( isGenerator ? GeneratorKind::Generator : GeneratorKind::NotGenerator, isAsync ? FunctionAsyncKind::AsyncFunction : FunctionAsyncKind::SyncFunction)); @@ -4540,598 +4189,94 @@ BinASTParser::parseInterfaceFunctionExpr MOZ_TRY_DECL(body, parseFunctionBody()); TRY_DECL(lexicalScopeData, NewLexicalScopeData(cx_, lexicalScope, alloc_, parseContext_)); TRY_VAR(body, factory_.newLexicalScope(*lexicalScopeData, body)); - MOZ_TRY_DECL(result, buildFunction(start, kind, name, params, body, funbox));return result; -} - - -/* - interface Getter : Node { + MOZ_TRY_DECL(result, buildFunction(start, kind, name, params, body, funbox)); + return result; +} + + +/* + interface EagerGetter : Node { AssertedVarScope? bodyScope; PropertyName name; FunctionBody body; } */ -JS::Result<ParseNode*> -BinASTParser::parseGetter() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceGetter(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceGetter(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (Getter)"); -} - - -/* - interface IdentifierExpression : Node { - Identifier name; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseIdentifierExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceIdentifierExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceIdentifierExpression(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::IdentifierExpression); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Name })); - - - RootedAtom name(cx_); - MOZ_TRY(readString(&name)); - - - if (!IsIdentifier(name)) - return raiseError("Invalid identifier"); - TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_));return result; -} - - -/* - interface IfStatement : Node { - Expression test; - Statement consequent; - Statement? alternate; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseIfStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceIfStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceIfStatement(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::IfStatement); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Test, BinField::Consequent, BinField::Alternate })); - - - - MOZ_TRY_DECL(test, parseExpression()); - - - - - MOZ_TRY_DECL(consequent, parseStatement()); - - - - - MOZ_TRY_DECL(alternate, parseOptionalStatement()); - - - TRY_DECL(result, factory_.newIfStatement(start, test, consequent, alternate));return result; -} - - -/* - interface Import : Node { - string moduleSpecifier; - BindingIdentifier? defaultBinding; - FrozenArray<ImportSpecifier> namedImports; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseImport() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceImport(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceImport(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (Import)"); -} - - -/* - interface ImportNamespace : Node { - string moduleSpecifier; - BindingIdentifier? defaultBinding; - BindingIdentifier namespaceBinding; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseImportNamespace() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceImportNamespace(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceImportNamespace(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (ImportNamespace)"); -} - - -/* - interface ImportSpecifier : Node { - IdentifierName? name; - BindingIdentifier binding; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseImportSpecifier() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceImportSpecifier(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceImportSpecifier(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (ImportSpecifier)"); -} - - -/* - interface LabelledStatement : Node { - Label label; - Statement body; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseLabelledStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceLabelledStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceLabelledStatement(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::LabelledStatement); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Label, BinField::Body })); - - - RootedAtom label(cx_); - MOZ_TRY(readString(&label)); - if (!IsIdentifier(label)) - return raiseError("Invalid identifier"); - ParseContext::LabelStatement stmt(parseContext_, label); - - - - MOZ_TRY_DECL(body, parseStatement()); - - - TRY_DECL(result, factory_.newLabeledStatement(label->asPropertyName(), body, start));return result; -} - - -/* - interface LiteralBooleanExpression : Node { - bool value; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseLiteralBooleanExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceLiteralBooleanExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceLiteralBooleanExpression(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::LiteralBooleanExpression); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Value })); - - - - MOZ_TRY_DECL(value, readBool()); - - - TRY_DECL(result, factory_.newBooleanLiteral(value, tokenizer_->pos(start)));return result; -} - - -/* - interface LiteralInfinityExpression : Node { - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseLiteralInfinityExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceLiteralInfinityExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceLiteralInfinityExpression(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (LiteralInfinityExpression)"); -} - - -/* - interface LiteralNullExpression : Node { - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseLiteralNullExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceLiteralNullExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceLiteralNullExpression(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::LiteralNullExpression); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields0(kind, fields)); - - TRY_DECL(result, factory_.newNullLiteral(tokenizer_->pos(start)));return result; -} - - -/* - interface LiteralNumericExpression : Node { - number value; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseLiteralNumericExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceLiteralNumericExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceLiteralNumericExpression(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::LiteralNumericExpression); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Value })); - - - - MOZ_TRY_DECL(value, readNumber()); - - - TRY_DECL(result, factory_.newNumber(value, DecimalPoint::HasDecimal, tokenizer_->pos(start)));return result; -} - - -/* - interface LiteralPropertyName : Node { - string value; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseLiteralPropertyName() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceLiteralPropertyName(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceLiteralPropertyName(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::LiteralPropertyName); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Value })); - - - RootedAtom value(cx_); - MOZ_TRY(readString(&value)); - - - ParseNode* result; - uint32_t index; - if (value->isIndex(&index)) - TRY_VAR(result, factory_.newNumber(index, NoDecimal, TokenPos(start, tokenizer_->offset()))); - else - TRY_VAR(result, factory_.newObjectLiteralPropertyName(value, tokenizer_->pos(start)));return result; -} - - -/* - interface LiteralRegExpExpression : Node { - string pattern; - string flags; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseLiteralRegExpExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceLiteralRegExpExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceLiteralRegExpExpression(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::LiteralRegExpExpression); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Pattern, BinField::Flags })); - - - RootedAtom pattern(cx_); - MOZ_TRY(readString(&pattern)); - - Chars flags(cx_); MOZ_TRY(readString(flags)); - - RegExpFlag reflags = NoFlags; - for (auto c : flags) { - if (c == 'g' && !(reflags & GlobalFlag)) - reflags = RegExpFlag(reflags | GlobalFlag); - else if (c == 'i' && !(reflags & IgnoreCaseFlag)) - reflags = RegExpFlag(reflags | IgnoreCaseFlag); - else if (c == 'm' && !(reflags & MultilineFlag)) - reflags = RegExpFlag(reflags | MultilineFlag); - else if (c == 'y' && !(reflags & StickyFlag)) - reflags = RegExpFlag(reflags | StickyFlag); - else if (c == 'u' && !(reflags & UnicodeFlag)) - reflags = RegExpFlag(reflags | UnicodeFlag); - else - return raiseInvalidEnum("RegExpLiteral", flags); - } - - - Rooted<RegExpObject*> reobj(cx_); - TRY_VAR(reobj, RegExpObject::create(cx_, - pattern, - reflags, - alloc_, - TenuredObject)); - - TRY_DECL(result, factory_.newRegExp(reobj, tokenizer_->pos(start), *this));return result; -} - - -/* - interface LiteralStringExpression : Node { - string value; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseLiteralStringExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceLiteralStringExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceLiteralStringExpression(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::LiteralStringExpression); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::Value })); - - - RootedAtom value(cx_); - MOZ_TRY(readString(&value)); - - - TRY_DECL(result, factory_.newStringLiteral(value, tokenizer_->pos(start)));return result; -} - - -/* - interface Method : Node { +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseEagerGetter() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceEagerGetter(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceEagerGetter(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (EagerGetter)"); +} + + +/* + interface EagerMethod : Node { bool isAsync; bool isGenerator; AssertedParameterScope? parameterScope; AssertedVarScope? bodyScope; PropertyName name; FormalParameters params; FunctionBody body; } */ -JS::Result<ParseNode*> -BinASTParser::parseMethod() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceMethod(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceMethod(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::Method); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseEagerMethod() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceEagerMethod(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceEagerMethod(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::EagerMethod); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body })); - - - - MOZ_TRY_DECL(isAsync, readBool()); - - - - - MOZ_TRY_DECL(isGenerator, readBool()); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body })); + + + + MOZ_TRY_DECL(isAsync, tokenizer_->readBool()); + + + + + MOZ_TRY_DECL(isGenerator, tokenizer_->readBool()); MOZ_TRY_DECL(funbox, buildFunctionBox( isGenerator ? GeneratorKind::Generator : GeneratorKind::NotGenerator, isAsync ? FunctionAsyncKind::AsyncFunction : FunctionAsyncKind::SyncFunction)); @@ -5163,730 +4308,1958 @@ BinASTParser::parseInterfaceMethod(const MOZ_TRY_DECL(body, parseFunctionBody()); MOZ_TRY_DECL(method, buildFunction(start, kind, name, params, body, funbox)); - TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, method, AccessorType::None));return result; + TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, method, AccessorType::None)); + return result; +} + + +/* + interface EagerSetter : Node { + AssertedParameterScope? parameterScope; + AssertedVarScope? bodyScope; + PropertyName name; + Parameter param; + FunctionBody body; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseEagerSetter() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceEagerSetter(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceEagerSetter(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (EagerSetter)"); +} + + +/* + interface EmptyStatement : Node { + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseEmptyStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceEmptyStatement(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceEmptyStatement(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::EmptyStatement); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields0(kind, fields)); + + TRY_DECL(result, factory_.newEmptyStatement(tokenizer_->pos(start))); + return result; +} + + +/* + interface Export : Node { + (FunctionDeclaration or ClassDeclaration or VariableDeclaration) declaration; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseExport() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceExport(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceExport(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (Export)"); +} + + +/* + interface ExportAllFrom : Node { + string moduleSpecifier; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseExportAllFrom() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceExportAllFrom(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceExportAllFrom(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (ExportAllFrom)"); +} + + +/* + interface ExportDefault : Node { + (FunctionDeclaration or ClassDeclaration or Expression) body; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseExportDefault() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceExportDefault(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceExportDefault(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (ExportDefault)"); +} + + +/* + interface ExportFrom : Node { + FrozenArray<ExportFromSpecifier> namedExports; + string moduleSpecifier; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseExportFrom() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceExportFrom(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceExportFrom(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (ExportFrom)"); +} + + +/* + interface ExportFromSpecifier : Node { + IdentifierName name; + IdentifierName? exportedName; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseExportFromSpecifier() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceExportFromSpecifier(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceExportFromSpecifier(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (ExportFromSpecifier)"); +} + + +/* + interface ExportLocalSpecifier : Node { + IdentifierExpression name; + IdentifierName? exportedName; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseExportLocalSpecifier() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceExportLocalSpecifier(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceExportLocalSpecifier(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (ExportLocalSpecifier)"); +} + + +/* + interface ExportLocals : Node { + FrozenArray<ExportLocalSpecifier> namedExports; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseExportLocals() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceExportLocals(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceExportLocals(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (ExportLocals)"); +} + + +/* + interface ExpressionStatement : Node { + Expression expression; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseExpressionStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceExpressionStatement(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceExpressionStatement(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::ExpressionStatement); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Expression })); + + + + MOZ_TRY_DECL(expression, parseExpression()); + + + TRY_DECL(result, factory_.newExprStatement(expression, tokenizer_->offset())); + return result; +} + + +/* + interface ForInOfBinding : Node { + VariableDeclarationKind kind; + Binding binding; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseForInOfBinding() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceForInOfBinding(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceForInOfBinding(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::ForInOfBinding); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Kind, BinField::Binding })); + AutoVariableDeclarationKind kindGuard(this); + + + MOZ_TRY_DECL(kind_, parseVariableDeclarationKind()); + + + + + MOZ_TRY_DECL(binding, parseBinding()); + + + // Restored by `kindGuard`. + variableDeclarationKind_ = kind_; + MOZ_TRY(checkBinding(binding->pn_atom->asPropertyName())); + auto pnk = + kind_ == VariableDeclarationKind::Let + ? ParseNodeKind::Let + : ParseNodeKind::Var; + TRY_DECL(result, factory_.newDeclarationList(pnk, tokenizer_->pos(start))); + factory_.addList(result, binding); + return result; +} + + +/* + interface ForInStatement : Node { + (ForInOfBinding or AssignmentTarget) left; + Expression right; + Statement body; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseForInStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceForInStatement(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceForInStatement(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::ForInStatement); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Left, BinField::Right, BinField::Body })); + ParseContext::Statement stmt(parseContext_, StatementKind::ForInLoop); + + // Implicit scope around the `for`, used to store `for (let x in ...)` + // or `for (const x in ...)`-style declarations. Detail on the + // declaration is stored as part of `scope`. + ParseContext::Scope scope(cx_, parseContext_, usedNames_); + TRY(scope.init(parseContext_)); + + + MOZ_TRY_DECL(left, parseForInOfBindingOrAssignmentTarget()); + + + + + MOZ_TRY_DECL(right, parseExpression()); + + + + + MOZ_TRY_DECL(body, parseStatement()); + + + TRY_DECL(forHead, factory_.newForInOrOfHead(ParseNodeKind::ForIn, left, right, tokenizer_->pos(start))); + TRY_DECL(result, factory_.newForStatement(start, forHead, body, /*flags*/ 0)); + + if (!scope.isEmpty()) { + TRY_DECL(bindings, NewLexicalScopeData(cx_, scope, alloc_, parseContext_)); + TRY_VAR(result, factory_.newLexicalScope(*bindings, result)); + } + return result; +} + + +/* + interface ForOfStatement : Node { + (ForInOfBinding or AssignmentTarget) left; + Expression right; + Statement body; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseForOfStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceForOfStatement(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceForOfStatement(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (ForOfStatement)"); +} + + +/* + interface ForStatement : Node { + (VariableDeclaration or Expression)? init; + Expression? test; + Expression? update; + Statement body; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseForStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceForStatement(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceForStatement(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::ForStatement); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Init, BinField::Test, BinField::Update, BinField::Body })); + ParseContext::Statement stmt(parseContext_, StatementKind::ForLoop); + + // Implicit scope around the `for`, used to store `for (let x; ...; ...)` + // or `for (const x; ...; ...)`-style declarations. Detail on the + // declaration is stored as part of `BINJS_Scope`. + ParseContext::Scope scope(cx_, parseContext_, usedNames_); + TRY(scope.init(parseContext_)); + + + MOZ_TRY_DECL(init, parseOptionalVariableDeclarationOrExpression()); + + + + + MOZ_TRY_DECL(test, parseOptionalExpression()); + + + + + MOZ_TRY_DECL(update, parseOptionalExpression()); + + + + + MOZ_TRY_DECL(body, parseStatement()); + + + TRY_DECL(forHead, factory_.newForHead(init, test, update, tokenizer_->pos(start))); + TRY_DECL(result, factory_.newForStatement(start, forHead, body, /* iflags = */ 0)); + + if (!scope.isEmpty()) { + TRY_DECL(bindings, NewLexicalScopeData(cx_, scope, alloc_, parseContext_)); + TRY_VAR(result, factory_.newLexicalScope(*bindings, result)); + } + return result; +} + + +/* + interface FormalParameters : Node { + FrozenArray<Parameter> items; + Binding? rest; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseFormalParameters() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceFormalParameters(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceFormalParameters(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::FormalParameters); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Items, BinField::Rest })); + + + + MOZ_TRY_DECL(items, parseListOfParameter()); + + + + + MOZ_TRY_DECL(rest, parseOptionalBinding()); + + + auto result = items; + if (rest) { + TRY_DECL(spread, factory_.newSpread(start, rest)); + factory_.addList(result, spread); + } + return result; +} + + +/* + interface FunctionBody : Node { + FrozenArray<Directive> directives; + FrozenArray<Statement> statements; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseFunctionBody() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceFunctionBody(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceFunctionBody(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::FunctionBody); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Directives, BinField::Statements })); + + + + MOZ_TRY_DECL(directives, parseListOfDirective()); + + + + + MOZ_TRY_DECL(statements, parseListOfStatement()); + + + MOZ_TRY_DECL(result, appendDirectivesToBody(/* body = */ statements, /* directives = */ directives)); + return result; +} + + +/* + interface IdentifierExpression : Node { + Identifier name; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseIdentifierExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceIdentifierExpression(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceIdentifierExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::IdentifierExpression); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Name })); + + + RootedAtom name(cx_); + MOZ_TRY_VAR(name, tokenizer_->readAtom()); + + + if (!IsIdentifier(name)) + return raiseError("Invalid identifier"); + TRY_DECL(result, factory_.newName(name->asPropertyName(), tokenizer_->pos(start), cx_)); + return result; +} + + +/* + interface IfStatement : Node { + Expression test; + Statement consequent; + Statement? alternate; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseIfStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceIfStatement(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceIfStatement(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::IfStatement); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Test, BinField::Consequent, BinField::Alternate })); + + + + MOZ_TRY_DECL(test, parseExpression()); + + + + + MOZ_TRY_DECL(consequent, parseStatement()); + + + + + MOZ_TRY_DECL(alternate, parseOptionalStatement()); + + + TRY_DECL(result, factory_.newIfStatement(start, test, consequent, alternate)); + return result; +} + + +/* + interface Import : Node { + string moduleSpecifier; + BindingIdentifier? defaultBinding; + FrozenArray<ImportSpecifier> namedImports; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseImport() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceImport(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceImport(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (Import)"); +} + + +/* + interface ImportNamespace : Node { + string moduleSpecifier; + BindingIdentifier? defaultBinding; + BindingIdentifier namespaceBinding; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseImportNamespace() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceImportNamespace(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceImportNamespace(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (ImportNamespace)"); +} + + +/* + interface ImportSpecifier : Node { + IdentifierName? name; + BindingIdentifier binding; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseImportSpecifier() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceImportSpecifier(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceImportSpecifier(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (ImportSpecifier)"); +} + + +/* + interface LabelledStatement : Node { + Label label; + Statement body; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseLabelledStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceLabelledStatement(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceLabelledStatement(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::LabelledStatement); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Label, BinField::Body })); + + + RootedAtom label(cx_); + MOZ_TRY_VAR(label, tokenizer_->readAtom()); + if (!IsIdentifier(label)) + return raiseError("Invalid identifier"); + ParseContext::LabelStatement stmt(parseContext_, label); + + + + MOZ_TRY_DECL(body, parseStatement()); + + + TRY_DECL(result, factory_.newLabeledStatement(label->asPropertyName(), body, start)); + return result; +} + + +/* + interface LiteralBooleanExpression : Node { + bool value; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseLiteralBooleanExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceLiteralBooleanExpression(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceLiteralBooleanExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::LiteralBooleanExpression); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Value })); + + + + MOZ_TRY_DECL(value, tokenizer_->readBool()); + + + TRY_DECL(result, factory_.newBooleanLiteral(value, tokenizer_->pos(start))); + return result; +} + + +/* + interface LiteralInfinityExpression : Node { + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseLiteralInfinityExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceLiteralInfinityExpression(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceLiteralInfinityExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (LiteralInfinityExpression)"); +} + + +/* + interface LiteralNullExpression : Node { + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseLiteralNullExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceLiteralNullExpression(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceLiteralNullExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::LiteralNullExpression); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields0(kind, fields)); + + TRY_DECL(result, factory_.newNullLiteral(tokenizer_->pos(start))); + return result; +} + + +/* + interface LiteralNumericExpression : Node { + number value; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseLiteralNumericExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceLiteralNumericExpression(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceLiteralNumericExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::LiteralNumericExpression); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Value })); + + + + MOZ_TRY_DECL(value, tokenizer_->readDouble()); + + + TRY_DECL(result, factory_.newNumber(value, DecimalPoint::HasDecimal, tokenizer_->pos(start))); + return result; +} + + +/* + interface LiteralPropertyName : Node { + string value; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseLiteralPropertyName() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceLiteralPropertyName(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceLiteralPropertyName(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::LiteralPropertyName); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Value })); + + + RootedAtom value(cx_); + MOZ_TRY_VAR(value, tokenizer_->readAtom()); + + + ParseNode* result; + uint32_t index; + if (value->isIndex(&index)) + TRY_VAR(result, factory_.newNumber(index, NoDecimal, TokenPos(start, tokenizer_->offset()))); + else + TRY_VAR(result, factory_.newObjectLiteralPropertyName(value, tokenizer_->pos(start))); + return result; +} + + +/* + interface LiteralRegExpExpression : Node { + string pattern; + string flags; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseLiteralRegExpExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceLiteralRegExpExpression(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceLiteralRegExpExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::LiteralRegExpExpression); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Pattern, BinField::Flags })); + + + RootedAtom pattern(cx_); + MOZ_TRY_VAR(pattern, tokenizer_->readAtom()); + + Chars flags(cx_); + MOZ_TRY(tokenizer_->readChars(flags)); + + RegExpFlag reflags = NoFlags; + for (auto c : flags) { + if (c == 'g' && !(reflags & GlobalFlag)) + reflags = RegExpFlag(reflags | GlobalFlag); + else if (c == 'i' && !(reflags & IgnoreCaseFlag)) + reflags = RegExpFlag(reflags | IgnoreCaseFlag); + else if (c == 'm' && !(reflags & MultilineFlag)) + reflags = RegExpFlag(reflags | MultilineFlag); + else if (c == 'y' && !(reflags & StickyFlag)) + reflags = RegExpFlag(reflags | StickyFlag); + else if (c == 'u' && !(reflags & UnicodeFlag)) + reflags = RegExpFlag(reflags | UnicodeFlag); + else + return raiseError("Invalid regexp flags"); + } + + + Rooted<RegExpObject*> reobj(cx_); + TRY_VAR(reobj, RegExpObject::create(cx_, + pattern, + reflags, + alloc_, + TenuredObject)); + + TRY_DECL(result, factory_.newRegExp(reobj, tokenizer_->pos(start), *this)); + return result; +} + + +/* + interface LiteralStringExpression : Node { + string value; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseLiteralStringExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceLiteralStringExpression(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceLiteralStringExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + MOZ_ASSERT(kind == BinKind::LiteralStringExpression); + CheckRecursionLimit(cx_); + + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Value })); + + + RootedAtom value(cx_); + MOZ_TRY_VAR(value, tokenizer_->readAtom()); + + + TRY_DECL(result, factory_.newStringLiteral(value, tokenizer_->pos(start))); + return result; } /* interface Module : Node { AssertedVarScope? scope; FrozenArray<Directive> directives; FrozenArray<(ImportDeclaration or ExportDeclaration or Statement)> items; } */ -JS::Result<ParseNode*> -BinASTParser::parseModule() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseModule() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceModule(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceModule(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceModule(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (Module)"); } /* interface NewExpression : Node { Expression callee; Arguments arguments; } */ -JS::Result<ParseNode*> -BinASTParser::parseNewExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseNewExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceNewExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceNewExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceNewExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::NewExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Callee, BinField::Arguments })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Callee, BinField::Arguments })); MOZ_TRY_DECL(callee, parseExpression()); MOZ_TRY_DECL(arguments, parseArguments()); auto result = arguments; result->setKind(ParseNodeKind::New); - result->prepend(callee);return result; + result->prepend(callee); + return result; } /* interface NewTargetExpression : Node { } */ -JS::Result<ParseNode*> -BinASTParser::parseNewTargetExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseNewTargetExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceNewTargetExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceNewTargetExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceNewTargetExpression(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (NewTargetExpression)"); } /* interface ObjectAssignmentTarget : Node { FrozenArray<AssignmentTargetProperty> properties; } */ -JS::Result<ParseNode*> -BinASTParser::parseObjectAssignmentTarget() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseObjectAssignmentTarget() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceObjectAssignmentTarget(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceObjectAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceObjectAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (ObjectAssignmentTarget)"); } /* interface ObjectBinding : Node { FrozenArray<BindingProperty> properties; } */ -JS::Result<ParseNode*> -BinASTParser::parseObjectBinding() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseObjectBinding() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceObjectBinding(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceObjectBinding(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceObjectBinding(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (ObjectBinding)"); } /* interface ObjectExpression : Node { FrozenArray<ObjectProperty> properties; } */ -JS::Result<ParseNode*> -BinASTParser::parseObjectExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseObjectExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceObjectExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceObjectExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceObjectExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::ObjectExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Properties })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Properties })); MOZ_TRY_DECL(properties, parseListOfObjectProperty()); - auto result = properties;return result; + auto result = properties; + return result; } /* interface ReturnStatement : Node { Expression? expression; } */ -JS::Result<ParseNode*> -BinASTParser::parseReturnStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseReturnStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceReturnStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceReturnStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceReturnStatement(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::ReturnStatement); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Expression })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Expression })); if (!parseContext_->isFunctionBox()) { // Return statements are permitted only inside functions. return raiseInvalidKind("Toplevel Statement", kind); } parseContext_->functionBox()->usesReturn = true; MOZ_TRY_DECL(expression, parseOptionalExpression()); - TRY_DECL(result, factory_.newReturnStatement(expression, tokenizer_->pos(start)));return result; + TRY_DECL(result, factory_.newReturnStatement(expression, tokenizer_->pos(start))); + return result; } /* interface Script : Node { AssertedVarScope? scope; FrozenArray<Directive> directives; FrozenArray<Statement> statements; } */ -JS::Result<ParseNode*> -BinASTParser::parseScript() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseScript() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceScript(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceScript(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceScript(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::Script); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Scope, BinField::Directives, BinField::Statements })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Scope, BinField::Directives, BinField::Statements })); MOZ_TRY(parseOptionalAssertedVarScope()); MOZ_TRY_DECL(directives, parseListOfDirective()); MOZ_TRY_DECL(statements, parseListOfStatement()); - MOZ_TRY_DECL(result, appendDirectivesToBody(/* body = */ statements, /* directives = */ directives));return result; -} - - -/* - interface Setter : Node { - AssertedParameterScope? parameterScope; - AssertedVarScope? bodyScope; - PropertyName name; - Parameter param; - FunctionBody body; - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseSetter() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceSetter(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceSetter(const size_t start, const BinKind kind, const BinFields& fields) -{ - MOZ_ASSERT(kind == BinKind::Setter); - CheckRecursionLimit(cx_); - - MOZ_TRY(checkFields(kind, fields, { BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Param, BinField::Body })); - const auto isAsync = false; - const auto isGenerator = false; - MOZ_TRY_DECL(funbox, buildFunctionBox( - isGenerator ? GeneratorKind::Generator - : GeneratorKind::NotGenerator, - isAsync ? FunctionAsyncKind::AsyncFunction - : FunctionAsyncKind::SyncFunction)); - - // Push a new ParseContext. It will be used to parse `scope`, the arguments, the function. - BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr); - TRY(funpc.init()); - parseContext_->functionScope().useAsVarScope(parseContext_); - MOZ_ASSERT(parseContext_->isFunctionBox()); - - ParseContext::Scope lexicalScope(cx_, parseContext_, usedNames_); - TRY(lexicalScope.init(parseContext_)); - - MOZ_TRY(parseOptionalAssertedParameterScope()); - - - - - MOZ_TRY(parseOptionalAssertedVarScope()); - - - - - MOZ_TRY_DECL(name, parsePropertyName()); - - - - - MOZ_TRY_DECL(param, parseParameter()); - - - - - MOZ_TRY_DECL(body, parseFunctionBody()); - - - TRY_DECL(params, factory_.newList(ParseNodeKind::ParamsBody, param)); - MOZ_TRY_DECL(method, buildFunction(start, kind, name, params, body, funbox)); - TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, method, AccessorType::Setter));return result; + MOZ_TRY_DECL(result, appendDirectivesToBody(/* body = */ statements, /* directives = */ directives)); + return result; } /* interface ShorthandProperty : Node { IdentifierExpression name; } */ -JS::Result<ParseNode*> -BinASTParser::parseShorthandProperty() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseShorthandProperty() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceShorthandProperty(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceShorthandProperty(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceShorthandProperty(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::ShorthandProperty); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Name })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Name })); MOZ_TRY_DECL(name, parseIdentifierExpression()); if (!factory_.isUsableAsObjectPropertyName(name)) TRY_VAR(name, factory_.newObjectLiteralPropertyName(name->name(), tokenizer_->pos(start))); - TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, name, AccessorType::None));return result; + TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, name, AccessorType::None)); + return result; +} + + +/* + interface SkippableArrowExpression : Node { + EagerArrowExpression skipped; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSkippableArrowExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceSkippableArrowExpression(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceSkippableArrowExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (SkippableArrowExpression)"); +} + + +/* + interface SkippableFunctionDeclaration : Node { + EagerFunctionDeclaration skipped; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSkippableFunctionDeclaration() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceSkippableFunctionDeclaration(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceSkippableFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (SkippableFunctionDeclaration)"); +} + + +/* + interface SkippableFunctionExpression : Node { + EagerFunctionExpression skipped; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSkippableFunctionExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceSkippableFunctionExpression(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceSkippableFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (SkippableFunctionExpression)"); +} + + +/* + interface SkippableGetter : Node { + EagerGetter skipped; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSkippableGetter() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceSkippableGetter(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceSkippableGetter(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (SkippableGetter)"); +} + + +/* + interface SkippableMethod : Node { + EagerMethod skipped; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSkippableMethod() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceSkippableMethod(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceSkippableMethod(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (SkippableMethod)"); +} + + +/* + interface SkippableSetter : Node { + EagerSetter skipped; + } +*/ +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSkippableSetter() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + const auto start = tokenizer_->offset(); + + MOZ_TRY_DECL(result, parseInterfaceSkippableSetter(start, kind, fields)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceSkippableSetter(const size_t start, const BinKind kind, const BinFields& fields) +{ + return raiseError("FIXME: Not implemented yet (SkippableSetter)"); } /* interface SpreadElement : Node { Expression expression; } */ -JS::Result<ParseNode*> -BinASTParser::parseSpreadElement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSpreadElement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceSpreadElement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceSpreadElement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceSpreadElement(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (SpreadElement)"); } /* interface StaticMemberAssignmentTarget : Node { (Expression or Super) object; IdentifierName property; } */ -JS::Result<ParseNode*> -BinASTParser::parseStaticMemberAssignmentTarget() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseStaticMemberAssignmentTarget() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceStaticMemberAssignmentTarget(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceStaticMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceStaticMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::StaticMemberAssignmentTarget); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Object, BinField::Property })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Object, BinField::Property })); MOZ_TRY_DECL(object, parseExpressionOrSuper()); RootedAtom property(cx_); - MOZ_TRY(readString(&property)); - - - TRY_DECL(result, factory_.newPropertyAccess(object, property->asPropertyName(), start));return result; + MOZ_TRY_VAR(property, tokenizer_->readAtom()); + + + TRY_DECL(result, factory_.newPropertyAccess(object, property->asPropertyName(), start)); + return result; } /* interface StaticMemberExpression : Node { (Expression or Super) object; IdentifierName property; } */ -JS::Result<ParseNode*> -BinASTParser::parseStaticMemberExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseStaticMemberExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceStaticMemberExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceStaticMemberExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceStaticMemberExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::StaticMemberExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Object, BinField::Property })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Object, BinField::Property })); MOZ_TRY_DECL(object, parseExpressionOrSuper()); RootedAtom property(cx_); - MOZ_TRY(readString(&property)); - - - TRY_DECL(result, factory_.newPropertyAccess(object, property->asPropertyName(), start));return result; + MOZ_TRY_VAR(property, tokenizer_->readAtom()); + + + TRY_DECL(result, factory_.newPropertyAccess(object, property->asPropertyName(), start)); + return result; } /* interface Super : Node { } */ -JS::Result<ParseNode*> -BinASTParser::parseSuper() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSuper() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceSuper(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceSuper(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceSuper(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (Super)"); } /* interface SwitchCase : Node { Expression test; FrozenArray<Statement> consequent; } */ -JS::Result<ParseNode*> -BinASTParser::parseSwitchCase() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSwitchCase() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceSwitchCase(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceSwitchCase(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceSwitchCase(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::SwitchCase); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Test, BinField::Consequent })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Test, BinField::Consequent })); MOZ_TRY_DECL(test, parseExpression()); MOZ_TRY_DECL(consequent, parseListOfStatement()); - TRY_DECL(result, factory_.newCaseOrDefault(start, test, consequent));return result; + TRY_DECL(result, factory_.newCaseOrDefault(start, test, consequent)); + return result; } /* interface SwitchDefault : Node { FrozenArray<Statement> consequent; } */ -JS::Result<ParseNode*> -BinASTParser::parseSwitchDefault() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSwitchDefault() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceSwitchDefault(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceSwitchDefault(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceSwitchDefault(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::SwitchDefault); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Consequent })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Consequent })); MOZ_TRY_DECL(consequent, parseListOfStatement()); - TRY_DECL(result, factory_.newCaseOrDefault(start, nullptr, consequent));return result; + TRY_DECL(result, factory_.newCaseOrDefault(start, nullptr, consequent)); + return result; } /* interface SwitchStatement : Node { Expression discriminant; FrozenArray<SwitchCase> cases; } */ -JS::Result<ParseNode*> -BinASTParser::parseSwitchStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSwitchStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceSwitchStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceSwitchStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceSwitchStatement(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::SwitchStatement); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Discriminant, BinField::Cases })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Discriminant, BinField::Cases })); MOZ_TRY_DECL(discriminant, parseExpression()); MOZ_TRY_DECL(cases, parseListOfSwitchCase()); TRY_DECL(scope, factory_.newLexicalScope(nullptr, cases)); - TRY_DECL(result, factory_.newSwitchStatement(start, discriminant, scope));return result; + TRY_DECL(result, factory_.newSwitchStatement(start, discriminant, scope)); + return result; } /* interface SwitchStatementWithDefault : Node { Expression discriminant; FrozenArray<SwitchCase> preDefaultCases; SwitchDefault defaultCase; FrozenArray<SwitchCase> postDefaultCases; } */ -JS::Result<ParseNode*> -BinASTParser::parseSwitchStatementWithDefault() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseSwitchStatementWithDefault() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceSwitchStatementWithDefault(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceSwitchStatementWithDefault(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceSwitchStatementWithDefault(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::SwitchStatementWithDefault); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Discriminant, BinField::PreDefaultCases, BinField::DefaultCase, BinField::PostDefaultCases })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Discriminant, BinField::PreDefaultCases, BinField::DefaultCase, BinField::PostDefaultCases })); MOZ_TRY_DECL(discriminant, parseExpression()); @@ -5908,233 +6281,237 @@ BinASTParser::parseInterfaceSwitchStatem factory_.addList(cases, defaultCase); ParseNode* iter = postDefaultCases->pn_head; while (iter) { ParseNode* next = iter->pn_next; factory_.addList(cases, iter); iter = next; } TRY_DECL(scope, factory_.newLexicalScope(nullptr, cases)); - TRY_DECL(result, factory_.newSwitchStatement(start, discriminant, scope));return result; + TRY_DECL(result, factory_.newSwitchStatement(start, discriminant, scope)); + return result; } /* interface TemplateElement : Node { string rawValue; } */ -JS::Result<ParseNode*> -BinASTParser::parseTemplateElement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseTemplateElement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceTemplateElement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceTemplateElement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceTemplateElement(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (TemplateElement)"); } /* interface TemplateExpression : Node { Expression? tag; FrozenArray<(Expression or TemplateElement)> elements; } */ -JS::Result<ParseNode*> -BinASTParser::parseTemplateExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseTemplateExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceTemplateExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceTemplateExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceTemplateExpression(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (TemplateExpression)"); } /* interface ThisExpression : Node { } */ -JS::Result<ParseNode*> -BinASTParser::parseThisExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseThisExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceThisExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceThisExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceThisExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::ThisExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields0(kind, fields)); + MOZ_TRY(tokenizer_->checkFields0(kind, fields)); if (parseContext_->isFunctionBox()) parseContext_->functionBox()->usesThis = true; TokenPos pos = tokenizer_->pos(start); ParseNode* thisName(nullptr); if (parseContext_->sc()->thisBinding() == ThisBinding::Function) TRY_VAR(thisName, factory_.newName(cx_->names().dotThis, pos, cx_)); - TRY_DECL(result, factory_.newThisLiteral(pos, thisName));return result; + TRY_DECL(result, factory_.newThisLiteral(pos, thisName)); + return result; } /* interface ThrowStatement : Node { Expression expression; } */ -JS::Result<ParseNode*> -BinASTParser::parseThrowStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseThrowStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceThrowStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceThrowStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceThrowStatement(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::ThrowStatement); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Expression })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Expression })); MOZ_TRY_DECL(expression, parseExpression()); - TRY_DECL(result, factory_.newThrowStatement(expression, tokenizer_->pos(start)));return result; + TRY_DECL(result, factory_.newThrowStatement(expression, tokenizer_->pos(start))); + return result; } /* interface TryCatchStatement : Node { Block body; CatchClause catchClause; } */ -JS::Result<ParseNode*> -BinASTParser::parseTryCatchStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseTryCatchStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceTryCatchStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceTryCatchStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceTryCatchStatement(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::TryCatchStatement); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Body, BinField::CatchClause })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Body, BinField::CatchClause })); ParseNode* body; { ParseContext::Statement stmt(parseContext_, StatementKind::Try); ParseContext::Scope scope(cx_, parseContext_, usedNames_); TRY(scope.init(parseContext_)); MOZ_TRY_VAR(body, parseBlock()); } MOZ_TRY_DECL(catchClause, parseCatchClause()); - TRY_DECL(result, factory_.newTryStatement(start, body, catchClause, /* finally = */ nullptr));return result; + TRY_DECL(result, factory_.newTryStatement(start, body, catchClause, /* finally = */ nullptr)); + return result; } /* interface TryFinallyStatement : Node { Block body; CatchClause? catchClause; Block finalizer; } */ -JS::Result<ParseNode*> -BinASTParser::parseTryFinallyStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseTryFinallyStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceTryFinallyStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceTryFinallyStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceTryFinallyStatement(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::TryFinallyStatement); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Body, BinField::CatchClause, BinField::Finalizer })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Body, BinField::CatchClause, BinField::Finalizer })); ParseNode* body; { ParseContext::Statement stmt(parseContext_, StatementKind::Try); ParseContext::Scope scope(cx_, parseContext_, usedNames_); TRY(scope.init(parseContext_)); MOZ_TRY_VAR(body, parseBlock()); @@ -6149,49 +6526,50 @@ BinASTParser::parseInterfaceTryFinallySt { ParseContext::Statement stmt(parseContext_, StatementKind::Finally); ParseContext::Scope scope(cx_, parseContext_, usedNames_); TRY(scope.init(parseContext_)); MOZ_TRY_VAR(finalizer, parseBlock()); } - TRY_DECL(result, factory_.newTryStatement(start, body, catchClause, finalizer));return result; + TRY_DECL(result, factory_.newTryStatement(start, body, catchClause, finalizer)); + return result; } /* interface UnaryExpression : Node { UnaryOperator operator; Expression operand; } */ -JS::Result<ParseNode*> -BinASTParser::parseUnaryExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseUnaryExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceUnaryExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceUnaryExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceUnaryExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::UnaryExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Operator, BinField::Operand })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Operator, BinField::Operand })); MOZ_TRY_DECL(operator_, parseUnaryOperator()); @@ -6235,54 +6613,55 @@ BinASTParser::parseInterfaceUnaryExpress pnk = ParseNodeKind::DeleteElem; break; default: pnk = ParseNodeKind::DeleteExpr; } break; } } - TRY_DECL(result, factory_.newUnary(pnk, start, operand));return result; + TRY_DECL(result, factory_.newUnary(pnk, start, operand)); + return result; } /* interface UpdateExpression : Node { bool isPrefix; UpdateOperator operator; SimpleAssignmentTarget operand; } */ -JS::Result<ParseNode*> -BinASTParser::parseUpdateExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseUpdateExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceUpdateExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceUpdateExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceUpdateExpression(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::UpdateExpression); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::IsPrefix, BinField::Operator, BinField::Operand })); - - - - MOZ_TRY_DECL(isPrefix, readBool()); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::IsPrefix, BinField::Operator, BinField::Operand })); + + + + MOZ_TRY_DECL(isPrefix, tokenizer_->readBool()); MOZ_TRY_DECL(operator_, parseUpdateOperator()); @@ -6296,49 +6675,50 @@ BinASTParser::parseInterfaceUpdateExpres pnk = isPrefix ? ParseNodeKind::PreIncrement : ParseNodeKind::PostIncrement; break; case UpdateOperator::Decr: pnk = isPrefix ? ParseNodeKind::PreDecrement : ParseNodeKind::PostDecrement; break; } - TRY_DECL(result, factory_.newUnary(pnk, start, operand));return result; + TRY_DECL(result, factory_.newUnary(pnk, start, operand)); + return result; } /* interface VariableDeclaration : Node { VariableDeclarationKind kind; FrozenArray<VariableDeclarator> declarators; } */ -JS::Result<ParseNode*> -BinASTParser::parseVariableDeclaration() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseVariableDeclaration() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceVariableDeclaration(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceVariableDeclaration(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceVariableDeclaration(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::VariableDeclaration); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Kind, BinField::Declarators })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Kind, BinField::Declarators })); AutoVariableDeclarationKind kindGuard(this); MOZ_TRY_DECL(kind_, parseVariableDeclarationKind()); // Restored by `kindGuard`. variableDeclarationKind_ = kind_; @@ -6358,49 +6738,50 @@ BinASTParser::parseInterfaceVariableDecl case VariableDeclarationKind::Let: pnk = ParseNodeKind::Let; break; case VariableDeclarationKind::Const: pnk = ParseNodeKind::Const; break; } declarators->setKind(pnk); - auto result = declarators;return result; + auto result = declarators; + return result; } /* interface VariableDeclarator : Node { Binding binding; Expression? init; } */ -JS::Result<ParseNode*> -BinASTParser::parseVariableDeclarator() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseVariableDeclarator() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceVariableDeclarator(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceVariableDeclarator(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceVariableDeclarator(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::VariableDeclarator); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Binding, BinField::Init })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Binding, BinField::Init })); MOZ_TRY_DECL(binding, parseBinding()); @@ -6419,191 +6800,167 @@ BinASTParser::parseInterfaceVariableDecl // `var pattern = bar` if (!init) { // Here, `init` is required. return raiseMissingField("VariableDeclarator (with non-trivial pattern)", BinField::Init); } MOZ_CRASH("Unimplemented: AssertedScope check for BindingPattern variable declaration"); TRY_VAR(result, factory_.newAssignment(ParseNodeKind::Assign, binding, init)); - }return result; + } + return result; } /* interface WhileStatement : Node { Expression test; Statement body; } */ -JS::Result<ParseNode*> -BinASTParser::parseWhileStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseWhileStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceWhileStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceWhileStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceWhileStatement(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::WhileStatement); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Test, BinField::Body })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Test, BinField::Body })); ParseContext::Statement stmt(parseContext_, StatementKind::WhileLoop); MOZ_TRY_DECL(test, parseExpression()); MOZ_TRY_DECL(body, parseStatement()); - TRY_DECL(result, factory_.newWhileStatement(start, test, body));return result; + TRY_DECL(result, factory_.newWhileStatement(start, test, body)); + return result; } /* interface WithStatement : Node { Expression object; Statement body; } */ -JS::Result<ParseNode*> -BinASTParser::parseWithStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseWithStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceWithStatement(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceWithStatement(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceWithStatement(const size_t start, const BinKind kind, const BinFields& fields) { MOZ_ASSERT(kind == BinKind::WithStatement); CheckRecursionLimit(cx_); - MOZ_TRY(checkFields(kind, fields, { BinField::Object, BinField::Body })); + MOZ_TRY(tokenizer_->checkFields(kind, fields, { BinField::Object, BinField::Body })); MOZ_TRY_DECL(object, parseExpression()); MOZ_TRY_DECL(body, parseStatement()); - TRY_DECL(result, factory_.newWithStatement(start, object, body));return result; + TRY_DECL(result, factory_.newWithStatement(start, object, body)); + return result; } /* interface YieldExpression : Node { Expression? expression; } */ -JS::Result<ParseNode*> -BinASTParser::parseYieldExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseYieldExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceYieldExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceYieldExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceYieldExpression(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (YieldExpression)"); } /* interface YieldStarExpression : Node { Expression expression; } */ -JS::Result<ParseNode*> -BinASTParser::parseYieldStarExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseYieldStarExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); const auto start = tokenizer_->offset(); MOZ_TRY_DECL(result, parseInterfaceYieldStarExpression(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceYieldStarExpression(const size_t start, const BinKind kind, const BinFields& fields) + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseInterfaceYieldStarExpression(const size_t start, const BinKind kind, const BinFields& fields) { return raiseError("FIXME: Not implemented yet (YieldStarExpression)"); } -/* - interface _Null : Node { - } -*/ -JS::Result<ParseNode*> -BinASTParser::parseNull() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - MOZ_TRY_DECL(result, parseInterfaceNull(start, kind, fields)); - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseInterfaceNull(const size_t start, const BinKind kind, const BinFields& fields) -{ - return raiseError("FIXME: Not implemented yet (Null)"); -} - - // ----- String enums (autogenerated, by lexicographical order) /* enum BinaryOperator { ",", "||", "&&", "|", @@ -6625,75 +6982,75 @@ enum BinaryOperator { "+", "-", "*", "/", "%", "**" }; */ -JS::Result<BinASTParser::BinaryOperator> -BinASTParser::parseBinaryOperator() -{ - // Unoptimized implementation. - Chars chars(cx_); - MOZ_TRY(readString(chars)); - - if (chars == ",") +template<typename Tok> JS::Result<typename BinASTParser<Tok>::BinaryOperator> +BinASTParser<Tok>::parseBinaryOperator() +{ + MOZ_TRY_DECL(variant, tokenizer_->readVariant()); + + switch (variant) { + case BinVariant::BinaryOperatorComma: return BinaryOperator::Comma; - if (chars == "||") + case BinVariant::BinaryOperatorLogicalOr: return BinaryOperator::LogicalOr; - if (chars == "&&") + case BinVariant::BinaryOperatorLogicalAnd: return BinaryOperator::LogicalAnd; - if (chars == "|") + case BinVariant::BinaryOperatorBitOr: return BinaryOperator::BitOr; - if (chars == "^") + case BinVariant::BinaryOperatorBitXor: return BinaryOperator::BitXor; - if (chars == "&") + case BinVariant::BinaryOperatorBitAnd: return BinaryOperator::BitAnd; - if (chars == "==") + case BinVariant::BinaryOperatorEq: return BinaryOperator::Eq; - if (chars == "!=") + case BinVariant::BinaryOperatorNeq: return BinaryOperator::Neq; - if (chars == "===") + case BinVariant::BinaryOperatorStrictEq: return BinaryOperator::StrictEq; - if (chars == "!==") + case BinVariant::BinaryOperatorStrictNeq: return BinaryOperator::StrictNeq; - if (chars == "<") + case BinVariant::BinaryOperatorLessThan: return BinaryOperator::LessThan; - if (chars == "<=") + case BinVariant::BinaryOperatorLeqThan: return BinaryOperator::LeqThan; - if (chars == ">") + case BinVariant::BinaryOperatorGreaterThan: return BinaryOperator::GreaterThan; - if (chars == ">=") + case BinVariant::BinaryOperatorGeqThan: return BinaryOperator::GeqThan; - if (chars == "in") + case BinVariant::BinaryOperatorIn: return BinaryOperator::In; - if (chars == "instanceof") + case BinVariant::BinaryOperatorInstanceof: return BinaryOperator::Instanceof; - if (chars == "<<") + case BinVariant::BinaryOperatorLsh: return BinaryOperator::Lsh; - if (chars == ">>") + case BinVariant::BinaryOperatorRsh: return BinaryOperator::Rsh; - if (chars == ">>>") + case BinVariant::BinaryOperatorUrsh: return BinaryOperator::Ursh; - if (chars == "+") + case BinVariant::BinaryOperatorOrUnaryOperatorPlus: return BinaryOperator::Plus; - if (chars == "-") + case BinVariant::BinaryOperatorOrUnaryOperatorMinus: return BinaryOperator::Minus; - if (chars == "*") + case BinVariant::BinaryOperatorMul: return BinaryOperator::Mul; - if (chars == "/") + case BinVariant::BinaryOperatorDiv: return BinaryOperator::Div; - if (chars == "%") + case BinVariant::BinaryOperatorMod: return BinaryOperator::Mod; - if (chars == "**") + case BinVariant::BinaryOperatorPow: return BinaryOperator::Pow; - - return raiseInvalidEnum("BinaryOperator", chars); + default: + return raiseInvalidVariant("BinaryOperator", variant); + } } /* enum CompoundAssignmentOperator { "+=", "-=", "*=", "/=", @@ -6702,624 +7059,631 @@ enum CompoundAssignmentOperator { "<<=", ">>=", ">>>=", "|=", "^=", "&=" }; */ -JS::Result<BinASTParser::CompoundAssignmentOperator> -BinASTParser::parseCompoundAssignmentOperator() -{ - // Unoptimized implementation. - Chars chars(cx_); - MOZ_TRY(readString(chars)); - - if (chars == "+=") +template<typename Tok> JS::Result<typename BinASTParser<Tok>::CompoundAssignmentOperator> +BinASTParser<Tok>::parseCompoundAssignmentOperator() +{ + MOZ_TRY_DECL(variant, tokenizer_->readVariant()); + + switch (variant) { + case BinVariant::CompoundAssignmentOperatorPlusAssign: return CompoundAssignmentOperator::PlusAssign; - if (chars == "-=") + case BinVariant::CompoundAssignmentOperatorMinusAssign: return CompoundAssignmentOperator::MinusAssign; - if (chars == "*=") + case BinVariant::CompoundAssignmentOperatorMulAssign: return CompoundAssignmentOperator::MulAssign; - if (chars == "/=") + case BinVariant::CompoundAssignmentOperatorDivAssign: return CompoundAssignmentOperator::DivAssign; - if (chars == "%=") + case BinVariant::CompoundAssignmentOperatorModAssign: return CompoundAssignmentOperator::ModAssign; - if (chars == "**=") + case BinVariant::CompoundAssignmentOperatorPowAssign: return CompoundAssignmentOperator::PowAssign; - if (chars == "<<=") + case BinVariant::CompoundAssignmentOperatorLshAssign: return CompoundAssignmentOperator::LshAssign; - if (chars == ">>=") + case BinVariant::CompoundAssignmentOperatorRshAssign: return CompoundAssignmentOperator::RshAssign; - if (chars == ">>>=") + case BinVariant::CompoundAssignmentOperatorUrshAssign: return CompoundAssignmentOperator::UrshAssign; - if (chars == "|=") + case BinVariant::CompoundAssignmentOperatorBitOrAssign: return CompoundAssignmentOperator::BitOrAssign; - if (chars == "^=") + case BinVariant::CompoundAssignmentOperatorBitXorAssign: return CompoundAssignmentOperator::BitXorAssign; - if (chars == "&=") + case BinVariant::CompoundAssignmentOperatorBitAndAssign: return CompoundAssignmentOperator::BitAndAssign; - - return raiseInvalidEnum("CompoundAssignmentOperator", chars); + default: + return raiseInvalidVariant("CompoundAssignmentOperator", variant); + } } /* enum UnaryOperator { "+", "-", "!", "~", "typeof", "void", "delete" }; */ -JS::Result<BinASTParser::UnaryOperator> -BinASTParser::parseUnaryOperator() -{ - // Unoptimized implementation. - Chars chars(cx_); - MOZ_TRY(readString(chars)); - - if (chars == "+") +template<typename Tok> JS::Result<typename BinASTParser<Tok>::UnaryOperator> +BinASTParser<Tok>::parseUnaryOperator() +{ + MOZ_TRY_DECL(variant, tokenizer_->readVariant()); + + switch (variant) { + case BinVariant::BinaryOperatorOrUnaryOperatorPlus: return UnaryOperator::Plus; - if (chars == "-") + case BinVariant::BinaryOperatorOrUnaryOperatorMinus: return UnaryOperator::Minus; - if (chars == "!") + case BinVariant::UnaryOperatorNot: return UnaryOperator::Not; - if (chars == "~") + case BinVariant::UnaryOperatorBitNot: return UnaryOperator::BitNot; - if (chars == "typeof") + case BinVariant::UnaryOperatorTypeof: return UnaryOperator::Typeof; - if (chars == "void") + case BinVariant::UnaryOperatorVoid: return UnaryOperator::Void; - if (chars == "delete") + case BinVariant::UnaryOperatorDelete: return UnaryOperator::Delete; - - return raiseInvalidEnum("UnaryOperator", chars); + default: + return raiseInvalidVariant("UnaryOperator", variant); + } } /* enum UpdateOperator { "++", "--" }; */ -JS::Result<BinASTParser::UpdateOperator> -BinASTParser::parseUpdateOperator() -{ - // Unoptimized implementation. - Chars chars(cx_); - MOZ_TRY(readString(chars)); - - if (chars == "++") +template<typename Tok> JS::Result<typename BinASTParser<Tok>::UpdateOperator> +BinASTParser<Tok>::parseUpdateOperator() +{ + MOZ_TRY_DECL(variant, tokenizer_->readVariant()); + + switch (variant) { + case BinVariant::UpdateOperatorIncr: return UpdateOperator::Incr; - if (chars == "--") + case BinVariant::UpdateOperatorDecr: return UpdateOperator::Decr; - - return raiseInvalidEnum("UpdateOperator", chars); + default: + return raiseInvalidVariant("UpdateOperator", variant); + } } /* enum VariableDeclarationKind { "var", "let", "const" }; */ -JS::Result<BinASTParser::VariableDeclarationKind> -BinASTParser::parseVariableDeclarationKind() -{ - // Unoptimized implementation. - Chars chars(cx_); - MOZ_TRY(readString(chars)); - - if (chars == "var") +template<typename Tok> JS::Result<typename BinASTParser<Tok>::VariableDeclarationKind> +BinASTParser<Tok>::parseVariableDeclarationKind() +{ + MOZ_TRY_DECL(variant, tokenizer_->readVariant()); + + switch (variant) { + case BinVariant::VariableDeclarationKindVar: return VariableDeclarationKind::Var; - if (chars == "let") + case BinVariant::VariableDeclarationKindLet: return VariableDeclarationKind::Let; - if (chars == "const") + case BinVariant::VariableDeclarationKindConst: return VariableDeclarationKind::Const; - - return raiseInvalidEnum("VariableDeclarationKind", chars); + default: + return raiseInvalidVariant("VariableDeclarationKind", variant); + } } // ----- Lists (autogenerated, by lexicographical order) -JS::Result<ParseNode*> -BinASTParser::parseArguments() +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseArguments() { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, guard)); TRY_DECL(result, factory_.newList(ParseNodeKind::ParamsBody, tokenizer_->pos(start))); for (uint32_t i = 0; i < length; ++i) { MOZ_TRY_DECL(item, parseSpreadElementOrExpression()); factory_.addList(/* list = */ result, /* child = */ item); } - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseListOfAssignmentTargetOrAssignmentTargetWithInitializer() + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfAssignmentTargetOrAssignmentTargetWithInitializer() { return raiseError("FIXME: Not implemented yet (ListOfAssignmentTargetOrAssignmentTargetWithInitializer)"); } -JS::Result<ParseNode*> -BinASTParser::parseListOfAssignmentTargetProperty() +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfAssignmentTargetProperty() { return raiseError("FIXME: Not implemented yet (ListOfAssignmentTargetProperty)"); } -JS::Result<ParseNode*> -BinASTParser::parseListOfBindingProperty() +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfBindingProperty() { return raiseError("FIXME: Not implemented yet (ListOfBindingProperty)"); } -JS::Result<ParseNode*> -BinASTParser::parseListOfClassElement() +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfClassElement() { return raiseError("FIXME: Not implemented yet (ListOfClassElement)"); } -JS::Result<ParseNode*> -BinASTParser::parseListOfDirective() +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfDirective() { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, guard)); TRY_DECL(result, factory_.newStatementList(tokenizer_->pos(start))); for (uint32_t i = 0; i < length; ++i) { MOZ_TRY_DECL(item, parseDirective()); factory_.addStatementToList(result, item); } - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseListOfExportFromSpecifier() + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfExportFromSpecifier() { return raiseError("FIXME: Not implemented yet (ListOfExportFromSpecifier)"); } -JS::Result<ParseNode*> -BinASTParser::parseListOfExportLocalSpecifier() +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfExportLocalSpecifier() { return raiseError("FIXME: Not implemented yet (ListOfExportLocalSpecifier)"); } -JS::Result<ParseNode*> -BinASTParser::parseListOfExpressionOrTemplateElement() +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfExpressionOrTemplateElement() { return raiseError("FIXME: Not implemented yet (ListOfExpressionOrTemplateElement)"); } -JS::Result<ParseNode*> -BinASTParser::parseListOfIdentifierName() +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfIdentifierName() { return raiseError("FIXME: Not implemented yet (ListOfIdentifierName)"); } -JS::Result<ParseNode*> -BinASTParser::parseListOfImportDeclarationOrExportDeclarationOrStatement() +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfImportDeclarationOrExportDeclarationOrStatement() { return raiseError("FIXME: Not implemented yet (ListOfImportDeclarationOrExportDeclarationOrStatement)"); } -JS::Result<ParseNode*> -BinASTParser::parseListOfImportSpecifier() +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfImportSpecifier() { return raiseError("FIXME: Not implemented yet (ListOfImportSpecifier)"); } -JS::Result<ParseNode*> -BinASTParser::parseListOfObjectProperty() +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfObjectProperty() { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, guard)); TRY_DECL(result, factory_.newObjectLiteral(start)); for (uint32_t i = 0; i < length; ++i) { MOZ_TRY_DECL(item, parseObjectProperty()); result->appendWithoutOrderAssumption(item); } - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseListOfOptionalBindingOrBindingWithInitializer() + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfOptionalBindingOrBindingWithInitializer() { return raiseError("FIXME: Not implemented yet (ListOfOptionalBindingOrBindingWithInitializer)"); } -JS::Result<ParseNode*> -BinASTParser::parseListOfOptionalSpreadElementOrExpression() +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfOptionalSpreadElementOrExpression() { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, guard)); TRY_DECL(result, factory_.newArrayLiteral(start)); for (uint32_t i = 0; i < length; ++i) { MOZ_TRY_DECL(item, parseOptionalSpreadElementOrExpression()); if (item) factory_.addArrayElement(result, item); // Infallible. else TRY(factory_.addElision(result, tokenizer_->pos(start))); } - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseListOfParameter() + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfParameter() { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, guard)); ParseNode* result = new_<ListNode>(ParseNodeKind::ParamsBody, tokenizer_->pos(start)); for (uint32_t i = 0; i < length; ++i) { MOZ_TRY_DECL(item, parseParameter()); factory_.addList(/* list = */ result, /* item = */ item); } - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseListOfStatement() + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfStatement() { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, guard)); TRY_DECL(result, factory_.newStatementList(tokenizer_->pos(start))); for (uint32_t i = 0; i < length; ++i) { MOZ_TRY_DECL(item, parseStatement()); factory_.addStatementToList(result, item); } - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseListOfSwitchCase() + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfSwitchCase() { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, guard)); TRY_DECL(result, factory_.newStatementList(tokenizer_->pos(start))); for (uint32_t i = 0; i < length; ++i) { MOZ_TRY_DECL(item, parseSwitchCase()); factory_.addCaseStatementToList(result, item); } - TRY(guard.done()); - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseListOfVariableDeclarator() + MOZ_TRY(guard.done()); + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseListOfVariableDeclarator() { uint32_t length; AutoList guard(*tokenizer_); const auto start = tokenizer_->offset(); - TRY(tokenizer_->enterList(length, guard)); + MOZ_TRY(tokenizer_->enterList(length, guard)); TRY_DECL(result, factory_.newDeclarationList(ParseNodeKind::Const /*Placeholder*/, tokenizer_->pos(start))); for (uint32_t i = 0; i < length; ++i) { MOZ_TRY_DECL(item, parseVariableDeclarator()); result->appendWithoutOrderAssumption(item); } - TRY(guard.done()); + MOZ_TRY(guard.done()); return result; } // ----- Default values (by lexicographical order) -JS::Result<Ok> -BinASTParser::parseOptionalAssertedBlockScope() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<Ok> +BinASTParser<Tok>::parseOptionalAssertedBlockScope() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); Ok result; if (kind == BinKind::_Null) { result = Ok(); } else { const auto start = tokenizer_->offset(); MOZ_TRY_VAR(result, parseInterfaceAssertedBlockScope(start, kind, fields)); } - TRY(guard.done()); - - return result; -} - -JS::Result<Ok> -BinASTParser::parseOptionalAssertedParameterScope() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<Ok> +BinASTParser<Tok>::parseOptionalAssertedParameterScope() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); Ok result; if (kind == BinKind::_Null) { result = Ok(); } else { const auto start = tokenizer_->offset(); MOZ_TRY_VAR(result, parseInterfaceAssertedParameterScope(start, kind, fields)); } - TRY(guard.done()); - - return result; -} - -JS::Result<Ok> -BinASTParser::parseOptionalAssertedVarScope() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<Ok> +BinASTParser<Tok>::parseOptionalAssertedVarScope() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); Ok result; if (kind == BinKind::_Null) { result = Ok(); } else { const auto start = tokenizer_->offset(); MOZ_TRY_VAR(result, parseInterfaceAssertedVarScope(start, kind, fields)); } - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseOptionalAssignmentTarget() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseOptionalAssignmentTarget() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); ParseNode* result; if (kind == BinKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); MOZ_TRY_VAR(result, parseSumAssignmentTarget(start, kind, fields)); } - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseOptionalBinding() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseOptionalBinding() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); ParseNode* result; if (kind == BinKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); MOZ_TRY_VAR(result, parseSumBinding(start, kind, fields)); } - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseOptionalBindingIdentifier() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseOptionalBindingIdentifier() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); ParseNode* result; if (kind == BinKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); MOZ_TRY_VAR(result, parseInterfaceBindingIdentifier(start, kind, fields)); } - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseOptionalBindingOrBindingWithInitializer() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseOptionalBindingOrBindingWithInitializer() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); ParseNode* result; if (kind == BinKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); MOZ_TRY_VAR(result, parseSumBindingOrBindingWithInitializer(start, kind, fields)); } - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseOptionalCatchClause() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseOptionalCatchClause() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); ParseNode* result; if (kind == BinKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); MOZ_TRY_VAR(result, parseInterfaceCatchClause(start, kind, fields)); } - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseOptionalExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseOptionalExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); ParseNode* result; if (kind == BinKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); MOZ_TRY_VAR(result, parseSumExpression(start, kind, fields)); } - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseOptionalIdentifierName() -{ - RootedAtom string(cx_); - MOZ_TRY(readMaybeString(&string)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseOptionalIdentifierName() +{ + MOZ_TRY_DECL(result, tokenizer_->readMaybeAtom()); return raiseError("FIXME: Not implemented yet (OptionalIdentifierName)"); } -JS::Result<ParseNode*> -BinASTParser::parseOptionalLabel() -{ - RootedAtom string(cx_); - MOZ_TRY(readMaybeString(&string)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseOptionalLabel() +{ + MOZ_TRY_DECL(result, tokenizer_->readMaybeAtom()); return raiseError("FIXME: Not implemented yet (OptionalLabel)"); } -JS::Result<ParseNode*> -BinASTParser::parseOptionalSpreadElementOrExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseOptionalSpreadElementOrExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); ParseNode* result; if (kind == BinKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); MOZ_TRY_VAR(result, parseSumSpreadElementOrExpression(start, kind, fields)); } - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseOptionalStatement() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseOptionalStatement() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); ParseNode* result; if (kind == BinKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); MOZ_TRY_VAR(result, parseSumStatement(start, kind, fields)); } - TRY(guard.done()); - - return result; -} - -JS::Result<ParseNode*> -BinASTParser::parseOptionalVariableDeclarationOrExpression() -{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); + MOZ_TRY(guard.done()); + + return result; +} + +template<typename Tok> JS::Result<ParseNode*> +BinASTParser<Tok>::parseOptionalVariableDeclarationOrExpression() +{ + BinKind kind; + BinFields fields(cx_); + AutoTaggedTuple guard(*tokenizer_); + + MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); ParseNode* result; if (kind == BinKind::_Null) { result = nullptr; } else { const auto start = tokenizer_->offset(); MOZ_TRY_VAR(result, parseSumVariableDeclarationOrExpression(start, kind, fields)); } - TRY(guard.done()); - - return result; -} - - + MOZ_TRY(guard.done()); + + return result; +} + + + +// Force class instantiation. +// This ensures that the symbols are built, without having to export all our +// code (and its baggage of #include and macros) in the header. +template class BinASTParser<BinTokenReaderMultipart>; +template class BinASTParser<BinTokenReaderTester>; + +} // namespace frontend +} // namespace js #undef TRY #undef TRY_VAR #undef TRY_DECL +#undef TRY_EMPL +#undef MOZ_TRY_EMPLACE #undef MOZ_TRY_DECL -} // namespace frontend -} // namespace js
new file mode 100644 --- /dev/null +++ b/js/src/frontend/BinSource-macros.h @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef frontend_BinSource_macros_h +#define frontend_BinSource_macros_h + + +// Evaluate an expression EXPR, checking that the result is not falsy. +// +// Throw `cx->alreadyReportedError()` if it returns 0/nullptr. +#define BINJS_TRY(EXPR) \ + do { \ + if (!EXPR) \ + return cx_->alreadyReportedError(); \ + } while(false) + + +// Evaluate an expression EXPR, checking that the result is not falsy. +// In case of success, assign the result to VAR. +// +// Throw `cx->alreadyReportedError()` if it returns 0/nullptr. +#define BINJS_TRY_VAR(VAR, EXPR) \ + do { \ + VAR = EXPR; \ + if (!VAR) \ + return cx_->alreadyReportedError(); \ + } while (false) + +// Evaluate an expression EXPR, checking that the result is not falsy. +// In case of success, assign the result to a new variable VAR. +// +// Throw `cx->alreadyReportedError()` if it returns 0/nullptr. +#define BINJS_TRY_DECL(VAR, EXPR) \ + auto VAR = EXPR; \ + if (!VAR) \ + return cx_->alreadyReportedError(); + +#define BINJS_TRY_EMPL(VAR, EXPR) \ + do { \ + auto _tryEmplResult = EXPR; \ + if (!_tryEmplResult) \ + return cx_->alreadyReportedError(); \ + VAR.emplace(_tryEmplResult.unwrap()); \ + } while (false) + +#define BINJS_MOZ_TRY_EMPLACE(VAR, EXPR) \ + do { \ + auto _tryEmplResult = EXPR; \ + if (_tryEmplResult.isErr()) \ + return ::mozilla::Err(_tryEmplResult.unwrapErr()); \ + VAR.emplace(_tryEmplResult.unwrap()); \ + } while (false) + +// Evaluate an expression EXPR, checking that the result is a success. +// In case of success, unwrap and assign the result to a new variable VAR. +// +// In case of error, propagate the error. +#define BINJS_MOZ_TRY_DECL(VAR, EXPR) \ + auto _##VAR = EXPR; \ + if (_##VAR.isErr()) \ + return ::mozilla::Err(_##VAR.unwrapErr()); \ + auto VAR = _##VAR.unwrap(); + +#endif // frontend_BinSource_macros_h
--- a/js/src/frontend/BinToken.h +++ b/js/src/frontend/BinToken.h @@ -56,292 +56,377 @@ namespace frontend { * #define WITH_KIND(CPP_NAME, SPEC_NAME) ... * FOR_EACH_BIN_KIND(WITH_KIND) * ``` * * * (sorted by alphabetical order) */ #define FOR_EACH_BIN_KIND(F) \ - F(Arguments, Arguments) \ - F(ArrayAssignmentTarget, ArrayAssignmentTarget) \ - F(ArrayBinding, ArrayBinding) \ - F(ArrayExpression, ArrayExpression) \ - F(ArrowExpression, ArrowExpression) \ - F(AssertedBlockScope, AssertedBlockScope) \ - F(AssertedParameterScope, AssertedParameterScope) \ - F(AssertedVarScope, AssertedVarScope) \ - F(AssignmentExpression, AssignmentExpression) \ - F(AssignmentTarget, AssignmentTarget) \ - F(AssignmentTargetIdentifier, AssignmentTargetIdentifier) \ - F(AssignmentTargetOrAssignmentTargetWithInitializer, AssignmentTargetOrAssignmentTargetWithInitializer) \ - F(AssignmentTargetPattern, AssignmentTargetPattern) \ - F(AssignmentTargetProperty, AssignmentTargetProperty) \ - F(AssignmentTargetPropertyIdentifier, AssignmentTargetPropertyIdentifier) \ - F(AssignmentTargetPropertyProperty, AssignmentTargetPropertyProperty) \ - F(AssignmentTargetWithInitializer, AssignmentTargetWithInitializer) \ - F(AwaitExpression, AwaitExpression) \ - F(BinaryExpression, BinaryExpression) \ - F(BinaryOperator, BinaryOperator) \ - F(Binding, Binding) \ - F(BindingIdentifier, BindingIdentifier) \ - F(BindingOrBindingWithInitializer, BindingOrBindingWithInitializer) \ - F(BindingPattern, BindingPattern) \ - F(BindingProperty, BindingProperty) \ - F(BindingPropertyIdentifier, BindingPropertyIdentifier) \ - F(BindingPropertyProperty, BindingPropertyProperty) \ - F(BindingWithInitializer, BindingWithInitializer) \ - F(Block, Block) \ - F(BreakStatement, BreakStatement) \ - F(CallExpression, CallExpression) \ - F(CatchClause, CatchClause) \ - F(ClassDeclaration, ClassDeclaration) \ - F(ClassElement, ClassElement) \ - F(ClassExpression, ClassExpression) \ - F(CompoundAssignmentExpression, CompoundAssignmentExpression) \ - F(CompoundAssignmentOperator, CompoundAssignmentOperator) \ - F(ComputedMemberAssignmentTarget, ComputedMemberAssignmentTarget) \ - F(ComputedMemberExpression, ComputedMemberExpression) \ - F(ComputedPropertyName, ComputedPropertyName) \ - F(ConditionalExpression, ConditionalExpression) \ - F(ContinueStatement, ContinueStatement) \ - F(DataProperty, DataProperty) \ - F(DebuggerStatement, DebuggerStatement) \ - F(Directive, Directive) \ - F(DoWhileStatement, DoWhileStatement) \ - F(EmptyStatement, EmptyStatement) \ - F(Export, Export) \ - F(ExportAllFrom, ExportAllFrom) \ - F(ExportDeclaration, ExportDeclaration) \ - F(ExportDefault, ExportDefault) \ - F(ExportFrom, ExportFrom) \ - F(ExportFromSpecifier, ExportFromSpecifier) \ - F(ExportLocalSpecifier, ExportLocalSpecifier) \ - F(ExportLocals, ExportLocals) \ - F(Expression, Expression) \ - F(ExpressionOrSuper, ExpressionOrSuper) \ - F(ExpressionOrTemplateElement, ExpressionOrTemplateElement) \ - F(ExpressionStatement, ExpressionStatement) \ - F(ForInOfBinding, ForInOfBinding) \ - F(ForInOfBindingOrAssignmentTarget, ForInOfBindingOrAssignmentTarget) \ - F(ForInStatement, ForInStatement) \ - F(ForOfStatement, ForOfStatement) \ - F(ForStatement, ForStatement) \ - F(FormalParameters, FormalParameters) \ - F(FunctionBody, FunctionBody) \ - F(FunctionBodyOrExpression, FunctionBodyOrExpression) \ - F(FunctionDeclaration, FunctionDeclaration) \ - F(FunctionDeclarationOrClassDeclarationOrExpression, FunctionDeclarationOrClassDeclarationOrExpression) \ - F(FunctionDeclarationOrClassDeclarationOrVariableDeclaration, FunctionDeclarationOrClassDeclarationOrVariableDeclaration) \ - F(FunctionExpression, FunctionExpression) \ - F(Getter, Getter) \ - F(Identifier, Identifier) \ - F(IdentifierExpression, IdentifierExpression) \ - F(IdentifierName, IdentifierName) \ - F(IfStatement, IfStatement) \ - F(Import, Import) \ - F(ImportDeclaration, ImportDeclaration) \ - F(ImportDeclarationOrExportDeclarationOrStatement, ImportDeclarationOrExportDeclarationOrStatement) \ - F(ImportNamespace, ImportNamespace) \ - F(ImportSpecifier, ImportSpecifier) \ - F(IterationStatement, IterationStatement) \ - F(Label, Label) \ - F(LabelledStatement, LabelledStatement) \ - F(ListOfAssignmentTargetOrAssignmentTargetWithInitializer, ListOfAssignmentTargetOrAssignmentTargetWithInitializer) \ - F(ListOfAssignmentTargetProperty, ListOfAssignmentTargetProperty) \ - F(ListOfBindingProperty, ListOfBindingProperty) \ - F(ListOfClassElement, ListOfClassElement) \ - F(ListOfDirective, ListOfDirective) \ - F(ListOfExportFromSpecifier, ListOfExportFromSpecifier) \ - F(ListOfExportLocalSpecifier, ListOfExportLocalSpecifier) \ - F(ListOfExpressionOrTemplateElement, ListOfExpressionOrTemplateElement) \ - F(ListOfIdentifierName, ListOfIdentifierName) \ - F(ListOfImportDeclarationOrExportDeclarationOrStatement, ListOfImportDeclarationOrExportDeclarationOrStatement) \ - F(ListOfImportSpecifier, ListOfImportSpecifier) \ - F(ListOfObjectProperty, ListOfObjectProperty) \ - F(ListOfOptionalBindingOrBindingWithInitializer, ListOfOptionalBindingOrBindingWithInitializer) \ - F(ListOfOptionalSpreadElementOrExpression, ListOfOptionalSpreadElementOrExpression) \ - F(ListOfParameter, ListOfParameter) \ - F(ListOfStatement, ListOfStatement) \ - F(ListOfSwitchCase, ListOfSwitchCase) \ - F(ListOfVariableDeclarator, ListOfVariableDeclarator) \ - F(Literal, Literal) \ - F(LiteralBooleanExpression, LiteralBooleanExpression) \ - F(LiteralInfinityExpression, LiteralInfinityExpression) \ - F(LiteralNullExpression, LiteralNullExpression) \ - F(LiteralNumericExpression, LiteralNumericExpression) \ - F(LiteralPropertyName, LiteralPropertyName) \ - F(LiteralRegExpExpression, LiteralRegExpExpression) \ - F(LiteralStringExpression, LiteralStringExpression) \ - F(Method, Method) \ - F(MethodDefinition, MethodDefinition) \ - F(Module, Module) \ - F(NewExpression, NewExpression) \ - F(NewTargetExpression, NewTargetExpression) \ - F(ObjectAssignmentTarget, ObjectAssignmentTarget) \ - F(ObjectBinding, ObjectBinding) \ - F(ObjectExpression, ObjectExpression) \ - F(ObjectProperty, ObjectProperty) \ - F(OptionalAssertedBlockScope, OptionalAssertedBlockScope) \ - F(OptionalAssertedParameterScope, OptionalAssertedParameterScope) \ - F(OptionalAssertedVarScope, OptionalAssertedVarScope) \ - F(OptionalAssignmentTarget, OptionalAssignmentTarget) \ - F(OptionalBinding, OptionalBinding) \ - F(OptionalBindingIdentifier, OptionalBindingIdentifier) \ - F(OptionalBindingOrBindingWithInitializer, OptionalBindingOrBindingWithInitializer) \ - F(OptionalCatchClause, OptionalCatchClause) \ - F(OptionalExpression, OptionalExpression) \ - F(OptionalIdentifierName, OptionalIdentifierName) \ - F(OptionalLabel, OptionalLabel) \ - F(OptionalSpreadElementOrExpression, OptionalSpreadElementOrExpression) \ - F(OptionalStatement, OptionalStatement) \ - F(OptionalVariableDeclarationOrExpression, OptionalVariableDeclarationOrExpression) \ - F(Parameter, Parameter) \ - F(Program, Program) \ - F(PropertyName, PropertyName) \ - F(ReturnStatement, ReturnStatement) \ - F(Script, Script) \ - F(Setter, Setter) \ - F(ShorthandProperty, ShorthandProperty) \ - F(SimpleAssignmentTarget, SimpleAssignmentTarget) \ - F(SpreadElement, SpreadElement) \ - F(SpreadElementOrExpression, SpreadElementOrExpression) \ - F(Statement, Statement) \ - F(StaticMemberAssignmentTarget, StaticMemberAssignmentTarget) \ - F(StaticMemberExpression, StaticMemberExpression) \ - F(Super, Super) \ - F(SwitchCase, SwitchCase) \ - F(SwitchDefault, SwitchDefault) \ - F(SwitchStatement, SwitchStatement) \ - F(SwitchStatementWithDefault, SwitchStatementWithDefault) \ - F(TemplateElement, TemplateElement) \ - F(TemplateExpression, TemplateExpression) \ - F(ThisExpression, ThisExpression) \ - F(ThrowStatement, ThrowStatement) \ - F(TryCatchStatement, TryCatchStatement) \ - F(TryFinallyStatement, TryFinallyStatement) \ - F(UnaryExpression, UnaryExpression) \ - F(UnaryOperator, UnaryOperator) \ - F(UpdateExpression, UpdateExpression) \ - F(UpdateOperator, UpdateOperator) \ - F(VariableDeclaration, VariableDeclaration) \ - F(VariableDeclarationKind, VariableDeclarationKind) \ - F(VariableDeclarationOrExpression, VariableDeclarationOrExpression) \ - F(VariableDeclarator, VariableDeclarator) \ - F(WhileStatement, WhileStatement) \ - F(WithStatement, WithStatement) \ - F(YieldExpression, YieldExpression) \ - F(YieldStarExpression, YieldStarExpression) \ - F(_Null, _Null) \ - F(string, string) - + F(_Null, "") \ + F(Arguments, "Arguments") \ + F(ArrayAssignmentTarget, "ArrayAssignmentTarget") \ + F(ArrayBinding, "ArrayBinding") \ + F(ArrayExpression, "ArrayExpression") \ + F(ArrowExpression, "ArrowExpression") \ + F(AssertedBlockScope, "AssertedBlockScope") \ + F(AssertedParameterScope, "AssertedParameterScope") \ + F(AssertedVarScope, "AssertedVarScope") \ + F(AssignmentExpression, "AssignmentExpression") \ + F(AssignmentTarget, "AssignmentTarget") \ + F(AssignmentTargetIdentifier, "AssignmentTargetIdentifier") \ + F(AssignmentTargetOrAssignmentTargetWithInitializer, "AssignmentTargetOrAssignmentTargetWithInitializer") \ + F(AssignmentTargetPattern, "AssignmentTargetPattern") \ + F(AssignmentTargetProperty, "AssignmentTargetProperty") \ + F(AssignmentTargetPropertyIdentifier, "AssignmentTargetPropertyIdentifier") \ + F(AssignmentTargetPropertyProperty, "AssignmentTargetPropertyProperty") \ + F(AssignmentTargetWithInitializer, "AssignmentTargetWithInitializer") \ + F(AwaitExpression, "AwaitExpression") \ + F(BinaryExpression, "BinaryExpression") \ + F(BinaryOperator, "BinaryOperator") \ + F(Binding, "Binding") \ + F(BindingIdentifier, "BindingIdentifier") \ + F(BindingOrBindingWithInitializer, "BindingOrBindingWithInitializer") \ + F(BindingPattern, "BindingPattern") \ + F(BindingProperty, "BindingProperty") \ + F(BindingPropertyIdentifier, "BindingPropertyIdentifier") \ + F(BindingPropertyProperty, "BindingPropertyProperty") \ + F(BindingWithInitializer, "BindingWithInitializer") \ + F(Block, "Block") \ + F(BreakStatement, "BreakStatement") \ + F(CallExpression, "CallExpression") \ + F(CatchClause, "CatchClause") \ + F(ClassDeclaration, "ClassDeclaration") \ + F(ClassElement, "ClassElement") \ + F(ClassExpression, "ClassExpression") \ + F(CompoundAssignmentExpression, "CompoundAssignmentExpression") \ + F(CompoundAssignmentOperator, "CompoundAssignmentOperator") \ + F(ComputedMemberAssignmentTarget, "ComputedMemberAssignmentTarget") \ + F(ComputedMemberExpression, "ComputedMemberExpression") \ + F(ComputedPropertyName, "ComputedPropertyName") \ + F(ConditionalExpression, "ConditionalExpression") \ + F(ContinueStatement, "ContinueStatement") \ + F(DataProperty, "DataProperty") \ + F(DebuggerStatement, "DebuggerStatement") \ + F(Directive, "Directive") \ + F(DoWhileStatement, "DoWhileStatement") \ + F(EagerArrowExpression, "EagerArrowExpression") \ + F(EagerFunctionDeclaration, "EagerFunctionDeclaration") \ + F(EagerFunctionExpression, "EagerFunctionExpression") \ + F(EagerGetter, "EagerGetter") \ + F(EagerMethod, "EagerMethod") \ + F(EagerSetter, "EagerSetter") \ + F(EmptyStatement, "EmptyStatement") \ + F(Export, "Export") \ + F(ExportAllFrom, "ExportAllFrom") \ + F(ExportDeclaration, "ExportDeclaration") \ + F(ExportDefault, "ExportDefault") \ + F(ExportFrom, "ExportFrom") \ + F(ExportFromSpecifier, "ExportFromSpecifier") \ + F(ExportLocalSpecifier, "ExportLocalSpecifier") \ + F(ExportLocals, "ExportLocals") \ + F(Expression, "Expression") \ + F(ExpressionOrSuper, "ExpressionOrSuper") \ + F(ExpressionOrTemplateElement, "ExpressionOrTemplateElement") \ + F(ExpressionStatement, "ExpressionStatement") \ + F(ForInOfBinding, "ForInOfBinding") \ + F(ForInOfBindingOrAssignmentTarget, "ForInOfBindingOrAssignmentTarget") \ + F(ForInStatement, "ForInStatement") \ + F(ForOfStatement, "ForOfStatement") \ + F(ForStatement, "ForStatement") \ + F(FormalParameters, "FormalParameters") \ + F(FunctionBody, "FunctionBody") \ + F(FunctionBodyOrExpression, "FunctionBodyOrExpression") \ + F(FunctionDeclaration, "FunctionDeclaration") \ + F(FunctionDeclarationOrClassDeclarationOrExpression, "FunctionDeclarationOrClassDeclarationOrExpression") \ + F(FunctionDeclarationOrClassDeclarationOrVariableDeclaration, "FunctionDeclarationOrClassDeclarationOrVariableDeclaration") \ + F(FunctionExpression, "FunctionExpression") \ + F(Getter, "Getter") \ + F(Identifier, "Identifier") \ + F(IdentifierExpression, "IdentifierExpression") \ + F(IdentifierName, "IdentifierName") \ + F(IfStatement, "IfStatement") \ + F(Import, "Import") \ + F(ImportDeclaration, "ImportDeclaration") \ + F(ImportDeclarationOrExportDeclarationOrStatement, "ImportDeclarationOrExportDeclarationOrStatement") \ + F(ImportNamespace, "ImportNamespace") \ + F(ImportSpecifier, "ImportSpecifier") \ + F(IterationStatement, "IterationStatement") \ + F(Label, "Label") \ + F(LabelledStatement, "LabelledStatement") \ + F(ListOfAssignmentTargetOrAssignmentTargetWithInitializer, "ListOfAssignmentTargetOrAssignmentTargetWithInitializer") \ + F(ListOfAssignmentTargetProperty, "ListOfAssignmentTargetProperty") \ + F(ListOfBindingProperty, "ListOfBindingProperty") \ + F(ListOfClassElement, "ListOfClassElement") \ + F(ListOfDirective, "ListOfDirective") \ + F(ListOfExportFromSpecifier, "ListOfExportFromSpecifier") \ + F(ListOfExportLocalSpecifier, "ListOfExportLocalSpecifier") \ + F(ListOfExpressionOrTemplateElement, "ListOfExpressionOrTemplateElement") \ + F(ListOfIdentifierName, "ListOfIdentifierName") \ + F(ListOfImportDeclarationOrExportDeclarationOrStatement, "ListOfImportDeclarationOrExportDeclarationOrStatement") \ + F(ListOfImportSpecifier, "ListOfImportSpecifier") \ + F(ListOfObjectProperty, "ListOfObjectProperty") \ + F(ListOfOptionalBindingOrBindingWithInitializer, "ListOfOptionalBindingOrBindingWithInitializer") \ + F(ListOfOptionalSpreadElementOrExpression, "ListOfOptionalSpreadElementOrExpression") \ + F(ListOfParameter, "ListOfParameter") \ + F(ListOfStatement, "ListOfStatement") \ + F(ListOfSwitchCase, "ListOfSwitchCase") \ + F(ListOfVariableDeclarator, "ListOfVariableDeclarator") \ + F(Literal, "Literal") \ + F(LiteralBooleanExpression, "LiteralBooleanExpression") \ + F(LiteralInfinityExpression, "LiteralInfinityExpression") \ + F(LiteralNullExpression, "LiteralNullExpression") \ + F(LiteralNumericExpression, "LiteralNumericExpression") \ + F(LiteralPropertyName, "LiteralPropertyName") \ + F(LiteralRegExpExpression, "LiteralRegExpExpression") \ + F(LiteralStringExpression, "LiteralStringExpression") \ + F(Method, "Method") \ + F(MethodDefinition, "MethodDefinition") \ + F(Module, "Module") \ + F(NewExpression, "NewExpression") \ + F(NewTargetExpression, "NewTargetExpression") \ + F(ObjectAssignmentTarget, "ObjectAssignmentTarget") \ + F(ObjectBinding, "ObjectBinding") \ + F(ObjectExpression, "ObjectExpression") \ + F(ObjectProperty, "ObjectProperty") \ + F(OptionalAssertedBlockScope, "OptionalAssertedBlockScope") \ + F(OptionalAssertedParameterScope, "OptionalAssertedParameterScope") \ + F(OptionalAssertedVarScope, "OptionalAssertedVarScope") \ + F(OptionalAssignmentTarget, "OptionalAssignmentTarget") \ + F(OptionalBinding, "OptionalBinding") \ + F(OptionalBindingIdentifier, "OptionalBindingIdentifier") \ + F(OptionalBindingOrBindingWithInitializer, "OptionalBindingOrBindingWithInitializer") \ + F(OptionalCatchClause, "OptionalCatchClause") \ + F(OptionalExpression, "OptionalExpression") \ + F(OptionalIdentifierName, "OptionalIdentifierName") \ + F(OptionalLabel, "OptionalLabel") \ + F(OptionalSpreadElementOrExpression, "OptionalSpreadElementOrExpression") \ + F(OptionalStatement, "OptionalStatement") \ + F(OptionalVariableDeclarationOrExpression, "OptionalVariableDeclarationOrExpression") \ + F(Parameter, "Parameter") \ + F(Program, "Program") \ + F(PropertyName, "PropertyName") \ + F(ReturnStatement, "ReturnStatement") \ + F(Script, "Script") \ + F(Setter, "Setter") \ + F(ShorthandProperty, "ShorthandProperty") \ + F(SimpleAssignmentTarget, "SimpleAssignmentTarget") \ + F(SkippableArrowExpression, "SkippableArrowExpression") \ + F(SkippableFunctionDeclaration, "SkippableFunctionDeclaration") \ + F(SkippableFunctionExpression, "SkippableFunctionExpression") \ + F(SkippableGetter, "SkippableGetter") \ + F(SkippableMethod, "SkippableMethod") \ + F(SkippableSetter, "SkippableSetter") \ + F(SpreadElement, "SpreadElement") \ + F(SpreadElementOrExpression, "SpreadElementOrExpression") \ + F(Statement, "Statement") \ + F(StaticMemberAssignmentTarget, "StaticMemberAssignmentTarget") \ + F(StaticMemberExpression, "StaticMemberExpression") \ + F(Super, "Super") \ + F(SwitchCase, "SwitchCase") \ + F(SwitchDefault, "SwitchDefault") \ + F(SwitchStatement, "SwitchStatement") \ + F(SwitchStatementWithDefault, "SwitchStatementWithDefault") \ + F(TemplateElement, "TemplateElement") \ + F(TemplateExpression, "TemplateExpression") \ + F(ThisExpression, "ThisExpression") \ + F(ThrowStatement, "ThrowStatement") \ + F(TryCatchStatement, "TryCatchStatement") \ + F(TryFinallyStatement, "TryFinallyStatement") \ + F(UnaryExpression, "UnaryExpression") \ + F(UnaryOperator, "UnaryOperator") \