Commit 5d6eabb0 authored by nikolaos's avatar nikolaos Committed by Commit bot

[parser] Refactor bookmark in SkipLazyFunctionBody

This patch refactors the scanner bookmark in SkipLazyFunctionBody,
so that it is only used locally, instead of being passed to several
other methods.  It is replaced by a "may_abort" parameter and an
appropriate result denoting whether lazy parsing has been aborted.

It also applies the hack of aborting lazy parsing for arrow
functions that are considered to be "initialization functions".

R=adamk@chromium.org, vogelheim@chromium.org
BUG=
LOG=N

Review-Url: https://codereview.chromium.org/2297733002
Cr-Commit-Position: refs/heads/master@{#39072}
parent 5e7428b5
......@@ -126,8 +126,8 @@ struct FormalParametersBase {
// thus it must never be used where only a single statement
// is correct (e.g. an if statement branch w/o braces)!
#define CHECK_OK_CUSTOM(x) ok); \
if (!*ok) return impl()->x(); \
#define CHECK_OK_CUSTOM(x, ...) ok); \
if (!*ok) return impl()->x(__VA_ARGS__); \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
......@@ -273,6 +273,7 @@ class ParserBase {
protected:
friend class v8::internal::ExpressionClassifier<ParserTypes<Impl>>;
// clang-format off
enum AllowRestrictedIdentifiers {
kAllowRestrictedIdentifiers,
kDontAllowRestrictedIdentifiers
......@@ -283,11 +284,17 @@ class ParserBase {
PARSE_EAGERLY
};
enum LazyParsingResult {
kLazyParsingComplete,
kLazyParsingAborted
};
enum VariableDeclarationContext {
kStatementListItem,
kStatement,
kForStatement
};
// clang-format on
class Checkpoint;
class ObjectLiteralCheckerBase;
......@@ -785,8 +792,12 @@ class ParserBase {
Expect(Token::SEMICOLON, ok);
}
// A dummy function, just useful as an argument to CHECK_OK_CUSTOM.
// Dummy functions, just useful as arguments to CHECK_OK_CUSTOM.
static void Void() {}
template <typename T>
static T Return(T result) {
return result;
}
bool is_any_identifier(Token::Value token) {
return token == Token::IDENTIFIER || token == Token::ENUM ||
......@@ -820,7 +831,7 @@ class ParserBase {
}
}
bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode, bool* ok) {
bool CheckInOrOf(ForEachStatement::VisitMode* visit_mode) {
if (Check(Token::IN)) {
*visit_mode = ForEachStatement::ENUMERATE;
return true;
......@@ -3484,12 +3495,15 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
return impl()->EmptyExpression();
}
typename Types::StatementList body;
typename Types::StatementList body = impl()->NullStatementList();
int num_parameters = formal_parameters.scope->num_parameters();
int materialized_literal_count = -1;
int expected_property_count = -1;
FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction;
FunctionLiteral::EagerCompileHint eager_compile_hint =
FunctionLiteral::kShouldLazyCompile;
bool should_be_used_once_hint = false;
{
FunctionState function_state(&function_state_, &scope_state_,
formal_parameters.scope, arrow_kind);
......@@ -3508,14 +3522,30 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
formal_parameters.scope->AllowsLazyParsing());
if (is_lazily_parsed) {
body = impl()->NewStatementList(0);
impl()->SkipLazyFunctionBody(&materialized_literal_count,
&expected_property_count, CHECK_OK);
Scanner::BookmarkScope bookmark(scanner());
bool may_abort = bookmark.Set();
LazyParsingResult result = impl()->SkipLazyFunctionBody(
&materialized_literal_count, &expected_property_count, may_abort,
CHECK_OK);
if (formal_parameters.materialized_literals_count > 0) {
materialized_literal_count +=
formal_parameters.materialized_literals_count;
}
} else {
if (result == kLazyParsingAborted) {
bookmark.Reset();
// Trigger eager (re-)parsing, just below this block.
is_lazily_parsed = false;
// This is probably an initialization function. Inform the compiler it
// should also eager-compile this function, and that we expect it to
// be used once.
eager_compile_hint = FunctionLiteral::kShouldEagerCompile;
should_be_used_once_hint = true;
}
}
if (!is_lazily_parsed) {
body = impl()->ParseEagerFunctionBody(
impl()->EmptyIdentifier(), kNoSourcePosition, formal_parameters,
arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK);
......@@ -3576,12 +3606,14 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
impl()->EmptyIdentifierString(), formal_parameters.scope, body,
materialized_literal_count, expected_property_count, num_parameters,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression,
FunctionLiteral::kShouldLazyCompile, arrow_kind,
FunctionLiteral::kAnonymousExpression, eager_compile_hint, arrow_kind,
formal_parameters.scope->start_position());
function_literal->set_function_token_position(
formal_parameters.scope->start_position());
if (should_be_used_once_hint) {
function_literal->set_should_be_used_once_hint();
}
if (fni_ != NULL) impl()->InferFunctionName(fni_, function_literal);
......@@ -3733,7 +3765,6 @@ void ParserBase<Impl>::CheckDestructuringElement(ExpressionT expression,
}
}
#undef CHECK_OK
#undef CHECK_OK_CUSTOM
......
......@@ -277,17 +277,14 @@ class TargetScope BASE_EMBEDDED {
// thus it must never be used where only a single statement
// is correct (e.g. an if statement branch w/o braces)!
#define CHECK_OK ok); \
if (!*ok) return nullptr; \
#define CHECK_OK_VALUE(x) ok); \
if (!*ok) return x; \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
#define CHECK_OK_VOID ok); \
if (!*ok) return; \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
#define CHECK_OK CHECK_OK_VALUE(nullptr)
#define CHECK_OK_VOID CHECK_OK_VALUE(this->Void())
#define CHECK_FAILED /**/); \
if (failed_) return nullptr; \
......@@ -3255,8 +3252,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
int each_beg_pos = scanner()->location().beg_pos;
int each_end_pos = scanner()->location().end_pos;
if (CheckInOrOf(&mode, ok)) {
if (!*ok) return nullptr;
if (CheckInOrOf(&mode)) {
if (parsing_result.declarations.length() != 1) {
ReportMessageAt(parsing_result.bindings_loc,
MessageTemplate::kForInOfLoopMultiBindings,
......@@ -3450,7 +3446,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
int lhs_end_pos = scanner()->location().end_pos;
ForEachStatement::VisitMode mode = ForEachStatement::ENUMERATE;
bool is_for_each = CheckInOrOf(&mode, CHECK_OK);
bool is_for_each = CheckInOrOf(&mode);
bool is_destructuring = is_for_each && (expression->IsArrayLiteral() ||
expression->IsObjectLiteral());
......@@ -3964,22 +3960,23 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
if (formals.has_rest) arity--;
// Eager or lazy parse?
// If is_lazily_parsed, we'll parse lazy. If we can set a bookmark, we'll
// pass it to SkipLazyFunctionBody, which may use it to abort lazy
// parsing if it suspect that wasn't a good idea. If so, or if we didn't
// try to lazy parse in the first place, we'll have to parse eagerly.
Scanner::BookmarkScope bookmark(scanner());
// If is_lazily_parsed, we'll parse lazily. We'll call SkipLazyFunctionBody,
// which may decide to abort lazy parsing if it suspects that wasn't a good
// idea. If so (in which case the parser is expected to have backtracked),
// or if we didn't try to lazy parse in the first place, we'll have to parse
// eagerly.
if (is_lazily_parsed) {
Scanner::BookmarkScope* maybe_bookmark =
bookmark.Set() ? &bookmark : nullptr;
SkipLazyFunctionBody(&materialized_literal_count,
&expected_property_count, /*CHECK_OK*/ ok,
maybe_bookmark);
Scanner::BookmarkScope bookmark(scanner());
bool may_abort = bookmark.Set();
LazyParsingResult result =
SkipLazyFunctionBody(&materialized_literal_count,
&expected_property_count, may_abort, CHECK_OK);
materialized_literal_count += formals.materialized_literals_count +
function_state.materialized_literal_count();
if (bookmark.HasBeenReset()) {
if (result == kLazyParsingAborted) {
bookmark.Reset();
// Trigger eager (re-)parsing, just below this block.
is_lazily_parsed = false;
......@@ -4079,10 +4076,9 @@ Expression* Parser::ParseAsyncFunctionExpression(bool* ok) {
language_mode(), CHECK_OK);
}
void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
int* expected_property_count, bool* ok,
Scanner::BookmarkScope* bookmark) {
DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
Parser::LazyParsingResult Parser::SkipLazyFunctionBody(
int* materialized_literal_count, int* expected_property_count,
bool may_abort, bool* ok) {
if (produce_cached_parse_data()) CHECK(log_);
int function_block_pos = position();
......@@ -4100,14 +4096,14 @@ void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
scanner()->SeekForward(entry.end_pos() - 1);
scope->set_end_position(entry.end_pos());
Expect(Token::RBRACE, CHECK_OK_VOID);
Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
total_preparse_skipped_ += scope->end_position() - function_block_pos;
*materialized_literal_count = entry.literal_count();
*expected_property_count = entry.property_count();
SetLanguageMode(scope, entry.language_mode());
if (entry.uses_super_property()) scope->RecordSuperPropertyUsage();
if (entry.calls_eval()) scope->RecordEvalCall();
return;
return kLazyParsingComplete;
}
cached_parse_data_->Reject();
}
......@@ -4115,25 +4111,26 @@ void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
// AST. This gathers the data needed to build a lazy function.
SingletonLogger logger;
PreParser::PreParseResult result =
ParseLazyFunctionBodyWithPreParser(&logger, bookmark);
if (bookmark && bookmark->HasBeenReset()) {
return; // Return immediately if pre-parser devided to abort parsing.
ParseLazyFunctionBodyWithPreParser(&logger, may_abort);
// Return immediately if pre-parser decided to abort parsing.
if (result == PreParser::kPreParseAbort) {
return kLazyParsingAborted;
}
if (result == PreParser::kPreParseStackOverflow) {
// Propagate stack overflow.
set_stack_overflow();
*ok = false;
return;
return kLazyParsingComplete;
}
if (logger.has_error()) {
ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
logger.message(), logger.argument_opt(),
logger.error_type());
*ok = false;
return;
return kLazyParsingComplete;
}
scope->set_end_position(logger.end());
Expect(Token::RBRACE, CHECK_OK_VOID);
Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
total_preparse_skipped_ += scope->end_position() - function_block_pos;
*materialized_literal_count = logger.literals();
*expected_property_count = logger.properties();
......@@ -4148,6 +4145,7 @@ void Parser::SkipLazyFunctionBody(int* materialized_literal_count,
*expected_property_count, language_mode(),
scope->uses_super_property(), scope->calls_eval());
}
return kLazyParsingComplete;
}
......@@ -4599,9 +4597,8 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
return result;
}
PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
SingletonLogger* logger, Scanner::BookmarkScope* bookmark) {
SingletonLogger* logger, bool may_abort) {
// This function may be called on a background thread too; record only the
// main thread preparse times.
if (pre_parse_timer_ != NULL) {
......@@ -4628,7 +4625,7 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
language_mode(), function_state_->kind(),
scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_,
logger, bookmark, use_counts_);
logger, may_abort, use_counts_);
if (pre_parse_timer_ != NULL) {
pre_parse_timer_->Stop();
}
......
......@@ -510,16 +510,14 @@ class Parser : public ParserBase<Parser> {
// Skip over a lazy function, either using cached data if we have it, or
// by parsing the function with PreParser. Consumes the ending }.
//
// If bookmark is set, the (pre-)parser may decide to abort skipping
// If may_abort == true, the (pre-)parser may decide to abort skipping
// in order to force the function to be eagerly parsed, after all.
// In this case, it'll reset the scanner using the bookmark.
void SkipLazyFunctionBody(int* materialized_literal_count,
int* expected_property_count, bool* ok,
Scanner::BookmarkScope* bookmark = nullptr);
LazyParsingResult SkipLazyFunctionBody(int* materialized_literal_count,
int* expected_property_count,
bool may_abort, bool* ok);
PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(
SingletonLogger* logger, Scanner::BookmarkScope* bookmark = nullptr);
SingletonLogger* logger, bool may_abort);
Block* BuildParameterInitializationBlock(
const ParserFormalParameters& parameters, bool* ok);
......@@ -849,6 +847,7 @@ class Parser : public ParserBase<Parser> {
V8_INLINE static ZoneList<Expression*>* NullExpressionList() {
return nullptr;
}
V8_INLINE static ZoneList<Statement*>* NullStatementList() { return nullptr; }
// Non-NULL empty string.
V8_INLINE const AstRawString* EmptyIdentifierString() const {
......
......@@ -29,18 +29,14 @@ namespace internal {
// thus it must never be used where only a single statement
// is correct (e.g. an if statement branch w/o braces)!
#define CHECK_OK ok); \
if (!*ok) return Statement::Default(); \
#define CHECK_OK_VALUE(x) ok); \
if (!*ok) return x; \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
// Used in functions where the return type is not ExpressionT.
#define CHECK_OK_CUSTOM(x) ok); \
if (!*ok) return this->x(); \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
#define CHECK_OK CHECK_OK_VALUE(Statement::Default())
#define CHECK_OK_VOID CHECK_OK_VALUE(this->Void())
PreParserIdentifier PreParser::GetSymbol() const {
switch (scanner()->current_token()) {
......@@ -75,8 +71,7 @@ PreParserIdentifier PreParser::GetSymbol() const {
PreParser::PreParseResult PreParser::PreParseLazyFunction(
LanguageMode language_mode, FunctionKind kind, bool has_simple_parameters,
bool parsing_module, ParserRecorder* log, Scanner::BookmarkScope* bookmark,
int* use_counts) {
bool parsing_module, ParserRecorder* log, bool may_abort, int* use_counts) {
parsing_module_ = parsing_module;
log_ = log;
use_counts_ = use_counts;
......@@ -93,10 +88,10 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
DCHECK_EQ(Token::LBRACE, scanner()->current_token());
bool ok = true;
int start_position = peek_position();
ParseLazyFunctionLiteralBody(&ok, bookmark);
LazyParsingResult result = ParseLazyFunctionLiteralBody(may_abort, &ok);
use_counts_ = nullptr;
if (bookmark && bookmark->HasBeenReset()) {
// Do nothing, as we've just aborted scanning this function.
if (result == kLazyParsingAborted) {
return kPreParseAbort;
} else if (stack_overflow()) {
return kPreParseStackOverflow;
} else if (!ok) {
......@@ -107,7 +102,6 @@ PreParser::PreParseResult PreParser::PreParseLazyFunction(
int end_pos = scanner()->location().end_pos;
CheckStrictOctalLiteral(start_position, end_pos, &ok);
CheckDecimalLiteralWithLeadingZero(use_counts, start_position, end_pos);
if (!ok) return kPreParseSuccess;
}
}
return kPreParseSuccess;
......@@ -171,15 +165,12 @@ PreParser::Statement PreParser::ParseStatementListItem(bool* ok) {
return ParseStatement(kAllowLabelledFunctionStatement, ok);
}
void PreParser::ParseStatementList(int end_token, bool* ok,
Scanner::BookmarkScope* bookmark) {
PreParser::LazyParsingResult PreParser::ParseStatementList(int end_token,
bool may_abort,
bool* ok) {
// SourceElements ::
// (Statement)* <end_token>
// Bookkeeping for trial parse if bookmark is set:
DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
bool maybe_reset = bookmark != nullptr;
int count_statements = 0;
bool directive_prologue = true;
......@@ -189,7 +180,8 @@ void PreParser::ParseStatementList(int end_token, bool* ok,
}
bool starts_with_identifier = peek() == Token::IDENTIFIER;
Scanner::Location token_loc = scanner()->peek_location();
Statement statement = ParseStatementListItem(CHECK_OK_CUSTOM(Void));
Statement statement =
ParseStatementListItem(CHECK_OK_VALUE(kLazyParsingComplete));
if (directive_prologue) {
bool use_strict_found = statement.IsUseStrictLiteral();
......@@ -209,7 +201,7 @@ void PreParser::ParseStatementList(int end_token, bool* ok,
MessageTemplate::kIllegalLanguageModeDirective,
"use strict");
*ok = false;
return;
return kLazyParsingComplete;
}
}
......@@ -218,15 +210,15 @@ void PreParser::ParseStatementList(int end_token, bool* ok,
// Our current definition of 'long and trivial' is:
// - over 200 statements
// - all starting with an identifier (i.e., no if, for, while, etc.)
if (maybe_reset && (!starts_with_identifier ||
++count_statements > kLazyParseTrialLimit)) {
if (count_statements > kLazyParseTrialLimit) {
bookmark->Reset();
return;
if (may_abort) {
if (!starts_with_identifier) {
may_abort = false;
} else if (++count_statements > kLazyParseTrialLimit) {
return kLazyParsingAborted;
}
maybe_reset = false;
}
}
return kLazyParsingComplete;
}
......@@ -815,8 +807,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
&is_binding_pattern, &first_initializer_loc,
&bindings_loc, CHECK_OK);
if (is_lexical) has_lexical = true;
if (CheckInOrOf(&mode, ok)) {
if (!*ok) return Statement::Default();
if (CheckInOrOf(&mode)) {
if (decl_count != 1) {
ReportMessageAt(bindings_loc,
MessageTemplate::kForInOfLoopMultiBindings,
......@@ -860,7 +851,7 @@ PreParser::Statement PreParser::ParseForStatement(bool* ok) {
ExpressionClassifier classifier(this);
Expression lhs = ParseExpressionCoverGrammar(false, CHECK_OK);
int lhs_end_pos = scanner()->location().end_pos;
bool is_for_each = CheckInOrOf(&mode, CHECK_OK);
bool is_for_each = CheckInOrOf(&mode);
bool is_destructuring = is_for_each &&
(lhs->IsArrayLiteral() || lhs->IsObjectLiteral());
......@@ -1020,12 +1011,7 @@ PreParser::Statement PreParser::ParseDebuggerStatement(bool* ok) {
// Redefinition of CHECK_OK for parsing expressions.
#undef CHECK_OK
#define CHECK_OK ok); \
if (!*ok) return Expression::Default(); \
((void)0
#define DUMMY ) // to make indentation work
#undef DUMMY
#define CHECK_OK CHECK_OK_VALUE(Expression::Default())
PreParser::Expression PreParser::ParseFunctionLiteral(
Identifier function_name, Scanner::Location function_name_location,
......@@ -1062,7 +1048,7 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
Expect(Token::LBRACE, CHECK_OK);
if (is_lazily_parsed) {
ParseLazyFunctionLiteralBody(CHECK_OK);
ParseLazyFunctionLiteralBody(false, CHECK_OK);
} else {
ParseStatementList(Token::RBRACE, CHECK_OK);
}
......@@ -1116,12 +1102,12 @@ PreParser::Expression PreParser::ParseAsyncFunctionExpression(bool* ok) {
return Expression::Default();
}
void PreParser::ParseLazyFunctionLiteralBody(bool* ok,
Scanner::BookmarkScope* bookmark) {
PreParser::LazyParsingResult PreParser::ParseLazyFunctionLiteralBody(
bool may_abort, bool* ok) {
int body_start = position();
ParseStatementList(Token::RBRACE, ok, bookmark);
if (!*ok) return;
if (bookmark && bookmark->HasBeenReset()) return;
LazyParsingResult result = ParseStatementList(
Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete));
if (result == kLazyParsingAborted) return result;
// Position right after terminal '}'.
DCHECK_EQ(Token::RBRACE, scanner()->peek());
......@@ -1132,6 +1118,7 @@ void PreParser::ParseLazyFunctionLiteralBody(bool* ok,
function_state_->materialized_literal_count(),
function_state_->expected_property_count(), language_mode(),
scope->uses_super_property(), scope->calls_eval());
return kLazyParsingComplete;
}
PreParserExpression PreParser::ParseClassLiteral(
......@@ -1228,7 +1215,7 @@ void PreParser::ParseAsyncArrowSingleExpressionBody(PreParserStatementList body,
scope()->ForceContextAllocation();
PreParserExpression return_value =
ParseAssignmentExpression(accept_IN, CHECK_OK_CUSTOM(Void));
ParseAssignmentExpression(accept_IN, CHECK_OK_VOID);
body->Add(PreParserStatement::ExpressionStatement(return_value), zone());
}
......
......@@ -296,6 +296,7 @@ class PreParserExpression {
// More dummy implementations of things PreParser doesn't need to track:
void set_index(int index) {} // For YieldExpressions
void set_should_eager_compile() {}
void set_should_be_used_once_hint() {}
int position() const { return kNoSourcePosition; }
void set_function_token_position(int position) {}
......@@ -642,6 +643,7 @@ class PreParser : public ParserBase<PreParser> {
enum PreParseResult {
kPreParseStackOverflow,
kPreParseAbort,
kPreParseSuccess
};
......@@ -698,11 +700,7 @@ class PreParser : public ParserBase<PreParser> {
FunctionKind kind,
bool has_simple_parameters,
bool parsing_module, ParserRecorder* log,
Scanner::BookmarkScope* bookmark,
int* use_counts);
// A dummy function, just useful as an argument to CHECK_OK_CUSTOM.
static void Void() {}
bool may_abort, int* use_counts);
private:
static const int kLazyParseTrialLimit = 200;
......@@ -717,8 +715,12 @@ class PreParser : public ParserBase<PreParser> {
// By making the 'exception handling' explicit, we are forced to check
// for failure at the call sites.
Statement ParseStatementListItem(bool* ok);
void ParseStatementList(int end_token, bool* ok,
Scanner::BookmarkScope* bookmark = nullptr);
V8_INLINE void ParseStatementList(int end_token, bool* ok) {
LazyParsingResult result = ParseStatementList(end_token, false, ok);
USE(result); // The result is just used in debug modes.
DCHECK_EQ(result, kLazyParsingComplete);
}
LazyParsingResult ParseStatementList(int end_token, bool may_abort, bool* ok);
Statement ParseStatement(AllowLabelledFunctionStatement allow_function,
bool* ok);
Statement ParseSubStatement(AllowLabelledFunctionStatement allow_function,
......@@ -764,18 +766,18 @@ class PreParser : public ParserBase<PreParser> {
const PreParserFormalParameters& parameters, FunctionKind kind,
FunctionLiteral::FunctionType function_type, bool* ok);
V8_INLINE void SkipLazyFunctionBody(
int* materialized_literal_count, int* expected_property_count, bool* ok,
Scanner::BookmarkScope* bookmark = nullptr) {
V8_INLINE LazyParsingResult
SkipLazyFunctionBody(int* materialized_literal_count,
int* expected_property_count, bool may_abort, bool* ok) {
UNREACHABLE();
return kLazyParsingComplete;
}
Expression ParseFunctionLiteral(
Identifier name, Scanner::Location function_name_location,
FunctionNameValidity function_name_validity, FunctionKind kind,
int function_token_pos, FunctionLiteral::FunctionType function_type,
LanguageMode language_mode, bool* ok);
void ParseLazyFunctionLiteralBody(bool* ok,
Scanner::BookmarkScope* bookmark = nullptr);
LazyParsingResult ParseLazyFunctionLiteralBody(bool may_abort, bool* ok);
PreParserExpression ParseClassLiteral(PreParserIdentifier name,
Scanner::Location class_name_location,
......@@ -1009,6 +1011,9 @@ class PreParser : public ParserBase<PreParser> {
V8_INLINE static PreParserExpressionList NullExpressionList() {
return PreParserExpressionList();
}
V8_INLINE static PreParserStatementList NullStatementList() {
return PreParserStatementList();
}
V8_INLINE PreParserIdentifier EmptyIdentifierString() const {
return PreParserIdentifier::Default();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment