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 <map> | |
6 #include <set> | 5 #include <set> |
7 #include <string> | 6 #include <string> |
8 | 7 |
9 #include "vm/kernel_to_il.h" | 8 #include "vm/kernel_to_il.h" |
10 | 9 |
11 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
12 #include "vm/intermediate_language.h" | 11 #include "vm/intermediate_language.h" |
13 #include "vm/kernel_reader.h" | 12 #include "vm/kernel_reader.h" |
14 #include "vm/kernel_binary_flowgraph.h" | 13 #include "vm/kernel_binary_flowgraph.h" |
15 #include "vm/longjump.h" | 14 #include "vm/longjump.h" |
(...skipping 2131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2147 | 2146 |
2148 instructions += LoadLocal(scopes_->this_variable); | 2147 instructions += LoadLocal(scopes_->this_variable); |
2149 instructions += LoadField(type_arguments_field_offset); | 2148 instructions += LoadField(type_arguments_field_offset); |
2150 } else { | 2149 } else { |
2151 instructions += NullConstant(); | 2150 instructions += NullConstant(); |
2152 } | 2151 } |
2153 return instructions; | 2152 return instructions; |
2154 } | 2153 } |
2155 | 2154 |
2156 | 2155 |
| 2156 Fragment FlowGraphBuilder::LoadFunctionTypeArguments() { |
| 2157 UNIMPLEMENTED(); // TODO(regis) |
| 2158 return Fragment(NULL); |
| 2159 } |
| 2160 |
| 2161 |
2157 Fragment FlowGraphBuilder::InstantiateType(const AbstractType& type) { | 2162 Fragment FlowGraphBuilder::InstantiateType(const AbstractType& type) { |
2158 InstantiateTypeInstr* instr = new (Z) | 2163 Value* function_type_args = Pop(); |
2159 InstantiateTypeInstr(TokenPosition::kNoSource, type, Pop(), | 2164 Value* instantiator_type_args = Pop(); |
2160 NULL); // TODO(regis): Pop function type arguments. | 2165 InstantiateTypeInstr* instr = |
| 2166 new (Z) InstantiateTypeInstr(TokenPosition::kNoSource, type, |
| 2167 instantiator_type_args, function_type_args); |
2161 Push(instr); | 2168 Push(instr); |
2162 return Fragment(instr); | 2169 return Fragment(instr); |
2163 } | 2170 } |
2164 | 2171 |
2165 | 2172 |
2166 Fragment FlowGraphBuilder::InstantiateTypeArguments( | 2173 Fragment FlowGraphBuilder::InstantiateTypeArguments( |
2167 const TypeArguments& type_arguments) { | 2174 const TypeArguments& type_arguments) { |
| 2175 Value* function_type_args = Pop(); |
| 2176 Value* instantiator_type_args = Pop(); |
2168 InstantiateTypeArgumentsInstr* instr = new (Z) InstantiateTypeArgumentsInstr( | 2177 InstantiateTypeArgumentsInstr* instr = new (Z) InstantiateTypeArgumentsInstr( |
2169 TokenPosition::kNoSource, type_arguments, *active_class_.klass, Pop(), | 2178 TokenPosition::kNoSource, type_arguments, *active_class_.klass, |
2170 NULL); // TODO(regis): Pop function type arguments. | 2179 instantiator_type_args, function_type_args); |
2171 Push(instr); | 2180 Push(instr); |
2172 return Fragment(instr); | 2181 return Fragment(instr); |
2173 } | 2182 } |
2174 | 2183 |
2175 | 2184 |
2176 Fragment FlowGraphBuilder::TranslateInstantiatedTypeArguments( | 2185 Fragment FlowGraphBuilder::TranslateInstantiatedTypeArguments( |
2177 const TypeArguments& type_arguments) { | 2186 const TypeArguments& type_arguments) { |
2178 Fragment instructions; | 2187 Fragment instructions; |
2179 | 2188 |
2180 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 2189 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
(...skipping 12 matching lines...) Expand all Loading... |
2193 // This is for example the case here: | 2202 // This is for example the case here: |
2194 // class Foo<T> { | 2203 // class Foo<T> { |
2195 // newList() => new List<T>(); | 2204 // newList() => new List<T>(); |
2196 // } | 2205 // } |
2197 // We just use the type argument vector from the [Foo] object and pass it | 2206 // We just use the type argument vector from the [Foo] object and pass it |
2198 // directly to the `new List<T>()` factory constructor. | 2207 // directly to the `new List<T>()` factory constructor. |
2199 instructions += LoadInstantiatorTypeArguments(); | 2208 instructions += LoadInstantiatorTypeArguments(); |
2200 } else { | 2209 } else { |
2201 // Otherwise we need to resolve [TypeParameterType]s in the type | 2210 // Otherwise we need to resolve [TypeParameterType]s in the type |
2202 // expression based on the current instantiator type argument vector. | 2211 // expression based on the current instantiator type argument vector. |
2203 instructions += LoadInstantiatorTypeArguments(); | 2212 if (!type_arguments.IsInstantiated(kCurrentClass)) { |
| 2213 instructions += LoadInstantiatorTypeArguments(); |
| 2214 } else { |
| 2215 instructions += NullConstant(); |
| 2216 } |
| 2217 if (!type_arguments.IsInstantiated(kCurrentFunction)) { |
| 2218 instructions += LoadFunctionTypeArguments(); |
| 2219 } else { |
| 2220 instructions += NullConstant(); |
| 2221 } |
2204 instructions += InstantiateTypeArguments(type_arguments); | 2222 instructions += InstantiateTypeArguments(type_arguments); |
2205 } | 2223 } |
2206 } | 2224 } |
2207 return instructions; | 2225 return instructions; |
2208 } | 2226 } |
2209 | 2227 |
2210 | 2228 |
2211 Fragment FlowGraphBuilder::AllocateContext(int size) { | 2229 Fragment FlowGraphBuilder::AllocateContext(int size) { |
2212 AllocateContextInstr* allocate = | 2230 AllocateContextInstr* allocate = |
2213 new (Z) AllocateContextInstr(TokenPosition::kNoSource, size); | 2231 new (Z) AllocateContextInstr(TokenPosition::kNoSource, size); |
(...skipping 1593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3807 Push(instr); | 3825 Push(instr); |
3808 return Fragment(instr); | 3826 return Fragment(instr); |
3809 } | 3827 } |
3810 | 3828 |
3811 | 3829 |
3812 Fragment FlowGraphBuilder::AssertAssignable(const dart::AbstractType& dst_type, | 3830 Fragment FlowGraphBuilder::AssertAssignable(const dart::AbstractType& dst_type, |
3813 const dart::String& dst_name) { | 3831 const dart::String& dst_name) { |
3814 Fragment instructions; | 3832 Fragment instructions; |
3815 Value* value = Pop(); | 3833 Value* value = Pop(); |
3816 | 3834 |
3817 instructions += LoadInstantiatorTypeArguments(); | 3835 if (!dst_type.IsInstantiated(kCurrentClass)) { |
3818 Value* type_args = Pop(); | 3836 instructions += LoadInstantiatorTypeArguments(); |
| 3837 } else { |
| 3838 instructions += NullConstant(); |
| 3839 } |
| 3840 Value* instantiator_type_args = Pop(); |
3819 | 3841 |
3820 AssertAssignableInstr* instr = new (Z) | 3842 if (!dst_type.IsInstantiated(kCurrentFunction)) { |
3821 AssertAssignableInstr(TokenPosition::kNoSource, value, type_args, | 3843 instructions += LoadFunctionTypeArguments(); |
3822 NULL, // TODO(regis): Pop function type arguments. | 3844 } else { |
3823 dst_type, dst_name, H.thread()->GetNextDeoptId()); | 3845 instructions += NullConstant(); |
| 3846 } |
| 3847 Value* function_type_args = Pop(); |
| 3848 |
| 3849 AssertAssignableInstr* instr = new (Z) AssertAssignableInstr( |
| 3850 TokenPosition::kNoSource, value, instantiator_type_args, |
| 3851 function_type_args, dst_type, dst_name, H.thread()->GetNextDeoptId()); |
3824 Push(instr); | 3852 Push(instr); |
3825 | 3853 |
3826 instructions += Fragment(instr); | 3854 instructions += Fragment(instr); |
3827 | 3855 |
3828 return instructions; | 3856 return instructions; |
3829 } | 3857 } |
3830 | 3858 |
3831 | 3859 |
3832 FlowGraph* FlowGraphBuilder::BuildGraphOfMethodExtractor( | 3860 FlowGraph* FlowGraphBuilder::BuildGraphOfMethodExtractor( |
3833 const Function& method) { | 3861 const Function& method) { |
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4648 | 4676 |
4649 | 4677 |
4650 void FlowGraphBuilder::VisitTypeLiteral(TypeLiteral* node) { | 4678 void FlowGraphBuilder::VisitTypeLiteral(TypeLiteral* node) { |
4651 const AbstractType& type = T.TranslateType(node->type()); | 4679 const AbstractType& type = T.TranslateType(node->type()); |
4652 if (type.IsMalformed()) H.ReportError("Malformed type literal"); | 4680 if (type.IsMalformed()) H.ReportError("Malformed type literal"); |
4653 | 4681 |
4654 Fragment instructions; | 4682 Fragment instructions; |
4655 if (type.IsInstantiated()) { | 4683 if (type.IsInstantiated()) { |
4656 instructions += Constant(type); | 4684 instructions += Constant(type); |
4657 } else { | 4685 } else { |
4658 instructions += LoadInstantiatorTypeArguments(); | 4686 if (!type.IsInstantiated(kCurrentClass)) { |
| 4687 instructions += LoadInstantiatorTypeArguments(); |
| 4688 } else { |
| 4689 instructions += NullConstant(); |
| 4690 } |
| 4691 if (!type.IsInstantiated(kCurrentFunction)) { |
| 4692 instructions += LoadFunctionTypeArguments(); |
| 4693 } else { |
| 4694 instructions += NullConstant(); |
| 4695 } |
4659 instructions += InstantiateType(type); | 4696 instructions += InstantiateType(type); |
4660 } | 4697 } |
4661 fragment_ = instructions; | 4698 fragment_ = instructions; |
4662 } | 4699 } |
4663 | 4700 |
4664 | 4701 |
4665 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { | 4702 void FlowGraphBuilder::VisitVariableGet(VariableGet* node) { |
4666 fragment_ = LoadLocal(LookupVariable(node->variable())); | 4703 fragment_ = LoadLocal(LookupVariable(node->variable())); |
4667 } | 4704 } |
4668 | 4705 |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5074 instructions += Constant(type); | 5111 instructions += Constant(type); |
5075 instructions += PushArgument(); // Type. | 5112 instructions += PushArgument(); // Type. |
5076 instructions += InstanceCall( | 5113 instructions += InstanceCall( |
5077 node->position(), | 5114 node->position(), |
5078 dart::Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()), | 5115 dart::Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()), |
5079 Token::kIS, 2, 2); // 2 checked arguments. | 5116 Token::kIS, 2, 2); // 2 checked arguments. |
5080 fragment_ = instructions; | 5117 fragment_ = instructions; |
5081 return; | 5118 return; |
5082 } | 5119 } |
5083 | 5120 |
5084 if (!type.IsInstantiated()) { | 5121 if (!type.IsInstantiated(kCurrentClass)) { |
5085 instructions += LoadInstantiatorTypeArguments(); | 5122 instructions += LoadInstantiatorTypeArguments(); |
5086 } else { | 5123 } else { |
5087 instructions += NullConstant(); | 5124 instructions += NullConstant(); |
5088 } | 5125 } |
5089 instructions += PushArgument(); // Type arguments. | 5126 instructions += PushArgument(); // Instantiator type arguments. |
| 5127 |
| 5128 if (!type.IsInstantiated(kCurrentFunction)) { |
| 5129 instructions += LoadFunctionTypeArguments(); |
| 5130 } else { |
| 5131 instructions += NullConstant(); |
| 5132 } |
| 5133 instructions += PushArgument(); // Function type arguments. |
5090 | 5134 |
5091 instructions += Constant(type); | 5135 instructions += Constant(type); |
5092 instructions += PushArgument(); // Type. | 5136 instructions += PushArgument(); // Type. |
5093 | 5137 |
5094 instructions += | 5138 instructions += |
5095 InstanceCall(node->position(), | 5139 InstanceCall(node->position(), |
5096 dart::Library::PrivateCoreLibName(Symbols::_instanceOf()), | 5140 dart::Library::PrivateCoreLibName(Symbols::_instanceOf()), |
5097 Token::kIS, 3); | 5141 Token::kIS, 4); |
5098 } | 5142 } |
5099 | 5143 |
5100 fragment_ = instructions; | 5144 fragment_ = instructions; |
5101 } | 5145 } |
5102 | 5146 |
5103 | 5147 |
5104 void FlowGraphBuilder::VisitAsExpression(AsExpression* node) { | 5148 void FlowGraphBuilder::VisitAsExpression(AsExpression* node) { |
5105 Fragment instructions = TranslateExpression(node->operand()); | 5149 Fragment instructions = TranslateExpression(node->operand()); |
5106 | 5150 |
5107 // The VM does not like an Object_as call with a dynamic type. We need to | 5151 // The VM does not like an Object_as call with a dynamic type. We need to |
5108 // special case this situation. | 5152 // special case this situation. |
5109 const Type& object_type = Type::Handle(Z, Type::ObjectType()); | 5153 const Type& object_type = Type::Handle(Z, Type::ObjectType()); |
5110 const AbstractType& type = T.TranslateType(node->type()); | 5154 const AbstractType& type = T.TranslateType(node->type()); |
5111 if (type.IsMalformed()) { | 5155 if (type.IsMalformed()) { |
5112 instructions += Drop(); | 5156 instructions += Drop(); |
5113 instructions += ThrowTypeError(); | 5157 instructions += ThrowTypeError(); |
5114 fragment_ = instructions; | 5158 fragment_ = instructions; |
5115 return; | 5159 return; |
5116 } | 5160 } |
5117 | 5161 |
5118 if (type.IsInstantiated() && | 5162 if (type.IsInstantiated() && |
5119 object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) { | 5163 object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) { |
5120 // We already evaluated the operand on the left and just leave it there as | 5164 // We already evaluated the operand on the left and just leave it there as |
5121 // the result of the `obj as dynamic` expression. | 5165 // the result of the `obj as dynamic` expression. |
5122 } else { | 5166 } else { |
5123 instructions += PushArgument(); | 5167 instructions += PushArgument(); |
5124 | 5168 |
5125 if (!type.IsInstantiated()) { | 5169 if (!type.IsInstantiated(kCurrentClass)) { |
5126 instructions += LoadInstantiatorTypeArguments(); | 5170 instructions += LoadInstantiatorTypeArguments(); |
5127 } else { | 5171 } else { |
5128 instructions += NullConstant(); | 5172 instructions += NullConstant(); |
5129 } | 5173 } |
5130 instructions += PushArgument(); // Type arguments. | 5174 instructions += PushArgument(); // Instantiator type arguments. |
| 5175 |
| 5176 if (!type.IsInstantiated(kCurrentFunction)) { |
| 5177 instructions += LoadFunctionTypeArguments(); |
| 5178 } else { |
| 5179 instructions += NullConstant(); |
| 5180 } |
| 5181 instructions += PushArgument(); // Function type arguments. |
5131 | 5182 |
5132 instructions += Constant(type); | 5183 instructions += Constant(type); |
5133 instructions += PushArgument(); // Type. | 5184 instructions += PushArgument(); // Type. |
5134 | 5185 |
5135 instructions += InstanceCall( | 5186 instructions += InstanceCall( |
5136 node->position(), dart::Library::PrivateCoreLibName(Symbols::_as()), | 5187 node->position(), dart::Library::PrivateCoreLibName(Symbols::_as()), |
5137 Token::kAS, 3); | 5188 Token::kAS, 4); |
5138 } | 5189 } |
5139 | 5190 |
5140 fragment_ = instructions; | 5191 fragment_ = instructions; |
5141 } | 5192 } |
5142 | 5193 |
5143 | 5194 |
5144 void FlowGraphBuilder::VisitConditionalExpression(ConditionalExpression* node) { | 5195 void FlowGraphBuilder::VisitConditionalExpression(ConditionalExpression* node) { |
5145 bool negate; | 5196 bool negate; |
5146 Fragment instructions = TranslateCondition(node->condition(), &negate); | 5197 Fragment instructions = TranslateCondition(node->condition(), &negate); |
5147 | 5198 |
(...skipping 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6168 } | 6219 } |
6169 | 6220 |
6170 if (type_guard != NULL) { | 6221 if (type_guard != NULL) { |
6171 if (type_guard->IsMalformed()) { | 6222 if (type_guard->IsMalformed()) { |
6172 catch_body += ThrowTypeError(); | 6223 catch_body += ThrowTypeError(); |
6173 catch_body += Drop(); | 6224 catch_body += Drop(); |
6174 } else { | 6225 } else { |
6175 catch_body += LoadLocal(CurrentException()); | 6226 catch_body += LoadLocal(CurrentException()); |
6176 catch_body += PushArgument(); // exception | 6227 catch_body += PushArgument(); // exception |
6177 catch_body += NullConstant(); | 6228 catch_body += NullConstant(); |
6178 catch_body += PushArgument(); // type arguments | 6229 catch_body += PushArgument(); // instantiator type arguments |
| 6230 catch_body += NullConstant(); |
| 6231 catch_body += PushArgument(); // function type arguments |
6179 catch_body += Constant(*type_guard); | 6232 catch_body += Constant(*type_guard); |
6180 catch_body += PushArgument(); // guard type | 6233 catch_body += PushArgument(); // guard type |
6181 catch_body += InstanceCall( | 6234 catch_body += InstanceCall( |
6182 TokenPosition::kNoSource, | 6235 TokenPosition::kNoSource, |
6183 dart::Library::PrivateCoreLibName(Symbols::_instanceOf()), | 6236 dart::Library::PrivateCoreLibName(Symbols::_instanceOf()), |
6184 Token::kIS, 3); | 6237 Token::kIS, 4); |
6185 | 6238 |
6186 TargetEntryInstr* catch_entry; | 6239 TargetEntryInstr* catch_entry; |
6187 TargetEntryInstr* next_catch_entry; | 6240 TargetEntryInstr* next_catch_entry; |
6188 catch_body += BranchIfTrue(&catch_entry, &next_catch_entry); | 6241 catch_body += BranchIfTrue(&catch_entry, &next_catch_entry); |
6189 | 6242 |
6190 Fragment(catch_entry) + catch_handler_body; | 6243 Fragment(catch_entry) + catch_handler_body; |
6191 catch_body = Fragment(next_catch_entry); | 6244 catch_body = Fragment(next_catch_entry); |
6192 } | 6245 } |
6193 } else { | 6246 } else { |
6194 catch_body += catch_handler_body; | 6247 catch_body += catch_handler_body; |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6503 thread->clear_sticky_error(); | 6556 thread->clear_sticky_error(); |
6504 return error.raw(); | 6557 return error.raw(); |
6505 } | 6558 } |
6506 } | 6559 } |
6507 | 6560 |
6508 | 6561 |
6509 } // namespace kernel | 6562 } // namespace kernel |
6510 } // namespace dart | 6563 } // namespace dart |
6511 | 6564 |
6512 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6565 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |