| Index: runtime/lib/mirrors.cc
|
| diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
|
| index 874915f014d0e29471272f1eac0dc59dd4f5c090..c7061d7797ad2ff44081be4e57df7d6e300b38f9 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,23 @@ 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));
|
| + ASSERT(!func.IsNull());
|
| + 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));
|
| + ASSERT(!func.IsNull());
|
| return CreateParameterMirrorList(func);
|
| }
|
|
|
| @@ -334,7 +376,8 @@ 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));
|
| + ASSERT(!func.IsNull());
|
| const AbstractType& return_type = AbstractType::Handle(func.result_type());
|
| return CreateTypeMirror(return_type);
|
| }
|
| @@ -723,10 +766,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());
|
| }
|
|
|
|
|
|
|