Bug 1508063 - Part 5: Move non-auto-generated part of BinASTParser into BinASTParserPerTokenizer. r=Yoric

This commit is contained in:
Tooru Fujisawa 2018-11-29 01:03:46 +09:00
parent f5534517cb
commit 05a6adee89
11 changed files with 617 additions and 335 deletions

View File

@ -113,7 +113,6 @@ included_inclnames_to_ignore = set([
# ignore #includes of them when checking #include ordering.
oddly_ordered_inclnames = set([
'ctypes/typedefs.h', # Included multiple times in the body of ctypes/CTypes.h
'frontend/BinASTParser.h', # Included in the body of frontend/BinSource.h
# Included in the body of frontend/TokenStream.h
'frontend/ReservedWordsGenerated.h',
'gc/StatsPhasesGenerated.h', # Included in the body of gc/Statistics.h

View File

@ -9,6 +9,8 @@
// To generate this file, see the documentation in
// js/src/frontend/binsource/README.md.
#include "frontend/BinASTParser.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Casting.h"
#include "mozilla/Maybe.h"
@ -16,7 +18,6 @@
#include "mozilla/PodOperations.h"
#include "mozilla/Vector.h"
#include "frontend/BinASTParserPerTokenizer.h"
#include "frontend/BinSource-macros.h"
#include "frontend/BinTokenReaderTester.h"
#include "frontend/FullParseHandler.h"
@ -2954,7 +2955,7 @@ BinASTParser<Tok>::parseInterfaceGetterContents(const size_t start, const BinKin
(void) isThisCaptured;
MOZ_TRY(parseAssertedVarScope());
BINJS_TRY_DECL(params, new_<ListNode>(ParseNodeKind::ParamsBody, tokenizer_->pos(start)));
BINJS_TRY_DECL(params, this->template new_<ListNode>(ParseNodeKind::ParamsBody, tokenizer_->pos(start)));
BINJS_MOZ_TRY_DECL(body, parseFunctionBody());
*paramsOut = params;
@ -3494,7 +3495,7 @@ BinASTParser<Tok>::parseInterfaceSetterContents(const size_t start, const BinKin
&positionalParams));
BINJS_MOZ_TRY_DECL(param, parseParameter());
BINJS_TRY_DECL(params, new_<ListNode>(ParseNodeKind::ParamsBody, param->pn_pos));
BINJS_TRY_DECL(params, this->template new_<ListNode>(ParseNodeKind::ParamsBody, param->pn_pos));
factory_.addList(params, param);
MOZ_TRY(checkPositionalParameterIndices(positionalParams, params));
MOZ_TRY(parseAssertedVarScope());
@ -4516,7 +4517,7 @@ BinASTParser<Tok>::parseListOfParameter()
const auto start = tokenizer_->offset();
MOZ_TRY(tokenizer_->enterList(length, guard));
BINJS_TRY_DECL(result, new_<ListNode>(ParseNodeKind::ParamsBody, tokenizer_->pos(start)));
BINJS_TRY_DECL(result, this->template new_<ListNode>(ParseNodeKind::ParamsBody, tokenizer_->pos(start)));
for (uint32_t i = 0; i < length; ++i) {
BINJS_MOZ_TRY_DECL(item, parseParameter());

View File

@ -9,238 +9,345 @@
// To generate this file, see the documentation in
// js/src/frontend/binsource/README.md.
// This file is meant to be included from the declaration
// of class `BinASTParser`. The include may be public or private.
#ifndef frontend_BinASTParser_h
#define frontend_BinASTParser_h
#include "mozilla/Maybe.h"
// ----- Sums of interfaces (by lexicographical order)
// Implementations are autogenerated
// `ParseNode*` may never be nullptr
JS::Result<Ok> parseAssertedMaybePositionalParameterName(
AssertedScopeKind scopeKind,
MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<ParseNode*> parseAssignmentTarget();
JS::Result<ParseNode*> parseBinding();
JS::Result<ParseNode*> parseExpression();
JS::Result<ParseNode*> parseExpressionOrSuper();
JS::Result<ParseNode*> parseForInOfBindingOrAssignmentTarget();
JS::Result<ParseNode*> parseObjectProperty();
JS::Result<ParseNode*> parseParameter();
JS::Result<ParseNode*> parseProgram();
JS::Result<ParseNode*> parsePropertyName();
JS::Result<ParseNode*> parseSimpleAssignmentTarget();
JS::Result<ParseNode*> parseSpreadElementOrExpression();
JS::Result<ParseNode*> parseStatement();
JS::Result<Ok> parseSumAssertedMaybePositionalParameterName(const size_t start, const BinKind kind, const BinFields& fields,
AssertedScopeKind scopeKind,
MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<ParseNode*> parseSumAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumBinding(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumExpressionOrSuper(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumForInOfBindingOrAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumObjectProperty(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumParameter(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumProgram(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumPropertyName(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumSimpleAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumSpreadElementOrExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumVariableDeclarationOrExpression(const size_t start, const BinKind kind, const BinFields& fields);
#include "frontend/BCEParserHandle.h"
#include "frontend/BinASTParserPerTokenizer.h"
#include "frontend/BinToken.h"
#include "frontend/BinTokenReaderMultipart.h"
#include "frontend/BinTokenReaderTester.h"
#include "frontend/FullParseHandler.h"
#include "frontend/ParseContext.h"
#include "frontend/ParseNode.h"
#include "frontend/SharedContext.h"
#include "js/CompileOptions.h"
#include "js/GCHashTable.h"
#include "js/GCVector.h"
#include "js/Result.h"
// ----- Interfaces (by lexicographical order)
// Implementations are autogenerated
// `ParseNode*` may never be nullptr
JS::Result<Ok> parseAssertedBlockScope();
JS::Result<Ok> parseAssertedBoundName(
AssertedScopeKind scopeKind);
JS::Result<Ok> parseAssertedBoundNamesScope();
JS::Result<Ok> parseAssertedDeclaredName(
AssertedScopeKind scopeKind);
JS::Result<Ok> parseAssertedParameterScope(
MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<Ok> parseAssertedScriptGlobalScope();
JS::Result<Ok> parseAssertedVarScope();
JS::Result<ParseNode*> parseBindingIdentifier();
JS::Result<ParseNode*> parseBlock();
JS::Result<LexicalScopeNode*> parseCatchClause();
JS::Result<ParseNode*> parseDirective();
JS::Result<ListNode*> parseFormalParameters();
JS::Result<Ok> parseFunctionExpressionContents(
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<Ok> parseFunctionOrMethodContents(
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<Ok> parseGetterContents(
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<ParseNode*> parseIdentifierExpression();
JS::Result<Ok> parseSetterContents(
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<CaseClause*> parseSwitchCase();
JS::Result<ParseNode*> parseSwitchDefault();
JS::Result<ParseNode*> parseVariableDeclarator();
JS::Result<ParseNode*> parseInterfaceArrayAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceArrayBinding(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceArrayExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedBlockScope(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedBoundName(const size_t start, const BinKind kind, const BinFields& fields,
AssertedScopeKind scopeKind);
JS::Result<Ok> parseInterfaceAssertedBoundNamesScope(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedDeclaredName(const size_t start, const BinKind kind, const BinFields& fields,
AssertedScopeKind scopeKind);
JS::Result<Ok> parseInterfaceAssertedParameterScope(const size_t start, const BinKind kind, const BinFields& fields,
MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<Ok> parseInterfaceAssertedPositionalParameterName(const size_t start, const BinKind kind, const BinFields& fields,
AssertedScopeKind scopeKind,
MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<Ok> parseInterfaceAssertedScriptGlobalScope(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedVarScope(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceAssignmentTargetIdentifier(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceAwaitExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBinaryExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBindingIdentifier(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBindingWithInitializer(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBlock(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBreakStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceCallExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<LexicalScopeNode*> parseInterfaceCatchClause(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceClassDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceClassExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceCompoundAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceComputedMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceComputedMemberExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceComputedPropertyName(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceConditionalExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceContinueStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceDataProperty(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceDebuggerStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceDirective(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceDoWhileStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerArrowExpressionWithExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerArrowExpressionWithFunctionBody(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerGetter(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerMethod(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerSetter(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEmptyStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceExpressionStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceForInOfBinding(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceForInStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceForOfStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceForStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ListNode*> parseInterfaceFormalParameters(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceFunctionExpressionContents(const size_t start, const BinKind kind, const BinFields& fields,
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<Ok> parseInterfaceFunctionOrMethodContents(const size_t start, const BinKind kind, const BinFields& fields,
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<Ok> parseInterfaceGetterContents(const size_t start, const BinKind kind, const BinFields& fields,
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<ParseNode*> parseInterfaceIdentifierExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceIfStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLabelledStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyArrowExpressionWithExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyArrowExpressionWithFunctionBody(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyGetter(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyMethod(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazySetter(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralBooleanExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralInfinityExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralNullExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralNumericExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralPropertyName(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralRegExpExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralStringExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceModule(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceNewExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceNewTargetExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceObjectAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceObjectBinding(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceObjectExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceReturnStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceScript(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceSetterContents(const size_t start, const BinKind kind, const BinFields& fields,
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<ParseNode*> parseInterfaceShorthandProperty(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceSpreadElement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceStaticMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceStaticMemberExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceSuper(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<CaseClause*> parseInterfaceSwitchCase(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceSwitchDefault(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceSwitchStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceSwitchStatementWithDefault(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceTemplateExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceThisExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceThrowStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceTryCatchStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceTryFinallyStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceUnaryExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceUpdateExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceVariableDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceVariableDeclarator(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceWhileStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceWithStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceYieldExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceYieldStarExpression(const size_t start, const BinKind kind, const BinFields& fields);
namespace js {
namespace frontend {
template<typename Tok>
class BinASTParser : public BinASTParserPerTokenizer<Tok>
{
public:
using Base = BinASTParserPerTokenizer<Tok>;
// ----- String enums (by lexicographical order)
// Implementations are autogenerated
JS::Result<typename BinASTParser<Tok>::AssertedDeclaredKind> parseAssertedDeclaredKind();
JS::Result<typename BinASTParser<Tok>::BinaryOperator> parseBinaryOperator();
JS::Result<typename BinASTParser<Tok>::CompoundAssignmentOperator> parseCompoundAssignmentOperator();
JS::Result<typename BinASTParser<Tok>::UnaryOperator> parseUnaryOperator();
JS::Result<typename BinASTParser<Tok>::UpdateOperator> parseUpdateOperator();
JS::Result<typename BinASTParser<Tok>::VariableDeclarationKind> parseVariableDeclarationKind();
using Tokenizer = Tok;
using BinFields = typename Tokenizer::BinFields;
using AutoList = typename Tokenizer::AutoList;
using AutoTaggedTuple = typename Tokenizer::AutoTaggedTuple;
using AutoTuple = typename Tokenizer::AutoTuple;
using Chars = typename Tokenizer::Chars;
// ----- Lists (by lexicographical order)
// Implementations are autogenerated
JS::Result<ParseNode*> parseArguments();
JS::Result<ListNode*> parseFunctionBody();
JS::Result<Ok> parseListOfAssertedBoundName(
AssertedScopeKind scopeKind);
JS::Result<Ok> parseListOfAssertedDeclaredName(
AssertedScopeKind scopeKind);
JS::Result<Ok> parseListOfAssertedMaybePositionalParameterName(
AssertedScopeKind scopeKind,
MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<ListNode*> parseListOfDirective();
JS::Result<ListNode*> parseListOfObjectProperty();
JS::Result<ListNode*> parseListOfOptionalSpreadElementOrExpression();
JS::Result<ListNode*> parseListOfParameter();
JS::Result<ListNode*> parseListOfStatement();
JS::Result<ListNode*> parseListOfSwitchCase();
JS::Result<ListNode*> parseListOfVariableDeclarator();
public:
// Auto-generated types.
using AssertedDeclaredKind = binast::AssertedDeclaredKind;
using BinaryOperator = binast::BinaryOperator;
using CompoundAssignmentOperator = binast::CompoundAssignmentOperator;
using UnaryOperator = binast::UnaryOperator;
using UpdateOperator = binast::UpdateOperator;
using VariableDeclarationKind = binast::VariableDeclarationKind;
public:
// BinASTParserPerTokenizer types.
using AssertedScopeKind = typename Base::AssertedScopeKind;
// ----- Default values (by lexicographical order)
// Implementations are autogenerated
JS::Result<ParseNode*> parseOptionalBinding();
JS::Result<ParseNode*> parseOptionalBindingIdentifier();
JS::Result<LexicalScopeNode*> parseOptionalCatchClause();
JS::Result<ParseNode*> parseOptionalExpression();
JS::Result<ParseNode*> parseOptionalSpreadElementOrExpression();
JS::Result<ParseNode*> parseOptionalStatement();
JS::Result<ParseNode*> parseOptionalVariableDeclarationOrExpression();
public:
BinASTParser(JSContext* cx, LifoAlloc& alloc, UsedNameTracker& usedNames,
const JS::ReadOnlyCompileOptions& options,
HandleScriptSourceObject sourceObject,
Handle<LazyScript*> lazyScript = nullptr)
: BinASTParserPerTokenizer<Tok>(cx, alloc, usedNames, options, sourceObject, lazyScript)
{}
~BinASTParser()
{}
protected:
// BinASTParserBase fields.
using Base::cx_;
using Base::alloc_;
using Base::usedNames_;
using Base::sourceObject_;
using Base::parseContext_;
using Base::factory_;
protected:
// BinASTParserPerTokenizer types.
using AutoVariableDeclarationKind = typename Base::AutoVariableDeclarationKind;
protected:
// BinASTParserPerTokenizer fields.
using Base::tokenizer_;
using Base::variableDeclarationKind_;
protected:
// BinASTParserPerTokenizer methods.
using Base::raiseInvalidClosedVar;
using Base::raiseMissingVariableInAssertedScope;
using Base::raiseMissingDirectEvalInAssertedScope;
using Base::raiseInvalidKind;
using Base::raiseInvalidVariant;
using Base::raiseMissingField;
using Base::raiseEmpty;
using Base::raiseOOM;
using Base::raiseError;
using Base::makeEmptyFunctionNode;
using Base::buildFunction;
using Base::buildFunctionBox;
using Base::addScopeName;
using Base::captureFunctionName;
using Base::getDeclaredScope;
using Base::getBoundScope;
using Base::checkBinding;
using Base::checkPositionalParameterIndices;
using Base::checkFunctionLength;
using Base::checkClosedVars;
using Base::prependDirectivesToBody;
using Base::forceStrictIfNecessary;
public:
// ----- Sums of interfaces (by lexicographical order)
// `ParseNode*` may never be nullptr
JS::Result<Ok> parseAssertedMaybePositionalParameterName(
AssertedScopeKind scopeKind,
MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<ParseNode*> parseAssignmentTarget();
JS::Result<ParseNode*> parseBinding();
JS::Result<ParseNode*> parseExpression();
JS::Result<ParseNode*> parseExpressionOrSuper();
JS::Result<ParseNode*> parseForInOfBindingOrAssignmentTarget();
JS::Result<ParseNode*> parseObjectProperty();
JS::Result<ParseNode*> parseParameter();
JS::Result<ParseNode*> parseProgram();
JS::Result<ParseNode*> parsePropertyName();
JS::Result<ParseNode*> parseSimpleAssignmentTarget();
JS::Result<ParseNode*> parseSpreadElementOrExpression();
JS::Result<ParseNode*> parseStatement();
JS::Result<Ok> parseSumAssertedMaybePositionalParameterName(const size_t start, const BinKind kind, const BinFields& fields,
AssertedScopeKind scopeKind,
MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<ParseNode*> parseSumAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumBinding(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumExpressionOrSuper(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumForInOfBindingOrAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumObjectProperty(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumParameter(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumProgram(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumPropertyName(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumSimpleAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumSpreadElementOrExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseSumVariableDeclarationOrExpression(const size_t start, const BinKind kind, const BinFields& fields);
// ----- Interfaces (by lexicographical order)
// `ParseNode*` may never be nullptr
JS::Result<Ok> parseAssertedBlockScope();
JS::Result<Ok> parseAssertedBoundName(
AssertedScopeKind scopeKind);
JS::Result<Ok> parseAssertedBoundNamesScope();
JS::Result<Ok> parseAssertedDeclaredName(
AssertedScopeKind scopeKind);
JS::Result<Ok> parseAssertedParameterScope(
MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<Ok> parseAssertedScriptGlobalScope();
JS::Result<Ok> parseAssertedVarScope();
JS::Result<ParseNode*> parseBindingIdentifier();
JS::Result<ParseNode*> parseBlock();
JS::Result<LexicalScopeNode*> parseCatchClause();
JS::Result<ParseNode*> parseDirective();
JS::Result<ListNode*> parseFormalParameters();
JS::Result<Ok> parseFunctionExpressionContents(
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<Ok> parseFunctionOrMethodContents(
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<Ok> parseGetterContents(
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<ParseNode*> parseIdentifierExpression();
JS::Result<Ok> parseSetterContents(
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<CaseClause*> parseSwitchCase();
JS::Result<ParseNode*> parseSwitchDefault();
JS::Result<ParseNode*> parseVariableDeclarator();
JS::Result<ParseNode*> parseInterfaceArrayAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceArrayBinding(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceArrayExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedBlockScope(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedBoundName(const size_t start, const BinKind kind, const BinFields& fields,
AssertedScopeKind scopeKind);
JS::Result<Ok> parseInterfaceAssertedBoundNamesScope(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedDeclaredName(const size_t start, const BinKind kind, const BinFields& fields,
AssertedScopeKind scopeKind);
JS::Result<Ok> parseInterfaceAssertedParameterScope(const size_t start, const BinKind kind, const BinFields& fields,
MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<Ok> parseInterfaceAssertedPositionalParameterName(const size_t start, const BinKind kind, const BinFields& fields,
AssertedScopeKind scopeKind,
MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<Ok> parseInterfaceAssertedScriptGlobalScope(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceAssertedVarScope(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceAssignmentTargetIdentifier(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceAwaitExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBinaryExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBindingIdentifier(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBindingWithInitializer(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBlock(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceBreakStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceCallExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<LexicalScopeNode*> parseInterfaceCatchClause(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceClassDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceClassExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceCompoundAssignmentExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceComputedMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceComputedMemberExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceComputedPropertyName(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceConditionalExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceContinueStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceDataProperty(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceDebuggerStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceDirective(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceDoWhileStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerArrowExpressionWithExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerArrowExpressionWithFunctionBody(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerGetter(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerMethod(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEagerSetter(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceEmptyStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceExpressionStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceForInOfBinding(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceForInStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceForOfStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceForStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ListNode*> parseInterfaceFormalParameters(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceFunctionExpressionContents(const size_t start, const BinKind kind, const BinFields& fields,
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<Ok> parseInterfaceFunctionOrMethodContents(const size_t start, const BinKind kind, const BinFields& fields,
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<Ok> parseInterfaceGetterContents(const size_t start, const BinKind kind, const BinFields& fields,
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<ParseNode*> parseInterfaceIdentifierExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceIfStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLabelledStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyArrowExpressionWithExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyArrowExpressionWithFunctionBody(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyGetter(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazyMethod(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLazySetter(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralBooleanExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralInfinityExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralNullExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralNumericExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralPropertyName(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralRegExpExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceLiteralStringExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceModule(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceNewExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceNewTargetExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceObjectAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceObjectBinding(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceObjectExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceReturnStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceScript(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<Ok> parseInterfaceSetterContents(const size_t start, const BinKind kind, const BinFields& fields,
uint32_t funLength,
ListNode** paramsOut,
ListNode** bodyOut);
JS::Result<ParseNode*> parseInterfaceShorthandProperty(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceSpreadElement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceStaticMemberAssignmentTarget(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceStaticMemberExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceSuper(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<CaseClause*> parseInterfaceSwitchCase(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceSwitchDefault(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceSwitchStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceSwitchStatementWithDefault(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceTemplateExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceThisExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceThrowStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceTryCatchStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceTryFinallyStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceUnaryExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceUpdateExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceVariableDeclaration(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceVariableDeclarator(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceWhileStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceWithStatement(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceYieldExpression(const size_t start, const BinKind kind, const BinFields& fields);
JS::Result<ParseNode*> parseInterfaceYieldStarExpression(const size_t start, const BinKind kind, const BinFields& fields);
// ----- String enums (by lexicographical order)
JS::Result<typename BinASTParser<Tok>::AssertedDeclaredKind> parseAssertedDeclaredKind();
JS::Result<typename BinASTParser<Tok>::BinaryOperator> parseBinaryOperator();
JS::Result<typename BinASTParser<Tok>::CompoundAssignmentOperator> parseCompoundAssignmentOperator();
JS::Result<typename BinASTParser<Tok>::UnaryOperator> parseUnaryOperator();
JS::Result<typename BinASTParser<Tok>::UpdateOperator> parseUpdateOperator();
JS::Result<typename BinASTParser<Tok>::VariableDeclarationKind> parseVariableDeclarationKind();
// ----- Lists (by lexicographical order)
JS::Result<ParseNode*> parseArguments();
JS::Result<ListNode*> parseFunctionBody();
JS::Result<Ok> parseListOfAssertedBoundName(
AssertedScopeKind scopeKind);
JS::Result<Ok> parseListOfAssertedDeclaredName(
AssertedScopeKind scopeKind);
JS::Result<Ok> parseListOfAssertedMaybePositionalParameterName(
AssertedScopeKind scopeKind,
MutableHandle<GCVector<JSAtom*>> positionalParams);
JS::Result<ListNode*> parseListOfDirective();
JS::Result<ListNode*> parseListOfObjectProperty();
JS::Result<ListNode*> parseListOfOptionalSpreadElementOrExpression();
JS::Result<ListNode*> parseListOfParameter();
JS::Result<ListNode*> parseListOfStatement();
JS::Result<ListNode*> parseListOfSwitchCase();
JS::Result<ListNode*> parseListOfVariableDeclarator();
// ----- Default values (by lexicographical order)
JS::Result<ParseNode*> parseOptionalBinding();
JS::Result<ParseNode*> parseOptionalBindingIdentifier();
JS::Result<LexicalScopeNode*> parseOptionalCatchClause();
JS::Result<ParseNode*> parseOptionalExpression();
JS::Result<ParseNode*> parseOptionalSpreadElementOrExpression();
JS::Result<ParseNode*> parseOptionalStatement();
JS::Result<ParseNode*> parseOptionalVariableDeclarationOrExpression();
};
extern template class BinASTParser<BinTokenReaderMultipart>;
extern template class BinASTParser<BinTokenReaderTester>;
} // namespace frontend
} // namespace js
#endif // frontend_BinASTParser_h

View File

@ -14,6 +14,7 @@
#include "mozilla/ScopeExit.h"
#include "mozilla/Vector.h"
#include "frontend/BinASTParser.h"
#include "frontend/BinSource-macros.h"
#include "frontend/BinTokenReaderTester.h"
#include "frontend/FullParseHandler.h"
@ -80,15 +81,16 @@ using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr;
// ------------- Toplevel constructions
template<typename Tok> JS::Result<ParseNode*>
BinASTParser<Tok>::parse(GlobalSharedContext* globalsc, const Vector<uint8_t>& data,
BinASTSourceMetadata** metadataPtr)
BinASTParserPerTokenizer<Tok>::parse(GlobalSharedContext* globalsc, const Vector<uint8_t>& data,
BinASTSourceMetadata** metadataPtr)
{
return parse(globalsc, data.begin(), data.length(), metadataPtr);
}
template<typename Tok> JS::Result<ParseNode*>
BinASTParser<Tok>::parse(GlobalSharedContext* globalsc, const uint8_t* start, const size_t length,
BinASTSourceMetadata** metadataPtr)
BinASTParserPerTokenizer<Tok>::parse(GlobalSharedContext* globalsc, const uint8_t* start,
const size_t length,
BinASTSourceMetadata** metadataPtr)
{
auto result = parseAux(globalsc, start, length, metadataPtr);
poison(); // Make sure that the parser is never used again accidentally.
@ -97,9 +99,9 @@ BinASTParser<Tok>::parse(GlobalSharedContext* globalsc, const uint8_t* start, co
template<typename Tok> JS::Result<ParseNode*>
BinASTParser<Tok>::parseAux(GlobalSharedContext* globalsc,
const uint8_t* start, const size_t length,
BinASTSourceMetadata** metadataPtr)
BinASTParserPerTokenizer<Tok>::parseAux(GlobalSharedContext* globalsc,
const uint8_t* start, const size_t length,
BinASTSourceMetadata** metadataPtr)
{
MOZ_ASSERT(globalsc);
@ -118,7 +120,7 @@ BinASTParser<Tok>::parseAux(GlobalSharedContext* globalsc,
MOZ_TRY(tokenizer_->readHeader());
ParseNode* result(nullptr);
MOZ_TRY_VAR(result, parseProgram());
MOZ_TRY_VAR(result, asFinalParser()->parseProgram());
mozilla::Maybe<GlobalScope::Data*> bindings = NewGlobalScopeData(cx_, varScope, alloc_,
parseContext_);
@ -135,7 +137,8 @@ BinASTParser<Tok>::parseAux(GlobalSharedContext* globalsc,
}
template<typename Tok> JS::Result<ParseNode*>
BinASTParser<Tok>::parseLazyFunction(ScriptSource* scriptSource, const size_t firstOffset)
BinASTParserPerTokenizer<Tok>::parseLazyFunction(ScriptSource* scriptSource,
const size_t firstOffset)
{
MOZ_ASSERT(lazyScript_);
MOZ_ASSERT(scriptSource->length() > firstOffset);
@ -170,9 +173,9 @@ BinASTParser<Tok>::parseLazyFunction(ScriptSource* scriptSource, const size_t fi
BINJS_TRY(lexicalScope.init(parseContext_));
ListNode* params;
ListNode* tmpBody;
auto parseFunc = isExpr ? &BinASTParser::parseFunctionExpressionContents
: &BinASTParser::parseFunctionOrMethodContents;
MOZ_TRY((this->*parseFunc)(func->nargs(), &params, &tmpBody));
auto parseFunc = isExpr ? &FinalParser::parseFunctionExpressionContents
: &FinalParser::parseFunctionOrMethodContents;
MOZ_TRY((asFinalParser()->*parseFunc)(func->nargs(), &params, &tmpBody));
BINJS_TRY_DECL(lexicalScopeData, NewLexicalScopeData(cx_, lexicalScope, alloc_, parseContext_));
BINJS_TRY_DECL(body, factory_.newLexicalScope(*lexicalScopeData, tmpBody));
@ -182,7 +185,7 @@ BinASTParser<Tok>::parseLazyFunction(ScriptSource* scriptSource, const size_t fi
}
template<typename Tok> void
BinASTParser<Tok>::forceStrictIfNecessary(SharedContext* sc, ListNode* directives)
BinASTParserPerTokenizer<Tok>::forceStrictIfNecessary(SharedContext* sc, ListNode* directives)
{
JSAtom* useStrict = cx_->names().useStrict;
@ -195,10 +198,10 @@ BinASTParser<Tok>::forceStrictIfNecessary(SharedContext* sc, ListNode* directive
}
template<typename Tok> JS::Result<FunctionBox*>
BinASTParser<Tok>::buildFunctionBox(GeneratorKind generatorKind,
FunctionAsyncKind functionAsyncKind,
FunctionSyntaxKind syntax,
ParseNode* name)
BinASTParserPerTokenizer<Tok>::buildFunctionBox(GeneratorKind generatorKind,
FunctionAsyncKind functionAsyncKind,
FunctionSyntaxKind syntax,
ParseNode* name)
{
MOZ_ASSERT_IF(!parseContext_, lazyScript_);
@ -255,7 +258,8 @@ BinASTParser<Tok>::buildFunctionBox(GeneratorKind generatorKind,
}
template<typename Tok> JS::Result<CodeNode*>
BinASTParser<Tok>::makeEmptyFunctionNode(const size_t start, const BinKind kind, FunctionBox* funbox)
BinASTParserPerTokenizer<Tok>::makeEmptyFunctionNode(const size_t start, const BinKind kind,
FunctionBox* funbox)
{
// LazyScript compilation requires basically none of the fields filled out.
TokenPos pos = tokenizer_->pos(start);
@ -272,8 +276,9 @@ BinASTParser<Tok>::makeEmptyFunctionNode(const size_t start, const BinKind kind,
}
template<typename Tok> JS::Result<ParseNode*>
BinASTParser<Tok>::buildFunction(const size_t start, const BinKind kind, ParseNode* name,
ListNode* params, ParseNode* body, FunctionBox* funbox)
BinASTParserPerTokenizer<Tok>::buildFunction(const size_t start, const BinKind kind,
ParseNode* name, ListNode* params, ParseNode* body,
FunctionBox* funbox)
{
// Set the argument count for building argument packets. Function.length is handled
// by setting the appropriate funbox field during argument parsing.
@ -371,9 +376,9 @@ BinASTParser<Tok>::buildFunction(const size_t start, const BinKind kind, ParseNo
}
template<typename Tok> JS::Result<Ok>
BinASTParser<Tok>::addScopeName(AssertedScopeKind scopeKind, HandleAtom name,
ParseContext::Scope* scope, DeclarationKind declKind,
bool isCaptured, bool allowDuplicateName)
BinASTParserPerTokenizer<Tok>::addScopeName(AssertedScopeKind scopeKind, HandleAtom name,
ParseContext::Scope* scope, DeclarationKind declKind,
bool isCaptured, bool allowDuplicateName)
{
auto ptr = scope->lookupDeclaredNameForAdd(name);
if (ptr) {
@ -396,7 +401,7 @@ BinASTParser<Tok>::addScopeName(AssertedScopeKind scopeKind, HandleAtom name,
}
template<typename Tok> void
BinASTParser<Tok>::captureFunctionName()
BinASTParserPerTokenizer<Tok>::captureFunctionName()
{
MOZ_ASSERT(parseContext_->isFunctionBox());
MOZ_ASSERT(parseContext_->functionBox()->function()->isNamedLambda());
@ -410,8 +415,10 @@ BinASTParser<Tok>::captureFunctionName()
}
template<typename Tok> JS::Result<Ok>
BinASTParser<Tok>::getDeclaredScope(AssertedScopeKind scopeKind, AssertedDeclaredKind kind,
ParseContext::Scope*& scope, DeclarationKind& declKind)
BinASTParserPerTokenizer<Tok>::getDeclaredScope(AssertedScopeKind scopeKind,
AssertedDeclaredKind kind,
ParseContext::Scope*& scope,
DeclarationKind& declKind)
{
MOZ_ASSERT(scopeKind == AssertedScopeKind::Block ||
scopeKind == AssertedScopeKind::Global ||
@ -438,8 +445,9 @@ BinASTParser<Tok>::getDeclaredScope(AssertedScopeKind scopeKind, AssertedDeclare
}
template<typename Tok> JS::Result<Ok>
BinASTParser<Tok>::getBoundScope(AssertedScopeKind scopeKind,
ParseContext::Scope*& scope, DeclarationKind& declKind)
BinASTParserPerTokenizer<Tok>::getBoundScope(AssertedScopeKind scopeKind,
ParseContext::Scope*& scope,
DeclarationKind& declKind)
{
MOZ_ASSERT(scopeKind == AssertedScopeKind::Catch ||
scopeKind == AssertedScopeKind::Parameter);
@ -462,7 +470,7 @@ BinASTParser<Tok>::getBoundScope(AssertedScopeKind scopeKind,
}
template<typename Tok> JS::Result<Ok>
BinASTParser<Tok>::checkBinding(JSAtom* name)
BinASTParserPerTokenizer<Tok>::checkBinding(JSAtom* name)
{
// Check that the variable appears in the corresponding scope.
ParseContext::Scope& scope =
@ -481,8 +489,8 @@ BinASTParser<Tok>::checkBinding(JSAtom* name)
// Binary AST (revision 8eab67e0c434929a66ff6abe99ff790bca087dda)
// 3.1.5 CheckPositionalParameterIndices.
template<typename Tok> JS::Result<Ok>
BinASTParser<Tok>::checkPositionalParameterIndices(Handle<GCVector<JSAtom*>> positionalParams,
ListNode* params)
BinASTParserPerTokenizer<Tok>::checkPositionalParameterIndices(Handle<GCVector<JSAtom*>> positionalParams,
ListNode* params)
{
// positionalParams should have the corresponding entry up to the last
// positional parameter.
@ -568,7 +576,7 @@ BinASTParser<Tok>::checkPositionalParameterIndices(Handle<GCVector<JSAtom*>> pos
// Binary AST (revision 8eab67e0c434929a66ff6abe99ff790bca087dda)
// 3.1.13 CheckFunctionLength.
template<typename Tok> JS::Result<Ok>
BinASTParser<Tok>::checkFunctionLength(uint32_t expectedLength)
BinASTParserPerTokenizer<Tok>::checkFunctionLength(uint32_t expectedLength)
{
if (parseContext_->functionBox()->length != expectedLength) {
return raiseError("Function length does't match");
@ -577,7 +585,7 @@ BinASTParser<Tok>::checkFunctionLength(uint32_t expectedLength)
}
template<typename Tok> JS::Result<Ok>
BinASTParser<Tok>::checkClosedVars(ParseContext::Scope& scope)
BinASTParserPerTokenizer<Tok>::checkClosedVars(ParseContext::Scope& scope)
{
for (ParseContext::Scope::BindingIter bi = scope.bindings(parseContext_); bi; bi++) {
if (UsedNamePtr p = usedNames_.lookup(bi.name())) {
@ -593,7 +601,7 @@ BinASTParser<Tok>::checkClosedVars(ParseContext::Scope& scope)
}
template<typename Tok> JS::Result<Ok>
BinASTParser<Tok>::checkFunctionClosedVars()
BinASTParserPerTokenizer<Tok>::checkFunctionClosedVars()
{
MOZ_ASSERT(parseContext_->isFunctionBox());
@ -607,7 +615,7 @@ BinASTParser<Tok>::checkFunctionClosedVars()
}
template<typename Tok> JS::Result<Ok>
BinASTParser<Tok>::prependDirectivesToBody(ListNode* body, ListNode* directives)
BinASTParserPerTokenizer<Tok>::prependDirectivesToBody(ListNode* body, ListNode* directives)
{
if (!directives) {
return Ok();
@ -623,7 +631,7 @@ BinASTParser<Tok>::prependDirectivesToBody(ListNode* body, ListNode* directives)
}
template<typename Tok> JS::Result<Ok>
BinASTParser<Tok>::prependDirectivesImpl(ListNode* body, ParseNode* directive)
BinASTParserPerTokenizer<Tok>::prependDirectivesImpl(ListNode* body, ParseNode* directive)
{
BINJS_TRY(CheckRecursionLimit(cx_));
@ -640,13 +648,13 @@ BinASTParser<Tok>::prependDirectivesImpl(ListNode* body, ParseNode* directive)
}
template<typename Tok> mozilla::GenericErrorResult<JS::Error&>
BinASTParser<Tok>::raiseInvalidClosedVar(JSAtom* name)
BinASTParserPerTokenizer<Tok>::raiseInvalidClosedVar(JSAtom* name)
{
return raiseError("Captured variable was not declared as captured");
}
template<typename Tok> mozilla::GenericErrorResult<JS::Error&>
BinASTParser<Tok>::raiseMissingVariableInAssertedScope(JSAtom* name)
BinASTParserPerTokenizer<Tok>::raiseMissingVariableInAssertedScope(JSAtom* name)
{
// For the moment, we don't trust inputs sufficiently to put the name
// in an error message.
@ -654,13 +662,13 @@ BinASTParser<Tok>::raiseMissingVariableInAssertedScope(JSAtom* name)
}
template<typename Tok> mozilla::GenericErrorResult<JS::Error&>
BinASTParser<Tok>::raiseMissingDirectEvalInAssertedScope()
BinASTParserPerTokenizer<Tok>::raiseMissingDirectEvalInAssertedScope()
{
return raiseError("Direct call to `eval` was not declared in AssertedScope");
}
template<typename Tok> mozilla::GenericErrorResult<JS::Error&>
BinASTParser<Tok>::raiseInvalidKind(const char* superKind, const BinKind kind)
BinASTParserPerTokenizer<Tok>::raiseInvalidKind(const char* superKind, const BinKind kind)
{
Sprinter out(cx_);
BINJS_TRY(out.init());
@ -669,7 +677,7 @@ BinASTParser<Tok>::raiseInvalidKind(const char* superKind, const BinKind kind)
}
template<typename Tok> mozilla::GenericErrorResult<JS::Error&>
BinASTParser<Tok>::raiseInvalidVariant(const char* kind, const BinVariant value)
BinASTParserPerTokenizer<Tok>::raiseInvalidVariant(const char* kind, const BinVariant value)
{
Sprinter out(cx_);
BINJS_TRY(out.init());
@ -679,7 +687,7 @@ BinASTParser<Tok>::raiseInvalidVariant(const char* kind, const BinVariant value)
}
template<typename Tok> mozilla::GenericErrorResult<JS::Error&>
BinASTParser<Tok>::raiseMissingField(const char* kind, const BinField field)
BinASTParserPerTokenizer<Tok>::raiseMissingField(const char* kind, const BinField field)
{
Sprinter out(cx_);
BINJS_TRY(out.init());
@ -689,7 +697,7 @@ BinASTParser<Tok>::raiseMissingField(const char* kind, const BinField field)
}
template<typename Tok> mozilla::GenericErrorResult<JS::Error&>
BinASTParser<Tok>::raiseEmpty(const char* description)
BinASTParserPerTokenizer<Tok>::raiseEmpty(const char* description)
{
Sprinter out(cx_);
BINJS_TRY(out.init());
@ -699,13 +707,13 @@ BinASTParser<Tok>::raiseEmpty(const char* description)
}
template<typename Tok> mozilla::GenericErrorResult<JS::Error&>
BinASTParser<Tok>::raiseOOM()
BinASTParserPerTokenizer<Tok>::raiseOOM()
{
return tokenizer_->raiseOOM();
}
template<typename Tok> mozilla::GenericErrorResult<JS::Error&>
BinASTParser<Tok>::raiseError(BinKind kind, const char* description)
BinASTParserPerTokenizer<Tok>::raiseError(BinKind kind, const char* description)
{
Sprinter out(cx_);
BINJS_TRY(out.init());
@ -714,19 +722,19 @@ BinASTParser<Tok>::raiseError(BinKind kind, const char* description)
}
template<typename Tok> mozilla::GenericErrorResult<JS::Error&>
BinASTParser<Tok>::raiseError(const char* description)
BinASTParserPerTokenizer<Tok>::raiseError(const char* description)
{
return tokenizer_->raiseError(description);
}
template<typename Tok> void
BinASTParser<Tok>::poison()
BinASTParserPerTokenizer<Tok>::poison()
{
tokenizer_.reset();
}
template<typename Tok> void
BinASTParser<Tok>::reportErrorNoOffsetVA(unsigned errorNumber, va_list args)
BinASTParserPerTokenizer<Tok>::reportErrorNoOffsetVA(unsigned errorNumber, va_list args)
{
ErrorMetadata metadata;
metadata.filename = getFilename();
@ -737,7 +745,7 @@ BinASTParser<Tok>::reportErrorNoOffsetVA(unsigned errorNumber, va_list args)
}
template<typename Tok> void
BinASTParser<Tok>::errorAtVA(uint32_t offset, unsigned errorNumber, va_list* args)
BinASTParserPerTokenizer<Tok>::errorAtVA(uint32_t offset, unsigned errorNumber, va_list* args)
{
ErrorMetadata metadata;
metadata.filename = getFilename();
@ -748,7 +756,9 @@ BinASTParser<Tok>::errorAtVA(uint32_t offset, unsigned errorNumber, va_list* arg
}
template<typename Tok> bool
BinASTParser<Tok>::reportExtraWarningErrorNumberVA(UniquePtr<JSErrorNotes> notes, uint32_t offset, unsigned errorNumber, va_list* args)
BinASTParserPerTokenizer<Tok>::reportExtraWarningErrorNumberVA(UniquePtr<JSErrorNotes> notes,
uint32_t offset,
unsigned errorNumber, va_list* args)
{
if (!options().extraWarningsOption) {
return true;
@ -776,18 +786,40 @@ TraceBinParser(JSTracer* trc, JS::AutoGCRooter* parser)
template<typename Tok>
void
BinASTParser<Tok>::doTrace(JSTracer* trc)
BinASTParserPerTokenizer<Tok>::doTrace(JSTracer* trc)
{
if (tokenizer_) {
tokenizer_->traceMetadata(trc);
}
}
template<typename Tok>
inline typename BinASTParserPerTokenizer<Tok>::FinalParser*
BinASTParserPerTokenizer<Tok>::asFinalParser()
{
// Same as GeneralParser::asFinalParser, verify the inheritance to
// make sure the static downcast works.
static_assert(mozilla::IsBaseOf<BinASTParserPerTokenizer<Tok>, FinalParser>::value,
"inheritance relationship required by the static_cast<> below");
return static_cast<FinalParser*>(this);
}
template<typename Tok>
inline const typename BinASTParserPerTokenizer<Tok>::FinalParser*
BinASTParserPerTokenizer<Tok>::asFinalParser() const
{
static_assert(mozilla::IsBaseOf<BinASTParserPerTokenizer<Tok>, FinalParser>::value,
"inheritance relationship required by the static_cast<> below");
return static_cast<const FinalParser*>(this);
}
// 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>;
template class BinASTParserPerTokenizer<BinTokenReaderMultipart>;
template class BinASTParserPerTokenizer<BinTokenReaderTester>;
} // namespace frontend
} // namespace js

View File

@ -35,6 +35,9 @@
namespace js {
namespace frontend {
template<typename Tok>
class BinASTParser;
/**
* The parser for a Binary AST.
*
@ -42,7 +45,7 @@ namespace frontend {
* recoverable.
*/
template<typename Tok>
class BinASTParser : public BinASTParserBase, public ErrorReporter, public BCEParserHandle
class BinASTParserPerTokenizer : public BinASTParserBase, public ErrorReporter, public BCEParserHandle
{
public:
using Tokenizer = Tok;
@ -56,21 +59,19 @@ class BinASTParser : public BinASTParserBase, public ErrorReporter, public BCEPa
public:
// Auto-generated types.
using AssertedDeclaredKind = binast::AssertedDeclaredKind;
using BinaryOperator = binast::BinaryOperator;
using CompoundAssignmentOperator = binast::CompoundAssignmentOperator;
using UnaryOperator = binast::UnaryOperator;
using UpdateOperator = binast::UpdateOperator;
using VariableDeclarationKind = binast::VariableDeclarationKind;
public:
BinASTParser(JSContext* cx, LifoAlloc& alloc, UsedNameTracker& usedNames, const JS::ReadOnlyCompileOptions& options,
HandleScriptSourceObject sourceObject, Handle<LazyScript*> lazyScript = nullptr)
BinASTParserPerTokenizer(JSContext* cx, LifoAlloc& alloc, UsedNameTracker& usedNames,
const JS::ReadOnlyCompileOptions& options,
HandleScriptSourceObject sourceObject,
Handle<LazyScript*> lazyScript = nullptr)
: BinASTParserBase(cx, alloc, usedNames, sourceObject, lazyScript)
, options_(options)
, variableDeclarationKind_(VariableDeclarationKind::Var)
{
}
~BinASTParser()
~BinASTParserPerTokenizer()
{
}
@ -78,8 +79,9 @@ class BinASTParser : public BinASTParserBase, public ErrorReporter, public BCEPa
* Parse a buffer, returning a node (which may be nullptr) in case of success
* or Nothing() in case of error.
*
* The instance of `ParseNode` MAY NOT survive the `BinASTParser`. Indeed,
* destruction of the `BinASTParser` will also destroy the `ParseNode`.
* The instance of `ParseNode` MAY NOT survive the
* `BinASTParserPerTokenizer`. Indeed, destruction of the
* `BinASTParserPerTokenizer` will also destroy the `ParseNode`.
*
* In case of error, the parser reports the JS error.
*/
@ -91,7 +93,7 @@ class BinASTParser : public BinASTParserBase, public ErrorReporter, public BCEPa
JS::Result<ParseNode*> parseLazyFunction(ScriptSource* src, const size_t firstOffset);
private:
protected:
MOZ_MUST_USE JS::Result<ParseNode*> parseAux(GlobalSharedContext* globalsc,
const uint8_t* start, const size_t length,
BinASTSourceMetadata** metadataPtr = nullptr);
@ -128,9 +130,6 @@ class BinASTParser : public BinASTParserBase, public ErrorReporter, public BCEPa
Var,
};
// Auto-generated methods
#include "frontend/BinASTParser.h"
// --- Auxiliary parsing functions
// Build a function object for a function-producing production. Called AFTER creating the scope.
@ -187,7 +186,7 @@ class BinASTParser : public BinASTParserBase, public ErrorReporter, public BCEPa
// directive.
void forceStrictIfNecessary(SharedContext* sc, ListNode* directives);
private: // Implement ErrorReporter
protected: // Implement ErrorReporter
const JS::ReadOnlyCompileOptions& options_;
const JS::ReadOnlyCompileOptions& options() const override {
@ -271,7 +270,7 @@ class BinASTParser : public BinASTParserBase, public ErrorReporter, public BCEPa
return this->options_.filename();
}
private: // Implement ErrorReporter
protected: // Implement ErrorReporter
mozilla::Maybe<Tokenizer> tokenizer_;
VariableDeclarationKind variableDeclarationKind_;
@ -281,7 +280,7 @@ class BinASTParser : public BinASTParserBase, public ErrorReporter, public BCEPa
// Helper class: Restore field `variableDeclarationKind` upon leaving a scope.
class MOZ_RAII AutoVariableDeclarationKind {
public:
explicit AutoVariableDeclarationKind(BinASTParser<Tok>* parser
explicit AutoVariableDeclarationKind(BinASTParserPerTokenizer<Tok>* parser
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: parser_(parser)
, kind(parser->variableDeclarationKind_)
@ -292,17 +291,27 @@ class BinASTParser : public BinASTParserBase, public ErrorReporter, public BCEPa
parser_->variableDeclarationKind_ = kind;
}
private:
BinASTParser<Tok>* parser_;
BinASTParser<Tok>::VariableDeclarationKind kind;
BinASTParserPerTokenizer<Tok>* parser_;
BinASTParserPerTokenizer<Tok>::VariableDeclarationKind kind;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
private:
// Some methods in this class require access to auto-generated methods in
// BinASTParser which derives this class.
// asFinalParser methods provide the access to BinASTParser class methods
// of this instance.
using FinalParser = BinASTParser<Tok>;
inline FinalParser* asFinalParser();
inline const FinalParser* asFinalParser() const;
};
class BinParseContext : public ParseContext
{
public:
template<typename Tok>
BinParseContext(JSContext* cx, BinASTParser<Tok>* parser, SharedContext* sc,
BinParseContext(JSContext* cx, BinASTParserPerTokenizer<Tok>* parser, SharedContext* sc,
Directives* newDirectives)
: ParseContext(cx, parser->parseContext_, sc, *parser,
parser->usedNames_, newDirectives, /* isFull = */ true)
@ -310,8 +319,8 @@ class BinParseContext : public ParseContext
};
extern template class BinASTParser<BinTokenReaderMultipart>;
extern template class BinASTParser<BinTokenReaderTester>;
extern template class BinASTParserPerTokenizer<BinTokenReaderMultipart>;
extern template class BinASTParserPerTokenizer<BinTokenReaderTester>;
} // namespace frontend
} // namespace js

View File

@ -27,6 +27,8 @@ cpp:
// To generate this file, see the documentation in
// js/src/frontend/binsource/README.md.
#include "frontend/BinASTParser.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Casting.h"
#include "mozilla/Maybe.h"
@ -34,7 +36,6 @@ cpp:
#include "mozilla/PodOperations.h"
#include "mozilla/Vector.h"
#include "frontend/BinASTParserPerTokenizer.h"
#include "frontend/BinSource-macros.h"
#include "frontend/BinTokenReaderTester.h"
#include "frontend/FullParseHandler.h"
@ -70,7 +71,7 @@ cpp:
hpp:
# Rules for generating BinSource-class.h
# Rules for generating BinASTParser.h
class:
header: |
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
@ -82,8 +83,126 @@ hpp:
// To generate this file, see the documentation in
// js/src/frontend/binsource/README.md.
// This file is meant to be included from the declaration
// of class `BinASTParser`. The include may be public or private.
#ifndef frontend_BinASTParser_h
#define frontend_BinASTParser_h
#include "mozilla/Maybe.h"
#include "frontend/BCEParserHandle.h"
#include "frontend/BinASTParserPerTokenizer.h"
#include "frontend/BinToken.h"
#include "frontend/BinTokenReaderMultipart.h"
#include "frontend/BinTokenReaderTester.h"
#include "frontend/FullParseHandler.h"
#include "frontend/ParseContext.h"
#include "frontend/ParseNode.h"
#include "frontend/SharedContext.h"
#include "js/CompileOptions.h"
#include "js/GCHashTable.h"
#include "js/GCVector.h"
#include "js/Result.h"
namespace js {
namespace frontend {
template<typename Tok>
class BinASTParser : public BinASTParserPerTokenizer<Tok>
{
public:
using Base = BinASTParserPerTokenizer<Tok>;
using Tokenizer = Tok;
using BinFields = typename Tokenizer::BinFields;
using AutoList = typename Tokenizer::AutoList;
using AutoTaggedTuple = typename Tokenizer::AutoTaggedTuple;
using AutoTuple = typename Tokenizer::AutoTuple;
using Chars = typename Tokenizer::Chars;
public:
// Auto-generated types.
using AssertedDeclaredKind = binast::AssertedDeclaredKind;
using BinaryOperator = binast::BinaryOperator;
using CompoundAssignmentOperator = binast::CompoundAssignmentOperator;
using UnaryOperator = binast::UnaryOperator;
using UpdateOperator = binast::UpdateOperator;
using VariableDeclarationKind = binast::VariableDeclarationKind;
public:
// BinASTParserPerTokenizer types.
using AssertedScopeKind = typename Base::AssertedScopeKind;
public:
BinASTParser(JSContext* cx, LifoAlloc& alloc, UsedNameTracker& usedNames,
const JS::ReadOnlyCompileOptions& options,
HandleScriptSourceObject sourceObject,
Handle<LazyScript*> lazyScript = nullptr)
: BinASTParserPerTokenizer<Tok>(cx, alloc, usedNames, options, sourceObject, lazyScript)
{}
~BinASTParser()
{}
protected:
// BinASTParserBase fields.
using Base::cx_;
using Base::alloc_;
using Base::usedNames_;
using Base::sourceObject_;
using Base::parseContext_;
using Base::factory_;
protected:
// BinASTParserPerTokenizer types.
using AutoVariableDeclarationKind = typename Base::AutoVariableDeclarationKind;
protected:
// BinASTParserPerTokenizer fields.
using Base::tokenizer_;
using Base::variableDeclarationKind_;
protected:
// BinASTParserPerTokenizer methods.
using Base::raiseInvalidClosedVar;
using Base::raiseMissingVariableInAssertedScope;
using Base::raiseMissingDirectEvalInAssertedScope;
using Base::raiseInvalidKind;
using Base::raiseInvalidVariant;
using Base::raiseMissingField;
using Base::raiseEmpty;
using Base::raiseOOM;
using Base::raiseError;
using Base::makeEmptyFunctionNode;
using Base::buildFunction;
using Base::buildFunctionBox;
using Base::addScopeName;
using Base::captureFunctionName;
using Base::getDeclaredScope;
using Base::getBoundScope;
using Base::checkBinding;
using Base::checkPositionalParameterIndices;
using Base::checkFunctionLength;
using Base::checkClosedVars;
using Base::prependDirectivesToBody;
using Base::forceStrictIfNecessary;
public:
footer: |
};
extern template class BinASTParser<BinTokenReaderMultipart>;
extern template class BinASTParser<BinTokenReaderTester>;
} // namespace frontend
} // namespace js
#endif // frontend_BinASTParser_h
enums:
header: |
@ -724,14 +843,14 @@ GetterContents:
fields:
body:
before: |
BINJS_TRY_DECL(params, new_<ListNode>(ParseNodeKind::ParamsBody, tokenizer_->pos(start)));
BINJS_TRY_DECL(params, this->template new_<ListNode>(ParseNodeKind::ParamsBody, tokenizer_->pos(start)));
SetterContents:
inherits: FunctionExpressionContents
fields:
param:
after: |
BINJS_TRY_DECL(params, new_<ListNode>(ParseNodeKind::ParamsBody, param->pn_pos));
BINJS_TRY_DECL(params, this->template new_<ListNode>(ParseNodeKind::ParamsBody, param->pn_pos));
factory_.addList(params, param);
MOZ_TRY(checkPositionalParameterIndices(positionalParams, params));
@ -1023,7 +1142,7 @@ ListOfParameter:
type-ok:
ListNode*
init: |
BINJS_TRY_DECL(result, new_<ListNode>(ParseNodeKind::ParamsBody, tokenizer_->pos(start)));
BINJS_TRY_DECL(result, this->template new_<ListNode>(ParseNodeKind::ParamsBody, tokenizer_->pos(start)));
append:
factory_.addList(/* list = */ result, /* kid = */ item);
@ -1040,7 +1159,7 @@ ListOfStatement:
# type-ok:
# ListNode*
# init:
# BINJS_TRY_DECL(result, new_<ListNode>(ParseNodeKind::ParamsBody, tokenizer_->pos()));
# BINJS_TRY_DECL(result, this->template new_<ListNode>(ParseNodeKind::ParamsBody, tokenizer_->pos()));
# append:
# result->appendWithoutOrderAssumption(item);

View File

@ -13,7 +13,7 @@
#include "builtin/ModuleObject.h"
#if defined(JS_BUILD_BINAST)
# include "frontend/BinASTParserPerTokenizer.h"
# include "frontend/BinASTParser.h"
#endif // JS_BUILD_BINAST
#include "frontend/BytecodeCompilation.h"
#include "frontend/BytecodeEmitter.h"

View File

@ -143,6 +143,10 @@ struct GlobalRules {
/// defining the class.
hpp_class_header: Option<String>,
/// Footer to add at the end of the .hpp file
/// defining the class.
hpp_class_footer: Option<String>,
/// Header to add at the start of the .hpp file.
/// defining the enums.
hpp_enums_header: Option<String>,
@ -184,6 +188,7 @@ impl GlobalRules {
let mut cpp_header = None;
let mut cpp_footer = None;
let mut hpp_class_header = None;
let mut hpp_class_footer = None;
let mut hpp_enums_header = None;
let mut hpp_enums_footer = None;
let mut hpp_tokens_header = None;
@ -221,6 +226,8 @@ impl GlobalRules {
"hpp" => {
update_rule(&mut hpp_class_header, &node_entries["class"]["header"])
.unwrap_or_else(|_| panic!("Rule hpp.class.header must be a string"));
update_rule(&mut hpp_class_footer, &node_entries["class"]["footer"])
.unwrap_or_else(|_| panic!("Rule hpp.class.footer must be a string"));
update_rule(&mut hpp_enums_header, &node_entries["enums"]["header"])
.unwrap_or_else(|_| panic!("Rule hpp.enum.header must be a string"));
update_rule(&mut hpp_enums_footer, &node_entries["enums"]["footer"])
@ -412,6 +419,7 @@ impl GlobalRules {
cpp_header,
cpp_footer,
hpp_class_header,
hpp_class_footer,
hpp_enums_header,
hpp_enums_footer,
hpp_tokens_header,
@ -1028,9 +1036,10 @@ enum class {name} {{
let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name()
.iter()
.sorted_by(|a, b| a.0.cmp(&b.0));
buffer.push_str("\n\n// ----- Sums of interfaces (by lexicographical order)\n");
buffer.push_str("// Implementations are autogenerated\n");
buffer.push_str("// `ParseNode*` may never be nullptr\n");
buffer.push_str("
// ----- Sums of interfaces (by lexicographical order)
// `ParseNode*` may never be nullptr
");
for &(ref name, _) in &sums_of_interfaces {
if !self.refgraph.is_used(name.to_rc_string().clone()) {
continue;
@ -1040,7 +1049,7 @@ enum class {name} {{
let extra_params = rules_for_this_sum.extra_params;
let rendered = self.get_method_signature(name, "", "",
&extra_params);
buffer.push_str(&rendered.reindent("")
buffer.push_str(&rendered.reindent(" ")
.newline_if_not_empty());
}
for (name, _) in sums_of_interfaces {
@ -1054,15 +1063,16 @@ enum class {name} {{
let rendered = self.get_method_signature(name, prefix,
INTERFACE_PARAMS,
&extra_params);
buffer.push_str(&rendered.reindent("")
buffer.push_str(&rendered.reindent(" ")
.newline_if_not_empty());
}
}
fn export_declare_single_interface_methods(&self, buffer: &mut String) {
buffer.push_str("\n\n// ----- Interfaces (by lexicographical order)\n");
buffer.push_str("// Implementations are autogenerated\n");
buffer.push_str("// `ParseNode*` may never be nullptr\n");
buffer.push_str("
// ----- Interfaces (by lexicographical order)
// `ParseNode*` may never be nullptr
");
let interfaces_by_name = self.syntax.interfaces_by_name()
.iter()
.sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str()));
@ -1076,7 +1086,7 @@ enum class {name} {{
if self.refgraph.is_used(name.to_rc_string().clone()) {
let outer = self.get_method_signature(name, "", "", &extra_params);
outer_parsers.push(outer.reindent(""));
outer_parsers.push(outer.reindent(" "));
}
let inner_prefix = "Interface";
@ -1086,7 +1096,7 @@ enum class {name} {{
let inner = self.get_method_signature(name, inner_prefix,
INTERFACE_PARAMS,
&extra_params);
inner_parsers.push(inner.reindent(""));
inner_parsers.push(inner.reindent(" "));
}
for parser in outer_parsers.drain(..) {
@ -1101,8 +1111,9 @@ enum class {name} {{
}
fn export_declare_string_enums_methods(&self, buffer: &mut String) {
buffer.push_str("\n\n// ----- String enums (by lexicographical order)\n");
buffer.push_str("// Implementations are autogenerated\n");
buffer.push_str("
// ----- String enums (by lexicographical order)
");
let string_enums_by_name = self.syntax.string_enums_by_name()
.iter()
.sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str()));
@ -1112,14 +1123,15 @@ enum class {name} {{
}
let rendered = self.get_method_signature(kind, "", "", &None);
buffer.push_str(&rendered.reindent(""));
buffer.push_str(&rendered.reindent(" "));
buffer.push_str("\n");
}
}
fn export_declare_list_methods(&self, buffer: &mut String) {
buffer.push_str("\n\n// ----- Lists (by lexicographical order)\n");
buffer.push_str("// Implementations are autogenerated\n");
buffer.push_str("
// ----- Lists (by lexicographical order)
");
for parser in &self.list_parsers_to_generate {
if !self.refgraph.is_used(parser.name.to_rc_string().clone()) {
continue;
@ -1129,14 +1141,15 @@ enum class {name} {{
let extra_params = rules_for_this_node.extra_params;
let rendered = self.get_method_signature(&parser.name, "", "",
&extra_params);
buffer.push_str(&rendered.reindent(""));
buffer.push_str(&rendered.reindent(" "));
buffer.push_str("\n");
}
}
fn export_declare_option_methods(&self, buffer: &mut String) {
buffer.push_str("\n\n// ----- Default values (by lexicographical order)\n");
buffer.push_str("// Implementations are autogenerated\n");
buffer.push_str("
// ----- Default values (by lexicographical order)
");
for parser in &self.option_parsers_to_generate {
if !self.refgraph.is_used(parser.name.to_rc_string().clone()) {
continue;
@ -1146,7 +1159,7 @@ enum class {name} {{
let extra_params = rules_for_this_node.extra_params;
let rendered = self.get_method_signature(&parser.name, "", "",
&extra_params);
buffer.push_str(&rendered.reindent(""));
buffer.push_str(&rendered.reindent(" "));
buffer.push_str("\n");
}
}
@ -1183,6 +1196,8 @@ enum class {name} {{
self.export_declare_list_methods(&mut buffer);
self.export_declare_option_methods(&mut buffer);
buffer.push_str("\n");
buffer.push_str(&self.rules.hpp_class_footer.reindent(""));
buffer.push_str("\n");
buffer
}

View File

@ -10,7 +10,7 @@
#include "jsapi.h"
#include "frontend/BinASTParserPerTokenizer.h"
#include "frontend/BinASTParser.h"
#include "frontend/FullParseHandler.h"
#include "frontend/ParseContext.h"
#include "frontend/Parser.h"

View File

@ -23,7 +23,7 @@
#include "jsapi.h"
#include "frontend/BinASTParserPerTokenizer.h"
#include "frontend/BinASTParser.h"
#include "frontend/FullParseHandler.h"
#include "frontend/ParseContext.h"
#include "frontend/Parser.h"

View File

@ -68,7 +68,7 @@
#include "builtin/RegExp.h"
#include "builtin/TestingFunctions.h"
#if defined(JS_BUILD_BINAST)
# include "frontend/BinASTParserPerTokenizer.h"
# include "frontend/BinASTParser.h"
#endif // defined(JS_BUILD_BINAST)
#include "frontend/ModuleSharedContext.h"
#include "frontend/Parser.h"