Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/ast/ast-expression-rewriter.h" | 10 #include "src/ast/ast-expression-rewriter.h" |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 } | 556 } |
| 557 | 557 |
| 558 return factory()->NewCallRuntime(context_index, args, pos); | 558 return factory()->NewCallRuntime(context_index, args, pos); |
| 559 } | 559 } |
| 560 | 560 |
| 561 Parser::Parser(ParseInfo* info) | 561 Parser::Parser(ParseInfo* info) |
| 562 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(), | 562 : ParserBase<Parser>(info->zone(), &scanner_, info->stack_limit(), |
| 563 info->extension(), info->ast_value_factory(), NULL), | 563 info->extension(), info->ast_value_factory(), NULL), |
| 564 scanner_(info->unicode_cache()), | 564 scanner_(info->unicode_cache()), |
| 565 reusable_preparser_(NULL), | 565 reusable_preparser_(NULL), |
| 566 original_scope_(NULL), | |
| 567 target_stack_(NULL), | 566 target_stack_(NULL), |
| 568 compile_options_(info->compile_options()), | 567 compile_options_(info->compile_options()), |
| 569 cached_parse_data_(NULL), | 568 cached_parse_data_(NULL), |
| 570 total_preparse_skipped_(0), | 569 total_preparse_skipped_(0), |
| 571 pre_parse_timer_(NULL), | 570 pre_parse_timer_(NULL), |
| 572 parsing_on_main_thread_(true) { | 571 parsing_on_main_thread_(true) { |
| 573 // Even though we were passed ParseInfo, we should not store it in | 572 // Even though we were passed ParseInfo, we should not store it in |
| 574 // Parser - this makes sure that Isolate is not accidentally accessed via | 573 // Parser - this makes sure that Isolate is not accidentally accessed via |
| 575 // ParseInfo during background parsing. | 574 // ParseInfo during background parsing. |
| 576 DCHECK(!info->script().is_null() || info->source_stream() != nullptr || | 575 DCHECK(!info->script().is_null() || info->source_stream() != nullptr || |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 593 } | 592 } |
| 594 if (info->ast_value_factory() == NULL) { | 593 if (info->ast_value_factory() == NULL) { |
| 595 // info takes ownership of AstValueFactory. | 594 // info takes ownership of AstValueFactory. |
| 596 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); | 595 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); |
| 597 info->set_ast_value_factory_owned(); | 596 info->set_ast_value_factory_owned(); |
| 598 ast_value_factory_ = info->ast_value_factory(); | 597 ast_value_factory_ = info->ast_value_factory(); |
| 599 ast_node_factory_.set_ast_value_factory(ast_value_factory_); | 598 ast_node_factory_.set_ast_value_factory(ast_value_factory_); |
| 600 } | 599 } |
| 601 } | 600 } |
| 602 | 601 |
| 603 void Parser::DeserializeScopeChain( | 602 void Parser::InspectScopeChain(ParseInfo* info, Handle<ScopeInfo> outer_scope) { |
| 604 ParseInfo* info, Handle<Context> context, | |
| 605 Scope::DeserializationMode deserialization_mode) { | |
| 606 DCHECK(ThreadId::Current().Equals(info->isolate()->thread_id())); | 603 DCHECK(ThreadId::Current().Equals(info->isolate()->thread_id())); |
| 607 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native | 604 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native |
| 608 // context, which will have the "this" binding for script scopes. | 605 // context, which will have the "this" binding for script scopes. |
| 609 DeclarationScope* script_scope = NewScriptScope(); | 606 DeclarationScope* script_scope = NewScriptScope(); |
| 610 info->set_script_scope(script_scope); | 607 info->set_script_scope(script_scope); |
| 611 Scope* scope = script_scope; | 608 if (!outer_scope.is_null()) { |
| 612 if (!context.is_null() && !context->IsNativeContext()) { | 609 if (outer_scope->scope_type() != SCRIPT_SCOPE) { |
| 613 scope = Scope::DeserializeScopeChain(info->isolate(), zone(), *context, | 610 info->set_allow_lazy_parsing(false); |
|
marja
2016/09/12 07:50:33
... here I was wondering why we do this... there's
jochen (gone - plz use gerrit)
2016/09/12 08:18:18
I moved this from line 722 in the old code
| |
| 614 script_scope, ast_value_factory(), | 611 } |
| 615 deserialization_mode); | 612 Handle<ScopeInfo> receiver_scope = outer_scope; |
| 616 DCHECK(!info->is_module() || scope->is_module_scope()); | 613 while (receiver_scope->scope_type() != SCRIPT_SCOPE && |
| 617 if (info->context().is_null()) { | 614 (receiver_scope->scope_type() != FUNCTION_SCOPE || |
| 618 DCHECK(deserialization_mode == | 615 IsArrowFunction(receiver_scope->function_kind()))) { |
| 619 Scope::DeserializationMode::kDeserializeOffHeap); | 616 if (!receiver_scope->HasOuterScopeInfo()) { |
| 620 } else { | 617 receiver_scope = Handle<ScopeInfo>::null(); |
| 621 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this | 618 break; |
| 622 // means the Parser cannot operate independent of the V8 heap. Tell the | 619 } |
| 623 // string table to internalize strings and values right after they're | 620 receiver_scope = Handle<ScopeInfo>(receiver_scope->OuterScopeInfo()); |
| 624 // created. This kind of parsing can only be done in the main thread. | 621 } |
| 625 DCHECK(parsing_on_main_thread_); | 622 if (!receiver_scope.is_null()) { |
| 626 ast_value_factory()->Internalize(info->isolate()); | 623 outer_most_receivers_function_kind_ = receiver_scope->function_kind(); |
| 624 outer_most_receivers_scope_type_ = receiver_scope->scope_type(); | |
| 627 } | 625 } |
| 628 } | 626 } |
| 629 original_scope_ = scope; | |
| 630 } | 627 } |
| 631 | 628 |
| 632 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { | 629 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { |
| 633 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 630 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
| 634 // see comment for HistogramTimerScope class. | 631 // see comment for HistogramTimerScope class. |
| 635 | 632 |
| 636 // It's OK to use the Isolate & counters here, since this function is only | 633 // It's OK to use the Isolate & counters here, since this function is only |
| 637 // called in the main thread. | 634 // called in the main thread. |
| 638 DCHECK(parsing_on_main_thread_); | 635 DCHECK(parsing_on_main_thread_); |
| 639 | 636 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 650 | 647 |
| 651 // Initialize parser state. | 648 // Initialize parser state. |
| 652 CompleteParserRecorder recorder; | 649 CompleteParserRecorder recorder; |
| 653 | 650 |
| 654 if (produce_cached_parse_data()) { | 651 if (produce_cached_parse_data()) { |
| 655 log_ = &recorder; | 652 log_ = &recorder; |
| 656 } else if (consume_cached_parse_data()) { | 653 } else if (consume_cached_parse_data()) { |
| 657 cached_parse_data_->Initialize(); | 654 cached_parse_data_->Initialize(); |
| 658 } | 655 } |
| 659 | 656 |
| 660 DeserializeScopeChain(info, info->context(), | 657 InspectScopeChain( |
| 661 Scope::DeserializationMode::kKeepScopeInfo); | 658 info, info->context().is_null() || info->context()->IsNativeContext() |
| 659 ? Handle<ScopeInfo>() | |
| 660 : Handle<ScopeInfo>(info->context()->scope_info())); | |
| 662 | 661 |
| 663 source = String::Flatten(source); | 662 source = String::Flatten(source); |
| 664 FunctionLiteral* result; | 663 FunctionLiteral* result; |
| 665 | 664 |
| 666 { | 665 { |
| 667 std::unique_ptr<Utf16CharacterStream> stream; | 666 std::unique_ptr<Utf16CharacterStream> stream; |
| 668 if (source->IsExternalTwoByteString()) { | 667 if (source->IsExternalTwoByteString()) { |
| 669 stream.reset(new ExternalTwoByteStringUtf16CharacterStream( | 668 stream.reset(new ExternalTwoByteStringUtf16CharacterStream( |
| 670 Handle<ExternalTwoByteString>::cast(source), 0, source->length())); | 669 Handle<ExternalTwoByteString>::cast(source), 0, source->length())); |
| 671 } else if (source->IsExternalOneByteString()) { | 670 } else if (source->IsExternalOneByteString()) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 // background thread. We should not access anything Isolate / heap dependent | 708 // background thread. We should not access anything Isolate / heap dependent |
| 710 // via ParseInfo, and also not pass it forward. | 709 // via ParseInfo, and also not pass it forward. |
| 711 DCHECK_NULL(scope_state_); | 710 DCHECK_NULL(scope_state_); |
| 712 DCHECK_NULL(target_stack_); | 711 DCHECK_NULL(target_stack_); |
| 713 | 712 |
| 714 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY; | 713 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY; |
| 715 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY; | 714 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY; |
| 716 | 715 |
| 717 FunctionLiteral* result = NULL; | 716 FunctionLiteral* result = NULL; |
| 718 { | 717 { |
| 719 Scope* outer = original_scope_; | 718 Scope* outer = info->script_scope(); |
| 720 DCHECK_NOT_NULL(outer); | 719 DCHECK_NOT_NULL(outer); |
| 721 if (info->is_eval()) { | 720 if (info->is_eval()) { |
| 722 if (!outer->is_script_scope() || is_strict(info->language_mode())) { | 721 if (is_strict(info->language_mode())) { |
| 723 parsing_mode = PARSE_EAGERLY; | 722 parsing_mode = PARSE_EAGERLY; |
| 724 } | 723 } |
| 725 outer = NewEvalScope(outer); | 724 outer = NewEvalScope(outer); |
| 726 } else if (info->is_module()) { | 725 } else if (info->is_module()) { |
| 727 DCHECK_EQ(outer, info->script_scope()); | 726 DCHECK_EQ(outer, info->script_scope()); |
| 728 outer = NewModuleScope(info->script_scope()); | 727 outer = NewModuleScope(info->script_scope()); |
| 729 } | 728 } |
| 730 | 729 |
| 731 DeclarationScope* scope = outer->AsDeclarationScope(); | 730 DeclarationScope* scope = outer->AsDeclarationScope(); |
| 732 | 731 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 760 if (ok && is_strict(language_mode())) { | 759 if (ok && is_strict(language_mode())) { |
| 761 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 760 CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
| 762 CheckDecimalLiteralWithLeadingZero(beg_pos, | 761 CheckDecimalLiteralWithLeadingZero(beg_pos, |
| 763 scanner()->location().end_pos); | 762 scanner()->location().end_pos); |
| 764 } | 763 } |
| 765 if (ok && is_sloppy(language_mode())) { | 764 if (ok && is_sloppy(language_mode())) { |
| 766 // TODO(littledan): Function bindings on the global object that modify | 765 // TODO(littledan): Function bindings on the global object that modify |
| 767 // pre-existing bindings should be made writable, enumerable and | 766 // pre-existing bindings should be made writable, enumerable and |
| 768 // nonconfigurable if possible, whereas this code will leave attributes | 767 // nonconfigurable if possible, whereas this code will leave attributes |
| 769 // unchanged if the property already exists. | 768 // unchanged if the property already exists. |
| 770 InsertSloppyBlockFunctionVarBindings(scope, &ok); | 769 scope->HoistSloppyBlockFunctions(factory(), &ok); |
| 771 } | 770 } |
| 772 if (ok) { | 771 if (ok) { |
| 773 CheckConflictingVarDeclarations(scope, &ok); | 772 CheckConflictingVarDeclarations(scope, &ok); |
| 774 } | 773 } |
| 775 | 774 |
| 776 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 775 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 777 if (body->length() != 1 || | 776 if (body->length() != 1 || |
| 778 !body->at(0)->IsExpressionStatement() || | 777 !body->at(0)->IsExpressionStatement() || |
| 779 !body->at(0)->AsExpressionStatement()-> | 778 !body->at(0)->AsExpressionStatement()-> |
| 780 expression()->IsFunctionLiteral()) { | 779 expression()->IsFunctionLiteral()) { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 805 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseLazy); | 804 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseLazy); |
| 806 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy()); | 805 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy()); |
| 807 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseLazy"); | 806 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseLazy"); |
| 808 Handle<String> source(String::cast(info->script()->source())); | 807 Handle<String> source(String::cast(info->script()->source())); |
| 809 isolate->counters()->total_parse_size()->Increment(source->length()); | 808 isolate->counters()->total_parse_size()->Increment(source->length()); |
| 810 base::ElapsedTimer timer; | 809 base::ElapsedTimer timer; |
| 811 if (FLAG_trace_parse) { | 810 if (FLAG_trace_parse) { |
| 812 timer.Start(); | 811 timer.Start(); |
| 813 } | 812 } |
| 814 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 813 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
| 815 DeserializeScopeChain(info, info->context(), | 814 InspectScopeChain( |
| 816 Scope::DeserializationMode::kKeepScopeInfo); | 815 info, info->context().is_null() || info->context()->IsNativeContext() |
| 816 ? Handle<ScopeInfo>() | |
| 817 : Handle<ScopeInfo>(info->context()->scope_info())); | |
| 817 | 818 |
| 818 // Initialize parser state. | 819 // Initialize parser state. |
| 819 source = String::Flatten(source); | 820 source = String::Flatten(source); |
| 820 FunctionLiteral* result; | 821 FunctionLiteral* result; |
| 821 { | 822 { |
| 822 std::unique_ptr<Utf16CharacterStream> stream; | 823 std::unique_ptr<Utf16CharacterStream> stream; |
| 823 if (source->IsExternalTwoByteString()) { | 824 if (source->IsExternalTwoByteString()) { |
| 824 stream.reset(new ExternalTwoByteStringUtf16CharacterStream( | 825 stream.reset(new ExternalTwoByteStringUtf16CharacterStream( |
| 825 Handle<ExternalTwoByteString>::cast(source), | 826 Handle<ExternalTwoByteString>::cast(source), |
| 826 shared_info->start_position(), shared_info->end_position())); | 827 shared_info->start_position(), shared_info->end_position())); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 872 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 873 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
| 873 fni_->PushEnclosingName(raw_name); | 874 fni_->PushEnclosingName(raw_name); |
| 874 | 875 |
| 875 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 876 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 876 | 877 |
| 877 // Place holder for the result. | 878 // Place holder for the result. |
| 878 FunctionLiteral* result = nullptr; | 879 FunctionLiteral* result = nullptr; |
| 879 | 880 |
| 880 { | 881 { |
| 881 // Parse the function literal. | 882 // Parse the function literal. |
| 882 Scope* outer = original_scope_; | 883 Scope* outer = info->script_scope(); |
| 883 DCHECK(outer); | 884 DCHECK(outer); |
| 884 FunctionState function_state(&function_state_, &scope_state_, outer, | 885 FunctionState function_state(&function_state_, &scope_state_, outer, |
| 885 info->function_kind()); | 886 info->function_kind()); |
| 886 DCHECK(is_sloppy(outer->language_mode()) || | |
| 887 is_strict(info->language_mode())); | |
| 888 FunctionLiteral::FunctionType function_type = ComputeFunctionType(info); | 887 FunctionLiteral::FunctionType function_type = ComputeFunctionType(info); |
| 889 bool ok = true; | 888 bool ok = true; |
| 890 | 889 |
| 891 if (info->is_arrow()) { | 890 if (info->is_arrow()) { |
| 892 bool is_async = allow_harmony_async_await() && info->is_async(); | 891 bool is_async = allow_harmony_async_await() && info->is_async(); |
| 893 if (is_async) { | 892 if (is_async) { |
| 894 DCHECK(!scanner()->HasAnyLineTerminatorAfterNext()); | 893 DCHECK(!scanner()->HasAnyLineTerminatorAfterNext()); |
| 895 if (!Check(Token::ASYNC)) { | 894 if (!Check(Token::ASYNC)) { |
| 896 CHECK(stack_overflow()); | 895 CHECK(stack_overflow()); |
| 897 return nullptr; | 896 return nullptr; |
| (...skipping 3113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4011 | 4010 |
| 4012 if (!parameters.is_simple) { | 4011 if (!parameters.is_simple) { |
| 4013 DCHECK_NOT_NULL(inner_scope); | 4012 DCHECK_NOT_NULL(inner_scope); |
| 4014 DCHECK_EQ(function_scope, scope()); | 4013 DCHECK_EQ(function_scope, scope()); |
| 4015 DCHECK_EQ(function_scope, inner_scope->outer_scope()); | 4014 DCHECK_EQ(function_scope, inner_scope->outer_scope()); |
| 4016 DCHECK_EQ(body, inner_block->statements()); | 4015 DCHECK_EQ(body, inner_block->statements()); |
| 4017 SetLanguageMode(function_scope, inner_scope->language_mode()); | 4016 SetLanguageMode(function_scope, inner_scope->language_mode()); |
| 4018 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK); | 4017 Block* init_block = BuildParameterInitializationBlock(parameters, CHECK_OK); |
| 4019 | 4018 |
| 4020 if (is_sloppy(inner_scope->language_mode())) { | 4019 if (is_sloppy(inner_scope->language_mode())) { |
| 4021 InsertSloppyBlockFunctionVarBindings(inner_scope, CHECK_OK); | 4020 inner_scope->HoistSloppyBlockFunctions(factory(), CHECK_OK); |
| 4022 } | 4021 } |
| 4023 | 4022 |
| 4024 // TODO(littledan): Merge the two rejection blocks into one | 4023 // TODO(littledan): Merge the two rejection blocks into one |
| 4025 if (IsAsyncFunction(kind)) { | 4024 if (IsAsyncFunction(kind)) { |
| 4026 init_block = BuildRejectPromiseOnException(init_block, CHECK_OK); | 4025 init_block = BuildRejectPromiseOnException(init_block, CHECK_OK); |
| 4027 } | 4026 } |
| 4028 | 4027 |
| 4029 DCHECK_NOT_NULL(init_block); | 4028 DCHECK_NOT_NULL(init_block); |
| 4030 | 4029 |
| 4031 inner_scope->set_end_position(scanner()->location().end_pos); | 4030 inner_scope->set_end_position(scanner()->location().end_pos); |
| 4032 if (inner_scope->FinalizeBlockScope() != nullptr) { | 4031 if (inner_scope->FinalizeBlockScope() != nullptr) { |
| 4033 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); | 4032 CheckConflictingVarDeclarations(inner_scope, CHECK_OK); |
| 4034 InsertShadowingVarBindingInitializers(inner_block); | 4033 InsertShadowingVarBindingInitializers(inner_block); |
| 4035 } | 4034 } |
| 4036 inner_scope = nullptr; | 4035 inner_scope = nullptr; |
| 4037 | 4036 |
| 4038 result->Add(init_block, zone()); | 4037 result->Add(init_block, zone()); |
| 4039 result->Add(inner_block, zone()); | 4038 result->Add(inner_block, zone()); |
| 4040 } else { | 4039 } else { |
| 4041 DCHECK_EQ(inner_scope, function_scope); | 4040 DCHECK_EQ(inner_scope, function_scope); |
| 4042 if (is_sloppy(function_scope->language_mode())) { | 4041 if (is_sloppy(function_scope->language_mode())) { |
| 4043 InsertSloppyBlockFunctionVarBindings(function_scope, CHECK_OK); | 4042 function_scope->HoistSloppyBlockFunctions(factory(), CHECK_OK); |
| 4044 } | 4043 } |
| 4045 } | 4044 } |
| 4046 | 4045 |
| 4047 if (function_type == FunctionLiteral::kNamedExpression) { | 4046 if (function_type == FunctionLiteral::kNamedExpression) { |
| 4048 // Now that we know the language mode, we can create the const assignment | 4047 // Now that we know the language mode, we can create the const assignment |
| 4049 // in the previously reserved spot. | 4048 // in the previously reserved spot. |
| 4050 DCHECK_EQ(function_scope, scope()); | 4049 DCHECK_EQ(function_scope, scope()); |
| 4051 Variable* fvar = function_scope->DeclareFunctionVar(function_name); | 4050 Variable* fvar = function_scope->DeclareFunctionVar(function_name); |
| 4052 VariableProxy* fproxy = factory()->NewVariableProxy(fvar); | 4051 VariableProxy* fproxy = factory()->NewVariableProxy(fvar); |
| 4053 result->Set(kFunctionNameAssignmentIndex, | 4052 result->Set(kFunctionNameAssignmentIndex, |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4251 VariableProxy* to = NewUnresolved(name); | 4250 VariableProxy* to = NewUnresolved(name); |
| 4252 VariableProxy* from = factory()->NewVariableProxy(parameter); | 4251 VariableProxy* from = factory()->NewVariableProxy(parameter); |
| 4253 Expression* assignment = | 4252 Expression* assignment = |
| 4254 factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition); | 4253 factory()->NewAssignment(Token::ASSIGN, to, from, kNoSourcePosition); |
| 4255 Statement* statement = | 4254 Statement* statement = |
| 4256 factory()->NewExpressionStatement(assignment, kNoSourcePosition); | 4255 factory()->NewExpressionStatement(assignment, kNoSourcePosition); |
| 4257 inner_block->statements()->InsertAt(0, statement, zone()); | 4256 inner_block->statements()->InsertAt(0, statement, zone()); |
| 4258 } | 4257 } |
| 4259 } | 4258 } |
| 4260 | 4259 |
| 4261 void Parser::InsertSloppyBlockFunctionVarBindings(DeclarationScope* scope, | |
| 4262 bool* ok) { | |
| 4263 scope->HoistSloppyBlockFunctions(factory(), CHECK_OK_VOID); | |
| 4264 | |
| 4265 SloppyBlockFunctionMap* map = scope->sloppy_block_function_map(); | |
| 4266 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { | |
| 4267 // Write in assignments to var for each block-scoped function declaration | |
| 4268 auto delegates = static_cast<SloppyBlockFunctionStatement*>(p->value); | |
| 4269 for (SloppyBlockFunctionStatement* delegate = delegates; | |
| 4270 delegate != nullptr; delegate = delegate->next()) { | |
| 4271 if (delegate->to() == nullptr) { | |
| 4272 continue; | |
| 4273 } | |
| 4274 Expression* assignment = factory()->NewAssignment( | |
| 4275 Token::ASSIGN, delegate->to(), delegate->from(), kNoSourcePosition); | |
| 4276 Statement* statement = | |
| 4277 factory()->NewExpressionStatement(assignment, kNoSourcePosition); | |
| 4278 delegate->set_statement(statement); | |
| 4279 } | |
| 4280 } | |
| 4281 } | |
| 4282 | |
| 4283 | |
| 4284 // ---------------------------------------------------------------------------- | 4260 // ---------------------------------------------------------------------------- |
| 4285 // Parser support | 4261 // Parser support |
| 4286 | 4262 |
| 4287 bool Parser::TargetStackContainsLabel(const AstRawString* label) { | 4263 bool Parser::TargetStackContainsLabel(const AstRawString* label) { |
| 4288 for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) { | 4264 for (ParserTarget* t = target_stack_; t != NULL; t = t->previous()) { |
| 4289 if (ContainsLabel(t->statement()->labels(), label)) return true; | 4265 if (ContainsLabel(t->statement()->labels(), label)) return true; |
| 4290 } | 4266 } |
| 4291 return false; | 4267 return false; |
| 4292 } | 4268 } |
| 4293 | 4269 |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4428 DCHECK(info->source_stream() == nullptr); | 4404 DCHECK(info->source_stream() == nullptr); |
| 4429 stream_ptr = info->character_stream(); | 4405 stream_ptr = info->character_stream(); |
| 4430 } else { | 4406 } else { |
| 4431 DCHECK(info->character_stream() == nullptr); | 4407 DCHECK(info->character_stream() == nullptr); |
| 4432 stream.reset(new ExternalStreamingStream(info->source_stream(), | 4408 stream.reset(new ExternalStreamingStream(info->source_stream(), |
| 4433 info->source_stream_encoding())); | 4409 info->source_stream_encoding())); |
| 4434 stream_ptr = stream.get(); | 4410 stream_ptr = stream.get(); |
| 4435 } | 4411 } |
| 4436 DCHECK(info->context().is_null() || info->context()->IsNativeContext()); | 4412 DCHECK(info->context().is_null() || info->context()->IsNativeContext()); |
| 4437 | 4413 |
| 4438 DCHECK(original_scope_); | |
| 4439 | |
| 4440 // When streaming, we don't know the length of the source until we have parsed | 4414 // When streaming, we don't know the length of the source until we have parsed |
| 4441 // it. The raw data can be UTF-8, so we wouldn't know the source length until | 4415 // it. The raw data can be UTF-8, so we wouldn't know the source length until |
| 4442 // we have decoded it anyway even if we knew the raw data length (which we | 4416 // we have decoded it anyway even if we knew the raw data length (which we |
| 4443 // don't). We work around this by storing all the scopes which need their end | 4417 // don't). We work around this by storing all the scopes which need their end |
| 4444 // position set at the end of the script (the top scope and possible eval | 4418 // position set at the end of the script (the top scope and possible eval |
| 4445 // scopes) and set their end position after we know the script length. | 4419 // scopes) and set their end position after we know the script length. |
| 4446 if (info->is_lazy()) { | 4420 if (info->is_lazy()) { |
| 4447 result = DoParseLazy(info, info->function_name(), stream_ptr); | 4421 result = DoParseLazy(info, info->function_name(), stream_ptr); |
| 4448 } else { | 4422 } else { |
| 4449 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 4423 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
| (...skipping 1524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5974 node->Print(Isolate::Current()); | 5948 node->Print(Isolate::Current()); |
| 5975 } | 5949 } |
| 5976 #endif // DEBUG | 5950 #endif // DEBUG |
| 5977 | 5951 |
| 5978 #undef CHECK_OK | 5952 #undef CHECK_OK |
| 5979 #undef CHECK_OK_VOID | 5953 #undef CHECK_OK_VOID |
| 5980 #undef CHECK_FAILED | 5954 #undef CHECK_FAILED |
| 5981 | 5955 |
| 5982 } // namespace internal | 5956 } // namespace internal |
| 5983 } // namespace v8 | 5957 } // namespace v8 |
| OLD | NEW |