Index: runtime/lib/mirrors.cc |
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc |
index 3b7391caf42238dba40a43e93faefaf52a13fafe..96d50daf048c39ae704952d7a521601365d4b90f 100644 |
--- a/runtime/lib/mirrors.cc |
+++ b/runtime/lib/mirrors.cc |
@@ -1301,6 +1301,83 @@ DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 1) { |
} |
+static RawInstance* MakeAccessorClosure(const Class& cls, |
+ const String& selector, |
+ RawFunction::Kind kind) { |
+ const Error& error = Error::Handle(cls.EnsureIsFinalized(Isolate::Current())); |
+ ASSERT(error.IsNull()); |
+ |
+ const String& func_name = String::Handle(Symbols::New(selector)); |
+ const Function& function = |
+ Function::Handle(Function::New(func_name, |
+ kind, |
+ true, // Static. |
+ false, // Not const. |
+ false, // Not abstract. |
+ false, // Not external. |
+ false, // Not native. |
+ cls, |
+ Scanner::kNoSourcePos)); |
+ const Type& dynamic_type = Type::Handle(Type::DynamicType()); |
+ function.set_result_type(dynamic_type); |
+ |
+ // 1 - the closure reciever, 2 - the object whose field is to be gotten. |
+ intptr_t num_params = (kind == RawFunction::kGetFieldClosure) ? 2 : 3; |
+ |
+ function.set_num_fixed_parameters(num_params); |
+ function.set_parameter_types( |
+ Array::Handle(Array::New(num_params, Heap::kOld))); |
+ function.set_parameter_names( |
+ Array::Handle(Array::New(num_params, Heap::kOld))); |
+ for (intptr_t i = 0; i < num_params; i++) { |
+ function.SetParameterTypeAt(i, dynamic_type); |
+ function.SetParameterNameAt(i, Symbols::Other()); |
+ } |
+ function.SetNumOptionalParameters(0, true); |
+ |
+ // Lookup or create a new signature class for the closure function in the |
+ // library of the owner class. |
+ const Library& library = Library::Handle(cls.library()); |
+ const String& signature = String::Handle(function.Signature()); |
+ Class& signature_class = Class::ZoneHandle( |
+ library.LookupLocalClass(signature)); |
+ if (signature_class.IsNull()) { |
+ const Script& script = Script::Handle(cls.script()); |
+ signature_class = Class::NewSignatureClass(signature, |
+ function, |
+ script, |
+ function.token_pos()); |
+ library.AddClass(signature_class); |
+ } else { |
+ function.set_signature_class(signature_class); |
+ } |
+ const Type& signature_type = Type::Handle(signature_class.SignatureType()); |
+ if (!signature_type.IsFinalized()) { |
+ ClassFinalizer::FinalizeType( |
+ signature_class, signature_type, ClassFinalizer::kCanonicalize); |
+ } |
+ ObjectStore* object_store = Isolate::Current()->object_store(); |
+ const Context& context = Context::Handle(object_store->empty_context()); |
+ return Closure::New(function, context, Heap::kOld); |
+} |
+ |
+ |
+DEFINE_NATIVE_ENTRY(Mirrors_makeGetter, 2) { |
+ GET_NON_NULL_NATIVE_ARGUMENT(String, selector, arguments->NativeArgAt(0)); |
+ GET_NON_NULL_NATIVE_ARGUMENT(Type, scratch_type, arguments->NativeArgAt(1)); |
+ const Class& cls = Class::Handle(scratch_type.type_class()); |
+ return MakeAccessorClosure(cls, selector, RawFunction::kGetFieldClosure); |
+} |
+ |
+ |
+DEFINE_NATIVE_ENTRY(Mirrors_makeSetter, 2) { |
+ GET_NON_NULL_NATIVE_ARGUMENT(String, selector, arguments->NativeArgAt(0)); |
+ GET_NON_NULL_NATIVE_ARGUMENT(Type, scratch_type, arguments->NativeArgAt(1)); |
+ const Class& cls = Class::Handle(scratch_type.type_class()); |
+ return MakeAccessorClosure(cls, selector, RawFunction::kSetFieldClosure); |
+} |
+ |
+ |
DEFINE_NATIVE_ENTRY(TypedefMirror_declaration, 1) { |
GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0)); |
const Class& cls = Class::Handle(type.type_class()); |