| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |