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.h" | 10 #include "src/ast/ast.h" |
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
850 } | 850 } |
851 if (info->ast_value_factory() == NULL) { | 851 if (info->ast_value_factory() == NULL) { |
852 // info takes ownership of AstValueFactory. | 852 // info takes ownership of AstValueFactory. |
853 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); | 853 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); |
854 info->set_ast_value_factory_owned(); | 854 info->set_ast_value_factory_owned(); |
855 ast_value_factory_ = info->ast_value_factory(); | 855 ast_value_factory_ = info->ast_value_factory(); |
856 ast_node_factory_.set_ast_value_factory(ast_value_factory_); | 856 ast_node_factory_.set_ast_value_factory(ast_value_factory_); |
857 } | 857 } |
858 } | 858 } |
859 | 859 |
860 void Parser::DeserializeScopeChain( | |
861 ParseInfo* info, Handle<Context> context, | |
862 Scope::DeserializationMode deserialization_mode) { | |
863 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native | |
864 // context, which will have the "this" binding for script scopes. | |
865 Scope* scope = NewScriptScope(); | |
866 info->set_script_scope(scope); | |
867 if (!context.is_null() && !context->IsNativeContext()) { | |
868 scope = | |
869 Scope::DeserializeScopeChain(info->isolate(), zone(), *context, scope, | |
870 ast_value_factory(), deserialization_mode); | |
871 if (info->context().is_null()) { | |
872 DCHECK(deserialization_mode == | |
873 Scope::DeserializationMode::kDeserializeOffHeap); | |
874 } else { | |
875 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this | |
876 // means the Parser cannot operate independent of the V8 heap. Tell the | |
877 // string table to internalize strings and values right after they're | |
878 // created. This kind of parsing can only be done in the main thread. | |
879 DCHECK(parsing_on_main_thread_); | |
880 ast_value_factory()->Internalize(info->isolate()); | |
881 } | |
882 } | |
883 original_scope_ = scope; | |
884 } | |
860 | 885 |
861 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { | 886 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { |
862 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 887 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
863 // see comment for HistogramTimerScope class. | 888 // see comment for HistogramTimerScope class. |
864 | 889 |
865 // It's OK to use the Isolate & counters here, since this function is only | 890 // It's OK to use the Isolate & counters here, since this function is only |
866 // called in the main thread. | 891 // called in the main thread. |
867 DCHECK(parsing_on_main_thread_); | 892 DCHECK(parsing_on_main_thread_); |
868 | 893 |
869 HistogramTimerScope timer_scope(isolate->counters()->parse(), true); | 894 HistogramTimerScope timer_scope(isolate->counters()->parse(), true); |
870 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::Parse); | 895 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::Parse); |
871 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.Parse"); | 896 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.Parse"); |
872 Handle<String> source(String::cast(info->script()->source())); | 897 Handle<String> source(String::cast(info->script()->source())); |
873 isolate->counters()->total_parse_size()->Increment(source->length()); | 898 isolate->counters()->total_parse_size()->Increment(source->length()); |
874 base::ElapsedTimer timer; | 899 base::ElapsedTimer timer; |
875 if (FLAG_trace_parse) { | 900 if (FLAG_trace_parse) { |
876 timer.Start(); | 901 timer.Start(); |
877 } | 902 } |
878 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 903 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
879 | 904 |
880 // Initialize parser state. | 905 // Initialize parser state. |
881 CompleteParserRecorder recorder; | 906 CompleteParserRecorder recorder; |
882 | 907 |
883 if (produce_cached_parse_data()) { | 908 if (produce_cached_parse_data()) { |
884 log_ = &recorder; | 909 log_ = &recorder; |
885 } else if (consume_cached_parse_data()) { | 910 } else if (consume_cached_parse_data()) { |
886 cached_parse_data_->Initialize(); | 911 cached_parse_data_->Initialize(); |
887 } | 912 } |
888 | 913 |
914 DeserializeScopeChain(info, info->context(), | |
915 Scope::DeserializationMode::kKeepScopeInfo); | |
916 | |
889 source = String::Flatten(source); | 917 source = String::Flatten(source); |
890 FunctionLiteral* result; | 918 FunctionLiteral* result; |
891 | 919 |
892 { | 920 { |
893 std::unique_ptr<Utf16CharacterStream> stream; | 921 std::unique_ptr<Utf16CharacterStream> stream; |
894 if (source->IsExternalTwoByteString()) { | 922 if (source->IsExternalTwoByteString()) { |
895 stream.reset(new ExternalTwoByteStringUtf16CharacterStream( | 923 stream.reset(new ExternalTwoByteStringUtf16CharacterStream( |
896 Handle<ExternalTwoByteString>::cast(source), 0, source->length())); | 924 Handle<ExternalTwoByteString>::cast(source), 0, source->length())); |
897 } else if (source->IsExternalOneByteString()) { | 925 } else if (source->IsExternalOneByteString()) { |
898 stream.reset(new ExternalOneByteStringUtf16CharacterStream( | 926 stream.reset(new ExternalOneByteStringUtf16CharacterStream( |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
935 // background thread. We should not access anything Isolate / heap dependent | 963 // background thread. We should not access anything Isolate / heap dependent |
936 // via ParseInfo, and also not pass it forward. | 964 // via ParseInfo, and also not pass it forward. |
937 DCHECK_NULL(scope_state_); | 965 DCHECK_NULL(scope_state_); |
938 DCHECK_NULL(target_stack_); | 966 DCHECK_NULL(target_stack_); |
939 | 967 |
940 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY; | 968 Mode parsing_mode = FLAG_lazy && allow_lazy() ? PARSE_LAZILY : PARSE_EAGERLY; |
941 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY; | 969 if (allow_natives() || extension_ != NULL) parsing_mode = PARSE_EAGERLY; |
942 | 970 |
943 FunctionLiteral* result = NULL; | 971 FunctionLiteral* result = NULL; |
944 { | 972 { |
945 // TODO(wingo): Add an outer SCRIPT_SCOPE corresponding to the native | 973 Scope* scope = original_scope_; |
946 // context, which will have the "this" binding for script scopes. | 974 DCHECK(scope); |
947 Scope* scope = NewScriptScope(); | |
948 info->set_script_scope(scope); | |
949 if (!info->context().is_null() && !info->context()->IsNativeContext()) { | |
950 scope = Scope::DeserializeScopeChain(info->isolate(), zone(), | |
951 *info->context(), scope, | |
952 ast_value_factory()); | |
953 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this | |
954 // means the Parser cannot operate independent of the V8 heap. Tell the | |
955 // string table to internalize strings and values right after they're | |
956 // created. This kind of parsing can only be done in the main thread. | |
957 DCHECK(parsing_on_main_thread_); | |
958 ast_value_factory()->Internalize(info->isolate()); | |
959 } | |
960 original_scope_ = scope; | |
961 if (info->is_eval()) { | 975 if (info->is_eval()) { |
962 if (!scope->is_script_scope() || is_strict(info->language_mode())) { | 976 if (!scope->is_script_scope() || is_strict(info->language_mode())) { |
963 parsing_mode = PARSE_EAGERLY; | 977 parsing_mode = PARSE_EAGERLY; |
964 } | 978 } |
965 scope = NewScopeWithParent(scope, EVAL_SCOPE); | 979 scope = NewScopeWithParent(scope, EVAL_SCOPE); |
966 } else if (info->is_module()) { | 980 } else if (info->is_module()) { |
967 scope = NewScopeWithParent(scope, MODULE_SCOPE); | 981 scope = NewScopeWithParent(scope, MODULE_SCOPE); |
968 } | 982 } |
969 | 983 |
970 scope->set_start_position(0); | 984 scope->set_start_position(0); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1041 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseLazy); | 1055 RuntimeCallTimerScope runtime_timer(isolate, &RuntimeCallStats::ParseLazy); |
1042 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy()); | 1056 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy()); |
1043 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseLazy"); | 1057 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.ParseLazy"); |
1044 Handle<String> source(String::cast(info->script()->source())); | 1058 Handle<String> source(String::cast(info->script()->source())); |
1045 isolate->counters()->total_parse_size()->Increment(source->length()); | 1059 isolate->counters()->total_parse_size()->Increment(source->length()); |
1046 base::ElapsedTimer timer; | 1060 base::ElapsedTimer timer; |
1047 if (FLAG_trace_parse) { | 1061 if (FLAG_trace_parse) { |
1048 timer.Start(); | 1062 timer.Start(); |
1049 } | 1063 } |
1050 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 1064 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
1065 DeserializeScopeChain(info, info->context(), | |
1066 Scope::DeserializationMode::kKeepScopeInfo); | |
1051 | 1067 |
1052 // Initialize parser state. | 1068 // Initialize parser state. |
1053 source = String::Flatten(source); | 1069 source = String::Flatten(source); |
1054 FunctionLiteral* result; | 1070 FunctionLiteral* result; |
1055 { | 1071 { |
1056 std::unique_ptr<Utf16CharacterStream> stream; | 1072 std::unique_ptr<Utf16CharacterStream> stream; |
1057 if (source->IsExternalTwoByteString()) { | 1073 if (source->IsExternalTwoByteString()) { |
1058 stream.reset(new ExternalTwoByteStringUtf16CharacterStream( | 1074 stream.reset(new ExternalTwoByteStringUtf16CharacterStream( |
1059 Handle<ExternalTwoByteString>::cast(source), | 1075 Handle<ExternalTwoByteString>::cast(source), |
1060 shared_info->start_position(), shared_info->end_position())); | 1076 shared_info->start_position(), shared_info->end_position())); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1103 const AstRawString* raw_name = ast_value_factory()->GetString(name); | 1119 const AstRawString* raw_name = ast_value_factory()->GetString(name); |
1104 fni_->PushEnclosingName(raw_name); | 1120 fni_->PushEnclosingName(raw_name); |
1105 | 1121 |
1106 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1122 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1107 | 1123 |
1108 // Place holder for the result. | 1124 // Place holder for the result. |
1109 FunctionLiteral* result = nullptr; | 1125 FunctionLiteral* result = nullptr; |
1110 | 1126 |
1111 { | 1127 { |
1112 // Parse the function literal. | 1128 // Parse the function literal. |
1113 Scope* scope = NewScriptScope(); | 1129 Scope* scope = original_scope_; |
1114 info->set_script_scope(scope); | 1130 DCHECK(scope); |
1115 if (!info->context().is_null()) { | |
1116 // Ok to use Isolate here, since lazy function parsing is only done in the | |
1117 // main thread. | |
1118 DCHECK(parsing_on_main_thread_); | |
1119 scope = Scope::DeserializeScopeChain(isolate, zone(), *info->context(), | |
1120 scope, ast_value_factory()); | |
1121 } | |
1122 original_scope_ = scope; | |
1123 FunctionState function_state(&function_state_, &scope_state_, scope, | 1131 FunctionState function_state(&function_state_, &scope_state_, scope, |
1124 shared_info->kind()); | 1132 shared_info->kind()); |
1125 DCHECK(is_sloppy(scope->language_mode()) || | 1133 DCHECK(is_sloppy(scope->language_mode()) || |
1126 is_strict(info->language_mode())); | 1134 is_strict(info->language_mode())); |
1127 DCHECK(info->language_mode() == shared_info->language_mode()); | 1135 DCHECK(info->language_mode() == shared_info->language_mode()); |
1128 FunctionLiteral::FunctionType function_type = | 1136 FunctionLiteral::FunctionType function_type = |
1129 ComputeFunctionType(shared_info); | 1137 ComputeFunctionType(shared_info); |
1130 bool ok = true; | 1138 bool ok = true; |
1131 | 1139 |
1132 if (shared_info->is_arrow()) { | 1140 if (shared_info->is_arrow()) { |
(...skipping 4329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5462 stream_ptr = info->character_stream(); | 5470 stream_ptr = info->character_stream(); |
5463 } else { | 5471 } else { |
5464 DCHECK(info->character_stream() == nullptr); | 5472 DCHECK(info->character_stream() == nullptr); |
5465 stream.reset(new ExternalStreamingStream(info->source_stream(), | 5473 stream.reset(new ExternalStreamingStream(info->source_stream(), |
5466 info->source_stream_encoding())); | 5474 info->source_stream_encoding())); |
5467 stream_ptr = stream.get(); | 5475 stream_ptr = stream.get(); |
5468 } | 5476 } |
5469 scanner_.Initialize(stream_ptr); | 5477 scanner_.Initialize(stream_ptr); |
5470 DCHECK(info->context().is_null() || info->context()->IsNativeContext()); | 5478 DCHECK(info->context().is_null() || info->context()->IsNativeContext()); |
5471 | 5479 |
5480 if (!original_scope_) { | |
Toon Verwaest
2016/08/03 12:31:46
Add a comment why we might (not) have original_sco
| |
5481 DeserializeScopeChain(info, info->context(), | |
5482 Scope::DeserializationMode::kDeserializeOffHeap); | |
5483 } | |
5484 | |
5472 // When streaming, we don't know the length of the source until we have parsed | 5485 // When streaming, we don't know the length of the source until we have parsed |
5473 // it. The raw data can be UTF-8, so we wouldn't know the source length until | 5486 // it. The raw data can be UTF-8, so we wouldn't know the source length until |
5474 // we have decoded it anyway even if we knew the raw data length (which we | 5487 // we have decoded it anyway even if we knew the raw data length (which we |
5475 // don't). We work around this by storing all the scopes which need their end | 5488 // don't). We work around this by storing all the scopes which need their end |
5476 // position set at the end of the script (the top scope and possible eval | 5489 // position set at the end of the script (the top scope and possible eval |
5477 // scopes) and set their end position after we know the script length. | 5490 // scopes) and set their end position after we know the script length. |
5478 result = DoParseProgram(info); | 5491 result = DoParseProgram(info); |
5479 | 5492 |
5480 info->set_literal(result); | 5493 info->set_literal(result); |
5481 | 5494 |
(...skipping 1605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7087 node->Print(Isolate::Current()); | 7100 node->Print(Isolate::Current()); |
7088 } | 7101 } |
7089 #endif // DEBUG | 7102 #endif // DEBUG |
7090 | 7103 |
7091 #undef CHECK_OK | 7104 #undef CHECK_OK |
7092 #undef CHECK_OK_VOID | 7105 #undef CHECK_OK_VOID |
7093 #undef CHECK_FAILED | 7106 #undef CHECK_FAILED |
7094 | 7107 |
7095 } // namespace internal | 7108 } // namespace internal |
7096 } // namespace v8 | 7109 } // namespace v8 |
OLD | NEW |