Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Unified Diff: src/parser.cc

Issue 203353002: New compilation API, part 2. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebased Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 62e9cbad77662d9b306760a893aea2655ddf6fb9..01bd85348f5744bae34f0f93f7e3c7fb1e76973c 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -205,19 +205,6 @@ void RegExpBuilder::AddQuantifierToAtom(
}
-Handle<String> Parser::LookupSymbol(int symbol_id) {
- // If there is no preparser symbol data, a negative number will be passed. In
- // that case, we'll just read the literal from Scanner. This also guards
- // against corrupt preparse data where the symbol id is larger than the symbol
- // count.
- if (symbol_id < 0 ||
- (pre_parse_data_ && symbol_id >= pre_parse_data_->symbol_count())) {
- return scanner()->AllocateInternalizedString(isolate_);
- }
- return LookupCachedSymbol(symbol_id);
-}
-
-
Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
// Make sure the cache is large enough to hold the symbol identifier.
if (symbol_cache_.length() <= symbol_id) {
@@ -600,11 +587,19 @@ void ParserTraits::ReportMessageAt(Scanner::Location source_location,
Handle<String> ParserTraits::GetSymbol(Scanner* scanner) {
- int symbol_id = -1;
- if (parser_->pre_parse_data() != NULL) {
- symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier();
+ if (parser_->cached_data_mode() == CONSUME_CACHED_DATA) {
+ int symbol_id = (*parser_->cached_data())->GetSymbolIdentifier();
+ // If there is no symbol data, -1 will be returned.
+ if (symbol_id >= 0 &&
+ symbol_id < (*parser_->cached_data())->symbol_count()) {
+ return parser_->LookupCachedSymbol(symbol_id);
+ }
+ } else if (parser_->cached_data_mode() == PRODUCE_CACHED_DATA) {
+ if (parser_->log_->ShouldLogSymbols()) {
+ parser_->scanner()->LogSymbol(parser_->log_, parser_->position());
+ }
}
- return parser_->LookupSymbol(symbol_id);
+ return parser_->scanner()->AllocateInternalizedString(parser_->isolate_);
}
@@ -702,6 +697,7 @@ Parser::Parser(CompilationInfo* info)
: ParserBase<ParserTraits>(&scanner_,
info->isolate()->stack_guard()->real_climit(),
info->extension(),
+ NULL,
info->zone(),
this),
isolate_(info->isolate()),
@@ -711,7 +707,8 @@ Parser::Parser(CompilationInfo* info)
reusable_preparser_(NULL),
original_scope_(NULL),
target_stack_(NULL),
- pre_parse_data_(NULL),
+ cached_data_(NULL),
+ cached_data_mode_(NO_CACHED_DATA),
info_(info) {
ASSERT(!script_.is_null());
isolate_->set_ast_node_id(0);
@@ -738,6 +735,13 @@ FunctionLiteral* Parser::ParseProgram() {
fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
// Initialize parser state.
+ CompleteParserRecorder recorder;
+ if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
+ log_ = &recorder;
+ } else if (cached_data_mode_ == CONSUME_CACHED_DATA) {
+ (*cached_data_)->Initialize();
+ }
+
source->TryFlatten();
FunctionLiteral* result;
if (source->IsExternalTwoByteString()) {
@@ -767,6 +771,11 @@ FunctionLiteral* Parser::ParseProgram() {
}
PrintF(" - took %0.3f ms]\n", ms);
}
+ if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
+ Vector<unsigned> store = recorder.ExtractData();
+ *cached_data_ = new ScriptDataImpl(store);
+ log_ = NULL;
+ }
return result;
}
@@ -775,7 +784,6 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
Handle<String> source) {
ASSERT(scope_ == NULL);
ASSERT(target_stack_ == NULL);
- if (pre_parse_data_ != NULL) pre_parse_data_->Initialize();
Handle<String> no_name = isolate()->factory()->empty_string();
@@ -3580,11 +3588,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
if (is_lazily_parsed) {
int function_block_pos = position();
FunctionEntry entry;
- if (pre_parse_data_ != NULL) {
- // If we have pre_parse_data_, we use it to skip parsing the function
- // body. The preparser data contains the information we need to
- // construct the lazy function.
- entry = pre_parse_data()->GetFunctionEntry(function_block_pos);
+ if (cached_data_mode_ == CONSUME_CACHED_DATA) {
+ // If we have cached data, we use it to skip parsing the function body.
+ // The data contains the information we need to construct the lazy
+ // function.
+ entry = (*cached_data())->GetFunctionEntry(function_block_pos);
if (entry.is_valid()) {
if (entry.end_pos() <= function_block_pos) {
// End position greater than end of stream is safe, and hard
@@ -3605,21 +3613,17 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
// an entry for the function. As a safety net, fall back to eager
// parsing. It is unclear whether PreParser's laziness analysis can
// produce different results than the Parser's laziness analysis (see
- // https://codereview.chromium.org/7565003 ). This safety net is
- // guarding against the case where Parser thinks a function should be
- // lazily parsed, but PreParser thinks it should be eagerly parsed --
- // in that case we fall back to eager parsing in Parser, too. Note
- // that the opposite case is worse: if PreParser thinks a function
- // should be lazily parsed, but Parser thinks it should be eagerly
- // parsed, it will never advance the preparse data beyond that
- // function and all further laziness will fail (all functions will be
- // parsed eagerly).
+ // https://codereview.chromium.org/7565003 ). In this case, we must
+ // discard all the preparse data, since the symbol data will be wrong.
is_lazily_parsed = false;
+ cached_data_mode_ = NO_CACHED_DATA;
}
} else {
- // With no preparser data, we partially parse the function, without
+ // With no cached data, we partially parse the function, without
// building an AST. This gathers the data needed to build a lazy
// function.
+ // FIXME(marja): Now the PreParser doesn't need to log functions /
+ // symbols; only errors -> clean that up.
SingletonLogger logger;
PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger);
if (result == PreParser::kPreParseStackOverflow) {
@@ -3648,6 +3652,15 @@ FunctionLiteral* Parser::ParseFunctionLiteral(
materialized_literal_count = logger.literals();
expected_property_count = logger.properties();
scope_->SetStrictMode(logger.strict_mode());
+ if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
+ ASSERT(log_);
+ // Position right after terminal '}'.
+ int body_end = scanner()->location().end_pos;
+ log_->LogFunction(function_block_pos, body_end,
+ materialized_literal_count,
+ expected_property_count,
+ scope_->strict_mode());
+ }
}
}
@@ -4922,12 +4935,13 @@ bool Parser::Parse() {
result = ParseProgram();
}
} else {
- ScriptDataImpl* pre_parse_data = info()->pre_parse_data();
- set_pre_parse_data(pre_parse_data);
- if (pre_parse_data != NULL && pre_parse_data->has_error()) {
- Scanner::Location loc = pre_parse_data->MessageLocation();
- const char* message = pre_parse_data->BuildMessage();
- Vector<const char*> args = pre_parse_data->BuildArgs();
+ SetCachedData(info()->cached_data(), info()->cached_data_mode());
+ if (info()->cached_data_mode() == CONSUME_CACHED_DATA &&
+ (*info()->cached_data())->has_error()) {
+ ScriptDataImpl* cached_data = *(info()->cached_data());
+ Scanner::Location loc = cached_data->MessageLocation();
+ const char* message = cached_data->BuildMessage();
+ Vector<const char*> args = cached_data->BuildArgs();
ParserTraits::ReportMessageAt(loc, message, args);
DeleteArray(message);
for (int i = 0; i < args.length(); i++) {
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698