Chromium Code Reviews| Index: runtime/lib/mirrors.cc |
| diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc |
| index 874915f014d0e29471272f1eac0dc59dd4f5c090..45c50a6d999054e59663f57f3e6b5979b3b0a5c3 100644 |
| --- a/runtime/lib/mirrors.cc |
| +++ b/runtime/lib/mirrors.cc |
| @@ -107,11 +107,18 @@ static RawInstance* CreateTypedefMirror(const Class& cls, |
| return CreateMirror(Symbols::_LocalTypedefMirrorImpl(), args); |
| } |
| +static RawInstance* CreateFunctionTypeMirror(const Class& cls, |
| + const Instance& owner_mirror) { |
| + const Array& args = Array::Handle(Array::New(2)); |
| + args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); |
| + args.SetAt(1, owner_mirror); |
| + return CreateMirror(Symbols::_LocalFunctionTypeMirrorImpl(), args); |
| +} |
| -static RawInstance* CreateFunctionTypeMirror(const Class& cls) { |
| +static RawInstance* CreateClosureTypeMirror(const Class& cls) { |
| const Array& args = Array::Handle(Array::New(1)); |
| args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); |
| - return CreateMirror(Symbols::_LocalFunctionTypeMirrorImpl(), args); |
| + return CreateMirror(Symbols::_LocalClosureTypeMirrorImpl(), args); |
| } |
| @@ -153,19 +160,41 @@ static RawInstance* CreateVariableMirror(const Field& field, |
| return CreateMirror(Symbols::_LocalVariableMirrorImpl(), args); |
| } |
| +static RawFunction* CallMethod(const Class& cls) { |
| + if (cls.IsSignatureClass()) { |
| + return cls.signature_function(); |
| + } |
| + |
| + Class& lookup_cls = Class::Handle(cls.raw()); |
| + Function& call_function = Function::Handle(); |
| + do { |
| + call_function = lookup_cls.LookupDynamicFunction(Symbols::Call()); |
| + if (!call_function.IsNull()) { |
| + return call_function.raw(); |
| + } |
| + lookup_cls = lookup_cls.SuperClass(); |
| + } while (!lookup_cls.IsNull()); |
| + return Function::null(); |
| +} |
| static RawInstance* CreateClassMirror(const Class& cls, |
| const Instance& owner_mirror) { |
| if (cls.IsSignatureClass()) { |
| if (cls.IsCanonicalSignatureClass()) { |
| // We represent function types as canonical signature classes. |
| - return CreateFunctionTypeMirror(cls); |
| + return CreateClosureTypeMirror(cls); |
| } else { |
| // We represent typedefs as non-canonical signature classes. |
| return CreateTypedefMirror(cls, owner_mirror); |
| } |
| } |
| + const Function& call_function = Function::Handle(CallMethod(cls)); |
| + if (!call_function.IsNull()) { |
| + // A user-defined class that implements the call operator. |
| + return CreateFunctionTypeMirror(cls, owner_mirror); |
| + } |
| + |
| const Array& args = Array::Handle(Array::New(2)); |
| args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); |
| args.SetAt(1, String::Handle(cls.UserVisibleName())); |
| @@ -323,10 +352,21 @@ DEFINE_NATIVE_ENTRY(DeclarationMirror_metadata, 1) { |
| } |
| +DEFINE_NATIVE_ENTRY(FunctionTypeMirror_call_method, 2) { |
| + GET_NON_NULL_NATIVE_ARGUMENT(Instance, |
| + owner_mirror, |
| + arguments->NativeArgAt(0)); |
| + GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| + const Class& cls = Class::Handle(ref.GetClassReferent()); |
| + const Function& func = Function::Handle(CallMethod(cls)); |
| + return CreateMethodMirror(func, owner_mirror); |
| +} |
| + |
| + |
| DEFINE_NATIVE_ENTRY(FunctionTypeMirror_parameters, 1) { |
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| const Class& cls = Class::Handle(ref.GetClassReferent()); |
| - const Function& func = Function::Handle(cls.signature_function()); |
| + const Function& func = Function::Handle(CallMethod(cls)); |
| return CreateParameterMirrorList(func); |
|
siva
2013/08/06 23:32:07
Does CreateParameterMirrorList deal with func bein
rmacnak
2013/08/07 00:10:21
The class reflected by a FunctionTypeMirror should
|
| } |
| @@ -334,7 +374,7 @@ DEFINE_NATIVE_ENTRY(FunctionTypeMirror_parameters, 1) { |
| DEFINE_NATIVE_ENTRY(FunctionTypeMirror_return_type, 1) { |
| GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| const Class& cls = Class::Handle(ref.GetClassReferent()); |
| - const Function& func = Function::Handle(cls.signature_function()); |
| + const Function& func = Function::Handle(CallMethod(cls)); |
| const AbstractType& return_type = AbstractType::Handle(func.result_type()); |
|
siva
2013/08/06 23:32:07
Ditto comment here about CallMethod returning Func
|
| return CreateTypeMirror(return_type); |
| } |
| @@ -723,10 +763,13 @@ DEFINE_NATIVE_ENTRY(ClosureMirror_apply, 2) { |
| DEFINE_NATIVE_ENTRY(ClosureMirror_function, 1) { |
| GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); |
| - ASSERT(closure.IsClosure()); |
| + ASSERT(!closure.IsNull()); |
| + |
| + Function& function = Function::Handle(); |
| + bool callable = closure.IsCallable(&function, NULL); |
| + ASSERT(callable); |
| - const Function& func = Function::Handle(Closure::function(closure)); |
| - return CreateMethodMirror(func, Instance::null_instance()); |
| + return CreateMethodMirror(function, Instance::null_instance()); |
| } |