OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
6 | 6 |
7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 2464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2475 void EffectGraphVisitor::BuildPushTypeArguments( | 2475 void EffectGraphVisitor::BuildPushTypeArguments( |
2476 const ArgumentListNode& node, | 2476 const ArgumentListNode& node, |
2477 ZoneGrowableArray<PushArgumentInstr*>* values) { | 2477 ZoneGrowableArray<PushArgumentInstr*>* values) { |
2478 if (node.type_args_len() > 0) { | 2478 if (node.type_args_len() > 0) { |
2479 Value* type_args_val; | 2479 Value* type_args_val; |
2480 if (node.type_args_var() != NULL) { | 2480 if (node.type_args_var() != NULL) { |
2481 type_args_val = | 2481 type_args_val = |
2482 Bind(new (Z) LoadLocalInstr(*node.type_args_var(), node.token_pos())); | 2482 Bind(new (Z) LoadLocalInstr(*node.type_args_var(), node.token_pos())); |
2483 } else { | 2483 } else { |
2484 const TypeArguments& type_args = node.type_arguments(); | 2484 const TypeArguments& type_args = node.type_arguments(); |
2485 ASSERT(!type_args.IsNull() && | 2485 ASSERT(!type_args.IsNull() && type_args.IsCanonical() && |
2486 (type_args.Length() == node.type_args_len())); | 2486 (type_args.Length() == node.type_args_len())); |
2487 type_args_val = | 2487 type_args_val = |
2488 BuildInstantiatedTypeArguments(node.token_pos(), type_args); | 2488 BuildInstantiatedTypeArguments(node.token_pos(), type_args); |
2489 } | 2489 } |
2490 PushArgumentInstr* push_type_args = PushArgument(type_args_val); | 2490 PushArgumentInstr* push_type_args = PushArgument(type_args_val); |
2491 values->Add(push_type_args); | 2491 values->Add(push_type_args); |
2492 } | 2492 } |
2493 } | 2493 } |
2494 | 2494 |
2495 | 2495 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2544 BuildInstanceCallConditional(node); | 2544 BuildInstanceCallConditional(node); |
2545 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); | 2545 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); |
2546 } else { | 2546 } else { |
2547 EffectGraphVisitor::VisitInstanceCallNode(node); | 2547 EffectGraphVisitor::VisitInstanceCallNode(node); |
2548 } | 2548 } |
2549 } | 2549 } |
2550 | 2550 |
2551 | 2551 |
2552 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 2552 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
2553 if (node->is_conditional()) { | 2553 if (node->is_conditional()) { |
| 2554 ASSERT(node->arguments()->type_args_len() == 0); |
2554 ValueGraphVisitor for_receiver(owner()); | 2555 ValueGraphVisitor for_receiver(owner()); |
2555 node->receiver()->Visit(&for_receiver); | 2556 node->receiver()->Visit(&for_receiver); |
2556 Append(for_receiver); | 2557 Append(for_receiver); |
2557 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); | 2558 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); |
2558 BuildInstanceCallConditional(node); | 2559 BuildInstanceCallConditional(node); |
2559 } else { | 2560 } else { |
2560 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2561 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
2561 new (Z) ZoneGrowableArray<PushArgumentInstr*>( | 2562 new (Z) ZoneGrowableArray<PushArgumentInstr*>( |
2562 node->arguments()->LengthWithTypeArgs() + 1); | 2563 node->arguments()->LengthWithTypeArgs() + 1); |
2563 BuildPushTypeArguments(*node->arguments(), arguments); | 2564 BuildPushTypeArguments(*node->arguments(), arguments); |
(...skipping 29 matching lines...) Expand all Loading... |
2593 } | 2594 } |
2594 ReturnDefinition(call); | 2595 ReturnDefinition(call); |
2595 } | 2596 } |
2596 | 2597 |
2597 | 2598 |
2598 void EffectGraphVisitor::BuildClosureCall(ClosureCallNode* node, | 2599 void EffectGraphVisitor::BuildClosureCall(ClosureCallNode* node, |
2599 bool result_needed) { | 2600 bool result_needed) { |
2600 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2601 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
2601 new (Z) ZoneGrowableArray<PushArgumentInstr*>( | 2602 new (Z) ZoneGrowableArray<PushArgumentInstr*>( |
2602 node->arguments()->LengthWithTypeArgs() + 1); | 2603 node->arguments()->LengthWithTypeArgs() + 1); |
2603 BuildPushTypeArguments(*node->arguments(), arguments); | |
2604 | 2604 |
2605 ValueGraphVisitor for_closure(owner()); | 2605 ValueGraphVisitor for_closure(owner()); |
2606 node->closure()->Visit(&for_closure); | 2606 node->closure()->Visit(&for_closure); |
2607 Append(for_closure); | 2607 Append(for_closure); |
2608 Value* closure_value = for_closure.value(); | 2608 Value* closure_value = for_closure.value(); |
2609 LocalVariable* tmp_var = EnterTempLocalScope(closure_value); | 2609 LocalVariable* tmp_var = EnterTempLocalScope(closure_value); |
2610 | 2610 |
| 2611 BuildPushTypeArguments(*node->arguments(), arguments); |
2611 Value* closure_val = | 2612 Value* closure_val = |
2612 Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos())); | 2613 Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
2613 PushArgumentInstr* push_closure = PushArgument(closure_val); | 2614 PushArgumentInstr* push_closure = PushArgument(closure_val); |
2614 arguments->Add(push_closure); | 2615 arguments->Add(push_closure); |
2615 BuildPushArguments(*node->arguments(), arguments); | 2616 BuildPushArguments(*node->arguments(), arguments); |
2616 | 2617 |
2617 closure_val = Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos())); | 2618 closure_val = Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
2618 LoadFieldInstr* function_load = new (Z) LoadFieldInstr( | 2619 LoadFieldInstr* function_load = new (Z) LoadFieldInstr( |
2619 closure_val, Closure::function_offset(), | 2620 closure_val, Closure::function_offset(), |
2620 AbstractType::ZoneHandle(Z, AbstractType::null()), node->token_pos()); | 2621 AbstractType::ZoneHandle(Z, AbstractType::null()), node->token_pos()); |
(...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3889 // the function. | 3890 // the function. |
3890 Value* null_constant = Bind( | 3891 Value* null_constant = Bind( |
3891 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); | 3892 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); |
3892 Do(BuildStoreLocal(*temp_local, null_constant, | 3893 Do(BuildStoreLocal(*temp_local, null_constant, |
3893 ST(node->token_pos()))); | 3894 ST(node->token_pos()))); |
3894 } | 3895 } |
3895 } | 3896 } |
3896 } | 3897 } |
3897 } | 3898 } |
3898 | 3899 |
| 3900 // Load the passed-in type argument vector from the temporary stack slot, |
| 3901 // prepend the function type arguments of the generic parent function, and |
| 3902 // store it to the final location, possibly in the context. |
| 3903 if (FLAG_reify_generic_functions && is_top_level_sequence && |
| 3904 function.IsGeneric()) { |
| 3905 const ParsedFunction& parsed_function = owner()->parsed_function(); |
| 3906 LocalVariable* type_args_var = parsed_function.function_type_arguments(); |
| 3907 ASSERT(type_args_var->owner() == scope); |
| 3908 LocalVariable* parent_type_args_var = |
| 3909 parsed_function.parent_type_arguments(); |
| 3910 if (type_args_var->is_captured() || (parent_type_args_var != NULL)) { |
| 3911 // Create a temporary local describing the original position. |
| 3912 const String& temp_name = Symbols::TempParam(); |
| 3913 LocalVariable* temp_local = |
| 3914 new (Z) LocalVariable(TokenPosition::kNoSource, // Token index. |
| 3915 TokenPosition::kNoSource, // Token index. |
| 3916 temp_name, |
| 3917 Object::dynamic_type()); // Type. |
| 3918 temp_local->set_index(parsed_function.first_stack_local_index()); |
| 3919 |
| 3920 // Mark this local as captured parameter so that the optimizer |
| 3921 // correctly handles these when compiling try-catch: Captured |
| 3922 // parameters are not in the stack environment, therefore they |
| 3923 // must be skipped when emitting sync-code in try-blocks. |
| 3924 temp_local->set_is_captured_parameter(true); // TODO(regis): Correct? |
| 3925 |
| 3926 Value* type_args_val = |
| 3927 Bind(BuildLoadLocal(*temp_local, node->token_pos())); |
| 3928 if (parent_type_args_var != NULL) { |
| 3929 ASSERT(parent_type_args_var->owner() != scope); |
| 3930 // Call the runtime to concatenate both vectors. |
| 3931 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3932 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3); |
| 3933 arguments->Add(PushArgument(type_args_val)); |
| 3934 Value* parent_type_args_val = |
| 3935 Bind(BuildLoadLocal(*parent_type_args_var, node->token_pos())); |
| 3936 arguments->Add(PushArgument(parent_type_args_val)); |
| 3937 Value* len_const = Bind(new (Z) ConstantInstr( |
| 3938 Smi::ZoneHandle(Z, Smi::New(function.NumTypeParameters() + |
| 3939 function.NumParentTypeParameters())))); |
| 3940 arguments->Add(PushArgument(len_const)); |
| 3941 const Library& dart_internal = |
| 3942 Library::Handle(Z, Library::InternalLibrary()); |
| 3943 const Function& prepend_function = |
| 3944 Function::ZoneHandle(Z, dart_internal.LookupFunctionAllowPrivate( |
| 3945 Symbols::PrependTypeArguments())); |
| 3946 ASSERT(!prepend_function.IsNull()); |
| 3947 const intptr_t kTypeArgsLen = 0; |
| 3948 type_args_val = Bind(new (Z) StaticCallInstr( |
| 3949 node->token_pos(), prepend_function, kTypeArgsLen, |
| 3950 Object::null_array(), // No names. |
| 3951 arguments, owner()->ic_data_array(), owner()->GetNextDeoptId())); |
| 3952 } |
| 3953 Do(BuildStoreLocal(*type_args_var, type_args_val, ST(node->token_pos()))); |
| 3954 if (type_args_var->is_captured()) { |
| 3955 // Write NULL to the source location to detect buggy accesses and |
| 3956 // allow GC of passed value if it gets overwritten by a new value in |
| 3957 // the function. |
| 3958 Value* null_constant = |
| 3959 Bind(new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); |
| 3960 Do(BuildStoreLocal(*temp_local, null_constant, ST(node->token_pos()))); |
| 3961 } else { |
| 3962 // Do not write NULL, since the temp is also the final location. |
| 3963 ASSERT(temp_local->index() == type_args_var->index()); |
| 3964 } |
| 3965 } else { |
| 3966 // The type args slot is the final location. No copy needed. |
| 3967 ASSERT(type_args_var->index() == |
| 3968 parsed_function.first_stack_local_index()); |
| 3969 } |
| 3970 } |
| 3971 |
3899 if (FLAG_causal_async_stacks && is_top_level_sequence && | 3972 if (FLAG_causal_async_stacks && is_top_level_sequence && |
3900 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) { | 3973 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) { |
3901 LocalScope* top_scope = node->scope(); | 3974 LocalScope* top_scope = node->scope(); |
3902 // Fetch the :async_stack_trace variable and store it into the thread. | 3975 // Fetch the :async_stack_trace variable and store it into the thread. |
3903 LocalVariable* async_stack_trace_var = | 3976 LocalVariable* async_stack_trace_var = |
3904 top_scope->LookupVariable(Symbols::AsyncStackTraceVar(), false); | 3977 top_scope->LookupVariable(Symbols::AsyncStackTraceVar(), false); |
3905 ASSERT((async_stack_trace_var != NULL) && | 3978 ASSERT((async_stack_trace_var != NULL) && |
3906 async_stack_trace_var->is_captured()); | 3979 async_stack_trace_var->is_captured()); |
3907 // Load :async_stack_trace | 3980 // Load :async_stack_trace |
3908 Value* async_stack_trace_value = Bind(BuildLoadLocal( | 3981 Value* async_stack_trace_value = Bind(BuildLoadLocal( |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4510 ASSERT(type.HasResolvedTypeClass()); | 4583 ASSERT(type.HasResolvedTypeClass()); |
4511 const Class& type_class = Class::Handle(type.type_class()); | 4584 const Class& type_class = Class::Handle(type.type_class()); |
4512 // Bail if the type has any type parameters. | 4585 // Bail if the type has any type parameters. |
4513 if (type_class.IsGeneric()) return false; | 4586 if (type_class.IsGeneric()) return false; |
4514 | 4587 |
4515 // Finally a simple class for instance of checking. | 4588 // Finally a simple class for instance of checking. |
4516 return true; | 4589 return true; |
4517 } | 4590 } |
4518 | 4591 |
4519 } // namespace dart | 4592 } // namespace dart |
OLD | NEW |