| 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
|
|
|