Chromium Code Reviews| Index: runtime/lib/mirrors.cc |
| diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc |
| index 9b7e9e6d593c31d3a5b02e8ba1036c685a7e5928..0c5f3690b162e1b2df4c536114d9c181aed23e87 100644 |
| --- a/runtime/lib/mirrors.cc |
| +++ b/runtime/lib/mirrors.cc |
| @@ -235,11 +235,16 @@ static RawInstance* CreateTypeVariableList(const Class& cls) { |
| static RawInstance* CreateTypedefMirror(const Class& cls, |
| + const AbstractType& type, |
| + const Bool& is_declaration, |
| const Instance& owner_mirror) { |
| - const Array& args = Array::Handle(Array::New(3)); |
| + const Array& args = Array::Handle(Array::New(6)); |
| args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); |
| - args.SetAt(1, String::Handle(cls.UserVisibleName())); |
| - args.SetAt(2, owner_mirror); |
| + args.SetAt(1, type); |
| + args.SetAt(2, String::Handle(cls.UserVisibleName())); |
| + args.SetAt(3, Bool::Get(cls.NumTypeParameters() != 0)); |
| + args.SetAt(4, cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration); |
| + args.SetAt(5, owner_mirror); |
| return CreateMirror(Symbols::_LocalTypedefMirrorImpl(), args); |
| } |
| @@ -328,7 +333,7 @@ static RawInstance* CreateClassMirror(const Class& cls, |
| return CreateFunctionTypeMirror(cls, type); |
| } else { |
| // We represent typedefs as non-canonical signature classes. |
| - return CreateTypedefMirror(cls, owner_mirror); |
| + return CreateTypedefMirror(cls, type, is_declaration, owner_mirror); |
| } |
| } |
| @@ -828,6 +833,31 @@ static RawInstance* LookupFunctionOrFieldInLibrary(const Library& library, |
| } |
| +static RawAbstractType* InstantiateType(const AbstractType& type, |
| + const AbstractType& instantiator) { |
| + ASSERT(type.IsFinalized()); |
| + ASSERT(instantiator.IsFinalized()); |
| + ASSERT(!type.IsMalformed()); |
| + ASSERT(!instantiator.IsMalformed()); |
| + |
| + if (type.IsInstantiated()) { |
| + return type.raw(); |
|
regis
2013/10/21 19:42:27
Do you care if the type is canonical or not?
rmacnak
2013/10/21 19:57:06
We do want to deal with canonical types, and rely
|
| + } |
| + |
| + const AbstractTypeArguments& type_args = |
| + AbstractTypeArguments::Handle(instantiator.arguments()); |
| + Error& bound_error = Error::Handle(); |
| + AbstractType& result = |
| + AbstractType::Handle(type.InstantiateFrom(type_args, &bound_error)); |
| + if (!bound_error.IsNull()) { |
| + ThrowInvokeError(bound_error); |
|
regis
2013/10/21 19:42:27
Are you sure you want to throw the bound error dir
rmacnak
2013/10/21 19:57:06
ThrowInvokeError will wrap it in a MirroredCompila
|
| + UNREACHABLE(); |
| + } |
| + ASSERT(result.IsFinalized()); |
| + return result.Canonicalize(); |
| +} |
| + |
| + |
| DEFINE_NATIVE_ENTRY(Mirrors_makeLocalMirrorSystem, 0) { |
| return CreateMirrorSystem(); |
| } |
| @@ -979,6 +1009,7 @@ DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) { |
| return super_type.raw(); |
| } |
| + |
| DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 1) { |
| GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
| ASSERT(!type.IsMalformed()); |
| @@ -988,25 +1019,8 @@ DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 1) { |
| UNREACHABLE(); |
| } |
| const Class& cls = Class::Handle(type.type_class()); |
| - AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| - AbstractType& result = AbstractType::Handle(super_type.raw()); |
| - |
| - ASSERT(super_type.IsType()); |
| - if (!super_type.IsInstantiated()) { |
| - AbstractTypeArguments& type_args = |
| - AbstractTypeArguments::Handle(type.arguments()); |
| - Error& bound_error = Error::Handle(); |
| - result ^= super_type.InstantiateFrom(type_args, &bound_error); |
| - if (!bound_error.IsNull()) { |
| - ThrowInvokeError(bound_error); |
| - UNREACHABLE(); |
| - } |
| - result ^= result.Canonicalize(); |
| - ASSERT(result.IsType()); |
| - } |
| - |
| - ASSERT(result.IsFinalized()); |
| - return result.raw(); |
| + const AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| + return InstantiateType(super_type, type); |
| } |
| @@ -1041,27 +1055,13 @@ DEFINE_NATIVE_ENTRY(ClassMirror_interfaces_instantiated, 1) { |
| ThrowInvokeError(error); |
| } |
| - AbstractTypeArguments& type_args = |
| - AbstractTypeArguments::Handle(type.arguments()); |
| - Error& bound_error = Error::Handle(); |
| - |
| Array& interfaces = Array::Handle(cls.interfaces()); |
| Array& interfaces_inst = Array::Handle(Array::New(interfaces.Length())); |
| AbstractType& interface = AbstractType::Handle(); |
| for (int i = 0; i < interfaces.Length(); i++) { |
| interface ^= interfaces.At(i); |
| - ASSERT(interface.IsType()); |
| - if (!interface.IsInstantiated()) { |
| - bound_error ^= Object::null(); |
| - interface ^= interface.InstantiateFrom(type_args, &bound_error); |
| - if (!bound_error.IsNull()) { |
| - ThrowInvokeError(bound_error); |
| - UNREACHABLE(); |
| - } |
| - interface ^= interface.Canonicalize(); |
| - ASSERT(interface.IsType()); |
| - } |
| + interface = InstantiateType(interface, type); |
| interfaces_inst.SetAt(i, interface); |
| } |
| @@ -1100,29 +1100,8 @@ DEFINE_NATIVE_ENTRY(ClassMirror_mixin_instantiated, 2) { |
| if (mixin_type.IsNull()) { |
| return mixin_type.raw(); |
| } |
| - ASSERT(mixin_type.IsFinalized()); |
| - |
| - ASSERT(!instantiator.IsMalformed()); |
| - ASSERT(instantiator.IsFinalized()); |
| - |
| - AbstractType& result = AbstractType::Handle(mixin_type.raw()); |
| - |
| - ASSERT(mixin_type.IsType()); |
| - if (!mixin_type.IsInstantiated()) { |
| - AbstractTypeArguments& type_args = |
| - AbstractTypeArguments::Handle(instantiator.arguments()); |
| - Error& bound_error = Error::Handle(); |
| - result ^= mixin_type.InstantiateFrom(type_args, &bound_error); |
| - if (!bound_error.IsNull()) { |
| - ThrowInvokeError(bound_error); |
| - UNREACHABLE(); |
| - } |
| - result ^= result.Canonicalize(); |
| - ASSERT(result.IsType()); |
| - } |
| - ASSERT(result.IsFinalized()); |
| - return result.raw(); |
| + return InstantiateType(mixin_type, instantiator); |
| } |
| @@ -1319,20 +1298,33 @@ DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 1) { |
| DEFINE_NATIVE_ENTRY(TypeVariableMirror_instantiate_from, 2) { |
| GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0)); |
| GET_NON_NULL_NATIVE_ARGUMENT(Type, instantiator, arguments->NativeArgAt(1)); |
| - |
| ASSERT(param.parameterized_class() == instantiator.type_class()); |
| + return InstantiateType(param, instantiator); |
| +} |
| - AbstractTypeArguments& type_args = |
| - AbstractTypeArguments::Handle(instantiator.arguments()); |
| - Error& bound_error = Error::Handle(); |
| - AbstractType& result = |
| - AbstractType::Handle(param.InstantiateFrom(type_args, &bound_error)); |
| - ASSERT(bound_error.IsNull()); |
| - ASSERT(result.IsFinalized()); |
| - return result.raw(); |
| + |
| +DEFINE_NATIVE_ENTRY(TypedefMirror_instantiate_from, 2) { |
| + GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0)); |
| + GET_NON_NULL_NATIVE_ARGUMENT(Type, instantiator, arguments->NativeArgAt(1)); |
| + const Class& cls = Class::Handle(type.type_class()); |
| + // We represent typedefs as non-canonical signature classes. |
| + ASSERT(cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass()); |
| + return InstantiateType(type, instantiator); |
| } |
| + |
| +DEFINE_NATIVE_ENTRY(TypedefMirror_declaration, 1) { |
| + GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0)); |
| + const Class& cls = Class::Handle(type.type_class()); |
| + // We represent typedefs as non-canonical signature classes. |
| + ASSERT(cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass()); |
| + return CreateTypedefMirror(cls, |
| + AbstractType::Handle(cls.DeclarationType()), |
| + Bool::True(), // is_declaration |
| + Object::null_instance()); |
| +} |
| + |
| DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 5) { |
| // Argument 0 is the mirror, which is unused by the native. It exists |
| // because this native is an instance method in order to be polymorphic |
| @@ -1956,11 +1948,15 @@ DEFINE_NATIVE_ENTRY(MethodMirror_source, 1) { |
| DEFINE_NATIVE_ENTRY(TypedefMirror_referent, 1) { |
| - GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| - const Class& cls = Class::Handle(ref.GetClassReferent()); |
| + GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0)); |
| + const Class& cls = Class::Handle(type.type_class()); |
| const Function& sig_func = Function::Handle(cls.signature_function()); |
| const Class& sig_cls = Class::Handle(sig_func.signature_class()); |
| - return MirrorReference::New(sig_cls); |
| + |
| + AbstractType& referent_type = AbstractType::Handle(sig_cls.DeclarationType()); |
| + referent_type = InstantiateType(referent_type, type); |
| + |
| + return CreateFunctionTypeMirror(sig_cls, referent_type); |
| } |