Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: runtime/vm/kernel_binary_flowgraph.cc

Issue 2931773005: [kernel] Delete most of the AST (Closed)
Patch Set: Remove getMainClosure handeling as it no longer exists Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698