Index: src/parsing/parser-base.h |
diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h |
index 96b54b4fd5ea25cf65b2f7d3f75863b444b349ba..aa2a46dc71a2aa849e88af5da77a5b07431d1681 100644 |
--- a/src/parsing/parser-base.h |
+++ b/src/parsing/parser-base.h |
@@ -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 |