Chromium Code Reviews| Index: runtime/vm/object.cc |
| =================================================================== |
| --- runtime/vm/object.cc (revision 463) |
| +++ runtime/vm/object.cc (working copy) |
| @@ -696,6 +696,35 @@ |
| } |
| +RawType* Class::SignatureType() const { |
| + // Return the cached signature type if any. |
| + if (raw_ptr()->signature_type_ != Type::null()) { |
| + return raw_ptr()->signature_type_; |
| + } |
| + ASSERT(IsSignatureClass()); |
| + TypeArguments& signature_type_arguments = TypeArguments::Handle(); |
| + if (IsParameterized()) { |
| + const intptr_t num_type_params = NumTypeParameters(); |
|
siva
2011/10/17 18:36:59
Should we add a num_type_params check? would avoid
regis
2011/10/17 19:02:47
Good point. I actually can replace the test IsPara
|
| + const Array& type_params = Array::Handle(type_parameters()); |
| + signature_type_arguments = TypeArguments::NewTypeArray(num_type_params); |
| + String& type_param_name = String::Handle(); |
| + Type& type_param = Type::Handle(); |
| + for (int i = 0; i < num_type_params; i++) { |
| + type_param_name ^= type_params.At(i); |
| + type_param = Type::NewTypeParameter(i, type_param_name); |
| + signature_type_arguments.SetTypeAt(i, type_param); |
| + } |
| + } |
| + const ParameterizedType& signature_type = ParameterizedType::Handle( |
| + ParameterizedType::New(*this, signature_type_arguments)); |
| + |
| + // Cache and return the still unfinalized signature type. |
| + ASSERT(!signature_type.IsFinalized()); |
| + set_signature_type(signature_type); |
| + return signature_type.raw(); |
| +} |
| + |
| + |
| template <class FakeObject> |
| RawClass* Class::New() { |
| Class& class_class = Class::Handle(Object::class_class()); |
| @@ -766,6 +795,11 @@ |
| } |
| +void Class::set_signature_type(const Type& value) const { |
| + StorePointer(&raw_ptr()->signature_type_, value.raw()); |
| +} |
| + |
| + |
| void Class::set_class_state(int8_t state) const { |
| ASSERT(state == RawClass::kAllocated || |
| state == RawClass::kPreFinalized || |
| @@ -802,7 +836,8 @@ |
| intptr_t Class::NumTypeArguments() const { |
| intptr_t num_type_args = NumTypeParameters(); |
| const Class& superclass = Class::Handle(SuperClass()); |
| - if (!superclass.IsNull()) { |
| + // Object is its own super class during bootstrap. |
| + if (!superclass.IsNull() && (superclass.raw() != raw())) { |
| num_type_args += superclass.NumTypeArguments(); |
| } |
| return num_type_args; |
| @@ -977,19 +1012,21 @@ |
| intptr_t token_index) { |
| ASSERT(!signature_function.IsNull()); |
| Type& super_type = Type::Handle(Type::ObjectType()); |
| + const Class& owner_class = Class::Handle(signature_function.owner()); |
| + ASSERT(!owner_class.IsNull()); |
| Array& type_parameters = Array::Handle(); |
| TypeArray& type_parameter_extends = TypeArray::Handle(); |
| if (!signature_function.is_static()) { |
| - const Class& owner_class = Class::Handle(signature_function.owner()); |
| - ASSERT(!owner_class.IsNull()); |
| - ASSERT(!owner_class.is_interface()); |
| - if (owner_class.IsParameterized()) { |
| + if (owner_class.IsParameterized() && |
| + !signature_function.HasInstantiatedSignature()) { |
| // Share the function owner super class as the super class of the |
| // signature class, so that the type argument vector of the closure at |
| // run time matches the type argument vector of the closure instantiator. |
| type_parameters = owner_class.type_parameters(); |
| type_parameter_extends = owner_class.type_parameter_extends(); |
| - super_type = owner_class.super_type(); |
| + if (!owner_class.is_interface()) { |
| + super_type = owner_class.super_type(); |
| + } |
| } |
| } |
| Class& result = Class::Handle(New<Closure>(name, script)); |
| @@ -1586,6 +1623,13 @@ |
| } |
| +bool Type::IsBeingFinalized() const { |
| + // Type is an abstract class. |
| + UNREACHABLE(); |
| + return false; |
| +} |
| + |
| + |
| RawType* Type::InstantiateFrom( |
| const TypeArguments& instantiator_type_arguments, |
| intptr_t offset) const { |
| @@ -1606,12 +1650,23 @@ |
| class_name = cls.Name(); |
| num_type_params = cls.NumTypeParameters(); // Do not print the full vector. |
| if (num_type_params > num_args) { |
| - ASSERT(!IsFinalized()); |
| + ASSERT(num_args == 0); // Type is raw. |
| // We fill up with "var". |
| first_type_param_index = 0; |
| } else { |
| first_type_param_index = num_args - num_type_params; |
| } |
| + if (cls.IsSignatureClass()) { |
| + const Function& signature_function = Function::Handle( |
| + cls.signature_function()); |
| + // We may be reporting an error about an illformed function type. In that |
| + // case, avoid instantiating the signature, since it may lead to cycles. |
| + if (IsBeingFinalized()) { |
| + return class_name.raw(); |
| + } |
| + return signature_function.InstantiatedSignatureFrom( |
| + args, first_type_param_index); |
| + } |
| } else { |
| const UnresolvedClass& type = UnresolvedClass::Handle(unresolved_class()); |
| class_name = type.Name(); |
| @@ -1645,7 +1700,7 @@ |
| ASSERT(s == num_strings); |
| type_name = String::ConcatAll(strings); |
| } |
| - // The name is only used for naming function types and for debugging purposes. |
| + // The name is only used for type checking and debugging purposes. |
| // Unless profiling data shows otherwise, it is not worth caching the name in |
| // the type. |
| return String::NewSymbol(type_name); |
| @@ -1842,7 +1897,7 @@ |
| void ParameterizedType::set_is_being_finalized() const { |
| - ASSERT(!IsFinalized() && !is_being_finalized()); |
| + ASSERT(!IsFinalized() && !IsBeingFinalized()); |
| set_type_state(RawParameterizedType::kBeingFinalized); |
| } |
| @@ -1901,8 +1956,11 @@ |
| type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments, |
| offset); |
| } |
| + const Class& cls = Class::Handle(type_class()); |
| ParameterizedType& instantiated_type = ParameterizedType::Handle( |
| - ParameterizedType::New(Object::Handle(type_class()), type_arguments)); |
| + ParameterizedType::New(cls, type_arguments)); |
| + ASSERT(type_arguments.IsNull() || |
| + (type_arguments.Length() == cls.NumTypeArguments())); |
| instantiated_type.set_is_finalized(); |
| return instantiated_type.raw(); |
| } |
| @@ -2910,21 +2968,21 @@ |
| } |
| -// Build a string of the form '<T>(A, [b: B, c: C]) => R)' representing the |
| -// signature of the given function. |
| -RawString* Function::Signature() const { |
| +RawString* Function::BuildSignature(bool instantiate, |
| + const TypeArguments& instantiator, |
| + intptr_t offset) const { |
| GrowableArray<const String*> pieces; |
| - const String& kSpaceExtendsSpace = |
| - String::Handle(String::NewSymbol(" extends ")); |
| const String& kCommaSpace = String::Handle(String::NewSymbol(", ")); |
| const String& kColonSpace = String::Handle(String::NewSymbol(": ")); |
| - const String& kLAngleBracket = String::Handle(String::NewSymbol("<")); |
| - const String& kRAngleBracket = String::Handle(String::NewSymbol(">")); |
| const String& kLParen = String::Handle(String::NewSymbol("(")); |
| const String& kRParen = String::Handle(String::NewSymbol(") => ")); |
| const String& kLBracket = String::Handle(String::NewSymbol("[")); |
| const String& kRBracket = String::Handle(String::NewSymbol("]")); |
| - if (!is_static()) { |
| + if (!instantiate && !is_static()) { |
| + const String& kSpaceExtendsSpace = |
| + String::Handle(String::NewSymbol(" extends ")); |
| + const String& kLAngleBracket = String::Handle(String::NewSymbol("<")); |
| + const String& kRAngleBracket = String::Handle(String::NewSymbol(">")); |
| const Class& function_class = Class::Handle(owner()); |
| ASSERT(!function_class.IsNull()); |
| const Array& type_parameters = Array::Handle( |
| @@ -2960,6 +3018,9 @@ |
| for (intptr_t i = 0; i < num_fixed_params; i++) { |
| param_type = ParameterTypeAt(i); |
| ASSERT(!param_type.IsNull()); |
| + if (instantiate && !param_type.IsInstantiated()) { |
| + param_type = param_type.InstantiateFrom(instantiator, offset); |
| + } |
| pieces.Add(&String::ZoneHandle(param_type.Name())); |
| if (i != (num_params - 1)) { |
| pieces.Add(&kCommaSpace); |
| @@ -2971,6 +3032,9 @@ |
| pieces.Add(&String::ZoneHandle(ParameterNameAt(i))); |
| pieces.Add(&kColonSpace); |
| param_type = ParameterTypeAt(i); |
| + if (instantiate && !param_type.IsInstantiated()) { |
| + param_type = param_type.InstantiateFrom(instantiator, offset); |
| + } |
| ASSERT(!param_type.IsNull()); |
| pieces.Add(&String::ZoneHandle(param_type.Name())); |
| if (i != (num_params - 1)) { |
| @@ -2980,13 +3044,32 @@ |
| pieces.Add(&kRBracket); |
| } |
| pieces.Add(&kRParen); |
| - const Type& res_type = Type::Handle(result_type()); |
| + Type& res_type = Type::Handle(result_type()); |
| + if (instantiate && !res_type.IsInstantiated()) { |
| + res_type = res_type.InstantiateFrom(instantiator, offset); |
| + } |
| pieces.Add(&String::Handle(res_type.Name())); |
| const Array& strings = Array::Handle(NewArray<const String>(pieces)); |
| return String::NewSymbol(String::Handle(String::ConcatAll(strings))); |
| } |
| +bool Function::HasInstantiatedSignature() const { |
| + Type& type = Type::Handle(result_type()); |
| + if (!type.IsInstantiated()) { |
| + return false; |
| + } |
| + const intptr_t num_parameters = NumberOfParameters(); |
| + for (intptr_t i = 0; i < num_parameters; i++) { |
| + type = ParameterTypeAt(i); |
| + if (!type.IsInstantiated()) { |
| + return false; |
| + } |
| + } |
| + return true; |
| +} |
| + |
| + |
| const char* Function::ToCString() const { |
| const char* f0 = is_static() ? " static" : ""; |
| const char* f1 = NULL; |