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 {
fni_(nullptr),
ast_value_factory_(ast_value_factory),
ast_node_factory_(ast_value_factory),
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
parsing_module_(false),
stack_limit_(stack_limit),
zone_(zone),
......@@ -255,8 +254,6 @@ class ParserBase {
kDontAllowRestrictedIdentifiers
};
enum Mode { PARSE_LAZILY, PARSE_EAGERLY };
enum LazyParsingResult { kLazyParsingComplete, kLazyParsingAborted };
enum VariableDeclarationContext {
......@@ -591,22 +588,6 @@ class ParserBase {
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 {
enum Kind { NORMAL, PARAMETER };
Scope* scope;
......@@ -753,7 +734,6 @@ class ParserBase {
int peek_position() const { return scanner_->peek_location().beg_pos; }
bool stack_overflow() const { return stack_overflow_; }
void set_stack_overflow() { stack_overflow_ = true; }
Mode mode() const { return mode_; }
INLINE(Token::Value peek()) {
if (stack_overflow_) return Token::ILLEGAL;
......@@ -1440,7 +1420,6 @@ class ParserBase {
FuncNameInferrer* fni_;
AstValueFactory* ast_value_factory_; // Not owned.
typename Types::Factory ast_node_factory_;
Mode mode_;
bool parsing_module_;
uintptr_t stack_limit_;
......@@ -3924,7 +3903,7 @@ ParserBase<Impl>::ParseArrowFunctionLiteral(
FunctionKind kind = formal_parameters.scope->function_kind();
FunctionLiteral::EagerCompileHint eager_compile_hint =
default_eager_compile_hint_;
bool can_preparse = mode() == PARSE_LAZILY &&
bool can_preparse = impl()->parse_lazily() &&
eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
// TODO(marja): consider lazy-parsing inner arrow functions too. is_this
// handling in Scope::ResolveVariable needs to change.
......@@ -4411,11 +4390,6 @@ ParserBase<Impl>::ParseStatementList(StatementListT body, int end_token,
*ok = false;
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) &&
token_loc.end_pos - token_loc.beg_pos ==
sizeof("use asm") + 1) {
......
......@@ -590,6 +590,7 @@ Parser::Parser(ParseInfo* info)
scanner_(info->unicode_cache()),
reusable_preparser_(nullptr),
original_scope_(nullptr),
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
target_stack_(nullptr),
compile_options_(info->compile_options()),
cached_parse_data_(nullptr),
......@@ -2569,11 +2570,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// 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
// that tracks unresolved variables.
DCHECK_IMPLIES(mode() == PARSE_LAZILY, FLAG_lazy);
DCHECK_IMPLIES(mode() == PARSE_LAZILY, allow_lazy());
DCHECK_IMPLIES(mode() == PARSE_LAZILY, extension_ == nullptr);
DCHECK_IMPLIES(parse_lazily(), FLAG_lazy);
DCHECK_IMPLIES(parse_lazily(), allow_lazy());
DCHECK_IMPLIES(parse_lazily(), extension_ == nullptr);
bool can_preparse = mode() == PARSE_LAZILY &&
bool can_preparse = parse_lazily() &&
eager_compile_hint == FunctionLiteral::kShouldLazyCompile;
bool is_lazy_top_level_function =
......
......@@ -235,6 +235,22 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
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.
enum CompletionKind {
kNormalCompletion,
......@@ -1119,6 +1135,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
Scanner scanner_;
PreParser* reusable_preparser_;
Scope* original_scope_; // for ES5 function declarations in sloppy eval
Mode mode_;
friend class ParserTarget;
friend class ParserTargetScope;
......
......@@ -911,7 +911,10 @@ class PreParser : public ParserBase<PreParser> {
const PreParserFormalParameters& parameters, FunctionKind kind,
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 parse_lazily() const { return false; }
V8_INLINE LazyParsingResult SkipFunction(
FunctionKind kind, DeclarationScope* function_scope, int* num_parameters,
......@@ -1523,7 +1526,6 @@ PreParserStatementList PreParser::ParseEagerFunctionBody(
PreParserIdentifier function_name, int pos,
const PreParserFormalParameters& parameters, FunctionKind kind,
FunctionLiteral::FunctionType function_type, bool* ok) {
ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
PreParserStatementList result;
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