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 1393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3889 // the function. | 3889 // the function. |
3890 Value* null_constant = Bind( | 3890 Value* null_constant = Bind( |
3891 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); | 3891 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); |
3892 Do(BuildStoreLocal(*temp_local, null_constant, | 3892 Do(BuildStoreLocal(*temp_local, null_constant, |
3893 ST(node->token_pos()))); | 3893 ST(node->token_pos()))); |
3894 } | 3894 } |
3895 } | 3895 } |
3896 } | 3896 } |
3897 } | 3897 } |
3898 | 3898 |
3899 // Load the passed-in type argument vector from the temporary stack slot, | |
3900 // prepend the function type arguments of the generic parent function, and | |
3901 // store it to the final location, possibly in the context. | |
3902 if (is_top_level_sequence && FLAG_reify_generic_functions && | |
Vyacheslav Egorov (Google)
2017/06/15 14:05:44
maybe reoder condition to be more logical, moving
regis
2017/06/15 21:38:26
Will do.
| |
3903 function.IsGeneric()) { | |
3904 const ParsedFunction& parsed_function = owner()->parsed_function(); | |
3905 LocalVariable* type_args_var = parsed_function.function_type_arguments(); | |
3906 ASSERT(type_args_var->owner() == scope); | |
3907 LocalVariable* parent_type_args_var = | |
3908 parsed_function.parent_type_arguments(); | |
3909 if (type_args_var->is_captured() || (parent_type_args_var != NULL)) { | |
3910 // Create a temporary local describing the original position. | |
3911 const String& temp_name = Symbols::TempParam(); | |
3912 LocalVariable* temp_local = | |
3913 new (Z) LocalVariable(TokenPosition::kNoSource, // Token index. | |
3914 TokenPosition::kNoSource, // Token index. | |
3915 temp_name, | |
3916 Object::dynamic_type()); // Type. | |
3917 temp_local->set_index(parsed_function.first_stack_local_index()); | |
3918 | |
3919 // Mark this local as captured parameter so that the optimizer | |
3920 // correctly handles these when compiling try-catch: Captured | |
3921 // parameters are not in the stack environment, therefore they | |
3922 // must be skipped when emitting sync-code in try-blocks. | |
3923 temp_local->set_is_captured_parameter(true); // TODO(regis): Correct? | |
3924 | |
3925 Value* type_args_val = | |
3926 Bind(BuildLoadLocal(*temp_local, node->token_pos())); | |
3927 if (parent_type_args_var != NULL) { | |
3928 ASSERT(parent_type_args_var->owner() != scope); | |
3929 // Call the runtime to concatenate both vectors. | |
3930 ZoneGrowableArray<PushArgumentInstr*>* arguments = | |
3931 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3); | |
3932 arguments->Add(PushArgument(type_args_val)); | |
3933 Value* parent_type_args_val = | |
3934 Bind(BuildLoadLocal(*parent_type_args_var, node->token_pos())); | |
3935 arguments->Add(PushArgument(parent_type_args_val)); | |
3936 Value* len_const = Bind(new (Z) ConstantInstr( | |
3937 Smi::ZoneHandle(Z, Smi::New(function.NumTypeParameters() + | |
3938 function.NumParentTypeParameters())))); | |
3939 arguments->Add(PushArgument(len_const)); | |
3940 const Class& cls = | |
3941 Class::Handle(Z, isolate()->object_store()->object_class()); | |
3942 const Function& prepend_function = | |
3943 Function::ZoneHandle(Z, cls.LookupStaticFunctionAllowPrivate( | |
3944 Symbols::PrependTypeArguments())); | |
3945 ASSERT(!prepend_function.IsNull()); | |
3946 const intptr_t kTypeArgsLen = 0; | |
3947 type_args_val = Bind(new (Z) StaticCallInstr( | |
3948 node->token_pos(), prepend_function, kTypeArgsLen, | |
3949 Object::null_array(), // No names. | |
3950 arguments, owner()->ic_data_array(), owner()->GetNextDeoptId())); | |
3951 } | |
3952 Do(BuildStoreLocal(*type_args_var, type_args_val, ST(node->token_pos()))); | |
3953 if (type_args_var->is_captured()) { | |
3954 // Write NULL to the source location to detect buggy accesses and | |
3955 // allow GC of passed value if it gets overwritten by a new value in | |
3956 // the function. | |
3957 Value* null_constant = | |
3958 Bind(new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); | |
3959 Do(BuildStoreLocal(*temp_local, null_constant, ST(node->token_pos()))); | |
3960 } else { | |
3961 // Do not write NULL, since the temp is also the final location. | |
3962 ASSERT(temp_local->index() == type_args_var->index()); | |
3963 } | |
3964 } else { | |
3965 // The type args slot is the final location. No copy needed. | |
3966 ASSERT(type_args_var->index() == | |
3967 parsed_function.first_stack_local_index()); | |
3968 } | |
3969 } | |
3970 | |
3899 if (FLAG_causal_async_stacks && is_top_level_sequence && | 3971 if (FLAG_causal_async_stacks && is_top_level_sequence && |
3900 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) { | 3972 (function.IsAsyncClosure() || function.IsAsyncGenClosure())) { |
3901 LocalScope* top_scope = node->scope(); | 3973 LocalScope* top_scope = node->scope(); |
3902 // Fetch the :async_stack_trace variable and store it into the thread. | 3974 // Fetch the :async_stack_trace variable and store it into the thread. |
3903 LocalVariable* async_stack_trace_var = | 3975 LocalVariable* async_stack_trace_var = |
3904 top_scope->LookupVariable(Symbols::AsyncStackTraceVar(), false); | 3976 top_scope->LookupVariable(Symbols::AsyncStackTraceVar(), false); |
3905 ASSERT((async_stack_trace_var != NULL) && | 3977 ASSERT((async_stack_trace_var != NULL) && |
3906 async_stack_trace_var->is_captured()); | 3978 async_stack_trace_var->is_captured()); |
3907 // Load :async_stack_trace | 3979 // Load :async_stack_trace |
3908 Value* async_stack_trace_value = Bind(BuildLoadLocal( | 3980 Value* async_stack_trace_value = Bind(BuildLoadLocal( |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4510 ASSERT(type.HasResolvedTypeClass()); | 4582 ASSERT(type.HasResolvedTypeClass()); |
4511 const Class& type_class = Class::Handle(type.type_class()); | 4583 const Class& type_class = Class::Handle(type.type_class()); |
4512 // Bail if the type has any type parameters. | 4584 // Bail if the type has any type parameters. |
4513 if (type_class.IsGeneric()) return false; | 4585 if (type_class.IsGeneric()) return false; |
4514 | 4586 |
4515 // Finally a simple class for instance of checking. | 4587 // Finally a simple class for instance of checking. |
4516 return true; | 4588 return true; |
4517 } | 4589 } |
4518 | 4590 |
4519 } // namespace dart | 4591 } // namespace dart |
OLD | NEW |