[parser] Give preparser and parser independent loggers
This - removes the ParserRecorder base class, - devirtualizes the LogFunction and LogMessage functions, - reuses the SingletonLogger for all preparser calls In a subsequent step the preparser should probably log directly to the CompleteParserRecorder rather than indirectly through the singleton logger... BUG= Review-Url: https://codereview.chromium.org/2474393003 Cr-Commit-Position: refs/heads/master@{#40803}
This commit is contained in:
parent
3de5204737
commit
32105d214d
@ -191,15 +191,13 @@ class ParserBase {
|
||||
const Impl* impl() const { return static_cast<const Impl*>(this); }
|
||||
|
||||
ParserBase(Zone* zone, Scanner* scanner, uintptr_t stack_limit,
|
||||
v8::Extension* extension, AstValueFactory* ast_value_factory,
|
||||
ParserRecorder* log)
|
||||
v8::Extension* extension, AstValueFactory* ast_value_factory)
|
||||
: scope_state_(nullptr),
|
||||
function_state_(nullptr),
|
||||
extension_(extension),
|
||||
fni_(nullptr),
|
||||
ast_value_factory_(ast_value_factory),
|
||||
ast_node_factory_(ast_value_factory),
|
||||
log_(log),
|
||||
mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
|
||||
parsing_module_(false),
|
||||
stack_limit_(stack_limit),
|
||||
@ -1442,7 +1440,6 @@ class ParserBase {
|
||||
FuncNameInferrer* fni_;
|
||||
AstValueFactory* ast_value_factory_; // Not owned.
|
||||
typename Types::Factory ast_node_factory_;
|
||||
ParserRecorder* log_;
|
||||
Mode mode_;
|
||||
bool parsing_module_;
|
||||
uintptr_t stack_limit_;
|
||||
|
@ -586,15 +586,16 @@ Expression* Parser::NewV8Intrinsic(const AstRawString* name,
|
||||
|
||||
Parser::Parser(ParseInfo* info)
|
||||
: ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(),
|
||||
info->extension(), info->ast_value_factory(), NULL),
|
||||
info->extension(), info->ast_value_factory()),
|
||||
scanner_(info->unicode_cache()),
|
||||
reusable_preparser_(NULL),
|
||||
original_scope_(NULL),
|
||||
target_stack_(NULL),
|
||||
reusable_preparser_(nullptr),
|
||||
original_scope_(nullptr),
|
||||
target_stack_(nullptr),
|
||||
compile_options_(info->compile_options()),
|
||||
cached_parse_data_(nullptr),
|
||||
total_preparse_skipped_(0),
|
||||
parsing_on_main_thread_(true) {
|
||||
parsing_on_main_thread_(true),
|
||||
log_(nullptr) {
|
||||
// Even though we were passed ParseInfo, we should not store it in
|
||||
// Parser - this makes sure that Isolate is not accidentally accessed via
|
||||
// ParseInfo during background parsing.
|
||||
@ -679,10 +680,10 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
|
||||
fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
|
||||
|
||||
// Initialize parser state.
|
||||
CompleteParserRecorder recorder;
|
||||
ParserLogger logger;
|
||||
|
||||
if (produce_cached_parse_data()) {
|
||||
log_ = &recorder;
|
||||
log_ = &logger;
|
||||
} else if (consume_cached_parse_data()) {
|
||||
cached_parse_data_->Initialize();
|
||||
}
|
||||
@ -702,7 +703,7 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
|
||||
}
|
||||
HandleSourceURLComments(isolate, info->script());
|
||||
|
||||
if (FLAG_trace_parse && result != NULL) {
|
||||
if (FLAG_trace_parse && result != nullptr) {
|
||||
double ms = timer.Elapsed().InMillisecondsF();
|
||||
if (info->is_eval()) {
|
||||
PrintF("[parsing eval");
|
||||
@ -715,10 +716,10 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) {
|
||||
}
|
||||
PrintF(" - took %0.3f ms]\n", ms);
|
||||
}
|
||||
if (produce_cached_parse_data()) {
|
||||
if (result != NULL) *info->cached_data() = recorder.GetScriptData();
|
||||
log_ = NULL;
|
||||
if (produce_cached_parse_data() && result != nullptr) {
|
||||
*info->cached_data() = logger.GetScriptData();
|
||||
}
|
||||
log_ = nullptr;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -2774,9 +2775,8 @@ Parser::LazyParsingResult Parser::SkipFunction(
|
||||
}
|
||||
// With no cached data, we partially parse the function, without building an
|
||||
// AST. This gathers the data needed to build a lazy function.
|
||||
SingletonLogger logger;
|
||||
PreParser::PreParseResult result = ParseFunctionWithPreParser(
|
||||
kind, function_scope, &logger, is_inner_function, may_abort);
|
||||
kind, function_scope, is_inner_function, may_abort);
|
||||
|
||||
// Return immediately if pre-parser decided to abort parsing.
|
||||
if (result == PreParser::kPreParseAbort) return kLazyParsingAborted;
|
||||
@ -2786,25 +2786,23 @@ Parser::LazyParsingResult Parser::SkipFunction(
|
||||
*ok = false;
|
||||
return kLazyParsingComplete;
|
||||
}
|
||||
if (logger.has_error()) {
|
||||
ReportMessageAt(Scanner::Location(logger.start(), logger.end()),
|
||||
logger.message(), logger.argument_opt(),
|
||||
logger.error_type());
|
||||
PreParserLogger* logger = reusable_preparser_->logger();
|
||||
if (logger->has_error()) {
|
||||
ReportMessageAt(Scanner::Location(logger->start(), logger->end()),
|
||||
logger->message(), logger->argument_opt(),
|
||||
logger->error_type());
|
||||
*ok = false;
|
||||
return kLazyParsingComplete;
|
||||
}
|
||||
function_scope->set_end_position(logger.end());
|
||||
function_scope->set_end_position(logger->end());
|
||||
Expect(Token::RBRACE, CHECK_OK_VALUE(kLazyParsingComplete));
|
||||
total_preparse_skipped_ +=
|
||||
function_scope->end_position() - function_scope->start_position();
|
||||
*num_parameters = logger.num_parameters();
|
||||
*function_length = logger.function_length();
|
||||
*has_duplicate_parameters = logger.has_duplicate_parameters();
|
||||
*materialized_literal_count = logger.literals();
|
||||
*expected_property_count = logger.properties();
|
||||
SetLanguageMode(function_scope, logger.language_mode());
|
||||
if (logger.uses_super_property()) function_scope->RecordSuperPropertyUsage();
|
||||
if (logger.calls_eval()) function_scope->RecordEvalCall();
|
||||
*num_parameters = logger->num_parameters();
|
||||
*function_length = logger->function_length();
|
||||
*has_duplicate_parameters = logger->has_duplicate_parameters();
|
||||
*materialized_literal_count = logger->literals();
|
||||
*expected_property_count = logger->properties();
|
||||
if (!is_inner_function && produce_cached_parse_data()) {
|
||||
DCHECK(log_);
|
||||
log_->LogFunction(
|
||||
@ -3287,13 +3285,13 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody(
|
||||
}
|
||||
|
||||
PreParser::PreParseResult Parser::ParseFunctionWithPreParser(
|
||||
FunctionKind kind, DeclarationScope* function_scope,
|
||||
SingletonLogger* logger, bool is_inner_function, bool may_abort) {
|
||||
FunctionKind kind, DeclarationScope* function_scope, bool is_inner_function,
|
||||
bool may_abort) {
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.PreParse");
|
||||
|
||||
if (reusable_preparser_ == NULL) {
|
||||
reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(),
|
||||
NULL, stack_limit_);
|
||||
reusable_preparser_ =
|
||||
new PreParser(zone(), &scanner_, ast_value_factory(), stack_limit_);
|
||||
reusable_preparser_->set_allow_lazy(true);
|
||||
#define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
|
||||
SET_ALLOW(natives);
|
||||
@ -3309,8 +3307,8 @@ PreParser::PreParseResult Parser::ParseFunctionWithPreParser(
|
||||
DCHECK(!is_inner_function || !may_abort);
|
||||
|
||||
PreParser::PreParseResult result = reusable_preparser_->PreParseFunction(
|
||||
kind, function_scope, parsing_module_, logger, is_inner_function,
|
||||
may_abort, use_counts_);
|
||||
kind, function_scope, parsing_module_, is_inner_function, may_abort,
|
||||
use_counts_);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -3809,8 +3807,8 @@ void Parser::ParseOnBackground(ParseInfo* info) {
|
||||
DCHECK(info->literal() == NULL);
|
||||
FunctionLiteral* result = NULL;
|
||||
|
||||
CompleteParserRecorder recorder;
|
||||
if (produce_cached_parse_data()) log_ = &recorder;
|
||||
ParserLogger logger;
|
||||
if (produce_cached_parse_data()) log_ = &logger;
|
||||
|
||||
std::unique_ptr<Utf16CharacterStream> stream;
|
||||
Utf16CharacterStream* stream_ptr;
|
||||
@ -3847,7 +3845,7 @@ void Parser::ParseOnBackground(ParseInfo* info) {
|
||||
// care of calling Parser::Internalize just before compilation.
|
||||
|
||||
if (produce_cached_parse_data()) {
|
||||
if (result != NULL) *info->cached_data() = recorder.GetScriptData();
|
||||
if (result != NULL) *info->cached_data() = logger.GetScriptData();
|
||||
log_ = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -134,7 +134,6 @@ class ParseData {
|
||||
// JAVASCRIPT PARSING
|
||||
|
||||
class Parser;
|
||||
class SingletonLogger;
|
||||
|
||||
|
||||
struct ParserFormalParameters : FormalParametersBase {
|
||||
@ -523,7 +522,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
|
||||
|
||||
PreParser::PreParseResult ParseFunctionWithPreParser(FunctionKind kind,
|
||||
DeclarationScope* scope,
|
||||
SingletonLogger* logger,
|
||||
bool is_inner_function,
|
||||
bool may_abort);
|
||||
|
||||
@ -1137,6 +1135,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
|
||||
int total_preparse_skipped_;
|
||||
|
||||
bool parsing_on_main_thread_;
|
||||
ParserLogger* log_;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -12,10 +12,11 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
void CompleteParserRecorder::LogFunction(
|
||||
int start, int end, int num_parameters, int function_length,
|
||||
bool has_duplicate_parameters, int literals, int properties,
|
||||
LanguageMode language_mode, bool uses_super_property, bool calls_eval) {
|
||||
void ParserLogger::LogFunction(int start, int end, int num_parameters,
|
||||
int function_length,
|
||||
bool has_duplicate_parameters, int literals,
|
||||
int properties, LanguageMode language_mode,
|
||||
bool uses_super_property, bool calls_eval) {
|
||||
function_store_.Add(start);
|
||||
function_store_.Add(end);
|
||||
function_store_.Add(num_parameters);
|
||||
@ -27,7 +28,7 @@ void CompleteParserRecorder::LogFunction(
|
||||
has_duplicate_parameters));
|
||||
}
|
||||
|
||||
CompleteParserRecorder::CompleteParserRecorder() {
|
||||
ParserLogger::ParserLogger() {
|
||||
preamble_[PreparseDataConstants::kMagicOffset] =
|
||||
PreparseDataConstants::kMagicNumber;
|
||||
preamble_[PreparseDataConstants::kVersionOffset] =
|
||||
@ -41,11 +42,9 @@ CompleteParserRecorder::CompleteParserRecorder() {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void CompleteParserRecorder::LogMessage(int start_pos, int end_pos,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg_opt,
|
||||
ParseErrorType error_type) {
|
||||
void ParserLogger::LogMessage(int start_pos, int end_pos,
|
||||
MessageTemplate::Template message,
|
||||
const char* arg_opt, ParseErrorType error_type) {
|
||||
if (HasError()) return;
|
||||
preamble_[PreparseDataConstants::kHasErrorOffset] = true;
|
||||
function_store_.Reset();
|
||||
@ -63,16 +62,14 @@ void CompleteParserRecorder::LogMessage(int start_pos, int end_pos,
|
||||
if (arg_opt != NULL) WriteString(CStrVector(arg_opt));
|
||||
}
|
||||
|
||||
|
||||
void CompleteParserRecorder::WriteString(Vector<const char> str) {
|
||||
void ParserLogger::WriteString(Vector<const char> str) {
|
||||
function_store_.Add(str.length());
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
function_store_.Add(str[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ScriptData* CompleteParserRecorder::GetScriptData() {
|
||||
ScriptData* ParserLogger::GetScriptData() {
|
||||
int function_size = function_store_.size();
|
||||
int total_size = PreparseDataConstants::kHeaderSize + function_size;
|
||||
unsigned* data = NewArray<unsigned>(total_size);
|
||||
|
@ -46,34 +46,9 @@ class ScriptData {
|
||||
DISALLOW_COPY_AND_ASSIGN(ScriptData);
|
||||
};
|
||||
|
||||
// Abstract interface for preparse data recorder.
|
||||
class ParserRecorder {
|
||||
class PreParserLogger final {
|
||||
public:
|
||||
ParserRecorder() { }
|
||||
virtual ~ParserRecorder() { }
|
||||
|
||||
// Logs the scope and some details of a function literal in the source.
|
||||
virtual void LogFunction(int start, int end, int num_parameters,
|
||||
int function_length, bool has_duplicate_parameters,
|
||||
int literals, int properties,
|
||||
LanguageMode language_mode, bool uses_super_property,
|
||||
bool calls_eval) = 0;
|
||||
|
||||
// Logs an error message and marks the log as containing an error.
|
||||
// Further logging will be ignored, and ExtractData will return a vector
|
||||
// representing the error only.
|
||||
virtual void LogMessage(int start, int end, MessageTemplate::Template message,
|
||||
const char* argument_opt,
|
||||
ParseErrorType error_type) = 0;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ParserRecorder);
|
||||
};
|
||||
|
||||
|
||||
class SingletonLogger : public ParserRecorder {
|
||||
public:
|
||||
SingletonLogger()
|
||||
PreParserLogger()
|
||||
: has_error_(false),
|
||||
start_(-1),
|
||||
end_(-1),
|
||||
@ -81,35 +56,24 @@ class SingletonLogger : public ParserRecorder {
|
||||
function_length_(-1),
|
||||
has_duplicate_parameters_(false),
|
||||
error_type_(kSyntaxError) {}
|
||||
virtual ~SingletonLogger() {}
|
||||
|
||||
void Reset() { has_error_ = false; }
|
||||
|
||||
virtual void LogFunction(int start, int end, int num_parameters,
|
||||
int function_length, bool has_duplicate_parameters,
|
||||
int literals, int properties,
|
||||
LanguageMode language_mode, bool uses_super_property,
|
||||
bool calls_eval) {
|
||||
void LogFunction(int end, int num_parameters, int function_length,
|
||||
bool has_duplicate_parameters, int literals,
|
||||
int properties) {
|
||||
DCHECK(!has_error_);
|
||||
// Check that we only log at most one function.
|
||||
DCHECK(start_ == -1 && end_ == -1);
|
||||
start_ = start;
|
||||
end_ = end;
|
||||
num_parameters_ = num_parameters;
|
||||
function_length_ = function_length;
|
||||
has_duplicate_parameters_ = has_duplicate_parameters;
|
||||
literals_ = literals;
|
||||
properties_ = properties;
|
||||
language_mode_ = language_mode;
|
||||
uses_super_property_ = uses_super_property;
|
||||
calls_eval_ = calls_eval;
|
||||
}
|
||||
|
||||
// Logs an error message and marks the log as containing an error.
|
||||
// Further logging will be ignored, and ExtractData will return a vector
|
||||
// representing the error only.
|
||||
virtual void LogMessage(int start, int end, MessageTemplate::Template message,
|
||||
const char* argument_opt, ParseErrorType error_type) {
|
||||
void LogMessage(int start, int end, MessageTemplate::Template message,
|
||||
const char* argument_opt, ParseErrorType error_type) {
|
||||
if (has_error_) return;
|
||||
has_error_ = true;
|
||||
start_ = start;
|
||||
@ -143,18 +107,6 @@ class SingletonLogger : public ParserRecorder {
|
||||
DCHECK(!has_error_);
|
||||
return properties_;
|
||||
}
|
||||
LanguageMode language_mode() const {
|
||||
DCHECK(!has_error_);
|
||||
return language_mode_;
|
||||
}
|
||||
bool uses_super_property() const {
|
||||
DCHECK(!has_error_);
|
||||
return uses_super_property_;
|
||||
}
|
||||
bool calls_eval() const {
|
||||
DCHECK(!has_error_);
|
||||
return calls_eval_;
|
||||
}
|
||||
ParseErrorType error_type() const {
|
||||
DCHECK(has_error_);
|
||||
return error_type_;
|
||||
@ -178,37 +130,31 @@ class SingletonLogger : public ParserRecorder {
|
||||
bool has_duplicate_parameters_;
|
||||
int literals_;
|
||||
int properties_;
|
||||
LanguageMode language_mode_;
|
||||
bool uses_super_property_;
|
||||
bool calls_eval_;
|
||||
// For error messages.
|
||||
MessageTemplate::Template message_;
|
||||
const char* argument_opt_;
|
||||
ParseErrorType error_type_;
|
||||
};
|
||||
|
||||
|
||||
class CompleteParserRecorder : public ParserRecorder {
|
||||
class ParserLogger final {
|
||||
public:
|
||||
struct Key {
|
||||
bool is_one_byte;
|
||||
Vector<const byte> literal_bytes;
|
||||
};
|
||||
|
||||
CompleteParserRecorder();
|
||||
virtual ~CompleteParserRecorder() {}
|
||||
ParserLogger();
|
||||
|
||||
virtual void LogFunction(int start, int end, int num_parameters,
|
||||
int function_length, bool has_duplicate_parameters,
|
||||
int literals, int properties,
|
||||
LanguageMode language_mode, bool uses_super_property,
|
||||
bool calls_eval);
|
||||
void LogFunction(int start, int end, int num_parameters, int function_length,
|
||||
bool has_duplicate_parameters, int literals, int properties,
|
||||
LanguageMode language_mode, bool uses_super_property,
|
||||
bool calls_eval);
|
||||
|
||||
// Logs an error message and marks the log as containing an error.
|
||||
// Further logging will be ignored, and ExtractData will return a vector
|
||||
// representing the error only.
|
||||
virtual void LogMessage(int start, int end, MessageTemplate::Template message,
|
||||
const char* argument_opt, ParseErrorType error_type);
|
||||
void LogMessage(int start, int end, MessageTemplate::Template message,
|
||||
const char* argument_opt, ParseErrorType error_type);
|
||||
ScriptData* GetScriptData();
|
||||
|
||||
bool HasError() {
|
||||
|
@ -85,11 +85,9 @@ PreParserIdentifier PreParser::GetSymbol() const {
|
||||
|
||||
PreParser::PreParseResult PreParser::PreParseFunction(
|
||||
FunctionKind kind, DeclarationScope* function_scope, bool parsing_module,
|
||||
SingletonLogger* log, bool is_inner_function, bool may_abort,
|
||||
int* use_counts) {
|
||||
bool is_inner_function, bool may_abort, int* use_counts) {
|
||||
DCHECK_EQ(FUNCTION_SCOPE, function_scope->scope_type());
|
||||
parsing_module_ = parsing_module;
|
||||
log_ = log;
|
||||
use_counts_ = use_counts;
|
||||
DCHECK(!track_unresolved_variables_);
|
||||
track_unresolved_variables_ = is_inner_function;
|
||||
@ -127,8 +125,7 @@ PreParser::PreParseResult PreParser::PreParseFunction(
|
||||
|
||||
Expect(Token::LBRACE, CHECK_OK_VALUE(kPreParseSuccess));
|
||||
LazyParsingResult result = ParseStatementListAndLogFunction(
|
||||
function_scope->start_position(), &formals, has_duplicate_parameters,
|
||||
may_abort, ok);
|
||||
&formals, has_duplicate_parameters, may_abort, ok);
|
||||
use_counts_ = nullptr;
|
||||
track_unresolved_variables_ = false;
|
||||
if (result == kLazyParsingAborted) {
|
||||
@ -136,7 +133,7 @@ PreParser::PreParseResult PreParser::PreParseFunction(
|
||||
} else if (stack_overflow()) {
|
||||
return kPreParseStackOverflow;
|
||||
} else if (!*ok) {
|
||||
DCHECK(log->has_error());
|
||||
DCHECK(log_.has_error());
|
||||
} else {
|
||||
DCHECK_EQ(Token::RBRACE, scanner()->peek());
|
||||
|
||||
@ -235,8 +232,8 @@ PreParser::Expression PreParser::ParseFunctionLiteral(
|
||||
}
|
||||
|
||||
PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction(
|
||||
int start_position, PreParserFormalParameters* formals,
|
||||
bool has_duplicate_parameters, bool may_abort, bool* ok) {
|
||||
PreParserFormalParameters* formals, bool has_duplicate_parameters,
|
||||
bool may_abort, bool* ok) {
|
||||
PreParserStatementList body;
|
||||
LazyParsingResult result = ParseStatementList(
|
||||
body, Token::RBRACE, may_abort, CHECK_OK_VALUE(kLazyParsingComplete));
|
||||
@ -245,13 +242,11 @@ PreParser::LazyParsingResult PreParser::ParseStatementListAndLogFunction(
|
||||
// Position right after terminal '}'.
|
||||
DCHECK_EQ(Token::RBRACE, scanner()->peek());
|
||||
int body_end = scanner()->peek_location().end_pos;
|
||||
DeclarationScope* scope = this->scope()->AsDeclarationScope();
|
||||
DCHECK(scope->is_function_scope());
|
||||
log_->LogFunction(start_position, body_end, formals->num_parameters(),
|
||||
formals->function_length, has_duplicate_parameters,
|
||||
function_state_->materialized_literal_count(),
|
||||
function_state_->expected_property_count(), language_mode(),
|
||||
scope->uses_super_property(), scope->calls_eval());
|
||||
DCHECK(this->scope()->is_function_scope());
|
||||
log_.LogFunction(body_end, formals->num_parameters(),
|
||||
formals->function_length, has_duplicate_parameters,
|
||||
function_state_->materialized_literal_count(),
|
||||
function_state_->expected_property_count());
|
||||
return kLazyParsingComplete;
|
||||
}
|
||||
|
||||
|
@ -838,12 +838,14 @@ class PreParser : public ParserBase<PreParser> {
|
||||
};
|
||||
|
||||
PreParser(Zone* zone, Scanner* scanner, AstValueFactory* ast_value_factory,
|
||||
ParserRecorder* log, uintptr_t stack_limit)
|
||||
: ParserBase<PreParser>(zone, scanner, stack_limit, NULL,
|
||||
ast_value_factory, log),
|
||||
uintptr_t stack_limit)
|
||||
: ParserBase<PreParser>(zone, scanner, stack_limit, nullptr,
|
||||
ast_value_factory),
|
||||
use_counts_(nullptr),
|
||||
track_unresolved_variables_(false) {}
|
||||
|
||||
PreParserLogger* logger() { return &log_; }
|
||||
|
||||
// Pre-parse the program from the character stream; returns true on
|
||||
// success (even if parsing failed, the pre-parse data successfully
|
||||
// captured the syntax error), and false if a stack-overflow happened
|
||||
@ -889,7 +891,7 @@ class PreParser : public ParserBase<PreParser> {
|
||||
// the final '}'.
|
||||
PreParseResult PreParseFunction(FunctionKind kind,
|
||||
DeclarationScope* function_scope,
|
||||
bool parsing_module, SingletonLogger* log,
|
||||
bool parsing_module,
|
||||
bool track_unresolved_variables,
|
||||
bool may_abort, int* use_counts);
|
||||
|
||||
@ -925,8 +927,8 @@ class PreParser : public ParserBase<PreParser> {
|
||||
int function_token_pos, FunctionLiteral::FunctionType function_type,
|
||||
LanguageMode language_mode, bool* ok);
|
||||
LazyParsingResult ParseStatementListAndLogFunction(
|
||||
int position_before_formals, PreParserFormalParameters* formals,
|
||||
bool has_duplicate_parameters, bool maybe_abort, bool* ok);
|
||||
PreParserFormalParameters* formals, bool has_duplicate_parameters,
|
||||
bool maybe_abort, bool* ok);
|
||||
|
||||
struct TemplateLiteralState {};
|
||||
|
||||
@ -1268,8 +1270,8 @@ class PreParser : public ParserBase<PreParser> {
|
||||
MessageTemplate::Template message,
|
||||
const char* arg = NULL,
|
||||
ParseErrorType error_type = kSyntaxError) {
|
||||
log_->LogMessage(source_location.beg_pos, source_location.end_pos, message,
|
||||
arg, error_type);
|
||||
log_.LogMessage(source_location.beg_pos, source_location.end_pos, message,
|
||||
arg, error_type);
|
||||
}
|
||||
|
||||
V8_INLINE void ReportMessageAt(Scanner::Location source_location,
|
||||
@ -1502,6 +1504,7 @@ class PreParser : public ParserBase<PreParser> {
|
||||
|
||||
int* use_counts_;
|
||||
bool track_unresolved_variables_;
|
||||
PreParserLogger log_;
|
||||
};
|
||||
|
||||
PreParserExpression PreParser::SpreadCall(PreParserExpression function,
|
||||
|
@ -168,36 +168,32 @@ TEST(ScanHTMLEndComments) {
|
||||
for (int i = 0; tests[i]; i++) {
|
||||
const char* source = tests[i];
|
||||
auto stream = i::ScannerStream::ForTesting(source);
|
||||
i::CompleteParserRecorder log;
|
||||
i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
|
||||
scanner.Initialize(stream.get());
|
||||
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
|
||||
i::AstValueFactory ast_value_factory(
|
||||
&zone, CcTest::i_isolate()->heap()->HashSeed());
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
|
||||
stack_limit);
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, stack_limit);
|
||||
preparser.set_allow_lazy(true);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
CHECK(!log.HasError());
|
||||
CHECK(!preparser.logger()->has_error());
|
||||
}
|
||||
|
||||
for (int i = 0; fail_tests[i]; i++) {
|
||||
const char* source = fail_tests[i];
|
||||
auto stream = i::ScannerStream::ForTesting(source);
|
||||
i::CompleteParserRecorder log;
|
||||
i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
|
||||
scanner.Initialize(stream.get());
|
||||
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
|
||||
i::AstValueFactory ast_value_factory(
|
||||
&zone, CcTest::i_isolate()->heap()->HashSeed());
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
|
||||
stack_limit);
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, stack_limit);
|
||||
preparser.set_allow_lazy(true);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
// Even in the case of a syntax error, kPreParseSuccess is returned.
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
CHECK(log.HasError());
|
||||
CHECK(preparser.logger()->has_error());
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,20 +354,18 @@ TEST(StandAlonePreParser) {
|
||||
uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
|
||||
for (int i = 0; programs[i]; i++) {
|
||||
auto stream = i::ScannerStream::ForTesting(programs[i]);
|
||||
i::CompleteParserRecorder log;
|
||||
i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
|
||||
scanner.Initialize(stream.get());
|
||||
|
||||
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
|
||||
i::AstValueFactory ast_value_factory(
|
||||
&zone, CcTest::i_isolate()->heap()->HashSeed());
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
|
||||
stack_limit);
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, stack_limit);
|
||||
preparser.set_allow_lazy(true);
|
||||
preparser.set_allow_natives(true);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
CHECK(!log.HasError());
|
||||
CHECK(!preparser.logger()->has_error());
|
||||
}
|
||||
}
|
||||
|
||||
@ -391,7 +385,6 @@ TEST(StandAlonePreParserNoNatives) {
|
||||
uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
|
||||
for (int i = 0; programs[i]; i++) {
|
||||
auto stream = i::ScannerStream::ForTesting(programs[i]);
|
||||
i::CompleteParserRecorder log;
|
||||
i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
|
||||
scanner.Initialize(stream.get());
|
||||
|
||||
@ -399,12 +392,11 @@ TEST(StandAlonePreParserNoNatives) {
|
||||
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
|
||||
i::AstValueFactory ast_value_factory(
|
||||
&zone, CcTest::i_isolate()->heap()->HashSeed());
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
|
||||
stack_limit);
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, stack_limit);
|
||||
preparser.set_allow_lazy(true);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
CHECK(log.HasError());
|
||||
CHECK(preparser.logger()->has_error());
|
||||
}
|
||||
}
|
||||
|
||||
@ -460,19 +452,18 @@ TEST(RegressChromium62639) {
|
||||
// failed in debug mode, and sometimes crashed in release mode.
|
||||
|
||||
auto stream = i::ScannerStream::ForTesting(program);
|
||||
i::CompleteParserRecorder log;
|
||||
i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
|
||||
scanner.Initialize(stream.get());
|
||||
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
|
||||
i::AstValueFactory ast_value_factory(&zone,
|
||||
CcTest::i_isolate()->heap()->HashSeed());
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory,
|
||||
CcTest::i_isolate()->stack_guard()->real_climit());
|
||||
preparser.set_allow_lazy(true);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
// Even in the case of a syntax error, kPreParseSuccess is returned.
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
CHECK(log.HasError());
|
||||
CHECK(preparser.logger()->has_error());
|
||||
}
|
||||
|
||||
|
||||
@ -533,15 +524,13 @@ TEST(PreParseOverflow) {
|
||||
uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
|
||||
|
||||
auto stream = i::ScannerStream::ForTesting(program.get(), kProgramSize);
|
||||
i::CompleteParserRecorder log;
|
||||
i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
|
||||
scanner.Initialize(stream.get());
|
||||
|
||||
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
|
||||
i::AstValueFactory ast_value_factory(&zone,
|
||||
CcTest::i_isolate()->heap()->HashSeed());
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
|
||||
stack_limit);
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, stack_limit);
|
||||
preparser.set_allow_lazy(true);
|
||||
i::PreParser::PreParseResult result = preparser.PreParseProgram();
|
||||
CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
|
||||
@ -1349,7 +1338,7 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
|
||||
int parser_materialized_literals = -2;
|
||||
|
||||
// Preparse the data.
|
||||
i::CompleteParserRecorder log;
|
||||
i::ParserLogger log;
|
||||
if (test_preparser) {
|
||||
i::Scanner scanner(isolate->unicode_cache());
|
||||
std::unique_ptr<i::Utf16CharacterStream> stream(
|
||||
@ -1357,13 +1346,18 @@ void TestParserSyncWithFlags(i::Handle<i::String> source,
|
||||
i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
|
||||
i::AstValueFactory ast_value_factory(
|
||||
&zone, CcTest::i_isolate()->heap()->HashSeed());
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, &log,
|
||||
stack_limit);
|
||||
i::PreParser preparser(&zone, &scanner, &ast_value_factory, stack_limit);
|
||||
SetParserFlags(&preparser, flags);
|
||||
scanner.Initialize(stream.get());
|
||||
i::PreParser::PreParseResult result =
|
||||
preparser.PreParseProgram(&preparser_materialized_literals, is_module);
|
||||
CHECK_EQ(i::PreParser::kPreParseSuccess, result);
|
||||
i::PreParserLogger* logger = preparser.logger();
|
||||
// Convert to complete log.
|
||||
if (logger->has_error()) {
|
||||
log.LogMessage(logger->start(), logger->end(), logger->message(),
|
||||
logger->argument_opt(), logger->error_type());
|
||||
}
|
||||
}
|
||||
bool preparse_error = log.HasError();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user