Index: src/parser.cc |
diff --git a/src/parser.cc b/src/parser.cc |
index 6c941daa978d3d53bdc6cfca5f1914195bc7d2f0..31fb4debdf84851e72190fc0a3d2f4b887942505 100644 |
--- a/src/parser.cc |
+++ b/src/parser.cc |
@@ -6,7 +6,6 @@ |
#include "src/api.h" |
#include "src/ast.h" |
-#include "src/base/platform/platform.h" |
#include "src/bootstrapper.h" |
#include "src/char-predicates-inl.h" |
#include "src/codegen.h" |
@@ -19,6 +18,8 @@ |
#include "src/scopeinfo.h" |
#include "src/string-stream.h" |
+#include "include/v8-platform.h" |
+ |
namespace v8 { |
namespace internal { |
@@ -705,10 +706,9 @@ FunctionLiteral* ParserTraits::ParseFunctionLiteral( |
} |
-Parser::Parser(CompilationInfo* info) |
- : ParserBase<ParserTraits>(&scanner_, |
- info->isolate()->stack_guard()->real_climit(), |
- info->extension(), NULL, info->zone(), this), |
+Parser::Parser(CompilationInfo* info, uintptr_t stack_limit, uint32_t hash_seed) |
+ : ParserBase<ParserTraits>(&scanner_, stack_limit, info->extension(), NULL, |
+ info->zone(), this), |
isolate_(info->isolate()), |
script_(info->script()), |
scanner_(isolate_->unicode_cache()), |
@@ -721,8 +721,9 @@ Parser::Parser(CompilationInfo* info) |
has_pending_error_(false), |
pending_error_message_(NULL), |
pending_error_arg_(NULL), |
- pending_error_char_arg_(NULL) { |
- DCHECK(!script_.is_null()); |
+ pending_error_char_arg_(NULL), |
+ hash_seed_(hash_seed) { |
+ DCHECK(!info->script().is_null() || info->source_stream() != NULL); |
isolate_->set_ast_node_id(0); |
set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
@@ -798,49 +799,73 @@ FunctionLiteral* Parser::ParseProgram() { |
FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
Handle<String> source) { |
+ Scope* scope = NULL; |
+ Scope* ad_hoc_eval_scope = NULL; |
+ FunctionLiteral* result = |
+ DoParseProgramInner(info, &scope, &ad_hoc_eval_scope); |
+ scope->set_end_position(source->length()); |
+ if (ad_hoc_eval_scope != NULL) { |
+ ad_hoc_eval_scope->set_end_position(source->length()); |
+ } |
+ |
+ ast_value_factory_->Internalize(isolate()); |
+ if (result == NULL) { |
+ if (stack_overflow()) { |
+ isolate()->StackOverflow(); |
+ } else { |
+ ThrowPendingError(); |
+ } |
+ } |
+ return result; |
+} |
+ |
+ |
+FunctionLiteral* Parser::DoParseProgramInner(CompilationInfo* info, |
+ Scope** scope, |
+ Scope** ad_hod_eval_scope) { |
DCHECK(scope_ == NULL); |
DCHECK(target_stack_ == NULL); |
FunctionLiteral* result = NULL; |
- { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
- info->SetGlobalScope(scope); |
+ { |
+ *scope = NewScope(scope_, GLOBAL_SCOPE); |
+ info->SetGlobalScope(*scope); |
if (!info->context().is_null() && !info->context()->IsNativeContext()) { |
- scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
+ *scope = Scope::DeserializeScopeChain(*info->context(), *scope, zone()); |
// The Scope is backed up by ScopeInfo (which is in the V8 heap); this |
// means the Parser cannot operate independent of the V8 heap. Tell the |
// string table to internalize strings and values right after they're |
// created. |
ast_value_factory_->Internalize(isolate()); |
} |
- original_scope_ = scope; |
+ original_scope_ = *scope; |
if (info->is_eval()) { |
- if (!scope->is_global_scope() || info->strict_mode() == STRICT) { |
- scope = NewScope(scope, EVAL_SCOPE); |
+ if (!(*scope)->is_global_scope() || info->strict_mode() == STRICT) { |
+ *scope = NewScope(*scope, EVAL_SCOPE); |
} |
} else if (info->is_global()) { |
- scope = NewScope(scope, GLOBAL_SCOPE); |
+ *scope = NewScope(*scope, GLOBAL_SCOPE); |
} |
- scope->set_start_position(0); |
- scope->set_end_position(source->length()); |
+ (*scope)->set_start_position(0); |
// Compute the parsing mode. |
Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY; |
- if (allow_natives_syntax() || |
- extension_ != NULL || |
- scope->is_eval_scope()) { |
+ if (allow_natives_syntax() || extension_ != NULL || |
+ (*scope)->is_eval_scope()) { |
mode = PARSE_EAGERLY; |
} |
ParsingModeScope parsing_mode(this, mode); |
// Enters 'scope'. |
- FunctionState function_state(&function_state_, &scope_, scope, zone(), |
+ FunctionState function_state(&function_state_, &scope_, *scope, zone(), |
ast_value_factory_); |
scope_->SetStrictMode(info->strict_mode()); |
ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
bool ok = true; |
int beg_pos = scanner()->location().beg_pos; |
- ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
+ ParseSourceElements(body, Token::EOS, info->is_eval(), true, |
+ ad_hod_eval_scope, &ok); |
HandleSourceURLComments(); |
@@ -862,7 +887,6 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
} |
} |
- ast_value_factory_->Internalize(isolate()); |
if (ok) { |
result = factory()->NewFunctionLiteral( |
ast_value_factory_->empty_string(), ast_value_factory_, scope_, body, |
@@ -876,10 +900,6 @@ FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
result->set_ast_properties(factory()->visitor()->ast_properties()); |
result->set_dont_optimize_reason( |
factory()->visitor()->dont_optimize_reason()); |
- } else if (stack_overflow()) { |
- isolate()->StackOverflow(); |
- } else { |
- ThrowPendingError(); |
} |
} |
@@ -999,10 +1019,8 @@ FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { |
void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
- int end_token, |
- bool is_eval, |
- bool is_global, |
- bool* ok) { |
+ int end_token, bool is_eval, bool is_global, |
+ Scope** ad_hod_eval_scope, bool* ok) { |
// SourceElements :: |
// (ModuleElement)* <end_token> |
@@ -1058,6 +1076,9 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
scope->set_start_position(scope_->start_position()); |
scope->set_end_position(scope_->end_position()); |
scope_ = scope; |
+ if (ad_hod_eval_scope != NULL) { |
+ *ad_hod_eval_scope = scope; |
+ } |
mode_ = PARSE_EAGERLY; |
} |
scope_->SetStrictMode(STRICT); |
@@ -3706,7 +3727,7 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
yield, RelocInfo::kNoPosition), zone()); |
} |
- ParseSourceElements(body, Token::RBRACE, false, false, CHECK_OK); |
+ ParseSourceElements(body, Token::RBRACE, false, false, NULL, CHECK_OK); |
if (is_generator) { |
VariableProxy* get_proxy = factory()->NewVariableProxy( |
@@ -3732,8 +3753,7 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
if (reusable_preparser_ == NULL) { |
- intptr_t stack_limit = isolate()->stack_guard()->real_climit(); |
- reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); |
+ reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_); |
reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
reusable_preparser_->set_allow_modules(allow_modules()); |
reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
@@ -4774,8 +4794,7 @@ bool Parser::Parse() { |
FunctionLiteral* result = NULL; |
ast_value_factory_ = info()->ast_value_factory(); |
if (ast_value_factory_ == NULL) { |
- ast_value_factory_ = |
- new AstValueFactory(zone(), isolate()->heap()->HashSeed()); |
+ ast_value_factory_ = new AstValueFactory(zone(), hash_seed_); |
} |
if (allow_natives_syntax() || extension_ != NULL) { |
// If intrinsics are allowed, the Parser cannot operate independent of the |
@@ -4808,4 +4827,44 @@ bool Parser::Parse() { |
return (result != NULL); |
} |
+ |
+void Parser::ParseOnBackground() { |
+ DCHECK(info()->function() == NULL); |
+ FunctionLiteral* result = NULL; |
+ ast_value_factory_ = info()->ast_value_factory(); |
+ if (ast_value_factory_ == NULL) { |
+ ast_value_factory_ = new AstValueFactory(zone(), hash_seed_); |
+ } |
+ fni_ = new (zone()) FuncNameInferrer(ast_value_factory_, zone()); |
+ |
+ CompleteParserRecorder recorder; |
+ if (compile_options() == ScriptCompiler::kProduceParserCache) { |
+ log_ = &recorder; |
+ } |
+ |
+ DCHECK(info()->source_stream() != NULL); |
+ ExternalStreamingStream stream(info()->source_stream()); |
+ scanner_.Initialize(&stream); |
+ DCHECK(info()->context().is_null() || info()->context()->IsNativeContext()); |
+ |
+ Scope* scope = NULL; |
+ Scope* ad_hoc_eval_scope = NULL; |
+ result = DoParseProgramInner(info(), &scope, &ad_hoc_eval_scope); |
+ |
+ scope->set_end_position(scanner()->location().end_pos); |
+ if (ad_hoc_eval_scope != NULL) { |
+ ad_hoc_eval_scope->set_end_position(scanner()->location().end_pos); |
+ } |
+ |
+ if (info()->ast_value_factory() == NULL) { |
+ info()->SetAstValueFactory(ast_value_factory_); |
+ } |
+ |
+ info()->SetFunction(result); |
+ |
+ if (compile_options() == ScriptCompiler::kProduceParserCache) { |
+ if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); |
+ log_ = NULL; |
+ } |
+} |
} } // namespace v8::internal |