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