OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/kernel_binary_flowgraph.h" | 5 #include "vm/kernel_binary_flowgraph.h" |
6 | 6 |
7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
8 #include "vm/longjump.h" | 8 #include "vm/longjump.h" |
9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
10 | 10 |
(...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 // TODO(jensj): From kernel_binary.cc | 811 // TODO(jensj): From kernel_binary.cc |
812 // forinstmt->variable_->set_end_position(forinstmt->position_); | 812 // forinstmt->variable_->set_end_position(forinstmt->position_); |
813 ExitScope(position, builder_->reader_->max_position()); | 813 ExitScope(position, builder_->reader_->max_position()); |
814 --depth_.loop_; | 814 --depth_.loop_; |
815 --depth_.for_in_; | 815 --depth_.for_in_; |
816 return; | 816 return; |
817 } | 817 } |
818 case kSwitchStatement: { | 818 case kSwitchStatement: { |
819 AddSwitchVariable(); | 819 AddSwitchVariable(); |
820 VisitExpression(); // read condition. | 820 VisitExpression(); // read condition. |
821 int num_cases = builder_->ReadListLength(); // read number of cases. | 821 int case_count = builder_->ReadListLength(); // read number of cases. |
822 for (intptr_t i = 0; i < num_cases; ++i) { | 822 for (intptr_t i = 0; i < case_count; ++i) { |
823 int num_expressions = | 823 int expression_count = |
824 builder_->ReadListLength(); // read number of expressions. | 824 builder_->ReadListLength(); // read number of expressions. |
825 for (intptr_t j = 0; j < num_expressions; ++j) { | 825 for (intptr_t j = 0; j < expression_count; ++j) { |
826 builder_->ReadPosition(); // read jth position. | 826 builder_->ReadPosition(); // read jth position. |
827 VisitExpression(); // read jth expression. | 827 VisitExpression(); // read jth expression. |
828 } | 828 } |
829 builder_->ReadBool(); // read is_default. | 829 builder_->ReadBool(); // read is_default. |
830 VisitStatement(); // read body. | 830 VisitStatement(); // read body. |
831 } | 831 } |
832 return; | 832 return; |
833 } | 833 } |
834 case kContinueSwitchStatement: | 834 case kContinueSwitchStatement: |
835 builder_->ReadUInt(); // read target_index. | 835 builder_->ReadUInt(); // read target_index. |
(...skipping 24 matching lines...) Expand all Loading... |
860 case kTryCatch: { | 860 case kTryCatch: { |
861 ++depth_.try_; | 861 ++depth_.try_; |
862 AddTryVariables(); | 862 AddTryVariables(); |
863 VisitStatement(); // read body. | 863 VisitStatement(); // read body. |
864 --depth_.try_; | 864 --depth_.try_; |
865 | 865 |
866 ++depth_.catch_; | 866 ++depth_.catch_; |
867 AddCatchVariables(); | 867 AddCatchVariables(); |
868 | 868 |
869 builder_->ReadBool(); // read any_catch_needs_stack_trace. | 869 builder_->ReadBool(); // read any_catch_needs_stack_trace. |
870 intptr_t num_catches = | 870 intptr_t catch_count = |
871 builder_->ReadListLength(); // read number of catches. | 871 builder_->ReadListLength(); // read number of catches. |
872 for (intptr_t i = 0; i < num_catches; ++i) { | 872 for (intptr_t i = 0; i < catch_count; ++i) { |
873 PositionScope scope(builder_->reader_); | 873 PositionScope scope(builder_->reader_); |
874 intptr_t offset = builder_->ReaderOffset(); // Catch has no tag. | 874 intptr_t offset = builder_->ReaderOffset(); // Catch has no tag. |
875 | 875 |
876 EnterScope(offset); | 876 EnterScope(offset); |
877 | 877 |
878 VisitDartType(); // Read the guard. | 878 VisitDartType(); // Read the guard. |
879 tag = builder_->ReadTag(); // read first part of exception. | 879 tag = builder_->ReadTag(); // read first part of exception. |
880 if (tag == kSomething) { | 880 if (tag == kSomething) { |
881 VisitVariableDeclaration(); // read exception. | 881 VisitVariableDeclaration(); // read exception. |
882 } | 882 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
937 VisitVariableDeclaration(); // read variable declaration. | 937 VisitVariableDeclaration(); // read variable declaration. |
938 HandleLocalFunction(offset); // read function node. | 938 HandleLocalFunction(offset); // read function node. |
939 return; | 939 return; |
940 } | 940 } |
941 default: | 941 default: |
942 UNREACHABLE(); | 942 UNREACHABLE(); |
943 } | 943 } |
944 } | 944 } |
945 | 945 |
946 void StreamingScopeBuilder::VisitArguments() { | 946 void StreamingScopeBuilder::VisitArguments() { |
947 builder_->ReadUInt(); // read num_arguments. | 947 builder_->ReadUInt(); // read argument_count. |
948 | 948 |
949 // Types | 949 // Types |
950 intptr_t list_length = builder_->ReadListLength(); // read list length. | 950 intptr_t list_length = builder_->ReadListLength(); // read list length. |
951 for (intptr_t i = 0; i < list_length; ++i) { | 951 for (intptr_t i = 0; i < list_length; ++i) { |
952 VisitDartType(); // read ith type. | 952 VisitDartType(); // read ith type. |
953 } | 953 } |
954 | 954 |
955 // Positional. | 955 // Positional. |
956 list_length = builder_->ReadListLength(); // read list length. | 956 list_length = builder_->ReadListLength(); // read list length. |
957 for (intptr_t i = 0; i < list_length; ++i) { | 957 for (intptr_t i = 0; i < list_length; ++i) { |
(...skipping 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2346 RawObject* StreamingConstantEvaluator::EvaluateConstConstructorCall( | 2346 RawObject* StreamingConstantEvaluator::EvaluateConstConstructorCall( |
2347 const dart::Class& type_class, | 2347 const dart::Class& type_class, |
2348 const TypeArguments& type_arguments, | 2348 const TypeArguments& type_arguments, |
2349 const Function& constructor, | 2349 const Function& constructor, |
2350 const Object& argument) { | 2350 const Object& argument) { |
2351 // Factories have one extra argument: the type arguments. | 2351 // Factories have one extra argument: the type arguments. |
2352 // Constructors have 1 extra arguments: receiver. | 2352 // Constructors have 1 extra arguments: receiver. |
2353 const int kTypeArgsLen = 0; | 2353 const int kTypeArgsLen = 0; |
2354 const int kNumArgs = 1; | 2354 const int kNumArgs = 1; |
2355 const int kNumExtraArgs = 1; | 2355 const int kNumExtraArgs = 1; |
2356 const int num_arguments = kNumArgs + kNumExtraArgs; | 2356 const int argument_count = kNumArgs + kNumExtraArgs; |
2357 const Array& arg_values = | 2357 const Array& arg_values = |
2358 Array::Handle(Z, Array::New(num_arguments, Heap::kOld)); | 2358 Array::Handle(Z, Array::New(argument_count, Heap::kOld)); |
2359 Instance& instance = Instance::Handle(Z); | 2359 Instance& instance = Instance::Handle(Z); |
2360 if (!constructor.IsFactory()) { | 2360 if (!constructor.IsFactory()) { |
2361 instance = Instance::New(type_class, Heap::kOld); | 2361 instance = Instance::New(type_class, Heap::kOld); |
2362 if (!type_arguments.IsNull()) { | 2362 if (!type_arguments.IsNull()) { |
2363 ASSERT(type_arguments.IsInstantiated()); | 2363 ASSERT(type_arguments.IsInstantiated()); |
2364 instance.SetTypeArguments( | 2364 instance.SetTypeArguments( |
2365 TypeArguments::Handle(Z, type_arguments.Canonicalize())); | 2365 TypeArguments::Handle(Z, type_arguments.Canonicalize())); |
2366 } | 2366 } |
2367 arg_values.SetAt(0, instance); | 2367 arg_values.SetAt(0, instance); |
2368 } else { | 2368 } else { |
2369 // Prepend type_arguments to list of arguments to factory. | 2369 // Prepend type_arguments to list of arguments to factory. |
2370 ASSERT(type_arguments.IsZoneHandle()); | 2370 ASSERT(type_arguments.IsZoneHandle()); |
2371 arg_values.SetAt(0, type_arguments); | 2371 arg_values.SetAt(0, type_arguments); |
2372 } | 2372 } |
2373 arg_values.SetAt((0 + kNumExtraArgs), argument); | 2373 arg_values.SetAt((0 + kNumExtraArgs), argument); |
2374 const Array& args_descriptor = | 2374 const Array& args_descriptor = |
2375 Array::Handle(Z, ArgumentsDescriptor::New(kTypeArgsLen, num_arguments, | 2375 Array::Handle(Z, ArgumentsDescriptor::New(kTypeArgsLen, argument_count, |
2376 Object::empty_array())); | 2376 Object::empty_array())); |
2377 const Object& result = Object::Handle( | 2377 const Object& result = Object::Handle( |
2378 Z, DartEntry::InvokeFunction(constructor, arg_values, args_descriptor)); | 2378 Z, DartEntry::InvokeFunction(constructor, arg_values, args_descriptor)); |
2379 ASSERT(!result.IsError()); | 2379 ASSERT(!result.IsError()); |
2380 if (constructor.IsFactory()) { | 2380 if (constructor.IsFactory()) { |
2381 // The factory method returns the allocated object. | 2381 // The factory method returns the allocated object. |
2382 instance ^= result.raw(); | 2382 instance ^= result.raw(); |
2383 } | 2383 } |
2384 return H.Canonicalize(instance); | 2384 return H.Canonicalize(instance); |
2385 } | 2385 } |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2671 body += LoadStaticField(); | 2671 body += LoadStaticField(); |
2672 } | 2672 } |
2673 body += Return(TokenPosition::kNoSource); | 2673 body += Return(TokenPosition::kNoSource); |
2674 | 2674 |
2675 return new (Z) | 2675 return new (Z) |
2676 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, | 2676 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, |
2677 flow_graph_builder_->next_block_id_ - 1); | 2677 flow_graph_builder_->next_block_id_ - 1); |
2678 } | 2678 } |
2679 | 2679 |
2680 void StreamingFlowGraphBuilder::SetupDefaultParameterValues() { | 2680 void StreamingFlowGraphBuilder::SetupDefaultParameterValues() { |
2681 intptr_t num_optional_parameters = | 2681 intptr_t optional_parameter_count = |
2682 parsed_function()->function().NumOptionalParameters(); | 2682 parsed_function()->function().NumOptionalParameters(); |
2683 if (num_optional_parameters > 0) { | 2683 if (optional_parameter_count > 0) { |
2684 ZoneGrowableArray<const Instance*>* default_values = | 2684 ZoneGrowableArray<const Instance*>* default_values = |
2685 new ZoneGrowableArray<const Instance*>(Z, num_optional_parameters); | 2685 new ZoneGrowableArray<const Instance*>(Z, optional_parameter_count); |
2686 | 2686 |
2687 AlternativeReadingScope alt(reader_); | 2687 AlternativeReadingScope alt(reader_); |
2688 FunctionNodeHelper function_node_helper(this); | 2688 FunctionNodeHelper function_node_helper(this); |
2689 function_node_helper.ReadUntilExcluding( | 2689 function_node_helper.ReadUntilExcluding( |
2690 FunctionNodeHelper::kPositionalParameters); | 2690 FunctionNodeHelper::kPositionalParameters); |
2691 | 2691 |
2692 if (parsed_function()->function().HasOptionalNamedParameters()) { | 2692 if (parsed_function()->function().HasOptionalNamedParameters()) { |
2693 // List of positional. | 2693 // List of positional. |
2694 intptr_t list_length = ReadListLength(); // read list length. | 2694 intptr_t list_length = ReadListLength(); // read list length. |
2695 for (intptr_t i = 0; i < list_length; ++i) { | 2695 for (intptr_t i = 0; i < list_length; ++i) { |
2696 SkipVariableDeclaration(); // read ith variable declaration. | 2696 SkipVariableDeclaration(); // read ith variable declaration. |
2697 } | 2697 } |
2698 | 2698 |
2699 // List of named. | 2699 // List of named. |
2700 list_length = ReadListLength(); // read list length. | 2700 list_length = ReadListLength(); // read list length. |
2701 ASSERT(num_optional_parameters == list_length); | 2701 ASSERT(optional_parameter_count == list_length); |
2702 ASSERT(!parsed_function()->function().HasOptionalPositionalParameters()); | 2702 ASSERT(!parsed_function()->function().HasOptionalPositionalParameters()); |
2703 for (intptr_t i = 0; i < list_length; ++i) { | 2703 for (intptr_t i = 0; i < list_length; ++i) { |
2704 Instance* default_value; | 2704 Instance* default_value; |
2705 | 2705 |
2706 // Read ith variable declaration | 2706 // Read ith variable declaration |
2707 VariableDeclarationHelper helper(this); | 2707 VariableDeclarationHelper helper(this); |
2708 helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer); | 2708 helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer); |
2709 Tag tag = ReadTag(); // read (first part of) initializer. | 2709 Tag tag = ReadTag(); // read (first part of) initializer. |
2710 if (tag == kSomething) { | 2710 if (tag == kSomething) { |
2711 // this will (potentially) read the initializer, | 2711 // this will (potentially) read the initializer, |
2712 // but reset the position. | 2712 // but reset the position. |
2713 default_value = | 2713 default_value = |
2714 &constant_evaluator_.EvaluateExpression(ReaderOffset()); | 2714 &constant_evaluator_.EvaluateExpression(ReaderOffset()); |
2715 SkipExpression(); // read (actual) initializer. | 2715 SkipExpression(); // read (actual) initializer. |
2716 } else { | 2716 } else { |
2717 default_value = &Instance::ZoneHandle(Z, Instance::null()); | 2717 default_value = &Instance::ZoneHandle(Z, Instance::null()); |
2718 } | 2718 } |
2719 default_values->Add(default_value); | 2719 default_values->Add(default_value); |
2720 } | 2720 } |
2721 } else { | 2721 } else { |
2722 // List of positional. | 2722 // List of positional. |
2723 intptr_t list_length = ReadListLength(); // read list length. | 2723 intptr_t list_length = ReadListLength(); // read list length. |
2724 ASSERT(list_length == function_node_helper.required_parameter_count_ + | 2724 ASSERT(list_length == function_node_helper.required_parameter_count_ + |
2725 num_optional_parameters); | 2725 optional_parameter_count); |
2726 ASSERT(parsed_function()->function().HasOptionalPositionalParameters()); | 2726 ASSERT(parsed_function()->function().HasOptionalPositionalParameters()); |
2727 for (intptr_t i = 0; i < function_node_helper.required_parameter_count_; | 2727 for (intptr_t i = 0; i < function_node_helper.required_parameter_count_; |
2728 ++i) { | 2728 ++i) { |
2729 SkipVariableDeclaration(); // read ith variable declaration. | 2729 SkipVariableDeclaration(); // read ith variable declaration. |
2730 } | 2730 } |
2731 for (intptr_t i = 0; i < num_optional_parameters; ++i) { | 2731 for (intptr_t i = 0; i < optional_parameter_count; ++i) { |
2732 Instance* default_value; | 2732 Instance* default_value; |
2733 | 2733 |
2734 // Read ith variable declaration | 2734 // Read ith variable declaration |
2735 VariableDeclarationHelper helper(this); | 2735 VariableDeclarationHelper helper(this); |
2736 helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer); | 2736 helper.ReadUntilExcluding(VariableDeclarationHelper::kInitializer); |
2737 Tag tag = ReadTag(); // read (first part of) initializer. | 2737 Tag tag = ReadTag(); // read (first part of) initializer. |
2738 if (tag == kSomething) { | 2738 if (tag == kSomething) { |
2739 // this will (potentially) read the initializer, | 2739 // this will (potentially) read the initializer, |
2740 // but reset the position. | 2740 // but reset the position. |
2741 default_value = | 2741 default_value = |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2987 argument_names); | 2987 argument_names); |
2988 | 2988 |
2989 // Return the result. | 2989 // Return the result. |
2990 body += Return(function_node_helper.end_position_); | 2990 body += Return(function_node_helper.end_position_); |
2991 | 2991 |
2992 return new (Z) | 2992 return new (Z) |
2993 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, | 2993 FlowGraph(*parsed_function(), flow_graph_builder_->graph_entry_, |
2994 flow_graph_builder_->next_block_id_ - 1); | 2994 flow_graph_builder_->next_block_id_ - 1); |
2995 } | 2995 } |
2996 | 2996 |
2997 static bool IsGetMainClosure(const String& name) { | |
2998 if (name.Length() < 16) return false; | |
2999 const char* cstr = "_getMainClosure@"; | |
3000 for (intptr_t i = 0; i < 16; ++i) { | |
3001 if (name.CharAt(i) != cstr[i]) return false; | |
3002 } | |
3003 return true; | |
3004 } | |
3005 | |
3006 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction( | 2997 FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFunction( |
3007 bool is_in_builtin_library_toplevel, | |
3008 intptr_t constructor_class_parent_offset) { | 2998 intptr_t constructor_class_parent_offset) { |
3009 const Function& dart_function = parsed_function()->function(); | 2999 const Function& dart_function = parsed_function()->function(); |
3010 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); | 3000 TargetEntryInstr* normal_entry = flow_graph_builder_->BuildTargetEntry(); |
3011 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr( | 3001 flow_graph_builder_->graph_entry_ = new (Z) GraphEntryInstr( |
3012 *parsed_function(), normal_entry, flow_graph_builder_->osr_id_); | 3002 *parsed_function(), normal_entry, flow_graph_builder_->osr_id_); |
3013 | 3003 |
3014 SetupDefaultParameterValues(); | 3004 SetupDefaultParameterValues(); |
3015 | 3005 |
3016 Fragment body; | 3006 Fragment body; |
3017 if (!dart_function.is_native()) | 3007 if (!dart_function.is_native()) |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3159 body += StoreLocal(TokenPosition::kNoSource, async_stack_trace_var); | 3149 body += StoreLocal(TokenPosition::kNoSource, async_stack_trace_var); |
3160 body += Drop(); | 3150 body += Drop(); |
3161 } | 3151 } |
3162 | 3152 |
3163 bool has_body = ReadTag() == kSomething; // read first part of body. | 3153 bool has_body = ReadTag() == kSomething; // read first part of body. |
3164 | 3154 |
3165 if (dart_function.is_native()) { | 3155 if (dart_function.is_native()) { |
3166 body += flow_graph_builder_->NativeFunctionBody(first_parameter_offset, | 3156 body += flow_graph_builder_->NativeFunctionBody(first_parameter_offset, |
3167 dart_function); | 3157 dart_function); |
3168 } else if (has_body) { | 3158 } else if (has_body) { |
3169 if (is_in_builtin_library_toplevel && | 3159 body += BuildStatement(); // read body. |
3170 IsGetMainClosure(dart::String::Handle(Z, dart_function.name()))) { | |
3171 body += BuildGetMainClosure(); | |
3172 } else { | |
3173 body += BuildStatement(); // read body. | |
3174 } | |
3175 } | 3160 } |
3176 if (body.is_open()) { | 3161 if (body.is_open()) { |
3177 body += NullConstant(); | 3162 body += NullConstant(); |
3178 body += Return(dart_function.end_token_pos()); | 3163 body += Return(dart_function.end_token_pos()); |
3179 } | 3164 } |
3180 | 3165 |
3181 // If functions body contains any yield points build switch statement that | 3166 // If functions body contains any yield points build switch statement that |
3182 // selects a continuation point based on the value of :await_jump_var. | 3167 // selects a continuation point based on the value of :await_jump_var. |
3183 if (!yield_continuations().is_empty()) { | 3168 if (!yield_continuations().is_empty()) { |
3184 // The code we are building will be executed right after we enter | 3169 // The code we are building will be executed right after we enter |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3286 if (NeedsDebugStepCheck(dart_function, function_node_helper.position_)) { | 3271 if (NeedsDebugStepCheck(dart_function, function_node_helper.position_)) { |
3287 const intptr_t current_context_depth = flow_graph_builder_->context_depth_; | 3272 const intptr_t current_context_depth = flow_graph_builder_->context_depth_; |
3288 flow_graph_builder_->context_depth_ = 0; | 3273 flow_graph_builder_->context_depth_ = 0; |
3289 // If a switch was added above: Start the switch by injecting a debuggable | 3274 // If a switch was added above: Start the switch by injecting a debuggable |
3290 // safepoint so stepping over an await works. | 3275 // safepoint so stepping over an await works. |
3291 // If not, still start the body with a debuggable safepoint to ensure | 3276 // If not, still start the body with a debuggable safepoint to ensure |
3292 // breaking on a method always happens, even if there are no | 3277 // breaking on a method always happens, even if there are no |
3293 // assignments/calls/runtimecalls in the first basic block. | 3278 // assignments/calls/runtimecalls in the first basic block. |
3294 // Place this check at the last parameter to ensure parameters | 3279 // Place this check at the last parameter to ensure parameters |
3295 // are in scope in the debugger at method entry. | 3280 // are in scope in the debugger at method entry. |
3296 const int num_params = dart_function.NumParameters(); | 3281 const int parameter_count = dart_function.NumParameters(); |
3297 TokenPosition check_pos = TokenPosition::kNoSource; | 3282 TokenPosition check_pos = TokenPosition::kNoSource; |
3298 if (num_params > 0) { | 3283 if (parameter_count > 0) { |
3299 LocalScope* scope = parsed_function()->node_sequence()->scope(); | 3284 LocalScope* scope = parsed_function()->node_sequence()->scope(); |
3300 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); | 3285 const LocalVariable& parameter = *scope->VariableAt(parameter_count - 1); |
3301 check_pos = parameter.token_pos(); | 3286 check_pos = parameter.token_pos(); |
3302 } | 3287 } |
3303 if (!check_pos.IsDebugPause()) { | 3288 if (!check_pos.IsDebugPause()) { |
3304 // No parameters or synthetic parameters. | 3289 // No parameters or synthetic parameters. |
3305 check_pos = function_node_helper.position_; | 3290 check_pos = function_node_helper.position_; |
3306 ASSERT(check_pos.IsDebugPause()); | 3291 ASSERT(check_pos.IsDebugPause()); |
3307 } | 3292 } |
3308 | 3293 |
3309 // TODO(29737): This sequence should be generated in order. | 3294 // TODO(29737): This sequence should be generated in order. |
3310 body = DebugStepCheck(check_pos) + body; | 3295 body = DebugStepCheck(check_pos) + body; |
3311 flow_graph_builder_->context_depth_ = current_context_depth; | 3296 flow_graph_builder_->context_depth_ = current_context_depth; |
3312 } | 3297 } |
3313 | 3298 |
3314 normal_entry->LinkTo(body.entry); | 3299 normal_entry->LinkTo(body.entry); |
3315 | 3300 |
3316 GraphEntryInstr* graph_entry = flow_graph_builder_->graph_entry_; | 3301 GraphEntryInstr* graph_entry = flow_graph_builder_->graph_entry_; |
3317 // When compiling for OSR, use a depth first search to find the OSR | 3302 // When compiling for OSR, use a depth first search to find the OSR |
3318 // entry and make graph entry jump to it instead of normal entry. | 3303 // entry and make graph entry jump to it instead of normal entry. |
3319 // Catch entries are always considered reachable, even if they | 3304 // Catch entries are always considered reachable, even if they |
3320 // become unreachable after OSR. | 3305 // become unreachable after OSR. |
3321 if (flow_graph_builder_->osr_id_ != Compiler::kNoOSRDeoptId) { | 3306 if (flow_graph_builder_->osr_id_ != Compiler::kNoOSRDeoptId) { |
3322 graph_entry->RelinkToOsrEntry(Z, flow_graph_builder_->next_block_id_); | 3307 graph_entry->RelinkToOsrEntry(Z, flow_graph_builder_->next_block_id_); |
3323 } | 3308 } |
3324 return new (Z) FlowGraph(*parsed_function(), graph_entry, | 3309 return new (Z) FlowGraph(*parsed_function(), graph_entry, |
3325 flow_graph_builder_->next_block_id_ - 1); | 3310 flow_graph_builder_->next_block_id_ - 1); |
3326 } | 3311 } |
3327 | 3312 |
3328 Fragment StreamingFlowGraphBuilder::BuildGetMainClosure() { | |
3329 // _getMainClosure in dart:_builtin. Compile that one specially here. | |
3330 const dart::Library& builtin = | |
3331 dart::Library::Handle(Z, I->object_store()->builtin_library()); | |
3332 const Object& main = | |
3333 Object::Handle(Z, builtin.LookupObjectAllowPrivate(dart::String::Handle( | |
3334 Z, dart::String::New("main")))); | |
3335 if (main.IsField()) { | |
3336 UNIMPLEMENTED(); | |
3337 } else if (main.IsFunction()) { | |
3338 const Function& function = Function::Cast(main); | |
3339 if (function.kind() == RawFunction::kRegularFunction) { | |
3340 const Function& closure_function = | |
3341 Function::Handle(Z, function.ImplicitClosureFunction()); | |
3342 const Instance& closure = | |
3343 Instance::ZoneHandle(Z, closure_function.ImplicitStaticClosure()); | |
3344 Fragment instructions = Constant(closure); | |
3345 instructions += Return(TokenPosition::kNoSource); | |
3346 return instructions; | |
3347 } else { | |
3348 UNIMPLEMENTED(); | |
3349 } | |
3350 } else { | |
3351 UNIMPLEMENTED(); | |
3352 } | |
3353 return Fragment(); | |
3354 } | |
3355 | |
3356 FlowGraph* StreamingFlowGraphBuilder::BuildGraph(intptr_t kernel_offset) { | 3313 FlowGraph* StreamingFlowGraphBuilder::BuildGraph(intptr_t kernel_offset) { |
3357 const Function& function = parsed_function()->function(); | 3314 const Function& function = parsed_function()->function(); |
3358 | 3315 |
3359 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used | 3316 // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be used |
3360 // e.g. for type translation. | 3317 // e.g. for type translation. |
3361 const dart::Class& klass = | 3318 const dart::Class& klass = |
3362 dart::Class::Handle(zone_, parsed_function()->function().Owner()); | 3319 dart::Class::Handle(zone_, parsed_function()->function().Owner()); |
3363 bool is_in_builtin_library_toplevel = | |
3364 klass.library() == I->object_store()->builtin_library() && | |
3365 klass.IsTopLevel(); | |
3366 | 3320 |
3367 Function& outermost_function = Function::Handle(Z); | 3321 Function& outermost_function = Function::Handle(Z); |
3368 intptr_t outermost_kernel_offset = -1; | 3322 intptr_t outermost_kernel_offset = -1; |
3369 intptr_t parent_class_offset = -1; | 3323 intptr_t parent_class_offset = -1; |
3370 DiscoverEnclosingElements(Z, function, &outermost_function, | 3324 DiscoverEnclosingElements(Z, function, &outermost_function, |
3371 &outermost_kernel_offset, &parent_class_offset); | 3325 &outermost_kernel_offset, &parent_class_offset); |
3372 // Use [klass]/[kernel_class] as active class. Type parameters will get | 3326 // Use [klass]/[kernel_class] as active class. Type parameters will get |
3373 // resolved via [kernel_class] unless we are nested inside a static factory | 3327 // resolved via [kernel_class] unless we are nested inside a static factory |
3374 // in which case we will use [member]. | 3328 // in which case we will use [member]. |
3375 intptr_t class_type_parameters = 0; | 3329 intptr_t class_type_parameters = 0; |
(...skipping 29 matching lines...) Expand all Loading... |
3405 SetOffset(kernel_offset); | 3359 SetOffset(kernel_offset); |
3406 | 3360 |
3407 switch (function.kind()) { | 3361 switch (function.kind()) { |
3408 case RawFunction::kClosureFunction: | 3362 case RawFunction::kClosureFunction: |
3409 case RawFunction::kRegularFunction: | 3363 case RawFunction::kRegularFunction: |
3410 case RawFunction::kGetterFunction: | 3364 case RawFunction::kGetterFunction: |
3411 case RawFunction::kSetterFunction: { | 3365 case RawFunction::kSetterFunction: { |
3412 ReadUntilFunctionNode(); // read until function node. | 3366 ReadUntilFunctionNode(); // read until function node. |
3413 return function.IsImplicitClosureFunction() | 3367 return function.IsImplicitClosureFunction() |
3414 ? BuildGraphOfImplicitClosureFunction(function) | 3368 ? BuildGraphOfImplicitClosureFunction(function) |
3415 : BuildGraphOfFunction(is_in_builtin_library_toplevel); | 3369 : BuildGraphOfFunction(); |
3416 } | 3370 } |
3417 case RawFunction::kConstructor: { | 3371 case RawFunction::kConstructor: { |
3418 bool is_factory = function.IsFactory(); | 3372 bool is_factory = function.IsFactory(); |
3419 if (is_factory) { | 3373 if (is_factory) { |
3420 ReadUntilFunctionNode(); // read until function node. | 3374 ReadUntilFunctionNode(); // read until function node. |
3421 return BuildGraphOfFunction(is_in_builtin_library_toplevel); | 3375 return BuildGraphOfFunction(); |
3422 } else { | 3376 } else { |
3423 // Constructor: Pass offset to parent class. | 3377 // Constructor: Pass offset to parent class. |
3424 return BuildGraphOfFunction( | 3378 return BuildGraphOfFunction( |
3425 is_in_builtin_library_toplevel, | |
3426 ReadUntilFunctionNode()); // read until function node. | 3379 ReadUntilFunctionNode()); // read until function node. |
3427 } | 3380 } |
3428 } | 3381 } |
3429 case RawFunction::kImplicitGetter: | 3382 case RawFunction::kImplicitGetter: |
3430 case RawFunction::kImplicitStaticFinalGetter: | 3383 case RawFunction::kImplicitStaticFinalGetter: |
3431 case RawFunction::kImplicitSetter: { | 3384 case RawFunction::kImplicitSetter: { |
3432 return IsStaticInitializer(function, Z) | 3385 return IsStaticInitializer(function, Z) |
3433 ? BuildGraphOfStaticFieldInitializer() | 3386 ? BuildGraphOfStaticFieldInitializer() |
3434 : BuildGraphOfFieldAccessor(scopes()->setter_value); | 3387 : BuildGraphOfFieldAccessor(scopes()->setter_value); |
3435 } | 3388 } |
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4039 } | 3992 } |
4040 case kForInStatement: | 3993 case kForInStatement: |
4041 case kAsyncForInStatement: | 3994 case kAsyncForInStatement: |
4042 ReadPosition(); // read position. | 3995 ReadPosition(); // read position. |
4043 SkipVariableDeclaration(); // read variable. | 3996 SkipVariableDeclaration(); // read variable. |
4044 SkipExpression(); // read iterable. | 3997 SkipExpression(); // read iterable. |
4045 SkipStatement(); // read body. | 3998 SkipStatement(); // read body. |
4046 return; | 3999 return; |
4047 case kSwitchStatement: { | 4000 case kSwitchStatement: { |
4048 SkipExpression(); // read condition. | 4001 SkipExpression(); // read condition. |
4049 int num_cases = ReadListLength(); // read number of cases. | 4002 int case_count = ReadListLength(); // read number of cases. |
4050 for (intptr_t i = 0; i < num_cases; ++i) { | 4003 for (intptr_t i = 0; i < case_count; ++i) { |
4051 int num_expressions = ReadListLength(); // read number of expressions. | 4004 int expression_count = ReadListLength(); // read number of expressions. |
4052 for (intptr_t j = 0; j < num_expressions; ++j) { | 4005 for (intptr_t j = 0; j < expression_count; ++j) { |
4053 ReadPosition(); // read jth position. | 4006 ReadPosition(); // read jth position. |
4054 SkipExpression(); // read jth expression. | 4007 SkipExpression(); // read jth expression. |
4055 } | 4008 } |
4056 ReadBool(); // read is_default. | 4009 ReadBool(); // read is_default. |
4057 SkipStatement(); // read body. | 4010 SkipStatement(); // read body. |
4058 } | 4011 } |
4059 return; | 4012 return; |
4060 } | 4013 } |
4061 case kContinueSwitchStatement: | 4014 case kContinueSwitchStatement: |
4062 ReadUInt(); // read target_index. | 4015 ReadUInt(); // read target_index. |
4063 return; | 4016 return; |
4064 case kIfStatement: | 4017 case kIfStatement: |
4065 SkipExpression(); // read condition. | 4018 SkipExpression(); // read condition. |
4066 SkipStatement(); // read then. | 4019 SkipStatement(); // read then. |
4067 SkipStatement(); // read otherwise. | 4020 SkipStatement(); // read otherwise. |
4068 return; | 4021 return; |
4069 case kReturnStatement: { | 4022 case kReturnStatement: { |
4070 ReadPosition(); // read position | 4023 ReadPosition(); // read position |
4071 Tag tag = ReadTag(); // read (first part of) expression. | 4024 Tag tag = ReadTag(); // read (first part of) expression. |
4072 if (tag == kSomething) { | 4025 if (tag == kSomething) { |
4073 SkipExpression(); // read (rest of) expression. | 4026 SkipExpression(); // read (rest of) expression. |
4074 } | 4027 } |
4075 return; | 4028 return; |
4076 } | 4029 } |
4077 case kTryCatch: { | 4030 case kTryCatch: { |
4078 SkipStatement(); // read body. | 4031 SkipStatement(); // read body. |
4079 ReadBool(); // read any_catch_needs_stack_trace. | 4032 ReadBool(); // read any_catch_needs_stack_trace. |
4080 intptr_t num_catches = ReadListLength(); // read number of catches. | 4033 intptr_t catch_count = ReadListLength(); // read number of catches. |
4081 for (intptr_t i = 0; i < num_catches; ++i) { | 4034 for (intptr_t i = 0; i < catch_count; ++i) { |
4082 SkipDartType(); // read guard. | 4035 SkipDartType(); // read guard. |
4083 tag = ReadTag(); // read first part of exception. | 4036 tag = ReadTag(); // read first part of exception. |
4084 if (tag == kSomething) { | 4037 if (tag == kSomething) { |
4085 SkipVariableDeclaration(); // read exception. | 4038 SkipVariableDeclaration(); // read exception. |
4086 } | 4039 } |
4087 tag = ReadTag(); // read first part of stack trace. | 4040 tag = ReadTag(); // read first part of stack trace. |
4088 if (tag == kSomething) { | 4041 if (tag == kSomething) { |
4089 SkipVariableDeclaration(); // read stack trace. | 4042 SkipVariableDeclaration(); // read stack trace. |
4090 } | 4043 } |
4091 SkipStatement(); // read body. | 4044 SkipStatement(); // read body. |
4092 } | 4045 } |
4093 return; | 4046 return; |
4094 } | 4047 } |
4095 case kTryFinally: | 4048 case kTryFinally: |
4096 SkipStatement(); // read body. | 4049 SkipStatement(); // read body. |
4097 SkipStatement(); // read finalizer. | 4050 SkipStatement(); // read finalizer. |
4098 return; | 4051 return; |
4099 case kYieldStatement: | 4052 case kYieldStatement: { |
4100 ReadPosition(); // read position. | 4053 TokenPosition position = ReadPosition(); // read position. |
| 4054 record_yield_position(position); |
4101 ReadByte(); // read flags. | 4055 ReadByte(); // read flags. |
4102 SkipExpression(); // read expression. | 4056 SkipExpression(); // read expression. |
4103 return; | 4057 return; |
| 4058 } |
4104 case kVariableDeclaration: | 4059 case kVariableDeclaration: |
4105 SkipVariableDeclaration(); // read variable declaration. | 4060 SkipVariableDeclaration(); // read variable declaration. |
4106 return; | 4061 return; |
4107 case kFunctionDeclaration: | 4062 case kFunctionDeclaration: |
4108 ReadPosition(); // read position. | 4063 ReadPosition(); // read position. |
4109 SkipVariableDeclaration(); // read variable. | 4064 SkipVariableDeclaration(); // read variable. |
4110 SkipFunctionNode(); // read function node. | 4065 SkipFunctionNode(); // read function node. |
4111 return; | 4066 return; |
4112 default: | 4067 default: |
4113 UNREACHABLE(); | 4068 UNREACHABLE(); |
(...skipping 24 matching lines...) Expand all Loading... |
4138 SkipStringReference(); // read ith name index. | 4093 SkipStringReference(); // read ith name index. |
4139 SkipExpression(); // read ith expression. | 4094 SkipExpression(); // read ith expression. |
4140 } | 4095 } |
4141 } | 4096 } |
4142 | 4097 |
4143 void StreamingFlowGraphBuilder::SkipVariableDeclaration() { | 4098 void StreamingFlowGraphBuilder::SkipVariableDeclaration() { |
4144 VariableDeclarationHelper helper(this); | 4099 VariableDeclarationHelper helper(this); |
4145 helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd); | 4100 helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd); |
4146 } | 4101 } |
4147 | 4102 |
| 4103 void StreamingFlowGraphBuilder::SkipLibraryCombinator() { |
| 4104 ReadBool(); // read is_show. |
| 4105 intptr_t name_count = ReadUInt(); // read list length. |
| 4106 for (intptr_t j = 0; j < name_count; ++j) { |
| 4107 ReadUInt(); // read ith entry of name_indices. |
| 4108 } |
| 4109 } |
| 4110 |
| 4111 void StreamingFlowGraphBuilder::SkipLibraryDependency() { |
| 4112 ReadFlags(); // read flags. |
| 4113 SkipListOfExpressions(); // Read annotations. |
| 4114 ReadCanonicalNameReference(); // read target_reference. |
| 4115 ReadStringReference(); // read name_index. |
| 4116 intptr_t combinator_count = ReadListLength(); // read list length. |
| 4117 for (intptr_t i = 0; i < combinator_count; ++i) { |
| 4118 SkipLibraryCombinator(); |
| 4119 } |
| 4120 } |
| 4121 |
| 4122 void StreamingFlowGraphBuilder::SkipLibraryTypedef() { |
| 4123 SkipCanonicalNameReference(); // read canonical name. |
| 4124 ReadPosition(); // read position. |
| 4125 SkipStringReference(); // read name index. |
| 4126 ReadUInt(); // read source_uri_index. |
| 4127 SkipListOfDartTypes(); // read type parameters. |
| 4128 SkipDartType(); // read type. |
| 4129 } |
| 4130 |
4148 TokenPosition StreamingFlowGraphBuilder::ReadPosition(bool record) { | 4131 TokenPosition StreamingFlowGraphBuilder::ReadPosition(bool record) { |
4149 return reader_->ReadPosition(record); | 4132 TokenPosition position = reader_->ReadPosition(); |
| 4133 if (record) { |
| 4134 record_token_position(position); |
| 4135 } |
| 4136 return position; |
| 4137 } |
| 4138 |
| 4139 void StreamingFlowGraphBuilder::record_token_position(TokenPosition position) { |
| 4140 if (record_for_script_id_ == current_script_id_ && |
| 4141 record_token_positions_into_ != NULL) { |
| 4142 record_token_positions_into_->Add(position.value()); |
| 4143 } |
| 4144 } |
| 4145 |
| 4146 void StreamingFlowGraphBuilder::record_yield_position(TokenPosition position) { |
| 4147 if (record_for_script_id_ == current_script_id_ && |
| 4148 record_yield_positions_into_ != NULL) { |
| 4149 record_yield_positions_into_->Add(position.value()); |
| 4150 } |
4150 } | 4151 } |
4151 | 4152 |
4152 Tag StreamingFlowGraphBuilder::ReadTag(uint8_t* payload) { | 4153 Tag StreamingFlowGraphBuilder::ReadTag(uint8_t* payload) { |
4153 return reader_->ReadTag(payload); | 4154 return reader_->ReadTag(payload); |
4154 } | 4155 } |
4155 | 4156 |
4156 Tag StreamingFlowGraphBuilder::PeekTag(uint8_t* payload) { | 4157 Tag StreamingFlowGraphBuilder::PeekTag(uint8_t* payload) { |
4157 return reader_->PeekTag(payload); | 4158 return reader_->PeekTag(payload); |
4158 } | 4159 } |
4159 | 4160 |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4380 } | 4381 } |
4381 | 4382 |
4382 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position, | 4383 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position, |
4383 const Function& target, | 4384 const Function& target, |
4384 intptr_t argument_count, | 4385 intptr_t argument_count, |
4385 const Array& argument_names) { | 4386 const Array& argument_names) { |
4386 return flow_graph_builder_->StaticCall(position, target, argument_count, | 4387 return flow_graph_builder_->StaticCall(position, target, argument_count, |
4387 argument_names); | 4388 argument_names); |
4388 } | 4389 } |
4389 | 4390 |
4390 Fragment StreamingFlowGraphBuilder::InstanceCall(TokenPosition position, | 4391 Fragment StreamingFlowGraphBuilder::InstanceCall( |
4391 const dart::String& name, | 4392 TokenPosition position, |
4392 Token::Kind kind, | 4393 const dart::String& name, |
4393 intptr_t argument_count, | 4394 Token::Kind kind, |
4394 intptr_t num_args_checked) { | 4395 intptr_t argument_count, |
| 4396 intptr_t checked_argument_count) { |
4395 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count, | 4397 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count, |
4396 num_args_checked); | 4398 checked_argument_count); |
4397 } | 4399 } |
4398 | 4400 |
4399 Fragment StreamingFlowGraphBuilder::ThrowException(TokenPosition position) { | 4401 Fragment StreamingFlowGraphBuilder::ThrowException(TokenPosition position) { |
4400 return flow_graph_builder_->ThrowException(position); | 4402 return flow_graph_builder_->ThrowException(position); |
4401 } | 4403 } |
4402 | 4404 |
4403 Fragment StreamingFlowGraphBuilder::BooleanNegate() { | 4405 Fragment StreamingFlowGraphBuilder::BooleanNegate() { |
4404 return flow_graph_builder_->BooleanNegate(); | 4406 return flow_graph_builder_->BooleanNegate(); |
4405 } | 4407 } |
4406 | 4408 |
4407 Fragment StreamingFlowGraphBuilder::TranslateInstantiatedTypeArguments( | 4409 Fragment StreamingFlowGraphBuilder::TranslateInstantiatedTypeArguments( |
4408 const TypeArguments& type_arguments) { | 4410 const TypeArguments& type_arguments) { |
4409 return flow_graph_builder_->TranslateInstantiatedTypeArguments( | 4411 return flow_graph_builder_->TranslateInstantiatedTypeArguments( |
4410 type_arguments); | 4412 type_arguments); |
4411 } | 4413 } |
4412 | 4414 |
4413 Fragment StreamingFlowGraphBuilder::StrictCompare(Token::Kind kind, | 4415 Fragment StreamingFlowGraphBuilder::StrictCompare(Token::Kind kind, |
4414 bool number_check) { | 4416 bool number_check) { |
4415 return flow_graph_builder_->StrictCompare(kind, number_check); | 4417 return flow_graph_builder_->StrictCompare(kind, number_check); |
4416 } | 4418 } |
4417 | 4419 |
4418 Fragment StreamingFlowGraphBuilder::AllocateObject(TokenPosition position, | 4420 Fragment StreamingFlowGraphBuilder::AllocateObject(TokenPosition position, |
4419 const dart::Class& klass, | 4421 const dart::Class& klass, |
4420 intptr_t argument_count) { | 4422 intptr_t argument_count) { |
4421 return flow_graph_builder_->AllocateObject(position, klass, argument_count); | 4423 return flow_graph_builder_->AllocateObject(position, klass, argument_count); |
4422 } | 4424 } |
4423 | 4425 |
4424 Fragment StreamingFlowGraphBuilder::InstanceCall(TokenPosition position, | 4426 Fragment StreamingFlowGraphBuilder::InstanceCall( |
4425 const dart::String& name, | 4427 TokenPosition position, |
4426 Token::Kind kind, | 4428 const dart::String& name, |
4427 intptr_t argument_count, | 4429 Token::Kind kind, |
4428 const Array& argument_names, | 4430 intptr_t argument_count, |
4429 intptr_t num_args_checked) { | 4431 const Array& argument_names, |
| 4432 intptr_t checked_argument_count) { |
4430 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count, | 4433 return flow_graph_builder_->InstanceCall(position, name, kind, argument_count, |
4431 argument_names, num_args_checked); | 4434 argument_names, |
| 4435 checked_argument_count); |
4432 } | 4436 } |
4433 | 4437 |
4434 Fragment StreamingFlowGraphBuilder::StoreLocal(TokenPosition position, | 4438 Fragment StreamingFlowGraphBuilder::StoreLocal(TokenPosition position, |
4435 LocalVariable* variable) { | 4439 LocalVariable* variable) { |
4436 return flow_graph_builder_->StoreLocal(position, variable); | 4440 return flow_graph_builder_->StoreLocal(position, variable); |
4437 } | 4441 } |
4438 | 4442 |
4439 Fragment StreamingFlowGraphBuilder::StoreStaticField(TokenPosition position, | 4443 Fragment StreamingFlowGraphBuilder::StoreStaticField(TokenPosition position, |
4440 const dart::Field& field) { | 4444 const dart::Field& field) { |
4441 return flow_graph_builder_->StoreStaticField(position, field); | 4445 return flow_graph_builder_->StoreStaticField(position, field); |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4951 | 4955 |
4952 instructions += PushArgument(); // push receiver as argument. | 4956 instructions += PushArgument(); // push receiver as argument. |
4953 | 4957 |
4954 // TODO(28109) Support generic methods in the VM or reify them away. | 4958 // TODO(28109) Support generic methods in the VM or reify them away. |
4955 Array& argument_names = Array::ZoneHandle(Z); | 4959 Array& argument_names = Array::ZoneHandle(Z); |
4956 intptr_t argument_count; | 4960 intptr_t argument_count; |
4957 instructions += | 4961 instructions += |
4958 BuildArguments(&argument_names, &argument_count); // read arguments. | 4962 BuildArguments(&argument_names, &argument_count); // read arguments. |
4959 ++argument_count; | 4963 ++argument_count; |
4960 | 4964 |
4961 intptr_t num_args_checked = 1; | 4965 intptr_t checked_argument_count = 1; |
4962 // If we have a special operation (e.g. +/-/==) we mark both arguments as | 4966 // If we have a special operation (e.g. +/-/==) we mark both arguments as |
4963 // to be checked. | 4967 // to be checked. |
4964 if (token_kind != Token::kILLEGAL) { | 4968 if (token_kind != Token::kILLEGAL) { |
4965 ASSERT(argument_count <= 2); | 4969 ASSERT(argument_count <= 2); |
4966 num_args_checked = argument_count; | 4970 checked_argument_count = argument_count; |
4967 } | 4971 } |
4968 | 4972 |
4969 instructions += InstanceCall(position, name, token_kind, argument_count, | 4973 instructions += InstanceCall(position, name, token_kind, argument_count, |
4970 argument_names, num_args_checked); | 4974 argument_names, checked_argument_count); |
4971 // Later optimization passes assume that result of a x.[]=(...) call is not | 4975 // Later optimization passes assume that result of a x.[]=(...) call is not |
4972 // used. We must guarantee this invariant because violation will lead to an | 4976 // used. We must guarantee this invariant because violation will lead to an |
4973 // illegal IL once we replace x.[]=(...) with a sequence that does not | 4977 // illegal IL once we replace x.[]=(...) with a sequence that does not |
4974 // actually produce any value. See http://dartbug.com/29135 for more details. | 4978 // actually produce any value. See http://dartbug.com/29135 for more details. |
4975 if (name.raw() == Symbols::AssignIndexToken().raw()) { | 4979 if (name.raw() == Symbols::AssignIndexToken().raw()) { |
4976 instructions += Drop(); | 4980 instructions += Drop(); |
4977 instructions += NullConstant(); | 4981 instructions += NullConstant(); |
4978 } | 4982 } |
4979 | 4983 |
4980 SkipCanonicalNameReference(); // read unused "interface_target_reference". | 4984 SkipCanonicalNameReference(); // read unused "interface_target_reference". |
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6006 | 6010 |
6007 loop_depth_dec(); | 6011 loop_depth_dec(); |
6008 for_in_depth_dec(); | 6012 for_in_depth_dec(); |
6009 return Fragment(instructions.entry, loop_exit); | 6013 return Fragment(instructions.entry, loop_exit); |
6010 } | 6014 } |
6011 | 6015 |
6012 Fragment StreamingFlowGraphBuilder::BuildSwitchStatement() { | 6016 Fragment StreamingFlowGraphBuilder::BuildSwitchStatement() { |
6013 // We need the number of cases. So start by getting that, then go back. | 6017 // We need the number of cases. So start by getting that, then go back. |
6014 intptr_t offset = ReaderOffset(); | 6018 intptr_t offset = ReaderOffset(); |
6015 SkipExpression(); // temporarily skip condition | 6019 SkipExpression(); // temporarily skip condition |
6016 int num_cases = ReadListLength(); // read number of cases. | 6020 int case_count = ReadListLength(); // read number of cases. |
6017 SetOffset(offset); | 6021 SetOffset(offset); |
6018 | 6022 |
6019 SwitchBlock block(flow_graph_builder_, num_cases); | 6023 SwitchBlock block(flow_graph_builder_, case_count); |
6020 | 6024 |
6021 // Instead of using a variable we should reuse the expression on the stack, | 6025 // Instead of using a variable we should reuse the expression on the stack, |
6022 // since it won't be assigned again, we don't need phi nodes. | 6026 // since it won't be assigned again, we don't need phi nodes. |
6023 Fragment head_instructions = BuildExpression(); // read condition. | 6027 Fragment head_instructions = BuildExpression(); // read condition. |
6024 head_instructions += | 6028 head_instructions += |
6025 StoreLocal(TokenPosition::kNoSource, scopes()->switch_variable); | 6029 StoreLocal(TokenPosition::kNoSource, scopes()->switch_variable); |
6026 head_instructions += Drop(); | 6030 head_instructions += Drop(); |
6027 | 6031 |
6028 num_cases = ReadListLength(); // read number of cases. | 6032 case_count = ReadListLength(); // read number of cases. |
6029 | 6033 |
6030 // Phase 1: Generate bodies and try to find out whether a body will be target | 6034 // Phase 1: Generate bodies and try to find out whether a body will be target |
6031 // of a jump due to: | 6035 // of a jump due to: |
6032 // * `continue case_label` | 6036 // * `continue case_label` |
6033 // * `case e1: case e2: body` | 6037 // * `case e1: case e2: body` |
6034 Fragment* body_fragments = new Fragment[num_cases]; | 6038 Fragment* body_fragments = new Fragment[case_count]; |
6035 intptr_t* case_expression_offsets = new intptr_t[num_cases]; | 6039 intptr_t* case_expression_offsets = new intptr_t[case_count]; |
6036 int default_case = -1; | 6040 int default_case = -1; |
6037 | 6041 |
6038 for (intptr_t i = 0; i < num_cases; ++i) { | 6042 for (intptr_t i = 0; i < case_count; ++i) { |
6039 case_expression_offsets[i] = ReaderOffset(); | 6043 case_expression_offsets[i] = ReaderOffset(); |
6040 int num_expressions = ReadListLength(); // read number of expressions. | 6044 int expression_count = ReadListLength(); // read number of expressions. |
6041 for (intptr_t j = 0; j < num_expressions; ++j) { | 6045 for (intptr_t j = 0; j < expression_count; ++j) { |
6042 ReadPosition(); // read jth position. | 6046 ReadPosition(); // read jth position. |
6043 SkipExpression(); // read jth expression. | 6047 SkipExpression(); // read jth expression. |
6044 } | 6048 } |
6045 bool is_default = ReadBool(); // read is_default. | 6049 bool is_default = ReadBool(); // read is_default. |
6046 if (is_default) default_case = i; | 6050 if (is_default) default_case = i; |
6047 Fragment& body_fragment = body_fragments[i] = | 6051 Fragment& body_fragment = body_fragments[i] = |
6048 BuildStatement(); // read body. | 6052 BuildStatement(); // read body. |
6049 | 6053 |
6050 if (body_fragment.entry == NULL) { | 6054 if (body_fragment.entry == NULL) { |
6051 // Make a NOP in order to ensure linking works properly. | 6055 // Make a NOP in order to ensure linking works properly. |
6052 body_fragment = NullConstant(); | 6056 body_fragment = NullConstant(); |
6053 body_fragment += Drop(); | 6057 body_fragment += Drop(); |
6054 } | 6058 } |
6055 | 6059 |
6056 // The Dart language specification mandates fall-throughs in [SwitchCase]es | 6060 // The Dart language specification mandates fall-throughs in [SwitchCase]es |
6057 // to be runtime errors. | 6061 // to be runtime errors. |
6058 if (!is_default && body_fragment.is_open() && (i < (num_cases - 1))) { | 6062 if (!is_default && body_fragment.is_open() && (i < (case_count - 1))) { |
6059 const dart::Class& klass = dart::Class::ZoneHandle( | 6063 const dart::Class& klass = dart::Class::ZoneHandle( |
6060 Z, dart::Library::LookupCoreClass(Symbols::FallThroughError())); | 6064 Z, dart::Library::LookupCoreClass(Symbols::FallThroughError())); |
6061 ASSERT(!klass.IsNull()); | 6065 ASSERT(!klass.IsNull()); |
6062 const dart::Function& constructor = dart::Function::ZoneHandle( | 6066 const dart::Function& constructor = dart::Function::ZoneHandle( |
6063 Z, klass.LookupConstructorAllowPrivate( | 6067 Z, klass.LookupConstructorAllowPrivate( |
6064 H.DartSymbol("FallThroughError._create"))); | 6068 H.DartSymbol("FallThroughError._create"))); |
6065 ASSERT(!constructor.IsNull()); | 6069 ASSERT(!constructor.IsNull()); |
6066 const dart::String& url = H.DartString( | 6070 const dart::String& url = H.DartString( |
6067 parsed_function()->function().ToLibNamePrefixedQualifiedCString(), | 6071 parsed_function()->function().ToLibNamePrefixedQualifiedCString(), |
6068 Heap::kOld); | 6072 Heap::kOld); |
(...skipping 26 matching lines...) Expand all Loading... |
6095 // | 6099 // |
6096 // switch(expr) { | 6100 // switch(expr) { |
6097 // case a: | 6101 // case a: |
6098 // case b: | 6102 // case b: |
6099 // <stmt-body> | 6103 // <stmt-body> |
6100 // } | 6104 // } |
6101 // | 6105 // |
6102 // This means that the <stmt-body> will have more than 1 incoming edge (one | 6106 // This means that the <stmt-body> will have more than 1 incoming edge (one |
6103 // from `a == expr` and one from `a != expr && b == expr`). The | 6107 // from `a == expr` and one from `a != expr && b == expr`). The |
6104 // `block.Destination()` records the additional jump. | 6108 // `block.Destination()` records the additional jump. |
6105 if (num_expressions > 1) { | 6109 if (expression_count > 1) { |
6106 block.DestinationDirect(i); | 6110 block.DestinationDirect(i); |
6107 } | 6111 } |
6108 } | 6112 } |
6109 | 6113 |
6110 intptr_t end_offset = ReaderOffset(); | 6114 intptr_t end_offset = ReaderOffset(); |
6111 | 6115 |
6112 // Phase 2: Generate everything except the real bodies: | 6116 // Phase 2: Generate everything except the real bodies: |
6113 // * jump directly to a body (if there is no jumper) | 6117 // * jump directly to a body (if there is no jumper) |
6114 // * jump to a wrapper block which jumps to the body (if there is a jumper) | 6118 // * jump to a wrapper block which jumps to the body (if there is a jumper) |
6115 Fragment current_instructions = head_instructions; | 6119 Fragment current_instructions = head_instructions; |
6116 for (intptr_t i = 0; i < num_cases; ++i) { | 6120 for (intptr_t i = 0; i < case_count; ++i) { |
6117 SetOffset(case_expression_offsets[i]); | 6121 SetOffset(case_expression_offsets[i]); |
6118 int num_expressions = ReadListLength(); // read length of expressions. | 6122 int expression_count = ReadListLength(); // read length of expressions. |
6119 | 6123 |
6120 if (i == default_case) { | 6124 if (i == default_case) { |
6121 ASSERT(i == (num_cases - 1)); | 6125 ASSERT(i == (case_count - 1)); |
6122 | 6126 |
6123 // Evaluate the conditions for the default [SwitchCase] just for the | 6127 // Evaluate the conditions for the default [SwitchCase] just for the |
6124 // purpose of potentially triggering a compile-time error. | 6128 // purpose of potentially triggering a compile-time error. |
6125 | 6129 |
6126 for (intptr_t j = 0; j < num_expressions; ++j) { | 6130 for (intptr_t j = 0; j < expression_count; ++j) { |
6127 ReadPosition(); // read jth position. | 6131 ReadPosition(); // read jth position. |
6128 // this reads the expression, but doesn't skip past it. | 6132 // this reads the expression, but doesn't skip past it. |
6129 constant_evaluator_.EvaluateExpression(ReaderOffset()); | 6133 constant_evaluator_.EvaluateExpression(ReaderOffset()); |
6130 SkipExpression(); // read jth expression. | 6134 SkipExpression(); // read jth expression. |
6131 } | 6135 } |
6132 | 6136 |
6133 if (block.HadJumper(i)) { | 6137 if (block.HadJumper(i)) { |
6134 // There are several branches to the body, so we will make a goto to | 6138 // There are several branches to the body, so we will make a goto to |
6135 // the join block (and prepend a join instruction to the real body). | 6139 // the join block (and prepend a join instruction to the real body). |
6136 JoinEntryInstr* join = block.DestinationDirect(i); | 6140 JoinEntryInstr* join = block.DestinationDirect(i); |
6137 current_instructions += Goto(join); | 6141 current_instructions += Goto(join); |
6138 | 6142 |
6139 current_instructions = Fragment(current_instructions.entry, join); | 6143 current_instructions = Fragment(current_instructions.entry, join); |
6140 current_instructions += body_fragments[i]; | 6144 current_instructions += body_fragments[i]; |
6141 } else { | 6145 } else { |
6142 current_instructions += body_fragments[i]; | 6146 current_instructions += body_fragments[i]; |
6143 } | 6147 } |
6144 } else { | 6148 } else { |
6145 JoinEntryInstr* body_join = NULL; | 6149 JoinEntryInstr* body_join = NULL; |
6146 if (block.HadJumper(i)) { | 6150 if (block.HadJumper(i)) { |
6147 body_join = block.DestinationDirect(i); | 6151 body_join = block.DestinationDirect(i); |
6148 body_fragments[i] = Fragment(body_join) + body_fragments[i]; | 6152 body_fragments[i] = Fragment(body_join) + body_fragments[i]; |
6149 } | 6153 } |
6150 | 6154 |
6151 for (intptr_t j = 0; j < num_expressions; ++j) { | 6155 for (intptr_t j = 0; j < expression_count; ++j) { |
6152 TargetEntryInstr* then; | 6156 TargetEntryInstr* then; |
6153 TargetEntryInstr* otherwise; | 6157 TargetEntryInstr* otherwise; |
6154 | 6158 |
6155 TokenPosition position = ReadPosition(); // read jth position. | 6159 TokenPosition position = ReadPosition(); // read jth position. |
6156 current_instructions += | 6160 current_instructions += |
6157 Constant(constant_evaluator_.EvaluateExpression(ReaderOffset())); | 6161 Constant(constant_evaluator_.EvaluateExpression(ReaderOffset())); |
6158 SkipExpression(); // read jth expression. | 6162 SkipExpression(); // read jth expression. |
6159 current_instructions += PushArgument(); | 6163 current_instructions += PushArgument(); |
6160 current_instructions += LoadLocal(scopes()->switch_variable); | 6164 current_instructions += LoadLocal(scopes()->switch_variable); |
6161 current_instructions += PushArgument(); | 6165 current_instructions += PushArgument(); |
6162 current_instructions += | 6166 current_instructions += |
6163 InstanceCall(position, Symbols::EqualOperator(), Token::kEQ, | 6167 InstanceCall(position, Symbols::EqualOperator(), Token::kEQ, |
6164 /*argument_count=*/2, | 6168 /*argument_count=*/2, |
6165 /*num_args_checked=*/2); | 6169 /*checked_argument_count=*/2); |
6166 current_instructions += BranchIfTrue(&then, &otherwise, false); | 6170 current_instructions += BranchIfTrue(&then, &otherwise, false); |
6167 | 6171 |
6168 Fragment then_fragment(then); | 6172 Fragment then_fragment(then); |
6169 | 6173 |
6170 if (body_join != NULL) { | 6174 if (body_join != NULL) { |
6171 // There are several branches to the body, so we will make a goto to | 6175 // There are several branches to the body, so we will make a goto to |
6172 // the join block (the real body has already been prepended with a | 6176 // the join block (the real body has already been prepended with a |
6173 // join instruction). | 6177 // join instruction). |
6174 then_fragment += Goto(body_join); | 6178 then_fragment += Goto(body_join); |
6175 } else { | 6179 } else { |
6176 // There is only a signle branch to the body, so we will just append | 6180 // There is only a signle branch to the body, so we will just append |
6177 // the body fragment. | 6181 // the body fragment. |
6178 then_fragment += body_fragments[i]; | 6182 then_fragment += body_fragments[i]; |
6179 } | 6183 } |
6180 | 6184 |
6181 current_instructions = Fragment(otherwise); | 6185 current_instructions = Fragment(otherwise); |
6182 } | 6186 } |
6183 } | 6187 } |
6184 } | 6188 } |
6185 | 6189 |
6186 if (num_cases > 0 && default_case < 0) { | 6190 if (case_count > 0 && default_case < 0) { |
6187 // There is no default, which means we have an open [current_instructions] | 6191 // There is no default, which means we have an open [current_instructions] |
6188 // (which is a [TargetEntryInstruction] for the last "otherwise" branch). | 6192 // (which is a [TargetEntryInstruction] for the last "otherwise" branch). |
6189 // | 6193 // |
6190 // Furthermore the last [SwitchCase] can be open as well. If so, we need | 6194 // Furthermore the last [SwitchCase] can be open as well. If so, we need |
6191 // to join these two. | 6195 // to join these two. |
6192 Fragment& last_body = body_fragments[num_cases - 1]; | 6196 Fragment& last_body = body_fragments[case_count - 1]; |
6193 if (last_body.is_open()) { | 6197 if (last_body.is_open()) { |
6194 ASSERT(current_instructions.is_open()); | 6198 ASSERT(current_instructions.is_open()); |
6195 ASSERT(current_instructions.current->IsTargetEntry()); | 6199 ASSERT(current_instructions.current->IsTargetEntry()); |
6196 | 6200 |
6197 // Join the last "otherwise" branch and the last [SwitchCase] fragment. | 6201 // Join the last "otherwise" branch and the last [SwitchCase] fragment. |
6198 JoinEntryInstr* join = BuildJoinEntry(); | 6202 JoinEntryInstr* join = BuildJoinEntry(); |
6199 current_instructions += Goto(join); | 6203 current_instructions += Goto(join); |
6200 last_body += Goto(join); | 6204 last_body += Goto(join); |
6201 | 6205 |
6202 current_instructions = Fragment(join); | 6206 current_instructions = Fragment(join); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6306 { | 6310 { |
6307 TryCatchBlock block(flow_graph_builder_, try_handler_index); | 6311 TryCatchBlock block(flow_graph_builder_, try_handler_index); |
6308 try_body += BuildStatement(); // read body. | 6312 try_body += BuildStatement(); // read body. |
6309 try_body += Goto(after_try); | 6313 try_body += Goto(after_try); |
6310 } | 6314 } |
6311 try_depth_dec(); | 6315 try_depth_dec(); |
6312 | 6316 |
6313 bool needs_stacktrace = ReadBool(); // read any_catch_needs_stack_trace | 6317 bool needs_stacktrace = ReadBool(); // read any_catch_needs_stack_trace |
6314 | 6318 |
6315 catch_depth_inc(); | 6319 catch_depth_inc(); |
6316 intptr_t num_catches = ReadListLength(); // read number of catches. | 6320 intptr_t catch_count = ReadListLength(); // read number of catches. |
6317 const Array& handler_types = | 6321 const Array& handler_types = |
6318 Array::ZoneHandle(Z, Array::New(num_catches, Heap::kOld)); | 6322 Array::ZoneHandle(Z, Array::New(catch_count, Heap::kOld)); |
6319 Fragment catch_body = | 6323 Fragment catch_body = |
6320 CatchBlockEntry(handler_types, try_handler_index, needs_stacktrace); | 6324 CatchBlockEntry(handler_types, try_handler_index, needs_stacktrace); |
6321 // Fill in the body of the catch. | 6325 // Fill in the body of the catch. |
6322 for (intptr_t i = 0; i < num_catches; ++i) { | 6326 for (intptr_t i = 0; i < catch_count; ++i) { |
6323 intptr_t catch_offset = ReaderOffset(); // Catch has no tag. | 6327 intptr_t catch_offset = ReaderOffset(); // Catch has no tag. |
6324 Tag tag = PeekTag(); // peek guard type. | 6328 Tag tag = PeekTag(); // peek guard type. |
6325 AbstractType* type_guard = NULL; | 6329 AbstractType* type_guard = NULL; |
6326 if (tag != kDynamicType) { | 6330 if (tag != kDynamicType) { |
6327 type_guard = &T.BuildType(); // read guard. | 6331 type_guard = &T.BuildType(); // read guard. |
6328 handler_types.SetAt(i, *type_guard); | 6332 handler_types.SetAt(i, *type_guard); |
6329 } else { | 6333 } else { |
6330 SkipDartType(); // read guard. | 6334 SkipDartType(); // read guard. |
6331 handler_types.SetAt(i, Object::dynamic_type()); | 6335 handler_types.SetAt(i, Object::dynamic_type()); |
6332 } | 6336 } |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6785 total_parameter_count - positional_parameters_count; | 6789 total_parameter_count - positional_parameters_count; |
6786 | 6790 |
6787 function.set_num_fixed_parameters(extra_parameters + | 6791 function.set_num_fixed_parameters(extra_parameters + |
6788 required_parameter_count); | 6792 required_parameter_count); |
6789 if (named_parameters_count > 0) { | 6793 if (named_parameters_count > 0) { |
6790 function.SetNumOptionalParameters(named_parameters_count, false); | 6794 function.SetNumOptionalParameters(named_parameters_count, false); |
6791 } else { | 6795 } else { |
6792 function.SetNumOptionalParameters( | 6796 function.SetNumOptionalParameters( |
6793 positional_parameters_count - required_parameter_count, true); | 6797 positional_parameters_count - required_parameter_count, true); |
6794 } | 6798 } |
6795 intptr_t num_parameters = extra_parameters + total_parameter_count; | 6799 intptr_t parameter_count = extra_parameters + total_parameter_count; |
6796 function.set_parameter_types( | 6800 function.set_parameter_types( |
6797 Array::Handle(Z, Array::New(num_parameters, Heap::kOld))); | 6801 Array::Handle(Z, Array::New(parameter_count, Heap::kOld))); |
6798 function.set_parameter_names( | 6802 function.set_parameter_names( |
6799 Array::Handle(Z, Array::New(num_parameters, Heap::kOld))); | 6803 Array::Handle(Z, Array::New(parameter_count, Heap::kOld))); |
6800 intptr_t pos = 0; | 6804 intptr_t pos = 0; |
6801 if (is_method) { | 6805 if (is_method) { |
6802 ASSERT(!klass.IsNull()); | 6806 ASSERT(!klass.IsNull()); |
6803 function.SetParameterTypeAt(pos, H.GetCanonicalType(klass)); | 6807 function.SetParameterTypeAt(pos, H.GetCanonicalType(klass)); |
6804 function.SetParameterNameAt(pos, Symbols::This()); | 6808 function.SetParameterNameAt(pos, Symbols::This()); |
6805 pos++; | 6809 pos++; |
6806 } else if (is_closure) { | 6810 } else if (is_closure) { |
6807 function.SetParameterTypeAt(pos, AbstractType::dynamic_type()); | 6811 function.SetParameterTypeAt(pos, AbstractType::dynamic_type()); |
6808 function.SetParameterNameAt(pos, Symbols::ClosureParameter()); | 6812 function.SetParameterNameAt(pos, Symbols::ClosureParameter()); |
6809 pos++; | 6813 pos++; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6931 for (intptr_t i = 0; i < list_length; ++i) { | 6935 for (intptr_t i = 0; i < list_length; ++i) { |
6932 // this will (potentially) read the expression, but reset the position. | 6936 // this will (potentially) read the expression, but reset the position. |
6933 Instance& value = constant_evaluator_.EvaluateExpression(ReaderOffset()); | 6937 Instance& value = constant_evaluator_.EvaluateExpression(ReaderOffset()); |
6934 SkipExpression(); // read (actual) initializer. | 6938 SkipExpression(); // read (actual) initializer. |
6935 metadata_values.SetAt(i, value); | 6939 metadata_values.SetAt(i, value); |
6936 } | 6940 } |
6937 | 6941 |
6938 return metadata_values.raw(); | 6942 return metadata_values.raw(); |
6939 } | 6943 } |
6940 | 6944 |
| 6945 void StreamingFlowGraphBuilder::CollectTokenPositionsFor( |
| 6946 intptr_t script_index, |
| 6947 GrowableArray<intptr_t>* record_token_positions_in, |
| 6948 GrowableArray<intptr_t>* record_yield_positions_in) { |
| 6949 record_token_positions_into_ = record_token_positions_in; |
| 6950 record_yield_positions_into_ = record_yield_positions_in; |
| 6951 record_for_script_id_ = script_index; |
| 6952 |
| 6953 // Get offset for 1st library. |
| 6954 SetOffset(reader_->size() - 4); |
| 6955 intptr_t library_count = reader_->ReadUInt32(); |
| 6956 |
| 6957 SetOffset(reader_->size() - 4 - 4 * library_count); |
| 6958 intptr_t offset = reader_->ReadUInt32(); |
| 6959 |
| 6960 SetOffset(offset); |
| 6961 for (intptr_t i = 0; i < library_count; ++i) { |
| 6962 LibraryHelper library_helper(this); |
| 6963 library_helper.ReadUntilExcluding(LibraryHelper::kEnd); |
| 6964 } |
| 6965 |
| 6966 record_token_positions_into_ = NULL; |
| 6967 record_yield_positions_into_ = NULL; |
| 6968 record_for_script_id_ = -1; |
| 6969 } |
| 6970 |
| 6971 intptr_t StreamingFlowGraphBuilder::SourceTableSize() { |
| 6972 AlternativeReadingScope alt(reader_); |
| 6973 SetOffset(reader_->size() - 4); |
| 6974 intptr_t library_count = reader_->ReadUInt32(); |
| 6975 SetOffset(reader_->size() - 4 - 4 * library_count - 3 * 4); |
| 6976 SetOffset(reader_->ReadUInt32()); // read source table offset. |
| 6977 return ReadUInt(); // read source table size. |
| 6978 } |
| 6979 |
| 6980 String& StreamingFlowGraphBuilder::SourceTableUriFor(intptr_t index) { |
| 6981 AlternativeReadingScope alt(reader_); |
| 6982 SetOffset(reader_->size() - 4); |
| 6983 intptr_t library_count = reader_->ReadUInt32(); |
| 6984 SetOffset(reader_->size() - 4 - 4 * library_count - 3 * 4); |
| 6985 SetOffset(reader_->ReadUInt32()); // read source table offset. |
| 6986 intptr_t size = ReadUInt(); // read source table size. |
| 6987 intptr_t start = 0; |
| 6988 intptr_t end = -1; |
| 6989 for (intptr_t i = 0; i < size; ++i) { |
| 6990 intptr_t offset = ReadUInt(); |
| 6991 if (i == index - 1) { |
| 6992 start = offset; |
| 6993 } else if (i == index) { |
| 6994 end = offset; |
| 6995 } |
| 6996 } |
| 6997 intptr_t end_offset = ReaderOffset(); |
| 6998 return H.DartString(reader_->buffer() + end_offset + start, end - start, |
| 6999 Heap::kOld); |
| 7000 } |
| 7001 |
| 7002 String& StreamingFlowGraphBuilder::GetSourceFor(intptr_t index) { |
| 7003 AlternativeReadingScope alt(reader_); |
| 7004 SetOffset(reader_->size() - 4); |
| 7005 intptr_t library_count = reader_->ReadUInt32(); |
| 7006 SetOffset(reader_->size() - 4 - 4 * library_count - 3 * 4); |
| 7007 SetOffset(reader_->ReadUInt32()); // read source table offset. |
| 7008 intptr_t size = ReadUInt(); // read source table size. |
| 7009 intptr_t uris_size = 0; |
| 7010 for (intptr_t i = 0; i < size; ++i) { |
| 7011 uris_size = ReadUInt(); |
| 7012 } |
| 7013 SkipBytes(uris_size); |
| 7014 |
| 7015 // Read the source code strings and line starts. |
| 7016 for (intptr_t i = 0; i < size; ++i) { |
| 7017 intptr_t length = ReadUInt(); |
| 7018 if (index == i) { |
| 7019 return H.DartString(reader_->buffer() + ReaderOffset(), length, |
| 7020 Heap::kOld); |
| 7021 } |
| 7022 SkipBytes(length); |
| 7023 intptr_t line_count = ReadUInt(); |
| 7024 for (intptr_t j = 0; j < line_count; ++j) { |
| 7025 ReadUInt(); |
| 7026 } |
| 7027 } |
| 7028 |
| 7029 return String::Handle(String::null()); |
| 7030 } |
| 7031 |
| 7032 Array& StreamingFlowGraphBuilder::GetLineStartsFor(intptr_t index) { |
| 7033 AlternativeReadingScope alt(reader_); |
| 7034 SetOffset(reader_->size() - 4); |
| 7035 intptr_t library_count = reader_->ReadUInt32(); |
| 7036 SetOffset(reader_->size() - 4 - 4 * library_count - 3 * 4); |
| 7037 SetOffset(reader_->ReadUInt32()); // read source table offset. |
| 7038 intptr_t size = ReadUInt(); // read source table size. |
| 7039 intptr_t uris_size = 0; |
| 7040 for (intptr_t i = 0; i < size; ++i) { |
| 7041 uris_size = ReadUInt(); |
| 7042 } |
| 7043 SkipBytes(uris_size); |
| 7044 |
| 7045 // Read the source code strings and line starts. |
| 7046 for (intptr_t i = 0; i < size; ++i) { |
| 7047 intptr_t length = ReadUInt(); |
| 7048 SkipBytes(length); |
| 7049 intptr_t line_count = ReadUInt(); |
| 7050 if (i == index) { |
| 7051 Array& array_object = |
| 7052 Array::Handle(Z, Array::New(line_count, Heap::kOld)); |
| 7053 Smi& value = Smi::Handle(Z); |
| 7054 intptr_t previous_line_start = 0; |
| 7055 for (intptr_t j = 0; j < line_count; ++j) { |
| 7056 intptr_t line_start = ReadUInt() + previous_line_start; |
| 7057 value = Smi::New(line_start); |
| 7058 array_object.SetAt(j, value); |
| 7059 previous_line_start = line_start; |
| 7060 } |
| 7061 return array_object; |
| 7062 } else { |
| 7063 for (intptr_t j = 0; j < line_count; ++j) { |
| 7064 ReadUInt(); |
| 7065 } |
| 7066 } |
| 7067 } |
| 7068 |
| 7069 return Array::Handle(Array::null()); |
| 7070 } |
| 7071 |
6941 } // namespace kernel | 7072 } // namespace kernel |
6942 } // namespace dart | 7073 } // namespace dart |
6943 | 7074 |
6944 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 7075 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |