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

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

Issue 2571393002: VM: [Kernel] don't crash when encountering generic methods in Kernel. (Closed)
Patch Set: Created 4 years 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
« no previous file with comments | « runtime/vm/kernel_to_il.h ('k') | tests/language/language_kernel.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <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
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
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
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
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
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)
OLDNEW
« no previous file with comments | « runtime/vm/kernel_to_il.h ('k') | tests/language/language_kernel.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698