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

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

Issue 23465004: More cleanup related to malformed and malbounded types. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/os_linux.cc » ('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) 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/cpu.h" 10 #include "vm/cpu.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000, 54 DEFINE_FLAG(int, huge_method_cutoff_in_code_size, 200000,
55 "Huge method cutoff in unoptimized code size (in bytes)."); 55 "Huge method cutoff in unoptimized code size (in bytes).");
56 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false, 56 DEFINE_FLAG(bool, throw_on_javascript_int_overflow, false,
57 "Throw an exception when the result of an integer calculation will not " 57 "Throw an exception when the result of an integer calculation will not "
58 "fit into a javascript integer."); 58 "fit into a javascript integer.");
59 DECLARE_FLAG(bool, trace_compiler); 59 DECLARE_FLAG(bool, trace_compiler);
60 DECLARE_FLAG(bool, eliminate_type_checks); 60 DECLARE_FLAG(bool, eliminate_type_checks);
61 DECLARE_FLAG(bool, enable_type_checks); 61 DECLARE_FLAG(bool, enable_type_checks);
62 DECLARE_FLAG(bool, trace_deoptimization); 62 DECLARE_FLAG(bool, trace_deoptimization);
63 DECLARE_FLAG(bool, trace_deoptimization_verbose); 63 DECLARE_FLAG(bool, trace_deoptimization_verbose);
64 DECLARE_FLAG(bool, error_on_malformed_type); 64 DECLARE_FLAG(bool, error_on_bad_type);
65 DECLARE_FLAG(bool, error_on_bad_override); 65 DECLARE_FLAG(bool, error_on_bad_override);
66 66
67 static const char* kGetterPrefix = "get:"; 67 static const char* kGetterPrefix = "get:";
68 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix); 68 static const intptr_t kGetterPrefixLength = strlen(kGetterPrefix);
69 static const char* kSetterPrefix = "set:"; 69 static const char* kSetterPrefix = "set:";
70 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix); 70 static const intptr_t kSetterPrefixLength = strlen(kSetterPrefix);
71 71
72 cpp_vtable Object::handle_vtable_ = 0; 72 cpp_vtable Object::handle_vtable_ = 0;
73 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 }; 73 cpp_vtable Object::builtin_vtables_[kNumPredefinedCids] = { 0 };
74 cpp_vtable Smi::handle_vtable_ = 0; 74 cpp_vtable Smi::handle_vtable_ = 0;
(...skipping 2386 matching lines...) Expand 10 before | Expand all | Expand 10 after
2461 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T. 2461 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T.
2462 // Type S is specified by this class parameterized with 'type_arguments', and 2462 // Type S is specified by this class parameterized with 'type_arguments', and
2463 // type T by class 'other' parameterized with 'other_type_arguments'. 2463 // type T by class 'other' parameterized with 'other_type_arguments'.
2464 // This class and class 'other' do not need to be finalized, however, they must 2464 // This class and class 'other' do not need to be finalized, however, they must
2465 // be resolved as well as their interfaces. 2465 // be resolved as well as their interfaces.
2466 bool Class::TypeTest( 2466 bool Class::TypeTest(
2467 TypeTestKind test_kind, 2467 TypeTestKind test_kind,
2468 const AbstractTypeArguments& type_arguments, 2468 const AbstractTypeArguments& type_arguments,
2469 const Class& other, 2469 const Class& other,
2470 const AbstractTypeArguments& other_type_arguments, 2470 const AbstractTypeArguments& other_type_arguments,
2471 Error* malformed_error) const { 2471 Error* bound_error) const {
2472 ASSERT(!IsVoidClass()); 2472 ASSERT(!IsVoidClass());
2473 // Check for DynamicType. 2473 // Check for DynamicType.
2474 // Each occurrence of DynamicType in type T is interpreted as the dynamic 2474 // Each occurrence of DynamicType in type T is interpreted as the dynamic
2475 // type, a supertype of all types. 2475 // type, a supertype of all types.
2476 if (other.IsDynamicClass()) { 2476 if (other.IsDynamicClass()) {
2477 return true; 2477 return true;
2478 } 2478 }
2479 // In the case of a subtype test, each occurrence of DynamicType in type S is 2479 // In the case of a subtype test, each occurrence of DynamicType in type S is
2480 // interpreted as the bottom type, a subtype of all types. 2480 // interpreted as the bottom type, a subtype of all types.
2481 // However, DynamicType is not more specific than any type. 2481 // However, DynamicType is not more specific than any type.
(...skipping 26 matching lines...) Expand all
2508 } 2508 }
2509 if (type_arguments.IsNull() || type_arguments.IsRaw(len)) { 2509 if (type_arguments.IsNull() || type_arguments.IsRaw(len)) {
2510 // Other type can't be more specific than this one because for that 2510 // Other type can't be more specific than this one because for that
2511 // it would have to have all dynamic type arguments which is checked 2511 // it would have to have all dynamic type arguments which is checked
2512 // above. 2512 // above.
2513 return test_kind == kIsSubtypeOf; 2513 return test_kind == kIsSubtypeOf;
2514 } 2514 }
2515 return type_arguments.TypeTest(test_kind, 2515 return type_arguments.TypeTest(test_kind,
2516 other_type_arguments, 2516 other_type_arguments,
2517 len, 2517 len,
2518 malformed_error); 2518 bound_error);
2519 } 2519 }
2520 const bool other_is_function_class = other.IsFunctionClass(); 2520 const bool other_is_function_class = other.IsFunctionClass();
2521 if (other.IsSignatureClass() || other_is_function_class) { 2521 if (other.IsSignatureClass() || other_is_function_class) {
2522 const Function& other_fun = Function::Handle(other.signature_function()); 2522 const Function& other_fun = Function::Handle(other.signature_function());
2523 if (IsSignatureClass()) { 2523 if (IsSignatureClass()) {
2524 if (other_is_function_class) { 2524 if (other_is_function_class) {
2525 return true; 2525 return true;
2526 } 2526 }
2527 // Check for two function types. 2527 // Check for two function types.
2528 const Function& fun = Function::Handle(signature_function()); 2528 const Function& fun = Function::Handle(signature_function());
2529 return fun.TypeTest(test_kind, 2529 return fun.TypeTest(test_kind,
2530 type_arguments, 2530 type_arguments,
2531 other_fun, 2531 other_fun,
2532 other_type_arguments, 2532 other_type_arguments,
2533 malformed_error); 2533 bound_error);
2534 } 2534 }
2535 // Check if type S has a call() method of function type T. 2535 // Check if type S has a call() method of function type T.
2536 Function& function = 2536 Function& function =
2537 Function::Handle(LookupDynamicFunction(Symbols::Call())); 2537 Function::Handle(LookupDynamicFunction(Symbols::Call()));
2538 if (function.IsNull()) { 2538 if (function.IsNull()) {
2539 // Walk up the super_class chain. 2539 // Walk up the super_class chain.
2540 Class& cls = Class::Handle(SuperClass()); 2540 Class& cls = Class::Handle(SuperClass());
2541 while (!cls.IsNull() && function.IsNull()) { 2541 while (!cls.IsNull() && function.IsNull()) {
2542 function = cls.LookupDynamicFunction(Symbols::Call()); 2542 function = cls.LookupDynamicFunction(Symbols::Call());
2543 cls = cls.SuperClass(); 2543 cls = cls.SuperClass();
2544 } 2544 }
2545 } 2545 }
2546 if (!function.IsNull()) { 2546 if (!function.IsNull()) {
2547 if (other_is_function_class || 2547 if (other_is_function_class ||
2548 function.TypeTest(test_kind, 2548 function.TypeTest(test_kind,
2549 type_arguments, 2549 type_arguments,
2550 other_fun, 2550 other_fun,
2551 other_type_arguments, 2551 other_type_arguments,
2552 malformed_error)) { 2552 bound_error)) {
2553 return true; 2553 return true;
2554 } 2554 }
2555 } 2555 }
2556 } 2556 }
2557 // Check for 'direct super type' specified in the implements clause 2557 // Check for 'direct super type' specified in the implements clause
2558 // and check for transitivity at the same time. 2558 // and check for transitivity at the same time.
2559 Array& interfaces = Array::Handle(this->interfaces()); 2559 Array& interfaces = Array::Handle(this->interfaces());
2560 AbstractType& interface = AbstractType::Handle(); 2560 AbstractType& interface = AbstractType::Handle();
2561 Class& interface_class = Class::Handle(); 2561 Class& interface_class = Class::Handle();
2562 AbstractTypeArguments& interface_args = AbstractTypeArguments::Handle(); 2562 AbstractTypeArguments& interface_args = AbstractTypeArguments::Handle();
2563 Error& args_malformed_error = Error::Handle(); 2563 Error& args_bound_error = Error::Handle();
2564 for (intptr_t i = 0; i < interfaces.Length(); i++) { 2564 for (intptr_t i = 0; i < interfaces.Length(); i++) {
2565 interface ^= interfaces.At(i); 2565 interface ^= interfaces.At(i);
2566 if (!interface.IsFinalized()) { 2566 if (!interface.IsFinalized()) {
2567 // We may be checking bounds at finalization time. Skipping this 2567 // We may be checking bounds at finalization time. Skipping this
2568 // unfinalized interface will postpone bound checking to run time. 2568 // unfinalized interface will postpone bound checking to run time.
2569 continue; 2569 continue;
2570 } 2570 }
2571 interface_class = interface.type_class(); 2571 interface_class = interface.type_class();
2572 interface_args = interface.arguments(); 2572 interface_args = interface.arguments();
2573 if (!interface_args.IsNull() && !interface_args.IsInstantiated()) { 2573 if (!interface_args.IsNull() && !interface_args.IsInstantiated()) {
2574 // This type class implements an interface that is parameterized with 2574 // This type class implements an interface that is parameterized with
2575 // generic type(s), e.g. it implements List<T>. 2575 // generic type(s), e.g. it implements List<T>.
2576 // The uninstantiated type T must be instantiated using the type 2576 // The uninstantiated type T must be instantiated using the type
2577 // parameters of this type before performing the type test. 2577 // parameters of this type before performing the type test.
2578 // The type arguments of this type that are referred to by the type 2578 // The type arguments of this type that are referred to by the type
2579 // parameters of the interface are at the end of the type vector, 2579 // parameters of the interface are at the end of the type vector,
2580 // after the type arguments of the super type of this type. 2580 // after the type arguments of the super type of this type.
2581 // The index of the type parameters is adjusted upon finalization. 2581 // The index of the type parameters is adjusted upon finalization.
2582 args_malformed_error = Error::null(); 2582 args_bound_error = Error::null();
2583 interface_args = interface_args.InstantiateFrom(type_arguments, 2583 interface_args = interface_args.InstantiateFrom(type_arguments,
2584 &args_malformed_error); 2584 &args_bound_error);
2585 if (!args_malformed_error.IsNull()) { 2585 if (!args_bound_error.IsNull()) {
2586 // Return the first malformed error to the caller if it requests it. 2586 // Return the first bound error to the caller if it requests it.
2587 if ((malformed_error != NULL) && malformed_error->IsNull()) { 2587 if ((bound_error != NULL) && bound_error->IsNull()) {
2588 *malformed_error = args_malformed_error.raw(); 2588 *bound_error = args_bound_error.raw();
2589 } 2589 }
2590 continue; // Another interface may work better. 2590 continue; // Another interface may work better.
2591 } 2591 }
2592 } 2592 }
2593 if (interface_class.TypeTest(test_kind, 2593 if (interface_class.TypeTest(test_kind,
2594 interface_args, 2594 interface_args,
2595 other, 2595 other,
2596 other_type_arguments, 2596 other_type_arguments,
2597 malformed_error)) { 2597 bound_error)) {
2598 return true; 2598 return true;
2599 } 2599 }
2600 } 2600 }
2601 const Class& super_class = Class::Handle(SuperClass()); 2601 const Class& super_class = Class::Handle(SuperClass());
2602 if (super_class.IsNull()) { 2602 if (super_class.IsNull()) {
2603 return false; 2603 return false;
2604 } 2604 }
2605 // Instead of truncating the type argument vector to the length of the super 2605 // Instead of truncating the type argument vector to the length of the super
2606 // type argument vector, we make sure that the code works with a vector that 2606 // type argument vector, we make sure that the code works with a vector that
2607 // is longer than necessary. 2607 // is longer than necessary.
2608 return super_class.TypeTest(test_kind, 2608 return super_class.TypeTest(test_kind,
2609 type_arguments, 2609 type_arguments,
2610 other, 2610 other,
2611 other_type_arguments, 2611 other_type_arguments,
2612 malformed_error); 2612 bound_error);
2613 } 2613 }
2614 2614
2615 2615
2616 bool Class::IsTopLevel() const { 2616 bool Class::IsTopLevel() const {
2617 return Name() == Symbols::TopLevel().raw(); 2617 return Name() == Symbols::TopLevel().raw();
2618 } 2618 }
2619 2619
2620 2620
2621 RawFunction* Class::LookupDynamicFunction(const String& name) const { 2621 RawFunction* Class::LookupDynamicFunction(const String& name) const {
2622 return LookupFunction(name, kInstance); 2622 return LookupFunction(name, kInstance);
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
3158 } 3158 }
3159 if (other_arguments.IsNull()) { 3159 if (other_arguments.IsNull()) {
3160 return arguments.IsDynamicTypes(false, arguments.Length()); 3160 return arguments.IsDynamicTypes(false, arguments.Length());
3161 } 3161 }
3162 return arguments.Equals(other_arguments); 3162 return arguments.Equals(other_arguments);
3163 } 3163 }
3164 3164
3165 3165
3166 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom( 3166 RawAbstractTypeArguments* AbstractTypeArguments::InstantiateFrom(
3167 const AbstractTypeArguments& instantiator_type_arguments, 3167 const AbstractTypeArguments& instantiator_type_arguments,
3168 Error* malformed_error) const { 3168 Error* bound_error) const {
3169 // AbstractTypeArguments is an abstract class. 3169 // AbstractTypeArguments is an abstract class.
3170 UNREACHABLE(); 3170 UNREACHABLE();
3171 return NULL; 3171 return NULL;
3172 } 3172 }
3173 3173
3174 3174
3175 bool AbstractTypeArguments::IsDynamicTypes(bool raw_instantiated, 3175 bool AbstractTypeArguments::IsDynamicTypes(bool raw_instantiated,
3176 intptr_t len) const { 3176 intptr_t len) const {
3177 ASSERT(Length() >= len); 3177 ASSERT(Length() >= len);
3178 AbstractType& type = AbstractType::Handle(); 3178 AbstractType& type = AbstractType::Handle();
(...skipping 17 matching lines...) Expand all
3196 return false; 3196 return false;
3197 } 3197 }
3198 } 3198 }
3199 return true; 3199 return true;
3200 } 3200 }
3201 3201
3202 3202
3203 bool AbstractTypeArguments::TypeTest(TypeTestKind test_kind, 3203 bool AbstractTypeArguments::TypeTest(TypeTestKind test_kind,
3204 const AbstractTypeArguments& other, 3204 const AbstractTypeArguments& other,
3205 intptr_t len, 3205 intptr_t len,
3206 Error* malformed_error) const { 3206 Error* bound_error) const {
3207 ASSERT(Length() >= len); 3207 ASSERT(Length() >= len);
3208 ASSERT(!other.IsNull()); 3208 ASSERT(!other.IsNull());
3209 ASSERT(other.Length() >= len); 3209 ASSERT(other.Length() >= len);
3210 AbstractType& type = AbstractType::Handle(); 3210 AbstractType& type = AbstractType::Handle();
3211 AbstractType& other_type = AbstractType::Handle(); 3211 AbstractType& other_type = AbstractType::Handle();
3212 for (intptr_t i = 0; i < len; i++) { 3212 for (intptr_t i = 0; i < len; i++) {
3213 type = TypeAt(i); 3213 type = TypeAt(i);
3214 ASSERT(!type.IsNull()); 3214 ASSERT(!type.IsNull());
3215 other_type = other.TypeAt(i); 3215 other_type = other.TypeAt(i);
3216 ASSERT(!other_type.IsNull()); 3216 ASSERT(!other_type.IsNull());
3217 if (!type.TypeTest(test_kind, other_type, malformed_error)) { 3217 if (!type.TypeTest(test_kind, other_type, bound_error)) {
3218 return false; 3218 return false;
3219 } 3219 }
3220 } 3220 }
3221 return true; 3221 return true;
3222 } 3222 }
3223 3223
3224 3224
3225 const char* AbstractTypeArguments::ToCString() const { 3225 const char* AbstractTypeArguments::ToCString() const {
3226 // AbstractTypeArguments is an abstract class, valid only for representing 3226 // AbstractTypeArguments is an abstract class, valid only for representing
3227 // null. 3227 // null.
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
3389 if (!type_args.IsNull() && type_args.IsBounded()) { 3389 if (!type_args.IsNull() && type_args.IsBounded()) {
3390 return true; 3390 return true;
3391 } 3391 }
3392 } 3392 }
3393 return false; 3393 return false;
3394 } 3394 }
3395 3395
3396 3396
3397 RawAbstractTypeArguments* TypeArguments::InstantiateFrom( 3397 RawAbstractTypeArguments* TypeArguments::InstantiateFrom(
3398 const AbstractTypeArguments& instantiator_type_arguments, 3398 const AbstractTypeArguments& instantiator_type_arguments,
3399 Error* malformed_error) const { 3399 Error* bound_error) const {
3400 ASSERT(!IsInstantiated()); 3400 ASSERT(!IsInstantiated());
3401 if (!instantiator_type_arguments.IsNull() && 3401 if (!instantiator_type_arguments.IsNull() &&
3402 IsUninstantiatedIdentity() && 3402 IsUninstantiatedIdentity() &&
3403 (instantiator_type_arguments.Length() == Length())) { 3403 (instantiator_type_arguments.Length() == Length())) {
3404 return instantiator_type_arguments.raw(); 3404 return instantiator_type_arguments.raw();
3405 } 3405 }
3406 const intptr_t num_types = Length(); 3406 const intptr_t num_types = Length();
3407 TypeArguments& instantiated_array = 3407 TypeArguments& instantiated_array =
3408 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); 3408 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew));
3409 AbstractType& type = AbstractType::Handle(); 3409 AbstractType& type = AbstractType::Handle();
3410 for (intptr_t i = 0; i < num_types; i++) { 3410 for (intptr_t i = 0; i < num_types; i++) {
3411 type = TypeAt(i); 3411 type = TypeAt(i);
3412 if (!type.IsInstantiated()) { 3412 if (!type.IsInstantiated()) {
3413 type = type.InstantiateFrom(instantiator_type_arguments, malformed_error); 3413 type = type.InstantiateFrom(instantiator_type_arguments, bound_error);
3414 } 3414 }
3415 instantiated_array.SetTypeAt(i, type); 3415 instantiated_array.SetTypeAt(i, type);
3416 } 3416 }
3417 return instantiated_array.raw(); 3417 return instantiated_array.raw();
3418 } 3418 }
3419 3419
3420 3420
3421 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { 3421 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) {
3422 if (len < 0 || len > kMaxElements) { 3422 if (len < 0 || len > kMaxElements) {
3423 // This should be caught before we reach here. 3423 // This should be caught before we reach here.
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
3586 uninstantiated_type_arguments()).Length(); 3586 uninstantiated_type_arguments()).Length();
3587 } 3587 }
3588 3588
3589 3589
3590 RawAbstractType* InstantiatedTypeArguments::TypeAt(intptr_t index) const { 3590 RawAbstractType* InstantiatedTypeArguments::TypeAt(intptr_t index) const {
3591 AbstractType& type = AbstractType::Handle(AbstractTypeArguments::Handle( 3591 AbstractType& type = AbstractType::Handle(AbstractTypeArguments::Handle(
3592 uninstantiated_type_arguments()).TypeAt(index)); 3592 uninstantiated_type_arguments()).TypeAt(index));
3593 if (!type.IsInstantiated()) { 3593 if (!type.IsInstantiated()) {
3594 const AbstractTypeArguments& instantiator_type_args = 3594 const AbstractTypeArguments& instantiator_type_args =
3595 AbstractTypeArguments::Handle(instantiator_type_arguments()); 3595 AbstractTypeArguments::Handle(instantiator_type_arguments());
3596 Error& malformed_error = Error::Handle(); 3596 Error& bound_error = Error::Handle();
3597 type = type.InstantiateFrom(instantiator_type_args, &malformed_error); 3597 type = type.InstantiateFrom(instantiator_type_args, &bound_error);
3598 // InstantiatedTypeArguments cannot include unchecked bounds. 3598 // InstantiatedTypeArguments cannot include unchecked bounds.
3599 // In the presence of unchecked bounds, no InstantiatedTypeArguments are 3599 // In the presence of unchecked bounds, no InstantiatedTypeArguments are
3600 // allocated, but the type arguments are instantiated individually and their 3600 // allocated, but the type arguments are instantiated individually and their
3601 // bounds are checked. 3601 // bounds are checked.
3602 ASSERT(malformed_error.IsNull()); 3602 ASSERT(bound_error.IsNull());
3603 } 3603 }
3604 return type.raw(); 3604 return type.raw();
3605 } 3605 }
3606 3606
3607 3607
3608 void InstantiatedTypeArguments::SetTypeAt(intptr_t index, 3608 void InstantiatedTypeArguments::SetTypeAt(intptr_t index,
3609 const AbstractType& value) const { 3609 const AbstractType& value) const {
3610 // We only replace individual argument types during resolution at compile 3610 // We only replace individual argument types during resolution at compile
3611 // time, when no type parameters are instantiated yet. 3611 // time, when no type parameters are instantiated yet.
3612 UNREACHABLE(); 3612 UNREACHABLE();
(...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after
4412 4412
4413 4413
4414 const char* Function::ToFullyQualifiedCString() const { 4414 const char* Function::ToFullyQualifiedCString() const {
4415 char* chars = NULL; 4415 char* chars = NULL;
4416 ConstructFunctionFullyQualifiedCString(*this, &chars, 0); 4416 ConstructFunctionFullyQualifiedCString(*this, &chars, 0);
4417 return chars; 4417 return chars;
4418 } 4418 }
4419 4419
4420 4420
4421 bool Function::HasCompatibleParametersWith(const Function& other, 4421 bool Function::HasCompatibleParametersWith(const Function& other,
4422 Error* error) const { 4422 Error* bound_error) const {
4423 ASSERT(FLAG_error_on_bad_override); 4423 ASSERT(FLAG_error_on_bad_override);
4424 // Check that this function's signature type is a subtype of the other 4424 // Check that this function's signature type is a subtype of the other
4425 // function's signature type. 4425 // function's signature type.
4426 if (!TypeTest(kIsSubtypeOf, Object::null_abstract_type_arguments(), 4426 if (!TypeTest(kIsSubtypeOf, Object::null_abstract_type_arguments(),
4427 other, Object::null_abstract_type_arguments(), error)) { 4427 other, Object::null_abstract_type_arguments(), bound_error)) {
4428 // For more informative error reporting, use the location of the other 4428 // For more informative error reporting, use the location of the other
4429 // function here, since the caller will use the location of this function. 4429 // function here, since the caller will use the location of this function.
4430 *error = FormatError( 4430 *bound_error = FormatError(
4431 *error, // A malformed error if non null. 4431 *bound_error, // A bound error if non null.
4432 Script::Handle(other.script()), 4432 Script::Handle(other.script()),
4433 other.token_pos(), 4433 other.token_pos(),
4434 "signature type '%s' of function '%s' is not a subtype of signature " 4434 "signature type '%s' of function '%s' is not a subtype of signature "
4435 "type '%s' of function '%s'", 4435 "type '%s' of function '%s'",
4436 String::Handle(UserVisibleSignature()).ToCString(), 4436 String::Handle(UserVisibleSignature()).ToCString(),
4437 String::Handle(UserVisibleName()).ToCString(), 4437 String::Handle(UserVisibleName()).ToCString(),
4438 String::Handle(other.UserVisibleSignature()).ToCString(), 4438 String::Handle(other.UserVisibleSignature()).ToCString(),
4439 String::Handle(other.UserVisibleName()).ToCString()); 4439 String::Handle(other.UserVisibleName()).ToCString());
4440 return false; 4440 return false;
4441 } 4441 }
(...skipping 15 matching lines...) Expand all
4457 // parameter of the other function. 4457 // parameter of the other function.
4458 // Note that we do not apply contravariance of parameter types, but covariance 4458 // Note that we do not apply contravariance of parameter types, but covariance
4459 // of both parameter types and result type. 4459 // of both parameter types and result type.
4460 bool Function::TestParameterType( 4460 bool Function::TestParameterType(
4461 TypeTestKind test_kind, 4461 TypeTestKind test_kind,
4462 intptr_t parameter_position, 4462 intptr_t parameter_position,
4463 intptr_t other_parameter_position, 4463 intptr_t other_parameter_position,
4464 const AbstractTypeArguments& type_arguments, 4464 const AbstractTypeArguments& type_arguments,
4465 const Function& other, 4465 const Function& other,
4466 const AbstractTypeArguments& other_type_arguments, 4466 const AbstractTypeArguments& other_type_arguments,
4467 Error* malformed_error) const { 4467 Error* bound_error) const {
4468 AbstractType& other_param_type = 4468 AbstractType& other_param_type =
4469 AbstractType::Handle(other.ParameterTypeAt(other_parameter_position)); 4469 AbstractType::Handle(other.ParameterTypeAt(other_parameter_position));
4470 if (!other_param_type.IsInstantiated()) { 4470 if (!other_param_type.IsInstantiated()) {
4471 other_param_type = other_param_type.InstantiateFrom(other_type_arguments, 4471 other_param_type = other_param_type.InstantiateFrom(other_type_arguments,
4472 malformed_error); 4472 bound_error);
4473 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); 4473 ASSERT((bound_error == NULL) || bound_error->IsNull());
4474 } 4474 }
4475 if (other_param_type.IsDynamicType()) { 4475 if (other_param_type.IsDynamicType()) {
4476 return true; 4476 return true;
4477 } 4477 }
4478 AbstractType& param_type = 4478 AbstractType& param_type =
4479 AbstractType::Handle(ParameterTypeAt(parameter_position)); 4479 AbstractType::Handle(ParameterTypeAt(parameter_position));
4480 if (!param_type.IsInstantiated()) { 4480 if (!param_type.IsInstantiated()) {
4481 param_type = param_type.InstantiateFrom(type_arguments, malformed_error); 4481 param_type = param_type.InstantiateFrom(type_arguments, bound_error);
4482 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); 4482 ASSERT((bound_error == NULL) || bound_error->IsNull());
4483 } 4483 }
4484 if (param_type.IsDynamicType()) { 4484 if (param_type.IsDynamicType()) {
4485 return test_kind == kIsSubtypeOf; 4485 return test_kind == kIsSubtypeOf;
4486 } 4486 }
4487 if (test_kind == kIsSubtypeOf) { 4487 if (test_kind == kIsSubtypeOf) {
4488 if (!param_type.IsSubtypeOf(other_param_type, malformed_error) && 4488 if (!param_type.IsSubtypeOf(other_param_type, bound_error) &&
4489 !other_param_type.IsSubtypeOf(param_type, malformed_error)) { 4489 !other_param_type.IsSubtypeOf(param_type, bound_error)) {
4490 return false; 4490 return false;
4491 } 4491 }
4492 } else { 4492 } else {
4493 ASSERT(test_kind == kIsMoreSpecificThan); 4493 ASSERT(test_kind == kIsMoreSpecificThan);
4494 if (!param_type.IsMoreSpecificThan(other_param_type, malformed_error)) { 4494 if (!param_type.IsMoreSpecificThan(other_param_type, bound_error)) {
4495 return false; 4495 return false;
4496 } 4496 }
4497 } 4497 }
4498 return true; 4498 return true;
4499 } 4499 }
4500 4500
4501 4501
4502 bool Function::TypeTest(TypeTestKind test_kind, 4502 bool Function::TypeTest(TypeTestKind test_kind,
4503 const AbstractTypeArguments& type_arguments, 4503 const AbstractTypeArguments& type_arguments,
4504 const Function& other, 4504 const Function& other,
4505 const AbstractTypeArguments& other_type_arguments, 4505 const AbstractTypeArguments& other_type_arguments,
4506 Error* malformed_error) const { 4506 Error* bound_error) const {
4507 const intptr_t num_fixed_params = num_fixed_parameters(); 4507 const intptr_t num_fixed_params = num_fixed_parameters();
4508 const intptr_t num_opt_pos_params = NumOptionalPositionalParameters(); 4508 const intptr_t num_opt_pos_params = NumOptionalPositionalParameters();
4509 const intptr_t num_opt_named_params = NumOptionalNamedParameters(); 4509 const intptr_t num_opt_named_params = NumOptionalNamedParameters();
4510 const intptr_t other_num_fixed_params = other.num_fixed_parameters(); 4510 const intptr_t other_num_fixed_params = other.num_fixed_parameters();
4511 const intptr_t other_num_opt_pos_params = 4511 const intptr_t other_num_opt_pos_params =
4512 other.NumOptionalPositionalParameters(); 4512 other.NumOptionalPositionalParameters();
4513 const intptr_t other_num_opt_named_params = 4513 const intptr_t other_num_opt_named_params =
4514 other.NumOptionalNamedParameters(); 4514 other.NumOptionalNamedParameters();
4515 // This function requires the same arguments or less and accepts the same 4515 // This function requires the same arguments or less and accepts the same
4516 // arguments or more. 4516 // arguments or more.
4517 // A generative constructor may be compared to a redirecting factory and be 4517 // A generative constructor may be compared to a redirecting factory and be
4518 // compatible although it has an additional phase parameter. 4518 // compatible although it has an additional phase parameter.
4519 // More generally, we can ignore implicit parameters. 4519 // More generally, we can ignore implicit parameters.
4520 const intptr_t num_ignored_params = NumImplicitParameters(); 4520 const intptr_t num_ignored_params = NumImplicitParameters();
4521 const intptr_t other_num_ignored_params = other.NumImplicitParameters(); 4521 const intptr_t other_num_ignored_params = other.NumImplicitParameters();
4522 if (((num_fixed_params - num_ignored_params) > 4522 if (((num_fixed_params - num_ignored_params) >
4523 (other_num_fixed_params - other_num_ignored_params)) || 4523 (other_num_fixed_params - other_num_ignored_params)) ||
4524 ((num_fixed_params - num_ignored_params + num_opt_pos_params) < 4524 ((num_fixed_params - num_ignored_params + num_opt_pos_params) <
4525 (other_num_fixed_params - other_num_ignored_params + 4525 (other_num_fixed_params - other_num_ignored_params +
4526 other_num_opt_pos_params)) || 4526 other_num_opt_pos_params)) ||
4527 (num_opt_named_params < other_num_opt_named_params)) { 4527 (num_opt_named_params < other_num_opt_named_params)) {
4528 return false; 4528 return false;
4529 } 4529 }
4530 // Check the result type. 4530 // Check the result type.
4531 AbstractType& other_res_type = AbstractType::Handle(other.result_type()); 4531 AbstractType& other_res_type = AbstractType::Handle(other.result_type());
4532 if (!other_res_type.IsInstantiated()) { 4532 if (!other_res_type.IsInstantiated()) {
4533 other_res_type = other_res_type.InstantiateFrom(other_type_arguments, 4533 other_res_type = other_res_type.InstantiateFrom(other_type_arguments,
4534 malformed_error); 4534 bound_error);
4535 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); 4535 ASSERT((bound_error == NULL) || bound_error->IsNull());
4536 } 4536 }
4537 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) { 4537 if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) {
4538 AbstractType& res_type = AbstractType::Handle(result_type()); 4538 AbstractType& res_type = AbstractType::Handle(result_type());
4539 if (!res_type.IsInstantiated()) { 4539 if (!res_type.IsInstantiated()) {
4540 res_type = res_type.InstantiateFrom(type_arguments, malformed_error); 4540 res_type = res_type.InstantiateFrom(type_arguments, bound_error);
4541 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); 4541 ASSERT((bound_error == NULL) || bound_error->IsNull());
4542 } 4542 }
4543 if (res_type.IsVoidType()) { 4543 if (res_type.IsVoidType()) {
4544 return false; 4544 return false;
4545 } 4545 }
4546 if (test_kind == kIsSubtypeOf) { 4546 if (test_kind == kIsSubtypeOf) {
4547 if (!res_type.IsSubtypeOf(other_res_type, malformed_error) && 4547 if (!res_type.IsSubtypeOf(other_res_type, bound_error) &&
4548 !other_res_type.IsSubtypeOf(res_type, malformed_error)) { 4548 !other_res_type.IsSubtypeOf(res_type, bound_error)) {
4549 return false; 4549 return false;
4550 } 4550 }
4551 } else { 4551 } else {
4552 ASSERT(test_kind == kIsMoreSpecificThan); 4552 ASSERT(test_kind == kIsMoreSpecificThan);
4553 if (!res_type.IsMoreSpecificThan(other_res_type, malformed_error)) { 4553 if (!res_type.IsMoreSpecificThan(other_res_type, bound_error)) {
4554 return false; 4554 return false;
4555 } 4555 }
4556 } 4556 }
4557 } 4557 }
4558 // Check the types of fixed and optional positional parameters. 4558 // Check the types of fixed and optional positional parameters.
4559 for (intptr_t i = 0; i < (other_num_fixed_params - other_num_ignored_params + 4559 for (intptr_t i = 0; i < (other_num_fixed_params - other_num_ignored_params +
4560 other_num_opt_pos_params); i++) { 4560 other_num_opt_pos_params); i++) {
4561 if (!TestParameterType(test_kind, 4561 if (!TestParameterType(test_kind,
4562 i + num_ignored_params, i + other_num_ignored_params, 4562 i + num_ignored_params, i + other_num_ignored_params,
4563 type_arguments, other, other_type_arguments, 4563 type_arguments, other, other_type_arguments,
4564 malformed_error)) { 4564 bound_error)) {
4565 return false; 4565 return false;
4566 } 4566 }
4567 } 4567 }
4568 // Check the names and types of optional named parameters. 4568 // Check the names and types of optional named parameters.
4569 if (other_num_opt_named_params == 0) { 4569 if (other_num_opt_named_params == 0) {
4570 return true; 4570 return true;
4571 } 4571 }
4572 // Check that for each optional named parameter of type T of the other 4572 // Check that for each optional named parameter of type T of the other
4573 // function type, there exists an optional named parameter of this function 4573 // function type, there exists an optional named parameter of this function
4574 // type with an identical name and with a type S that is a either a subtype 4574 // type with an identical name and with a type S that is a either a subtype
(...skipping 10 matching lines...) Expand all
4585 other_param_name = other.ParameterNameAt(i); 4585 other_param_name = other.ParameterNameAt(i);
4586 ASSERT(other_param_name.IsSymbol()); 4586 ASSERT(other_param_name.IsSymbol());
4587 found_param_name = false; 4587 found_param_name = false;
4588 for (intptr_t j = num_fixed_params; j < num_params; j++) { 4588 for (intptr_t j = num_fixed_params; j < num_params; j++) {
4589 ASSERT(String::Handle(ParameterNameAt(j)).IsSymbol()); 4589 ASSERT(String::Handle(ParameterNameAt(j)).IsSymbol());
4590 if (ParameterNameAt(j) == other_param_name.raw()) { 4590 if (ParameterNameAt(j) == other_param_name.raw()) {
4591 found_param_name = true; 4591 found_param_name = true;
4592 if (!TestParameterType(test_kind, 4592 if (!TestParameterType(test_kind,
4593 j, i, 4593 j, i,
4594 type_arguments, other, other_type_arguments, 4594 type_arguments, other, other_type_arguments,
4595 malformed_error)) { 4595 bound_error)) {
4596 return false; 4596 return false;
4597 } 4597 }
4598 break; 4598 break;
4599 } 4599 }
4600 } 4600 }
4601 if (!found_param_name) { 4601 if (!found_param_name) {
4602 return false; 4602 return false;
4603 } 4603 }
4604 } 4604 }
4605 return true; 4605 return true;
(...skipping 5641 matching lines...) Expand 10 before | Expand all | Expand 10 after
10247 10247
10248 10248
10249 void Instance::SetTypeArguments(const AbstractTypeArguments& value) const { 10249 void Instance::SetTypeArguments(const AbstractTypeArguments& value) const {
10250 const Class& cls = Class::Handle(clazz()); 10250 const Class& cls = Class::Handle(clazz());
10251 intptr_t field_offset = cls.type_arguments_field_offset(); 10251 intptr_t field_offset = cls.type_arguments_field_offset();
10252 ASSERT(field_offset != Class::kNoTypeArguments); 10252 ASSERT(field_offset != Class::kNoTypeArguments);
10253 SetFieldAtOffset(field_offset, value); 10253 SetFieldAtOffset(field_offset, value);
10254 } 10254 }
10255 10255
10256 10256
10257 // TODO(regis): Rename malformed_error to bound_error.
10258 bool Instance::IsInstanceOf(const AbstractType& other, 10257 bool Instance::IsInstanceOf(const AbstractType& other,
10259 const AbstractTypeArguments& other_instantiator, 10258 const AbstractTypeArguments& other_instantiator,
10260 Error* malformed_error) const { 10259 Error* bound_error) const {
10261 ASSERT(other.IsFinalized()); 10260 ASSERT(other.IsFinalized());
10262 ASSERT(!other.IsDynamicType()); 10261 ASSERT(!other.IsDynamicType());
10263 ASSERT(!other.IsMalformed()); 10262 ASSERT(!other.IsMalformed());
10264 ASSERT(!other.IsMalbounded()); 10263 ASSERT(!other.IsMalbounded());
10265 if (other.IsVoidType()) { 10264 if (other.IsVoidType()) {
10266 return false; 10265 return false;
10267 } 10266 }
10268 const Class& cls = Class::Handle(clazz()); 10267 const Class& cls = Class::Handle(clazz());
10269 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle(); 10268 AbstractTypeArguments& type_arguments = AbstractTypeArguments::Handle();
10270 const intptr_t num_type_arguments = cls.NumTypeArguments(); 10269 const intptr_t num_type_arguments = cls.NumTypeArguments();
(...skipping 12 matching lines...) Expand all
10283 // Also, an optimization reuses the type argument vector of the instantiator 10282 // Also, an optimization reuses the type argument vector of the instantiator
10284 // of generic instances when its layout is compatible. 10283 // of generic instances when its layout is compatible.
10285 ASSERT(type_arguments.IsNull() || 10284 ASSERT(type_arguments.IsNull() ||
10286 (type_arguments.Length() >= num_type_arguments)); 10285 (type_arguments.Length() >= num_type_arguments));
10287 } 10286 }
10288 Class& other_class = Class::Handle(); 10287 Class& other_class = Class::Handle();
10289 AbstractTypeArguments& other_type_arguments = AbstractTypeArguments::Handle(); 10288 AbstractTypeArguments& other_type_arguments = AbstractTypeArguments::Handle();
10290 // Note that we may encounter a bound error in checked mode. 10289 // Note that we may encounter a bound error in checked mode.
10291 if (!other.IsInstantiated()) { 10290 if (!other.IsInstantiated()) {
10292 const AbstractType& instantiated_other = AbstractType::Handle( 10291 const AbstractType& instantiated_other = AbstractType::Handle(
10293 other.InstantiateFrom(other_instantiator, malformed_error)); 10292 other.InstantiateFrom(other_instantiator, bound_error));
10294 if ((malformed_error != NULL) && !malformed_error->IsNull()) { 10293 if ((bound_error != NULL) && !bound_error->IsNull()) {
10295 ASSERT(FLAG_enable_type_checks); 10294 ASSERT(FLAG_enable_type_checks);
10296 return false; 10295 return false;
10297 } 10296 }
10298 other_class = instantiated_other.type_class(); 10297 other_class = instantiated_other.type_class();
10299 other_type_arguments = instantiated_other.arguments(); 10298 other_type_arguments = instantiated_other.arguments();
10300 } else { 10299 } else {
10301 other_class = other.type_class(); 10300 other_class = other.type_class();
10302 other_type_arguments = other.arguments(); 10301 other_type_arguments = other.arguments();
10303 } 10302 }
10304 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments, 10303 return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments,
10305 malformed_error); 10304 bound_error);
10306 } 10305 }
10307 10306
10308 10307
10309 void Instance::SetNativeField(int index, intptr_t value) const { 10308 void Instance::SetNativeField(int index, intptr_t value) const {
10310 ASSERT(IsValidNativeIndex(index)); 10309 ASSERT(IsValidNativeIndex(index));
10311 Object& native_fields = Object::Handle(*NativeFieldsAddr()); 10310 Object& native_fields = Object::Handle(*NativeFieldsAddr());
10312 if (native_fields.IsNull()) { 10311 if (native_fields.IsNull()) {
10313 // Allocate backing storage for the native fields. 10312 // Allocate backing storage for the native fields.
10314 const Class& cls = Class::Handle(clazz()); 10313 const Class& cls = Class::Handle(clazz());
10315 int num_native_fields = cls.num_native_fields(); 10314 int num_native_fields = cls.num_native_fields();
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
10510 10509
10511 bool AbstractType::Equals(const Instance& other) const { 10510 bool AbstractType::Equals(const Instance& other) const {
10512 // AbstractType is an abstract class. 10511 // AbstractType is an abstract class.
10513 ASSERT(raw() == AbstractType::null()); 10512 ASSERT(raw() == AbstractType::null());
10514 return other.IsNull(); 10513 return other.IsNull();
10515 } 10514 }
10516 10515
10517 10516
10518 RawAbstractType* AbstractType::InstantiateFrom( 10517 RawAbstractType* AbstractType::InstantiateFrom(
10519 const AbstractTypeArguments& instantiator_type_arguments, 10518 const AbstractTypeArguments& instantiator_type_arguments,
10520 Error* malformed_error) const { 10519 Error* bound_error) const {
10521 // AbstractType is an abstract class. 10520 // AbstractType is an abstract class.
10522 UNREACHABLE(); 10521 UNREACHABLE();
10523 return NULL; 10522 return NULL;
10524 } 10523 }
10525 10524
10526 10525
10527 RawAbstractType* AbstractType::Canonicalize() const { 10526 RawAbstractType* AbstractType::Canonicalize() const {
10528 // AbstractType is an abstract class. 10527 // AbstractType is an abstract class.
10529 UNREACHABLE(); 10528 UNREACHABLE();
10530 return NULL; 10529 return NULL;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
10680 10679
10681 10680
10682 bool AbstractType::IsFunctionType() const { 10681 bool AbstractType::IsFunctionType() const {
10683 return HasResolvedTypeClass() && 10682 return HasResolvedTypeClass() &&
10684 (type_class() == Type::Handle(Type::Function()).type_class()); 10683 (type_class() == Type::Handle(Type::Function()).type_class());
10685 } 10684 }
10686 10685
10687 10686
10688 bool AbstractType::TypeTest(TypeTestKind test_kind, 10687 bool AbstractType::TypeTest(TypeTestKind test_kind,
10689 const AbstractType& other, 10688 const AbstractType& other,
10690 Error* malformed_error) const { 10689 Error* bound_error) const {
10691 ASSERT(IsResolved()); 10690 ASSERT(IsResolved());
10692 ASSERT(other.IsResolved()); 10691 ASSERT(other.IsResolved());
10693 // In case the type checked in a type test is malformed, the code generator 10692 ASSERT(!IsMalformed());
10693 ASSERT(!other.IsMalformed());
10694 // In case the type checked in a type test is malbounded, the code generator
10694 // may compile a throw instead of a run time call performing the type check. 10695 // may compile a throw instead of a run time call performing the type check.
10695 // However, in checked mode, a function type may include malformed result type 10696 // However, in checked mode, a function type may include malbounded result
10696 // and/or malformed parameter types, which will then be encountered here at 10697 // type and/or malbounded parameter types, which will then be encountered here
10697 // run time. 10698 // at run time.
10698 if (IsMalformed()) { 10699 if (IsMalbounded()) {
10699 ASSERT(FLAG_enable_type_checks); 10700 ASSERT(FLAG_enable_type_checks);
10700 if ((malformed_error != NULL) && malformed_error->IsNull()) { 10701 if ((bound_error != NULL) && bound_error->IsNull()) {
10701 *malformed_error = this->malformed_error(); 10702 const bool is_malbounded = IsMalboundedWithError(bound_error);
10703 ASSERT(is_malbounded);
10702 } 10704 }
10703 return false; 10705 return false;
10704 } 10706 }
10705 if (other.IsMalformed()) { 10707 if (other.IsMalbounded()) {
10706 // Note that 'other' may represent an unresolved bound that is checked at 10708 ASSERT(FLAG_enable_type_checks);
10707 // compile time, even in production mode, in which case the resulting 10709 if ((bound_error != NULL) && bound_error->IsNull()) {
10708 // BoundedType is ignored at run time if in production mode. 10710 const bool other_is_malbounded = other.IsMalboundedWithError(bound_error);
10709 // Therefore, we cannot assert that we are in checked mode here. 10711 ASSERT(other_is_malbounded);
10710 if ((malformed_error != NULL) && malformed_error->IsNull()) {
10711 *malformed_error = other.malformed_error();
10712 } 10712 }
10713 return false; 10713 return false;
10714 } 10714 }
10715 if (IsBoundedType() || other.IsBoundedType()) { 10715 if (IsBoundedType() || other.IsBoundedType()) {
10716 if (Equals(other)) { 10716 if (Equals(other)) {
10717 return true; 10717 return true;
10718 } 10718 }
10719 return false; // TODO(regis): We should return "maybe after instantiation". 10719 return false; // TODO(regis): We should return "maybe after instantiation".
10720 } 10720 }
10721 // Type parameters cannot be handled by Class::TypeTest(). 10721 // Type parameters cannot be handled by Class::TypeTest().
(...skipping 10 matching lines...) Expand all
10732 // uninstantiated at compile time. 10732 // uninstantiated at compile time.
10733 if (IsTypeParameter()) { 10733 if (IsTypeParameter()) {
10734 const TypeParameter& type_param = TypeParameter::Cast(*this); 10734 const TypeParameter& type_param = TypeParameter::Cast(*this);
10735 if (other.IsTypeParameter()) { 10735 if (other.IsTypeParameter()) {
10736 const TypeParameter& other_type_param = TypeParameter::Cast(other); 10736 const TypeParameter& other_type_param = TypeParameter::Cast(other);
10737 if (type_param.Equals(other_type_param)) { 10737 if (type_param.Equals(other_type_param)) {
10738 return true; 10738 return true;
10739 } 10739 }
10740 } 10740 }
10741 const AbstractType& bound = AbstractType::Handle(type_param.bound()); 10741 const AbstractType& bound = AbstractType::Handle(type_param.bound());
10742 if (bound.IsMoreSpecificThan(other, malformed_error)) { 10742 if (bound.IsMoreSpecificThan(other, bound_error)) {
10743 return true; 10743 return true;
10744 } 10744 }
10745 return false; // TODO(regis): We should return "maybe after instantiation". 10745 return false; // TODO(regis): We should return "maybe after instantiation".
10746 } 10746 }
10747 if (other.IsTypeParameter()) { 10747 if (other.IsTypeParameter()) {
10748 return false; // TODO(regis): We should return "maybe after instantiation". 10748 return false; // TODO(regis): We should return "maybe after instantiation".
10749 } 10749 }
10750 const Class& cls = Class::Handle(type_class()); 10750 const Class& cls = Class::Handle(type_class());
10751 return cls.TypeTest(test_kind, 10751 return cls.TypeTest(test_kind,
10752 AbstractTypeArguments::Handle(arguments()), 10752 AbstractTypeArguments::Handle(arguments()),
10753 Class::Handle(other.type_class()), 10753 Class::Handle(other.type_class()),
10754 AbstractTypeArguments::Handle(other.arguments()), 10754 AbstractTypeArguments::Handle(other.arguments()),
10755 malformed_error); 10755 bound_error);
10756 } 10756 }
10757 10757
10758 10758
10759 intptr_t AbstractType::Hash() const { 10759 intptr_t AbstractType::Hash() const {
10760 // AbstractType is an abstract class. 10760 // AbstractType is an abstract class.
10761 UNREACHABLE(); 10761 UNREACHABLE();
10762 return 0; 10762 return 0;
10763 } 10763 }
10764 10764
10765 10765
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
10886 set_type_state(RawType::kBeingFinalized); 10886 set_type_state(RawType::kBeingFinalized);
10887 } 10887 }
10888 10888
10889 10889
10890 bool Type::IsMalformed() const { 10890 bool Type::IsMalformed() const {
10891 return raw_ptr()->malformed_error_ != Error::null(); 10891 return raw_ptr()->malformed_error_ != Error::null();
10892 } 10892 }
10893 10893
10894 10894
10895 bool Type::IsMalboundedWithError(Error* bound_error) const { 10895 bool Type::IsMalboundedWithError(Error* bound_error) const {
10896 if (!FLAG_enable_type_checks && !FLAG_error_on_malformed_type) { 10896 if (!FLAG_enable_type_checks && !FLAG_error_on_bad_type) {
10897 return false; 10897 return false;
10898 } 10898 }
10899 ASSERT(IsFinalized()); 10899 ASSERT(IsResolved());
10900 ASSERT(!IsMalformed()); // Must be checked first. 10900 ASSERT(!IsMalformed()); // Must be checked first.
10901 if (arguments() == AbstractTypeArguments::null()) { 10901 if (arguments() == AbstractTypeArguments::null()) {
10902 return false; 10902 return false;
10903 } 10903 }
10904 const AbstractTypeArguments& type_arguments = 10904 const AbstractTypeArguments& type_arguments =
10905 AbstractTypeArguments::Handle(arguments()); 10905 AbstractTypeArguments::Handle(arguments());
10906 const intptr_t num_type_args = type_arguments.Length(); 10906 const intptr_t num_type_args = type_arguments.Length();
10907 AbstractType& type_arg = AbstractType::Handle(); 10907 AbstractType& type_arg = AbstractType::Handle();
10908 for (intptr_t i = 0; i < num_type_args; i++) { 10908 for (intptr_t i = 0; i < num_type_args; i++) {
10909 type_arg = type_arguments.TypeAt(i); 10909 type_arg = type_arguments.TypeAt(i);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
10997 return false; 10997 return false;
10998 } 10998 }
10999 const AbstractTypeArguments& args = 10999 const AbstractTypeArguments& args =
11000 AbstractTypeArguments::Handle(arguments()); 11000 AbstractTypeArguments::Handle(arguments());
11001 return args.IsNull() || args.IsInstantiated(); 11001 return args.IsNull() || args.IsInstantiated();
11002 } 11002 }
11003 11003
11004 11004
11005 RawAbstractType* Type::InstantiateFrom( 11005 RawAbstractType* Type::InstantiateFrom(
11006 const AbstractTypeArguments& instantiator_type_arguments, 11006 const AbstractTypeArguments& instantiator_type_arguments,
11007 Error* malformed_error) const { 11007 Error* bound_error) const {
11008 ASSERT(IsResolved()); 11008 ASSERT(IsResolved());
11009 ASSERT(!IsInstantiated()); 11009 ASSERT(!IsInstantiated());
11010 // Return the uninstantiated type unchanged if malformed. No copy needed. 11010 // Return the uninstantiated type unchanged if malformed. No copy needed.
11011 if (IsMalformed()) { 11011 if (IsMalformed()) {
11012 return raw(); 11012 return raw();
11013 } 11013 }
11014 AbstractTypeArguments& type_arguments = 11014 AbstractTypeArguments& type_arguments =
11015 AbstractTypeArguments::Handle(arguments()); 11015 AbstractTypeArguments::Handle(arguments());
11016 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, 11016 type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments,
11017 malformed_error); 11017 bound_error);
11018 // Note that the type class has to be resolved at this time, but not 11018 // Note that the type class has to be resolved at this time, but not
11019 // necessarily finalized yet. We may be checking bounds at compile time. 11019 // necessarily finalized yet. We may be checking bounds at compile time.
11020 const Class& cls = Class::Handle(type_class()); 11020 const Class& cls = Class::Handle(type_class());
11021 // This uninstantiated type is not modified, as it can be instantiated 11021 // This uninstantiated type is not modified, as it can be instantiated
11022 // with different instantiators. 11022 // with different instantiators.
11023 Type& instantiated_type = Type::Handle( 11023 Type& instantiated_type = Type::Handle(
11024 Type::New(cls, type_arguments, token_pos())); 11024 Type::New(cls, type_arguments, token_pos()));
11025 ASSERT(type_arguments.IsNull() || 11025 ASSERT(type_arguments.IsNull() ||
11026 (type_arguments.Length() == cls.NumTypeArguments())); 11026 (type_arguments.Length() == cls.NumTypeArguments()));
11027 instantiated_type.SetIsFinalized(); 11027 instantiated_type.SetIsFinalized();
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
11270 } 11270 }
11271 11271
11272 11272
11273 void TypeParameter::set_bound(const AbstractType& value) const { 11273 void TypeParameter::set_bound(const AbstractType& value) const {
11274 StorePointer(&raw_ptr()->bound_, value.raw()); 11274 StorePointer(&raw_ptr()->bound_, value.raw());
11275 } 11275 }
11276 11276
11277 11277
11278 RawAbstractType* TypeParameter::InstantiateFrom( 11278 RawAbstractType* TypeParameter::InstantiateFrom(
11279 const AbstractTypeArguments& instantiator_type_arguments, 11279 const AbstractTypeArguments& instantiator_type_arguments,
11280 Error* malformed_error) const { 11280 Error* bound_error) const {
11281 ASSERT(IsFinalized()); 11281 ASSERT(IsFinalized());
11282 if (instantiator_type_arguments.IsNull()) { 11282 if (instantiator_type_arguments.IsNull()) {
11283 return Type::DynamicType(); 11283 return Type::DynamicType();
11284 } 11284 }
11285 // Bound checks may appear in the instantiator type arguments, as is the case 11285 // Bound checks may appear in the instantiator type arguments, as is the case
11286 // with a pair of type parameters of the same class referring to each other 11286 // with a pair of type parameters of the same class referring to each other
11287 // via their bounds. 11287 // via their bounds.
11288 AbstractType& type_arg = AbstractType::Handle( 11288 AbstractType& type_arg = AbstractType::Handle(
11289 instantiator_type_arguments.TypeAt(index())); 11289 instantiator_type_arguments.TypeAt(index()));
11290 if (type_arg.IsBoundedType()) { 11290 if (type_arg.IsBoundedType()) {
11291 const BoundedType& bounded_type = BoundedType::Cast(type_arg); 11291 const BoundedType& bounded_type = BoundedType::Cast(type_arg);
11292 // Bounds checking of a type is postponed to run time if the type is still 11292 // Bounds checking of a type is postponed to run time if the type is still
11293 // uninstantiated at compile time, or if the bound and the type are mutually 11293 // uninstantiated at compile time, or if the bound and the type are mutually
11294 // recursive. In the latter case, the type may already be instantiated. 11294 // recursive. In the latter case, the type may already be instantiated.
11295 if (!bounded_type.IsInstantiated()) { 11295 if (!bounded_type.IsInstantiated()) {
11296 ASSERT(AbstractType::Handle(bounded_type.bound()).IsInstantiated()); 11296 ASSERT(AbstractType::Handle(bounded_type.bound()).IsInstantiated());
11297 type_arg = bounded_type.InstantiateFrom(AbstractTypeArguments::Handle(), 11297 type_arg = bounded_type.InstantiateFrom(AbstractTypeArguments::Handle(),
11298 malformed_error); 11298 bound_error);
11299 } 11299 }
11300 } 11300 }
11301 return type_arg.raw(); 11301 return type_arg.raw();
11302 } 11302 }
11303 11303
11304 11304
11305 bool TypeParameter::CheckBound(const AbstractType& bounded_type, 11305 bool TypeParameter::CheckBound(const AbstractType& bounded_type,
11306 const AbstractType& upper_bound, 11306 const AbstractType& upper_bound,
11307 Error* malformed_error) const { 11307 Error* bound_error) const {
11308 ASSERT((malformed_error == NULL) || malformed_error->IsNull()); 11308 ASSERT((bound_error == NULL) || bound_error->IsNull());
11309 ASSERT(bounded_type.IsFinalized()); 11309 ASSERT(bounded_type.IsFinalized());
11310 ASSERT(upper_bound.IsFinalized()); 11310 ASSERT(upper_bound.IsFinalized());
11311 ASSERT(!bounded_type.IsMalformed()); 11311 ASSERT(!bounded_type.IsMalformed());
11312 if (bounded_type.IsSubtypeOf(upper_bound, malformed_error)) { 11312 if (bounded_type.IsSubtypeOf(upper_bound, bound_error)) {
11313 return true; 11313 return true;
11314 } 11314 }
11315 if ((malformed_error != NULL) && malformed_error->IsNull()) { 11315 if ((bound_error != NULL) && bound_error->IsNull()) {
11316 // Report the bound error. 11316 // Report the bound error.
11317 const String& bounded_type_name = String::Handle( 11317 const String& bounded_type_name = String::Handle(
11318 bounded_type.UserVisibleName()); 11318 bounded_type.UserVisibleName());
11319 const String& upper_bound_name = String::Handle( 11319 const String& upper_bound_name = String::Handle(
11320 upper_bound.UserVisibleName()); 11320 upper_bound.UserVisibleName());
11321 const AbstractType& declared_bound = AbstractType::Handle(bound()); 11321 const AbstractType& declared_bound = AbstractType::Handle(bound());
11322 const String& declared_bound_name = String::Handle( 11322 const String& declared_bound_name = String::Handle(
11323 declared_bound.UserVisibleName()); 11323 declared_bound.UserVisibleName());
11324 const String& type_param_name = String::Handle(UserVisibleName()); 11324 const String& type_param_name = String::Handle(UserVisibleName());
11325 const Class& cls = Class::Handle(parameterized_class()); 11325 const Class& cls = Class::Handle(parameterized_class());
11326 const String& class_name = String::Handle(cls.Name()); 11326 const String& class_name = String::Handle(cls.Name());
11327 const Script& script = Script::Handle(cls.script()); 11327 const Script& script = Script::Handle(cls.script());
11328 // Since the bound may have been canonicalized, its token index is 11328 // Since the bound may have been canonicalized, its token index is
11329 // meaningless, therefore use the token index of this type parameter. 11329 // meaningless, therefore use the token index of this type parameter.
11330 *malformed_error = FormatError( 11330 *bound_error = FormatError(
11331 *malformed_error, 11331 *bound_error,
11332 script, 11332 script,
11333 token_pos(), 11333 token_pos(),
11334 "type parameter '%s' of class '%s' must extend bound '%s', " 11334 "type parameter '%s' of class '%s' must extend bound '%s', "
11335 "but type argument '%s' is not a subtype of '%s'\n", 11335 "but type argument '%s' is not a subtype of '%s'\n",
11336 type_param_name.ToCString(), 11336 type_param_name.ToCString(),
11337 class_name.ToCString(), 11337 class_name.ToCString(),
11338 declared_bound_name.ToCString(), 11338 declared_bound_name.ToCString(),
11339 bounded_type_name.ToCString(), 11339 bounded_type_name.ToCString(),
11340 upper_bound_name.ToCString()); 11340 upper_bound_name.ToCString());
11341 } 11341 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
11411 stream->CloseObject(); 11411 stream->CloseObject();
11412 } 11412 }
11413 11413
11414 11414
11415 bool BoundedType::IsMalformed() const { 11415 bool BoundedType::IsMalformed() const {
11416 return AbstractType::Handle(type()).IsMalformed(); 11416 return AbstractType::Handle(type()).IsMalformed();
11417 } 11417 }
11418 11418
11419 11419
11420 bool BoundedType::IsMalboundedWithError(Error* bound_error) const { 11420 bool BoundedType::IsMalboundedWithError(Error* bound_error) const {
11421 if (!FLAG_enable_type_checks && !FLAG_error_on_malformed_type) { 11421 if (!FLAG_enable_type_checks && !FLAG_error_on_bad_type) {
11422 return false; 11422 return false;
11423 } 11423 }
11424 const AbstractType& upper_bound = AbstractType::Handle(bound()); 11424 const AbstractType& upper_bound = AbstractType::Handle(bound());
11425 if (upper_bound.IsMalformed()) { 11425 if (upper_bound.IsMalformed()) {
11426 if (bound_error != NULL) { 11426 if (bound_error != NULL) {
11427 *bound_error = upper_bound.malformed_error(); 11427 *bound_error = upper_bound.malformed_error();
11428 ASSERT(!bound_error->IsNull()); 11428 ASSERT(!bound_error->IsNull());
11429 } 11429 }
11430 return true; 11430 return true;
11431 } 11431 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
11488 } 11488 }
11489 11489
11490 11490
11491 void BoundedType::set_is_being_checked(bool value) const { 11491 void BoundedType::set_is_being_checked(bool value) const {
11492 raw_ptr()->is_being_checked_ = value; 11492 raw_ptr()->is_being_checked_ = value;
11493 } 11493 }
11494 11494
11495 11495
11496 RawAbstractType* BoundedType::InstantiateFrom( 11496 RawAbstractType* BoundedType::InstantiateFrom(
11497 const AbstractTypeArguments& instantiator_type_arguments, 11497 const AbstractTypeArguments& instantiator_type_arguments,
11498 Error* malformed_error) const { 11498 Error* bound_error) const {
11499 ASSERT(IsFinalized()); 11499 ASSERT(IsFinalized());
11500 AbstractType& bounded_type = AbstractType::Handle(type()); 11500 AbstractType& bounded_type = AbstractType::Handle(type());
11501 if (!bounded_type.IsInstantiated()) { 11501 if (!bounded_type.IsInstantiated()) {
11502 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments, 11502 bounded_type = bounded_type.InstantiateFrom(instantiator_type_arguments,
11503 malformed_error); 11503 bound_error);
11504 } 11504 }
11505 if (FLAG_enable_type_checks && 11505 if (FLAG_enable_type_checks &&
11506 malformed_error->IsNull() && 11506 bound_error->IsNull() &&
11507 !is_being_checked()) { 11507 !is_being_checked()) {
11508 // Avoid endless recursion while checking and instantiating bound. 11508 // Avoid endless recursion while checking and instantiating bound.
11509 set_is_being_checked(true); 11509 set_is_being_checked(true);
11510 AbstractType& upper_bound = AbstractType::Handle(bound()); 11510 AbstractType& upper_bound = AbstractType::Handle(bound());
11511 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType()); 11511 ASSERT(!upper_bound.IsObjectType() && !upper_bound.IsDynamicType());
11512 const TypeParameter& type_param = TypeParameter::Handle(type_parameter()); 11512 const TypeParameter& type_param = TypeParameter::Handle(type_parameter());
11513 if (!upper_bound.IsInstantiated()) { 11513 if (!upper_bound.IsInstantiated()) {
11514 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments, 11514 upper_bound = upper_bound.InstantiateFrom(instantiator_type_arguments,
11515 malformed_error); 11515 bound_error);
11516 } 11516 }
11517 if (malformed_error->IsNull()) { 11517 if (bound_error->IsNull()) {
11518 type_param.CheckBound(bounded_type, upper_bound, malformed_error); 11518 type_param.CheckBound(bounded_type, upper_bound, bound_error);
11519 } 11519 }
11520 set_is_being_checked(false); 11520 set_is_being_checked(false);
11521 } 11521 }
11522 return bounded_type.raw(); 11522 return bounded_type.raw();
11523 } 11523 }
11524 11524
11525 11525
11526 intptr_t BoundedType::Hash() const { 11526 intptr_t BoundedType::Hash() const {
11527 uword result = 0; 11527 uword result = 0;
11528 result += AbstractType::Handle(type()).Hash(); 11528 result += AbstractType::Handle(type()).Hash();
(...skipping 3323 matching lines...) Expand 10 before | Expand all | Expand 10 after
14852 } 14852 }
14853 14853
14854 14854
14855 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 14855 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
14856 stream->OpenObject(); 14856 stream->OpenObject();
14857 stream->CloseObject(); 14857 stream->CloseObject();
14858 } 14858 }
14859 14859
14860 14860
14861 } // namespace dart 14861 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/os_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698