| 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> | 5 #include <map> |
| 6 #include <set> | 6 #include <set> |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "vm/kernel_to_il.h" | 9 #include "vm/kernel_to_il.h" |
| 10 | 10 |
| (...skipping 3933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3944 | 3944 |
| 3945 | 3945 |
| 3946 void DartTypeTranslator::VisitFunctionType(FunctionType* node) { | 3946 void DartTypeTranslator::VisitFunctionType(FunctionType* node) { |
| 3947 // The spec describes in section "19.1 Static Types": | 3947 // The spec describes in section "19.1 Static Types": |
| 3948 // | 3948 // |
| 3949 // Any use of a malformed type gives rise to a static warning. A | 3949 // Any use of a malformed type gives rise to a static warning. A |
| 3950 // malformed type is then interpreted as dynamic by the static type | 3950 // malformed type is then interpreted as dynamic by the static type |
| 3951 // checker and the runtime unless explicitly specified otherwise. | 3951 // checker and the runtime unless explicitly specified otherwise. |
| 3952 // | 3952 // |
| 3953 // So we convert malformed return/parameter types to `dynamic`. | 3953 // So we convert malformed return/parameter types to `dynamic`. |
| 3954 TypeParameterScope scope(this, &node->type_parameters()); |
| 3954 | 3955 |
| 3955 const Function& signature_function = Function::ZoneHandle( | 3956 const Function& signature_function = Function::ZoneHandle( |
| 3956 Z, Function::NewSignatureFunction(*active_class_->klass, | 3957 Z, Function::NewSignatureFunction(*active_class_->klass, |
| 3957 TokenPosition::kNoSource)); | 3958 TokenPosition::kNoSource)); |
| 3958 | 3959 |
| 3959 node->return_type()->AcceptDartTypeVisitor(this); | 3960 node->return_type()->AcceptDartTypeVisitor(this); |
| 3960 if (result_.IsMalformed()) { | 3961 if (result_.IsMalformed()) { |
| 3961 result_ = AbstractType::dynamic_type().raw(); | 3962 result_ = AbstractType::dynamic_type().raw(); |
| 3962 } | 3963 } |
| 3963 signature_function.set_result_type(result_); | 3964 signature_function.set_result_type(result_); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4007 if (finalize_) { | 4008 if (finalize_) { |
| 4008 signature_type ^= ClassFinalizer::FinalizeType( | 4009 signature_type ^= ClassFinalizer::FinalizeType( |
| 4009 *active_class_->klass, signature_type, ClassFinalizer::kCanonicalize); | 4010 *active_class_->klass, signature_type, ClassFinalizer::kCanonicalize); |
| 4010 } | 4011 } |
| 4011 signature_function.SetSignatureType(signature_type); | 4012 signature_function.SetSignatureType(signature_type); |
| 4012 | 4013 |
| 4013 result_ = signature_type.raw(); | 4014 result_ = signature_type.raw(); |
| 4014 } | 4015 } |
| 4015 | 4016 |
| 4016 | 4017 |
| 4018 static intptr_t FindTypeParameterIndex(List<TypeParameter>* parameters, |
| 4019 TypeParameter* param) { |
| 4020 for (intptr_t i = 0; i < parameters->length(); i++) { |
| 4021 if (param == (*parameters)[i]) { |
| 4022 return i; |
| 4023 } |
| 4024 } |
| 4025 return -1; |
| 4026 } |
| 4027 |
| 4028 |
| 4017 void DartTypeTranslator::VisitTypeParameterType(TypeParameterType* node) { | 4029 void DartTypeTranslator::VisitTypeParameterType(TypeParameterType* node) { |
| 4018 ASSERT(active_class_->kernel_class != NULL); | 4030 for (TypeParameterScope* scope = type_parameter_scope_; scope != NULL; |
| 4031 scope = scope->outer()) { |
| 4032 const intptr_t index = |
| 4033 FindTypeParameterIndex(scope->parameters(), node->parameter()); |
| 4034 if (index >= 0) { |
| 4035 result_ ^= dart::Type::DynamicType(); |
| 4036 return; |
| 4037 } |
| 4038 } |
| 4019 | 4039 |
| 4020 List<TypeParameter>* parameters = | |
| 4021 &active_class_->kernel_class->type_parameters(); | |
| 4022 if ((active_class_->member != NULL) && active_class_->member->IsProcedure()) { | 4040 if ((active_class_->member != NULL) && active_class_->member->IsProcedure()) { |
| 4023 Procedure* procedure = Procedure::Cast(active_class_->member); | 4041 Procedure* procedure = Procedure::Cast(active_class_->member); |
| 4024 if ((procedure->function() != NULL) && | 4042 if ((procedure->function() != NULL) && |
| 4025 (procedure->function()->type_parameters().length() > 0)) { | 4043 (procedure->function()->type_parameters().length() > 0)) { |
| 4026 // | 4044 // |
| 4027 // WARNING: This is a little hackish: | 4045 // WARNING: This is a little hackish: |
| 4028 // | 4046 // |
| 4029 // We have a static factory constructor. The kernel IR gives the factory | 4047 // We have a static factory constructor. The kernel IR gives the factory |
| 4030 // constructor function it's own type parameters (which are equal in name | 4048 // constructor function it's own type parameters (which are equal in name |
| 4031 // and number to the ones of the enclosing class). | 4049 // and number to the ones of the enclosing class). |
| 4032 // I.e., | 4050 // I.e., |
| 4033 // | 4051 // |
| 4034 // class A<T> { | 4052 // class A<T> { |
| 4035 // factory A.x() { return new B<T>(); } | 4053 // factory A.x() { return new B<T>(); } |
| 4036 // } | 4054 // } |
| 4037 // | 4055 // |
| 4038 // is basically translated to this: | 4056 // is basically translated to this: |
| 4039 // | 4057 // |
| 4040 // class A<T> { | 4058 // class A<T> { |
| 4041 // static A.x<T'>() { return new B<T'>(); } | 4059 // static A.x<T'>() { return new B<T'>(); } |
| 4042 // } | 4060 // } |
| 4043 // | 4061 // |
| 4044 parameters = &procedure->function()->type_parameters(); | 4062 const intptr_t index = FindTypeParameterIndex( |
| 4063 &procedure->function()->type_parameters(), node->parameter()); |
| 4064 if (index >= 0) { |
| 4065 if (procedure->kind() == Procedure::kFactory) { |
| 4066 // The index of the type parameter in [parameters] is |
| 4067 // the same index into the `klass->type_parameters()` array. |
| 4068 result_ ^= dart::TypeArguments::Handle( |
| 4069 Z, active_class_->klass->type_parameters()) |
| 4070 .TypeAt(index); |
| 4071 } else { |
| 4072 result_ ^= dart::Type::DynamicType(); |
| 4073 } |
| 4074 return; |
| 4075 } |
| 4045 } | 4076 } |
| 4046 } | 4077 } |
| 4047 | 4078 |
| 4048 for (intptr_t i = 0; i < parameters->length(); i++) { | 4079 ASSERT(active_class_->kernel_class != NULL); |
| 4049 TypeParameter* type_parameter = (*parameters)[i]; | 4080 List<TypeParameter>* parameters = |
| 4050 if (node->parameter() == type_parameter) { | 4081 &active_class_->kernel_class->type_parameters(); |
| 4051 // The index of the type parameter in [parameters] is | 4082 const intptr_t index = FindTypeParameterIndex(parameters, node->parameter()); |
| 4052 // the same index into the `klass->type_parameters()` array. | 4083 if (index >= 0) { |
| 4053 result_ ^= dart::TypeArguments::Handle( | 4084 // The index of the type parameter in [parameters] is |
| 4054 Z, active_class_->klass->type_parameters()) | 4085 // the same index into the `klass->type_parameters()` array. |
| 4055 .TypeAt(i); | 4086 result_ ^= |
| 4056 return; | 4087 dart::TypeArguments::Handle(Z, active_class_->klass->type_parameters()) |
| 4057 } | 4088 .TypeAt(index); |
| 4089 return; |
| 4058 } | 4090 } |
| 4059 | 4091 |
| 4060 UNREACHABLE(); | 4092 UNREACHABLE(); |
| 4061 } | 4093 } |
| 4062 | 4094 |
| 4063 | 4095 |
| 4064 void DartTypeTranslator::VisitInterfaceType(InterfaceType* node) { | 4096 void DartTypeTranslator::VisitInterfaceType(InterfaceType* node) { |
| 4065 // NOTE: That an interface type like `T<A, B>` is considered to be | 4097 // NOTE: That an interface type like `T<A, B>` is considered to be |
| 4066 // malformed iff `T` is malformed. | 4098 // malformed iff `T` is malformed. |
| 4067 // => We therefore ignore errors in `A` or `B`. | 4099 // => We therefore ignore errors in `A` or `B`. |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4385 // into Kernel. | 4417 // into Kernel. |
| 4386 List<DartType>& kernel_type_arguments = node->arguments()->types(); | 4418 List<DartType>& kernel_type_arguments = node->arguments()->types(); |
| 4387 | 4419 |
| 4388 const TypeArguments& type_arguments = T.TranslateInstantiatedTypeArguments( | 4420 const TypeArguments& type_arguments = T.TranslateInstantiatedTypeArguments( |
| 4389 klass, kernel_type_arguments.raw_array(), | 4421 klass, kernel_type_arguments.raw_array(), |
| 4390 kernel_type_arguments.length()); | 4422 kernel_type_arguments.length()); |
| 4391 | 4423 |
| 4392 instructions += TranslateInstantiatedTypeArguments(type_arguments); | 4424 instructions += TranslateInstantiatedTypeArguments(type_arguments); |
| 4393 instructions += PushArgument(); | 4425 instructions += PushArgument(); |
| 4394 } else { | 4426 } else { |
| 4395 ASSERT(node->arguments()->types().length() == 0); | 4427 // TODO(28109) Support generic methods in the VM or reify them away. |
| 4396 } | 4428 } |
| 4397 | 4429 |
| 4398 // Special case identical(x, y) call. | 4430 // Special case identical(x, y) call. |
| 4399 // TODO(27590) consider moving this into the inliner and force inline it | 4431 // TODO(27590) consider moving this into the inliner and force inline it |
| 4400 // there. | 4432 // there. |
| 4401 if (klass.IsTopLevel() && (klass.library() == dart::Library::CoreLibrary()) && | 4433 if (klass.IsTopLevel() && (klass.library() == dart::Library::CoreLibrary()) && |
| 4402 (target.name() == Symbols::Identical().raw())) { | 4434 (target.name() == Symbols::Identical().raw())) { |
| 4403 ASSERT(argument_count == 2); | 4435 ASSERT(argument_count == 2); |
| 4404 | 4436 |
| 4405 List<Expression>& positional = node->arguments()->positional(); | 4437 List<Expression>& positional = node->arguments()->positional(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4446 if (!result.IsError()) { | 4478 if (!result.IsError()) { |
| 4447 fragment_ = Constant(result); | 4479 fragment_ = Constant(result); |
| 4448 return; | 4480 return; |
| 4449 } | 4481 } |
| 4450 } | 4482 } |
| 4451 } | 4483 } |
| 4452 | 4484 |
| 4453 Fragment instructions = TranslateExpression(node->receiver()); | 4485 Fragment instructions = TranslateExpression(node->receiver()); |
| 4454 instructions += PushArgument(); | 4486 instructions += PushArgument(); |
| 4455 | 4487 |
| 4456 // Dart does not support generic methods yet. | 4488 // TODO(28109) Support generic methods in the VM or reify them away. |
| 4457 ASSERT(node->arguments()->types().length() == 0); | |
| 4458 | |
| 4459 Array& argument_names = Array::ZoneHandle(Z); | 4489 Array& argument_names = Array::ZoneHandle(Z); |
| 4460 instructions += TranslateArguments(node->arguments(), &argument_names); | 4490 instructions += TranslateArguments(node->arguments(), &argument_names); |
| 4461 | 4491 |
| 4462 intptr_t num_args_checked = 1; | 4492 intptr_t num_args_checked = 1; |
| 4463 // If we have a special operation (e.g. +/-/==) we mark both arguments as | 4493 // If we have a special operation (e.g. +/-/==) we mark both arguments as |
| 4464 // to be checked. | 4494 // to be checked. |
| 4465 if (token_kind != Token::kILLEGAL) { | 4495 if (token_kind != Token::kILLEGAL) { |
| 4466 ASSERT(argument_count <= 2); | 4496 ASSERT(argument_count <= 2); |
| 4467 num_args_checked = argument_count; | 4497 num_args_checked = argument_count; |
| 4468 } | 4498 } |
| 4469 | 4499 |
| 4470 fragment_ = instructions + InstanceCall(node->position(), name, token_kind, | 4500 fragment_ = instructions + InstanceCall(node->position(), name, token_kind, |
| 4471 argument_count, argument_names, | 4501 argument_count, argument_names, |
| 4472 num_args_checked); | 4502 num_args_checked); |
| 4473 } | 4503 } |
| 4474 | 4504 |
| 4475 | 4505 |
| 4476 void FlowGraphBuilder::VisitDirectMethodInvocation( | 4506 void FlowGraphBuilder::VisitDirectMethodInvocation( |
| 4477 DirectMethodInvocation* node) { | 4507 DirectMethodInvocation* node) { |
| 4478 const dart::String& method_name = H.DartMethodName(node->target()->name()); | 4508 const dart::String& method_name = H.DartMethodName(node->target()->name()); |
| 4479 const Function& target = Function::ZoneHandle( | 4509 const Function& target = Function::ZoneHandle( |
| 4480 Z, LookupMethodByMember(node->target(), method_name)); | 4510 Z, LookupMethodByMember(node->target(), method_name)); |
| 4481 | 4511 |
| 4482 intptr_t argument_count = node->arguments()->count() + 1; | 4512 intptr_t argument_count = node->arguments()->count() + 1; |
| 4483 Array& argument_names = Array::ZoneHandle(Z); | 4513 Array& argument_names = Array::ZoneHandle(Z); |
| 4484 | 4514 |
| 4485 ASSERT(node->arguments()->types().length() == 0); | 4515 // TODO(28109) Support generic methods in the VM or reify them away. |
| 4486 Fragment instructions = TranslateExpression(node->receiver()); | 4516 Fragment instructions = TranslateExpression(node->receiver()); |
| 4487 instructions += PushArgument(); | 4517 instructions += PushArgument(); |
| 4488 instructions += TranslateArguments(node->arguments(), &argument_names); | 4518 instructions += TranslateArguments(node->arguments(), &argument_names); |
| 4489 fragment_ = instructions + StaticCall(node->position(), target, | 4519 fragment_ = instructions + StaticCall(node->position(), target, |
| 4490 argument_count, argument_names); | 4520 argument_count, argument_names); |
| 4491 } | 4521 } |
| 4492 | 4522 |
| 4493 | 4523 |
| 4494 void FlowGraphBuilder::VisitConstructorInvocation(ConstructorInvocation* node) { | 4524 void FlowGraphBuilder::VisitConstructorInvocation(ConstructorInvocation* node) { |
| 4495 if (node->is_const()) { | 4525 if (node->is_const()) { |
| (...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5807 instructions += LoadLocal(parsed_function_->current_context_var()); | 5837 instructions += LoadLocal(parsed_function_->current_context_var()); |
| 5808 instructions += StoreInstanceField(Closure::context_offset()); | 5838 instructions += StoreInstanceField(Closure::context_offset()); |
| 5809 | 5839 |
| 5810 return instructions; | 5840 return instructions; |
| 5811 } | 5841 } |
| 5812 | 5842 |
| 5813 | 5843 |
| 5814 } // namespace kernel | 5844 } // namespace kernel |
| 5815 } // namespace dart | 5845 } // namespace dart |
| 5816 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 5846 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |