Commit 56b8afc1 authored by verwaest's avatar verwaest Committed by Commit bot

[parser] Only track parsing-mode (and possibly switch to the preparser) in the parser

Otherwise we could in theory abort preparsing to the preparser and preparse again before aborting again... We shouldn't have this mess; so only set up mode_ in the parser in the first place.

BUG=

Review-Url: https://codereview.chromium.org/2479213002
Cr-Commit-Position: refs/heads/master@{#40809}
parent 21463f73
...@@ -198,7 +198,6 @@ class ParserBase { ...@@ -198,7 +198,6 @@ class ParserBase {
fni_(nullptr), fni_(nullptr),
ast_value_factory_(ast_value_factory), ast_value_factory_(ast_value_factory),
ast_node_factory_(ast_value_factory), ast_node_factory_(ast_value_factory),
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
parsing_module_(false), parsing_module_(false),
stack_limit_(stack_limit), stack_limit_(stack_limit),
zone_(zone), zone_(zone),
...@@ -255,8 +254,6 @@ class ParserBase { ...@@ -255,8 +254,6 @@ class ParserBase {
kDontAllowRestrictedIdentifiers kDontAllowRestrictedIdentifiers
}; };
enum Mode { PARSE_LAZILY, PARSE_EAGERLY };
enum LazyParsingResult { kLazyParsingComplete, kLazyParsingAborted }; enum LazyParsingResult { kLazyParsingComplete, kLazyParsingAborted };
enum VariableDeclarationContext { enum VariableDeclarationContext {
...@@ -591,22 +588,6 @@ class ParserBase { ...@@ -591,22 +588,6 @@ class ParserBase {
int expected_property_count_; int expected_property_count_;
}; };
class ParsingModeScope BASE_EMBEDDED {
public:
ParsingModeScope(ParserBase* parser, Mode mode)
: parser_(parser),
old_mode_(parser->mode()) {
parser_->mode_ = mode;
}
~ParsingModeScope() {
parser_->mode_ = old_mode_;
}
private:
ParserBase* parser_;
Mode old_mode_;
};
struct DeclarationDescriptor { struct DeclarationDescriptor {
enum Kind { NORMAL, PARAMETER }; enum Kind { NORMAL, PARAMETER };
Scope* scope; Scope* scope;
...@@ -753,7 +734,6 @@ class ParserBase { ...@@ -753,7 +734,6 @@ class ParserBase {
int peek_position() const { return scanner_->peek_location().beg_pos; } int peek_position() const { return scanner_->peek_location().beg_pos; }
bool stack_overflow() const { return stack_overflow_; } bool stack_overflow() const { return stack_overflow_; }
void set_stack_overflow() { stack_overflow_ = true; } void set_stack_overflow() { stack_overflow_ = true; }
Mode mode() const { return mode_; }
INLINE(Token::Value peek()) { INLINE(Token::Value peek()) {
if (stack_overflow_) return Token::ILLEGAL; if (stack_overflow_) return Token::ILLEGAL;
...@@ -1440,7 +1420,6 @@ class ParserBase { ...@@ -1440,7 +1420,6 @@ class ParserBase {
FuncNameInferrer* fni_; FuncNameInferrer* fni_;
AstValueFactory* ast_value_factory_; // Not owned. AstValueFactory* ast_value_factory_; // Not owned.
typename Types::Factory ast_node_factory_; typename Types::Factory ast_node_factory_;
Mode mode_;
bool parsing_module_; bool parsing_module_;
uintptr_t stack_limit_; uintptr_t stack_limit_;
...@@ -3924,7 +3903,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral( ...@@ -3924,7 +3903,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
FunctionKind kind = formal_parameters.scope->function_kind(); FunctionKind kind = formal_parameters.scope->function_kind();
FunctionLiteral::EagerCompileHint eager_compile_hint = FunctionLiteral::EagerCompileHint eager_compile_hint =
default_eager_compile_hint_; default_eager_compile_hint_;
bool can_preparse = mode() == PARSE_LAZILY && bool can_preparse = impl()->parse_lazily() &&
eager_compile_hint == FunctionLiteral::kShouldLazyCompile; eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
// TODO(marja): consider lazy-parsing inner arrow functions too. is_this // TODO(marja): consider lazy-parsing inner arrow functions too. is_this
// handling in Scope::ResolveVariable needs to change. // handling in Scope::ResolveVariable needs to change.
...@@ -4411,11 +4390,6 @@ ParserBase<Impl>::ParseStatementList(StatementListT body, int end_token, ...@@ -4411,11 +4390,6 @@ ParserBase<Impl>::ParseStatementList(StatementListT body, int end_token,
*ok = false; *ok = false;
return kLazyParsingComplete; return kLazyParsingComplete;
} }
// Because declarations in strict eval code don't leak into the scope
// of the eval call, it is likely that functions declared in strict
// eval code will be used within the eval code, so lazy parsing is
// probably not a win.
if (scope()->is_eval_scope()) mode_ = PARSE_EAGERLY;
} else if (impl()->IsUseAsmDirective(stat) && } else if (impl()->IsUseAsmDirective(stat) &&
token_loc.end_pos - token_loc.beg_pos == token_loc.end_pos - token_loc.beg_pos ==
sizeof("use asm") + 1) { sizeof("use asm") + 1) {
......
...@@ -590,6 +590,7 @@ Parser::Parser(ParseInfo* info) ...@@ -590,6 +590,7 @@ Parser::Parser(ParseInfo* info)
scanner_(info->unicode_cache()), scanner_(info->unicode_cache()),
reusable_preparser_(nullptr), reusable_preparser_(nullptr),
original_scope_(nullptr), original_scope_(nullptr),
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
target_stack_(nullptr), target_stack_(nullptr),
compile_options_(info->compile_options()), compile_options_(info->compile_options()),
cached_parse_data_(nullptr), cached_parse_data_(nullptr),
...@@ -2569,11 +2570,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral( ...@@ -2569,11 +2570,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// parenthesis before the function means that it will be called // parenthesis before the function means that it will be called
// immediately). bar can be parsed lazily, but we need to parse it in a mode // immediately). bar can be parsed lazily, but we need to parse it in a mode
// that tracks unresolved variables. // that tracks unresolved variables.
DCHECK_IMPLIES(mode() == PARSE_LAZILY, FLAG_lazy); DCHECK_IMPLIES(parse_lazily(), FLAG_lazy);
DCHECK_IMPLIES(mode() == PARSE_LAZILY, allow_lazy()); DCHECK_IMPLIES(parse_lazily(), allow_lazy());
DCHECK_IMPLIES(mode() == PARSE_LAZILY, extension_ == nullptr); DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
bool can_preparse = mode() == PARSE_LAZILY && bool can_preparse = parse_lazily() &&
eager_compile_hint == FunctionLiteral::kShouldLazyCompile; eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
bool is_lazy_top_level_function = bool is_lazy_top_level_function =
......
...@@ -235,6 +235,22 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -235,6 +235,22 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
original_scope_); original_scope_);
} }
bool parse_lazily() const { return mode_ == PARSE_LAZILY; }
enum Mode { PARSE_LAZILY, PARSE_EAGERLY };
class ParsingModeScope BASE_EMBEDDED {
public:
ParsingModeScope(Parser* parser, Mode mode)
: parser_(parser), old_mode_(parser->mode_) {
parser_->mode_ = mode;
}
~ParsingModeScope() { parser_->mode_ = old_mode_; }
private:
Parser* parser_;
Mode old_mode_;
};
// Runtime encoding of different completion modes. // Runtime encoding of different completion modes.
enum CompletionKind { enum CompletionKind {
kNormalCompletion, kNormalCompletion,
...@@ -1119,6 +1135,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) { ...@@ -1119,6 +1135,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
Scanner scanner_; Scanner scanner_;
PreParser* reusable_preparser_; PreParser* reusable_preparser_;
Scope* original_scope_; // for ES5 function declarations in sloppy eval Scope* original_scope_; // for ES5 function declarations in sloppy eval
Mode mode_;
friend class ParserTarget; friend class ParserTarget;
friend class ParserTargetScope; friend class ParserTargetScope;
......
...@@ -911,7 +911,10 @@ class PreParser : public ParserBase<PreParser> { ...@@ -911,7 +911,10 @@ class PreParser : public ParserBase<PreParser> {
const PreParserFormalParameters& parameters, FunctionKind kind, const PreParserFormalParameters& parameters, FunctionKind kind,
FunctionLiteral::FunctionType function_type, bool* ok); FunctionLiteral::FunctionType function_type, bool* ok);
// Indicates that we won't switch from the preparser to the preparser; we'll
// just stay where we are.
bool AllowsLazyParsingWithoutUnresolvedVariables() const { return false; } bool AllowsLazyParsingWithoutUnresolvedVariables() const { return false; }
bool parse_lazily() const { return false; }
V8_INLINE LazyParsingResult SkipFunction( V8_INLINE LazyParsingResult SkipFunction(
FunctionKind kind, DeclarationScope* function_scope, int* num_parameters, FunctionKind kind, DeclarationScope* function_scope, int* num_parameters,
...@@ -1523,7 +1526,6 @@ PreParserStatementList PreParser::ParseEagerFunctionBody( ...@@ -1523,7 +1526,6 @@ PreParserStatementList PreParser::ParseEagerFunctionBody(
PreParserIdentifier function_name, int pos, PreParserIdentifier function_name, int pos,
const PreParserFormalParameters& parameters, FunctionKind kind, const PreParserFormalParameters& parameters, FunctionKind kind,
FunctionLiteral::FunctionType function_type, bool* ok) { FunctionLiteral::FunctionType function_type, bool* ok) {
ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
PreParserStatementList result; PreParserStatementList result;
Scope* inner_scope = scope(); Scope* inner_scope = scope();
......
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