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

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

Issue 3007623002: Fix many bugs with closure conversion in checked mode. (Closed)
Patch Set: Review comments Created 3 years, 3 months 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_binary_flowgraph.cc ('k') | no next file » | 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) 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/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/become.h" 10 #include "vm/become.h"
(...skipping 5990 matching lines...) Expand 10 before | Expand all | Expand 10 after
6001 } 6001 }
6002 6002
6003 intptr_t Function::NumImplicitParameters() const { 6003 intptr_t Function::NumImplicitParameters() const {
6004 const RawFunction::Kind k = kind(); 6004 const RawFunction::Kind k = kind();
6005 if (k == RawFunction::kConstructor) { 6005 if (k == RawFunction::kConstructor) {
6006 // Type arguments for factory; instance for generative constructor. 6006 // Type arguments for factory; instance for generative constructor.
6007 return 1; 6007 return 1;
6008 } 6008 }
6009 if ((k == RawFunction::kClosureFunction) || 6009 if ((k == RawFunction::kClosureFunction) ||
6010 (k == RawFunction::kImplicitClosureFunction) || 6010 (k == RawFunction::kImplicitClosureFunction) ||
6011 (k == RawFunction::kSignatureFunction)) { 6011 (k == RawFunction::kSignatureFunction) ||
6012 (k == RawFunction::kConvertedClosureFunction)) {
6012 return 1; // Closure object. 6013 return 1; // Closure object.
6013 } 6014 }
6014 if (!is_static()) { 6015 if (!is_static()) {
6015 // Closure functions defined inside instance (i.e. non-static) functions are 6016 // Closure functions defined inside instance (i.e. non-static) functions are
6016 // marked as non-static, but they do not have a receiver. 6017 // marked as non-static, but they do not have a receiver.
6017 // Closures are handled above. 6018 // Closures are handled above.
6018 ASSERT((k != RawFunction::kClosureFunction) && 6019 ASSERT((k != RawFunction::kClosureFunction) &&
6019 (k != RawFunction::kImplicitClosureFunction) && 6020 (k != RawFunction::kImplicitClosureFunction) &&
6020 (k != RawFunction::kSignatureFunction)); 6021 (k != RawFunction::kSignatureFunction));
6021 return 1; // Receiver. 6022 return 1; // Receiver.
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
6325 RawFunction* Function::InstantiateSignatureFrom( 6326 RawFunction* Function::InstantiateSignatureFrom(
6326 const TypeArguments& instantiator_type_arguments, 6327 const TypeArguments& instantiator_type_arguments,
6327 const TypeArguments& function_type_arguments, 6328 const TypeArguments& function_type_arguments,
6328 Heap::Space space) const { 6329 Heap::Space space) const {
6329 Zone* zone = Thread::Current()->zone(); 6330 Zone* zone = Thread::Current()->zone();
6330 const Object& owner = Object::Handle(zone, RawOwner()); 6331 const Object& owner = Object::Handle(zone, RawOwner());
6331 // Note that parent pointers in newly instantiated signatures still points to 6332 // Note that parent pointers in newly instantiated signatures still points to
6332 // the original uninstantiated parent signatures. That is not a problem. 6333 // the original uninstantiated parent signatures. That is not a problem.
6333 const Function& parent = Function::Handle(zone, parent_function()); 6334 const Function& parent = Function::Handle(zone, parent_function());
6334 ASSERT(!HasInstantiatedSignature()); 6335 ASSERT(!HasInstantiatedSignature());
6335 Function& sig = Function::Handle( 6336
6336 zone, Function::NewSignatureFunction(owner, parent, 6337 Function& sig = Function::Handle(zone, Function::null());
6337 TokenPosition::kNoSource, space)); 6338 if (IsConvertedClosureFunction()) {
6338 sig.set_type_parameters(TypeArguments::Handle(zone, type_parameters())); 6339 sig = Function::NewConvertedClosureFunction(
6340 String::Handle(zone, name()), parent, TokenPosition::kNoSource);
6341 // TODO(sjindel): Kernel generic methods undone. Handle type parameters
6342 // correctly when generic closures are supported. Until then, all type
6343 // parameters to this target are used for captured type variables, so they
6344 // aren't relevant to the type of the function.
6345 sig.set_type_parameters(TypeArguments::Handle(zone, TypeArguments::null()));
6346 } else {
6347 sig = Function::NewSignatureFunction(owner, parent,
6348 TokenPosition::kNoSource, space);
6349 sig.set_type_parameters(TypeArguments::Handle(zone, type_parameters()));
6350 }
6351
6339 AbstractType& type = AbstractType::Handle(zone, result_type()); 6352 AbstractType& type = AbstractType::Handle(zone, result_type());
6340 if (!type.IsInstantiated()) { 6353 if (!type.IsInstantiated()) {
6341 type = 6354 type =
6342 type.InstantiateFrom(instantiator_type_arguments, 6355 type.InstantiateFrom(instantiator_type_arguments,
6343 function_type_arguments, NULL, NULL, NULL, space); 6356 function_type_arguments, NULL, NULL, NULL, space);
6344 } 6357 }
6345 sig.set_result_type(type); 6358 sig.set_result_type(type);
6346 const intptr_t num_params = NumParameters(); 6359 const intptr_t num_params = NumParameters();
6347 sig.set_num_fixed_parameters(num_fixed_parameters()); 6360 sig.set_num_fixed_parameters(num_fixed_parameters());
6348 sig.SetNumOptionalParameters(NumOptionalParameters(), 6361 sig.SetNumOptionalParameters(NumOptionalParameters(),
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
6399 bound_trail, space)) { 6412 bound_trail, space)) {
6400 return false; 6413 return false;
6401 } 6414 }
6402 } 6415 }
6403 return true; 6416 return true;
6404 } 6417 }
6405 6418
6406 bool Function::HasSameTypeParametersAndBounds(const Function& other) const { 6419 bool Function::HasSameTypeParametersAndBounds(const Function& other) const {
6407 Thread* thread = Thread::Current(); 6420 Thread* thread = Thread::Current();
6408 Zone* zone = thread->zone(); 6421 Zone* zone = thread->zone();
6422
6409 const intptr_t num_type_params = NumTypeParameters(thread); 6423 const intptr_t num_type_params = NumTypeParameters(thread);
6410 if (num_type_params != other.NumTypeParameters(thread)) { 6424 if (num_type_params != other.NumTypeParameters(thread)) {
6411 return false; 6425 return false;
6412 } 6426 }
6413 if (num_type_params > 0) { 6427 if (num_type_params > 0) {
6414 const TypeArguments& type_params = 6428 const TypeArguments& type_params =
6415 TypeArguments::Handle(zone, type_parameters()); 6429 TypeArguments::Handle(zone, type_parameters());
6416 ASSERT(!type_params.IsNull()); 6430 ASSERT(!type_params.IsNull());
6417 const TypeArguments& other_type_params = 6431 const TypeArguments& other_type_params =
6418 TypeArguments::Handle(zone, other.type_parameters()); 6432 TypeArguments::Handle(zone, other.type_parameters());
(...skipping 748 matching lines...) Expand 10 before | Expand all | Expand 10 after
7167 pieces.Add(Symbols::RParenArrow()); 7181 pieces.Add(Symbols::RParenArrow());
7168 const AbstractType& res_type = AbstractType::Handle(zone, result_type()); 7182 const AbstractType& res_type = AbstractType::Handle(zone, result_type());
7169 name = res_type.BuildName(name_visibility); 7183 name = res_type.BuildName(name_visibility);
7170 pieces.Add(name); 7184 pieces.Add(name);
7171 return Symbols::FromConcatAll(thread, pieces); 7185 return Symbols::FromConcatAll(thread, pieces);
7172 } 7186 }
7173 7187
7174 bool Function::HasInstantiatedSignature(Genericity genericity, 7188 bool Function::HasInstantiatedSignature(Genericity genericity,
7175 intptr_t num_free_fun_type_params, 7189 intptr_t num_free_fun_type_params,
7176 TrailPtr trail) const { 7190 TrailPtr trail) const {
7191 // This function works differently for converted closures.
7192 //
7193 // Unlike regular closures, it's not possible to know which type parameters
7194 // are supposed to come from parent functions or classes and which are
7195 // actually parameters to the closure it represents. For example, consider:
7196 //
7197 // class C<T> {
7198 // getf() => (T x) { return x; }
7199 // }
7200 //
7201 // class D {
7202 // getf() {
7203 // dynamic fn<T>(T x) { return x; }
7204 // return fn;
7205 // }
7206 // }
7207 //
7208 // The signature of `fn` as a converted closure will in both cases look like
7209 // `<T>(T) => dynamic`, because the signaute of the converted closure function
7210 // is the same as it's top-level target function. However, in the first case
7211 // the closure's type is instantiated, and in the second case it's not.
7212 //
7213 // Since we can never assume a converted closure is instantiated if it has any
7214 // type parameters, we always return true in these cases.
7215 if (IsConvertedClosureFunction()) {
7216 return genericity == kCurrentClass || NumTypeParameters() == 0;
7217 }
7218
7177 if (genericity != kCurrentClass) { 7219 if (genericity != kCurrentClass) {
7178 // A generic typedef may declare a non-generic function type and get 7220 // A generic typedef may declare a non-generic function type and get
7179 // instantiated with unrelated function type parameters. In that case, its 7221 // instantiated with unrelated function type parameters. In that case, its
7180 // signature is still uninstantiated, because these type parameters are 7222 // signature is still uninstantiated, because these type parameters are
7181 // free (they are not declared by the typedef). 7223 // free (they are not declared by the typedef).
7182 // For that reason, we only adjust num_free_fun_type_params if this 7224 // For that reason, we only adjust num_free_fun_type_params if this
7183 // signature is generic or has a generic parent. 7225 // signature is generic or has a generic parent.
7184 if (IsGeneric() || HasGenericParent()) { 7226 if (IsGeneric() || HasGenericParent()) {
7185 // We only consider the function type parameters declared by the parents 7227 // We only consider the function type parameters declared by the parents
7186 // of this signature function as free. 7228 // of this signature function as free.
(...skipping 8167 matching lines...) Expand 10 before | Expand all | Expand 10 after
15354 instantiated_other.IsDartFunctionType()) { 15396 instantiated_other.IsDartFunctionType()) {
15355 return true; 15397 return true;
15356 } 15398 }
15357 } 15399 }
15358 if (!instantiated_other.IsFunctionType()) { 15400 if (!instantiated_other.IsFunctionType()) {
15359 return false; 15401 return false;
15360 } 15402 }
15361 Function& other_signature = 15403 Function& other_signature =
15362 Function::Handle(zone, Type::Cast(instantiated_other).signature()); 15404 Function::Handle(zone, Type::Cast(instantiated_other).signature());
15363 Function& sig_fun = Function::Handle(zone, Closure::Cast(*this).function()); 15405 Function& sig_fun = Function::Handle(zone, Closure::Cast(*this).function());
15364 if (sig_fun.IsConvertedClosureFunction()) {
15365 const String& closure_name = String::Handle(zone, sig_fun.name());
15366 const Function& new_sig_fun = Function::Handle(
15367 zone,
15368 Function::NewConvertedClosureFunction(
15369 closure_name, Function::Handle(zone, sig_fun.parent_function()),
15370 TokenPosition::kNoSource));
15371
15372 new_sig_fun.set_type_parameters(
15373 TypeArguments::Handle(zone, sig_fun.type_parameters()));
15374 new_sig_fun.set_result_type(
15375 AbstractType::Handle(zone, sig_fun.result_type()));
15376 new_sig_fun.set_end_token_pos(TokenPosition::kNoSource);
15377
15378 new_sig_fun.set_is_debuggable(false);
15379 new_sig_fun.set_is_visible(false);
15380
15381 // The converted closed top-level function type should have its first
15382 // required optional parameter, i.e. context, removed.
15383 const int num_fixed_params = sig_fun.num_fixed_parameters() - 1;
15384 const int num_opt_params = sig_fun.NumOptionalParameters();
15385 const bool has_opt_pos_params = sig_fun.HasOptionalPositionalParameters();
15386 const int num_params = num_fixed_params + num_opt_params;
15387 new_sig_fun.set_num_fixed_parameters(num_fixed_params);
15388 new_sig_fun.SetNumOptionalParameters(num_opt_params, has_opt_pos_params);
15389 new_sig_fun.set_parameter_types(
15390 Array::Handle(zone, Array::New(num_params, Heap::kOld)));
15391 new_sig_fun.set_parameter_names(
15392 Array::Handle(zone, Array::New(num_params, Heap::kOld)));
15393 AbstractType& param_type = AbstractType::Handle(zone);
15394 String& param_name = String::Handle(zone);
15395 for (int i = 0; i < num_params; i++) {
15396 param_type = sig_fun.ParameterTypeAt(i + 1);
15397 new_sig_fun.SetParameterTypeAt(i, param_type);
15398 param_name = sig_fun.ParameterNameAt(i + 1);
15399 new_sig_fun.SetParameterNameAt(i, param_name);
15400 }
15401
15402 sig_fun = new_sig_fun.raw();
15403 }
15404 if (!sig_fun.HasInstantiatedSignature()) { 15406 if (!sig_fun.HasInstantiatedSignature()) {
15405 const TypeArguments& instantiator_type_arguments = TypeArguments::Handle( 15407 const TypeArguments& instantiator_type_arguments = TypeArguments::Handle(
15406 zone, Closure::Cast(*this).instantiator_type_arguments()); 15408 zone, Closure::Cast(*this).instantiator_type_arguments());
15407 const TypeArguments& function_type_arguments = TypeArguments::Handle( 15409 const TypeArguments& function_type_arguments = TypeArguments::Handle(
15408 zone, Closure::Cast(*this).function_type_arguments()); 15410 zone, Closure::Cast(*this).function_type_arguments());
15409 sig_fun = sig_fun.InstantiateSignatureFrom( 15411 sig_fun = sig_fun.InstantiateSignatureFrom(
15410 instantiator_type_arguments, function_type_arguments, Heap::kOld); 15412 instantiator_type_arguments, function_type_arguments, Heap::kOld);
15411 } 15413 }
15412 return sig_fun.IsSubtypeOf(other_signature, bound_error, NULL, Heap::kOld); 15414 return sig_fun.IsSubtypeOf(other_signature, bound_error, NULL, Heap::kOld);
15413 } 15415 }
(...skipping 7054 matching lines...) Expand 10 before | Expand all | Expand 10 after
22468 } 22470 }
22469 return UserTag::null(); 22471 return UserTag::null();
22470 } 22472 }
22471 22473
22472 const char* UserTag::ToCString() const { 22474 const char* UserTag::ToCString() const {
22473 const String& tag_label = String::Handle(label()); 22475 const String& tag_label = String::Handle(label());
22474 return tag_label.ToCString(); 22476 return tag_label.ToCString();
22475 } 22477 }
22476 22478
22477 } // namespace dart 22479 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/kernel_binary_flowgraph.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698