1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "lib/mirrors.h"
6
7#include "lib/invocation_mirror.h"
8#include "vm/bootstrap_natives.h"
9#include "vm/class_finalizer.h"
10#include "vm/dart_api_impl.h"
11#include "vm/dart_entry.h"
12#include "vm/exceptions.h"
13#include "vm/kernel.h"
14#include "vm/object_store.h"
15#include "vm/parser.h"
16#include "vm/port.h"
17#include "vm/resolver.h"
18#include "vm/symbols.h"
19
20namespace dart {
21
22#if !defined(DART_PRECOMPILED_RUNTIME)
23
24#define RETURN_OR_PROPAGATE(expr) \
25 ObjectPtr result = expr; \
26 if (IsErrorClassId(result->GetClassIdMayBeSmi())) { \
27 Exceptions::PropagateError(Error::Handle(Error::RawCast(result))); \
28 } \
29 return result;
30
31static InstancePtr CreateMirror(const String& mirror_class_name,
32 const Array& constructor_arguments) {
33 const Library& mirrors_lib = Library::Handle(ptr: Library::MirrorsLibrary());
34 const String& constructor_name = Symbols::DotUnder();
35
36 const Object& result = Object::Handle(ptr: DartLibraryCalls::InstanceCreate(
37 library: mirrors_lib, exception_name: mirror_class_name, constructor_name, arguments: constructor_arguments));
38 if (result.IsError()) {
39 Exceptions::PropagateError(error: Error::Cast(obj: result));
40 }
41 return Instance::Cast(obj: result).ptr();
42}
43
44// Conventions:
45// * For throwing a NSM in a class klass we use its runtime type as receiver,
46// i.e., klass.RareType().
47// * For throwing a NSM in a library, we just pass the null instance as
48// receiver.
49static void ThrowNoSuchMethod(const Instance& receiver,
50 const String& function_name,
51 const Array& arguments,
52 const Array& argument_names,
53 const InvocationMirror::Level level,
54 const InvocationMirror::Kind kind) {
55 const Smi& invocation_type =
56 Smi::Handle(ptr: Smi::New(value: InvocationMirror::EncodeType(level, kind)));
57
58 const Array& args = Array::Handle(ptr: Array::New(len: 7));
59 args.SetAt(index: 0, value: receiver);
60 args.SetAt(index: 1, value: function_name);
61 args.SetAt(index: 2, value: invocation_type);
62 args.SetAt(index: 3, value: Object::smi_zero()); // Type arguments length.
63 args.SetAt(index: 4, value: Object::null_type_arguments());
64 args.SetAt(index: 5, value: arguments);
65 args.SetAt(index: 6, value: argument_names);
66
67 const Library& libcore = Library::Handle(ptr: Library::CoreLibrary());
68 const Class& cls =
69 Class::Handle(ptr: libcore.LookupClass(name: Symbols::NoSuchMethodError()));
70 const auto& error = cls.EnsureIsFinalized(thread: Thread::Current());
71 ASSERT(error == Error::null());
72 const Function& throwNew =
73 Function::Handle(ptr: cls.LookupFunctionAllowPrivate(name: Symbols::ThrowNew()));
74 const Object& result =
75 Object::Handle(ptr: DartEntry::InvokeFunction(function: throwNew, arguments: args));
76 ASSERT(result.IsError());
77 Exceptions::PropagateError(error: Error::Cast(obj: result));
78 UNREACHABLE();
79}
80
81static void EnsureConstructorsAreCompiled(const Function& func) {
82 // Only generative constructors can have initializing formals.
83 if (!func.IsGenerativeConstructor()) return;
84
85 Thread* thread = Thread::Current();
86 Zone* zone = thread->zone();
87 const Class& cls = Class::Handle(zone, ptr: func.Owner());
88 const Error& error = Error::Handle(zone, ptr: cls.EnsureIsFinalized(thread));
89 if (!error.IsNull()) {
90 Exceptions::PropagateError(error);
91 UNREACHABLE();
92 }
93 func.EnsureHasCode();
94}
95
96static InstancePtr CreateParameterMirrorList(const Function& func,
97 const FunctionType& signature,
98 const Instance& owner_mirror) {
99 Thread* const T = Thread::Current();
100 Zone* const Z = T->zone();
101 HANDLESCOPE(T);
102 const intptr_t implicit_param_count = signature.num_implicit_parameters();
103 const intptr_t non_implicit_param_count =
104 signature.NumParameters() - implicit_param_count;
105 const intptr_t index_of_first_optional_param =
106 non_implicit_param_count - signature.NumOptionalParameters();
107 const intptr_t index_of_first_named_param =
108 non_implicit_param_count - signature.NumOptionalNamedParameters();
109 const Array& results = Array::Handle(zone: Z, ptr: Array::New(len: non_implicit_param_count));
110 const Array& args = Array::Handle(zone: Z, ptr: Array::New(len: 9));
111
112 Smi& pos = Smi::Handle(zone: Z);
113 String& name = String::Handle(zone: Z);
114 Instance& param = Instance::Handle(zone: Z);
115 Bool& is_final = Bool::Handle(zone: Z);
116 Object& default_value = Object::Handle(zone: Z);
117 Object& metadata = Object::Handle(zone: Z);
118
119 // We force compilation of constructors to ensure the types of initializing
120 // formals have been corrected. We do not force the compilation of all types
121 // of functions because some have no body, e.g. signature functions.
122 if (!func.IsNull()) {
123 EnsureConstructorsAreCompiled(func);
124 }
125
126 bool has_extra_parameter_info = true;
127 if (non_implicit_param_count == 0) {
128 has_extra_parameter_info = false;
129 }
130 if (func.IsNull() || func.IsImplicitConstructor()) {
131 // This covers the default constructor and forwarding constructors.
132 has_extra_parameter_info = false;
133 }
134 Array& param_descriptor = Array::Handle();
135 if (has_extra_parameter_info) {
136 // Reparse the function for the following information:
137 // * The default value of a parameter.
138 // * Whether a parameters has been declared as final.
139 // * Any metadata associated with the parameter.
140 Object& result = Object::Handle(ptr: kernel::BuildParameterDescriptor(function: func));
141 if (result.IsError()) {
142 Exceptions::PropagateError(error: Error::Cast(obj: result));
143 UNREACHABLE();
144 }
145 param_descriptor ^= result.ptr();
146 ASSERT(param_descriptor.Length() ==
147 (Parser::kParameterEntrySize * non_implicit_param_count));
148 }
149
150 args.SetAt(index: 0, value: MirrorReference::Handle(ptr: MirrorReference::New(referent: signature)));
151 args.SetAt(index: 2, value: owner_mirror);
152
153 if (!has_extra_parameter_info) {
154 is_final = Bool::True().ptr();
155 default_value = Object::null();
156 metadata = Object::null();
157 }
158
159 for (intptr_t i = 0; i < non_implicit_param_count; i++) {
160 pos = Smi::New(value: i);
161 if (i >= index_of_first_named_param) {
162 // Named parameters are stored in the signature.
163 name = signature.ParameterNameAt(index: implicit_param_count + i);
164 } else if (!func.IsNull()) {
165 // Positional parameters are stored in the function.
166 name = func.ParameterNameAt(index: implicit_param_count + i);
167 } else {
168 // We were not given a function, only the type, so create placeholder
169 // names for the positional parameters.
170 const char* const placeholder = OS::SCreate(zone: Z, format: ":param%" Pd "", i);
171 name = String::New(cstr: placeholder);
172 }
173 if (has_extra_parameter_info) {
174 is_final ^= param_descriptor.At(index: i * Parser::kParameterEntrySize +
175 Parser::kParameterIsFinalOffset);
176 default_value = param_descriptor.At(index: i * Parser::kParameterEntrySize +
177 Parser::kParameterDefaultValueOffset);
178 metadata = param_descriptor.At(index: i * Parser::kParameterEntrySize +
179 Parser::kParameterMetadataOffset);
180 }
181 ASSERT(default_value.IsNull() || default_value.IsInstance());
182
183 // Arguments 0 (referent) and 2 (owner) are the same for all parameters. See
184 // above.
185 args.SetAt(index: 1, value: name);
186 args.SetAt(index: 3, value: pos);
187 args.SetAt(index: 4, value: Bool::Get(value: i >= index_of_first_optional_param));
188 args.SetAt(index: 5, value: Bool::Get(value: i >= index_of_first_named_param));
189 args.SetAt(index: 6, value: is_final);
190 args.SetAt(index: 7, value: default_value);
191 args.SetAt(index: 8, value: metadata);
192 param = CreateMirror(mirror_class_name: Symbols::_ParameterMirror(), constructor_arguments: args);
193 results.SetAt(index: i, value: param);
194 }
195 results.MakeImmutable();
196 return results.ptr();
197}
198
199static InstancePtr CreateTypeVariableMirror(const TypeParameter& param,
200 const Instance& owner_mirror) {
201 const Array& args = Array::Handle(ptr: Array::New(len: 3));
202 args.SetAt(index: 0, value: param);
203 args.SetAt(index: 1, value: String::Handle(ptr: param.UserVisibleName()));
204 args.SetAt(index: 2, value: owner_mirror);
205 return CreateMirror(mirror_class_name: Symbols::_TypeVariableMirror(), constructor_arguments: args);
206}
207
208// We create a list in native code and let Dart code create the type mirror
209// object and the ordered map.
210static InstancePtr CreateTypeVariableList(const Class& cls) {
211 const intptr_t num_type_params = cls.NumTypeParameters();
212 if (num_type_params == 0) {
213 return Object::empty_array().ptr();
214 }
215 const Array& result = Array::Handle(ptr: Array::New(len: num_type_params * 2));
216 TypeParameter& type = TypeParameter::Handle();
217 String& name = String::Handle();
218 for (intptr_t i = 0; i < num_type_params; i++) {
219 type = cls.TypeParameterAt(index: i, nullability: Nullability::kLegacy);
220 ASSERT(type.IsFinalized());
221 name = type.UserVisibleName();
222 result.SetAt(index: 2 * i, value: name);
223 result.SetAt(index: 2 * i + 1, value: type);
224 }
225 return result.ptr();
226}
227
228static InstancePtr CreateFunctionTypeMirror(const AbstractType& type) {
229 ASSERT(type.IsFunctionType());
230 const Class& closure_class =
231 Class::Handle(ptr: IsolateGroup::Current()->object_store()->closure_class());
232 const FunctionType& sig = FunctionType::Cast(obj: type);
233 const Array& args = Array::Handle(ptr: Array::New(len: 3));
234 args.SetAt(index: 0, value: MirrorReference::Handle(ptr: MirrorReference::New(referent: closure_class)));
235 args.SetAt(index: 1, value: MirrorReference::Handle(ptr: MirrorReference::New(referent: sig)));
236 args.SetAt(index: 2, value: type);
237 return CreateMirror(mirror_class_name: Symbols::_FunctionTypeMirror(), constructor_arguments: args);
238}
239
240static InstancePtr CreateMethodMirror(const Function& func,
241 const Instance& owner_mirror,
242 const AbstractType& instantiator) {
243 const Array& args = Array::Handle(ptr: Array::New(len: 6));
244 args.SetAt(index: 0, value: MirrorReference::Handle(ptr: MirrorReference::New(referent: func)));
245
246 String& name = String::Handle(ptr: func.name());
247 name = String::ScrubNameRetainPrivate(name, is_extension: func.is_extension_member());
248 args.SetAt(index: 1, value: name);
249 args.SetAt(index: 2, value: owner_mirror);
250 args.SetAt(index: 3, value: instantiator);
251 args.SetAt(index: 4, value: Bool::Get(value: func.is_static()));
252
253 intptr_t kind_flags = 0;
254 kind_flags |=
255 (static_cast<intptr_t>(func.is_abstract()) << Mirrors::kAbstract);
256 kind_flags |=
257 (static_cast<intptr_t>(func.IsGetterFunction()) << Mirrors::kGetter);
258 kind_flags |=
259 (static_cast<intptr_t>(func.IsSetterFunction()) << Mirrors::kSetter);
260 bool is_ctor = (func.kind() == UntaggedFunction::kConstructor);
261 kind_flags |= (static_cast<intptr_t>(is_ctor) << Mirrors::kConstructor);
262 kind_flags |= (static_cast<intptr_t>(is_ctor && func.is_const())
263 << Mirrors::kConstCtor);
264 kind_flags |=
265 (static_cast<intptr_t>(is_ctor && func.IsGenerativeConstructor())
266 << Mirrors::kGenerativeCtor);
267 kind_flags |= (static_cast<intptr_t>(false) << Mirrors::kRedirectingCtor);
268 kind_flags |= (static_cast<intptr_t>(is_ctor && func.IsFactory())
269 << Mirrors::kFactoryCtor);
270 kind_flags |=
271 (static_cast<intptr_t>(func.is_external()) << Mirrors::kExternal);
272 bool is_synthetic = func.is_synthetic();
273 kind_flags |= (static_cast<intptr_t>(is_synthetic) << Mirrors::kSynthetic);
274 kind_flags |= (static_cast<intptr_t>(func.is_extension_member())
275 << Mirrors::kExtensionMember);
276 args.SetAt(index: 5, value: Smi::Handle(ptr: Smi::New(value: kind_flags)));
277
278 return CreateMirror(mirror_class_name: Symbols::_MethodMirror(), constructor_arguments: args);
279}
280
281static InstancePtr CreateVariableMirror(const Field& field,
282 const Instance& owner_mirror) {
283 const MirrorReference& field_ref =
284 MirrorReference::Handle(ptr: MirrorReference::New(referent: field));
285
286 const String& name = String::Handle(ptr: field.name());
287
288 const Array& args = Array::Handle(ptr: Array::New(len: 8));
289 args.SetAt(index: 0, value: field_ref);
290 args.SetAt(index: 1, value: name);
291 args.SetAt(index: 2, value: owner_mirror);
292 args.SetAt(index: 3, value: Object::null_instance()); // Null for type.
293 args.SetAt(index: 4, value: Bool::Get(value: field.is_static()));
294 args.SetAt(index: 5, value: Bool::Get(value: field.is_final()));
295 args.SetAt(index: 6, value: Bool::Get(value: field.is_const()));
296 args.SetAt(index: 7, value: Bool::Get(value: field.is_extension_member()));
297
298 return CreateMirror(mirror_class_name: Symbols::_VariableMirror(), constructor_arguments: args);
299}
300
301static InstancePtr CreateClassMirror(const Class& cls,
302 const AbstractType& type,
303 const Bool& is_declaration,
304 const Instance& owner_mirror) {
305 ASSERT(!cls.IsDynamicClass());
306 ASSERT(!cls.IsVoidClass());
307 ASSERT(!cls.IsNeverClass());
308 ASSERT(!type.IsNull());
309 ASSERT(type.IsFinalized());
310 ASSERT(type.IsCanonical());
311 const Array& args = Array::Handle(ptr: Array::New(len: 9));
312 args.SetAt(index: 0, value: MirrorReference::Handle(ptr: MirrorReference::New(referent: cls)));
313 args.SetAt(index: 1, value: type);
314 args.SetAt(index: 2, value: String::Handle(ptr: cls.Name()));
315 args.SetAt(index: 3, value: owner_mirror);
316 args.SetAt(index: 4, value: Bool::Get(value: cls.is_abstract()));
317 args.SetAt(index: 5, value: Bool::Get(value: cls.IsGeneric()));
318 args.SetAt(index: 6, value: Bool::Get(value: cls.is_transformed_mixin_application()));
319 args.SetAt(index: 7, value: cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration);
320 args.SetAt(index: 8, value: Bool::Get(value: cls.is_enum_class()));
321 return CreateMirror(mirror_class_name: Symbols::_ClassMirror(), constructor_arguments: args);
322}
323
324static bool IsCensoredLibrary(const String& url) {
325 static const char* const censored_libraries[] = {
326 "dart:_builtin",
327 "dart:_vmservice",
328 "dart:vmservice_io",
329 };
330 for (const char* censored_library : censored_libraries) {
331 if (url.Equals(cstr: censored_library)) {
332 return true;
333 }
334 }
335 if (!Api::IsFfiEnabled() && url.Equals(str: Symbols::DartFfi())) {
336 return true;
337 }
338 return false;
339}
340
341static InstancePtr CreateLibraryMirror(Thread* thread, const Library& lib) {
342 Zone* zone = thread->zone();
343 ASSERT(!lib.IsNull());
344 const Array& args = Array::Handle(zone, ptr: Array::New(len: 3));
345 args.SetAt(index: 0, value: MirrorReference::Handle(zone, ptr: MirrorReference::New(referent: lib)));
346 String& str = String::Handle(zone);
347 str = lib.name();
348 args.SetAt(index: 1, value: str);
349 str = lib.url();
350 if (IsCensoredLibrary(url: str)) {
351 // Censored library (grumble).
352 return Instance::null();
353 }
354 args.SetAt(index: 2, value: str);
355 return CreateMirror(mirror_class_name: Symbols::_LibraryMirror(), constructor_arguments: args);
356}
357
358static InstancePtr CreateCombinatorMirror(const Object& identifiers,
359 bool is_show) {
360 const Array& args = Array::Handle(ptr: Array::New(len: 2));
361 args.SetAt(index: 0, value: identifiers);
362 args.SetAt(index: 1, value: Bool::Get(value: is_show));
363 return CreateMirror(mirror_class_name: Symbols::_CombinatorMirror(), constructor_arguments: args);
364}
365
366static InstancePtr CreateLibraryDependencyMirror(Thread* thread,
367 const Instance& importer,
368 const Library& importee,
369 const Array& show_names,
370 const Array& hide_names,
371 const Object& metadata,
372 const LibraryPrefix& prefix,
373 const String& prefix_name,
374 const bool is_import,
375 const bool is_deferred) {
376 const Instance& importee_mirror =
377 Instance::Handle(ptr: CreateLibraryMirror(thread, lib: importee));
378 if (importee_mirror.IsNull()) {
379 // Imported library is censored: censor the import.
380 return Instance::null();
381 }
382
383 intptr_t n = show_names.IsNull() ? 0 : show_names.Length();
384 intptr_t m = hide_names.IsNull() ? 0 : hide_names.Length();
385 const Array& combinators = Array::Handle(ptr: Array::New(len: n + m));
386 Object& t = Object::Handle();
387 intptr_t i = 0;
388 for (intptr_t j = 0; j < n; j++) {
389 t = show_names.At(index: j);
390 t = CreateCombinatorMirror(identifiers: t, is_show: true);
391 combinators.SetAt(index: i++, value: t);
392 }
393 for (intptr_t j = 0; j < m; j++) {
394 t = hide_names.At(index: j);
395 t = CreateCombinatorMirror(identifiers: t, is_show: false);
396 combinators.SetAt(index: i++, value: t);
397 }
398
399 const Array& args = Array::Handle(ptr: Array::New(len: 7));
400 args.SetAt(index: 0, value: importer);
401 if (importee.Loaded() || prefix.IsNull()) {
402 // A native extension is never "loaded" by the embedder. Use the fact that
403 // it doesn't have an prefix where asa deferred import does to distinguish
404 // it from a deferred import. It will appear like an empty library.
405 args.SetAt(index: 1, value: importee_mirror);
406 } else {
407 args.SetAt(index: 1, value: prefix);
408 }
409 args.SetAt(index: 2, value: combinators);
410 args.SetAt(index: 3, value: prefix_name);
411 args.SetAt(index: 4, value: Bool::Get(value: is_import));
412 args.SetAt(index: 5, value: Bool::Get(value: is_deferred));
413 args.SetAt(index: 6, value: metadata);
414 return CreateMirror(mirror_class_name: Symbols::_LibraryDependencyMirror(), constructor_arguments: args);
415}
416
417static InstancePtr CreateLibraryDependencyMirror(Thread* thread,
418 const Instance& importer,
419 const Namespace& ns,
420 const LibraryPrefix& prefix,
421 const bool is_import,
422 const bool is_deferred) {
423 const Library& importee = Library::Handle(ptr: ns.target());
424 const Array& show_names = Array::Handle(ptr: ns.show_names());
425 const Array& hide_names = Array::Handle(ptr: ns.hide_names());
426
427 const Library& owner = Library::Handle(ptr: ns.owner());
428 Object& metadata = Object::Handle(ptr: owner.GetMetadata(declaration: ns));
429 if (metadata.IsError()) {
430 Exceptions::PropagateError(error: Error::Cast(obj: metadata));
431 UNREACHABLE();
432 }
433
434 auto& prefix_name = String::Handle();
435 if (!prefix.IsNull()) {
436 prefix_name = prefix.name();
437 }
438
439 return CreateLibraryDependencyMirror(thread, importer, importee, show_names,
440 hide_names, metadata, prefix,
441 prefix_name, is_import, is_deferred);
442}
443
444DEFINE_NATIVE_ENTRY(LibraryMirror_fromPrefix, 0, 1) {
445 GET_NON_NULL_NATIVE_ARGUMENT(LibraryPrefix, prefix,
446 arguments->NativeArgAt(0));
447 const Library& deferred_lib = Library::Handle(ptr: prefix.GetLibrary(index: 0));
448 if (!deferred_lib.Loaded()) {
449 return Instance::null();
450 }
451 return CreateLibraryMirror(thread, lib: deferred_lib);
452}
453
454DEFINE_NATIVE_ENTRY(LibraryMirror_libraryDependencies, 0, 2) {
455 GET_NON_NULL_NATIVE_ARGUMENT(Instance, lib_mirror, arguments->NativeArgAt(0));
456 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
457 const Library& lib = Library::Handle(ptr: ref.GetLibraryReferent());
458
459 Array& ports = Array::Handle();
460 Namespace& ns = Namespace::Handle();
461 Instance& dep = Instance::Handle();
462 LibraryPrefix& prefix = LibraryPrefix::Handle();
463 GrowableObjectArray& deps =
464 GrowableObjectArray::Handle(ptr: GrowableObjectArray::New());
465
466 // Unprefixed imports.
467 ports = lib.imports();
468 for (intptr_t i = 0; i < ports.Length(); i++) {
469 ns ^= ports.At(index: i);
470 if (!ns.IsNull()) {
471 dep = CreateLibraryDependencyMirror(thread, importer: lib_mirror, ns, prefix, is_import: true,
472 is_deferred: false);
473 if (!dep.IsNull()) {
474 deps.Add(value: dep);
475 }
476 }
477 }
478
479 // Exports.
480 ports = lib.exports();
481 for (intptr_t i = 0; i < ports.Length(); i++) {
482 ns ^= ports.At(index: i);
483 dep = CreateLibraryDependencyMirror(thread, importer: lib_mirror, ns, prefix, is_import: false,
484 is_deferred: false);
485 if (!dep.IsNull()) {
486 deps.Add(value: dep);
487 }
488 }
489
490 // Prefixed imports.
491 DictionaryIterator entries(lib);
492 Object& entry = Object::Handle();
493 while (entries.HasNext()) {
494 entry = entries.GetNext();
495 if (entry.IsLibraryPrefix()) {
496 prefix ^= entry.ptr();
497 ports = prefix.imports();
498 for (intptr_t i = 0; i < ports.Length(); i++) {
499 ns ^= ports.At(index: i);
500 if (!ns.IsNull()) {
501 dep = CreateLibraryDependencyMirror(thread, importer: lib_mirror, ns, prefix,
502 is_import: true, is_deferred: prefix.is_deferred_load());
503 if (!dep.IsNull()) {
504 deps.Add(value: dep);
505 }
506 }
507 }
508 }
509 }
510
511 return deps.ptr();
512}
513
514static InstancePtr CreateTypeMirror(const AbstractType& type) {
515 ASSERT(type.IsFinalized());
516 ASSERT(type.IsCanonical());
517
518 if (type.IsFunctionType()) {
519 return CreateFunctionTypeMirror(type);
520 }
521 if (type.IsRecordType()) {
522 const Class& cls =
523 Class::Handle(ptr: IsolateGroup::Current()->object_store()->record_class());
524 return CreateClassMirror(cls, type: AbstractType::Handle(ptr: cls.DeclarationType()),
525 is_declaration: Bool::False(), owner_mirror: Object::null_instance());
526 }
527 if (type.HasTypeClass()) {
528 const Class& cls = Class::Handle(ptr: type.type_class());
529 // Handle void and dynamic types.
530 if (cls.IsVoidClass()) {
531 Array& args = Array::Handle(ptr: Array::New(len: 1));
532 args.SetAt(index: 0, value: Symbols::Void());
533 return CreateMirror(mirror_class_name: Symbols::_SpecialTypeMirror(), constructor_arguments: args);
534 } else if (cls.IsDynamicClass()) {
535 Array& args = Array::Handle(ptr: Array::New(len: 1));
536 args.SetAt(index: 0, value: Symbols::Dynamic());
537 return CreateMirror(mirror_class_name: Symbols::_SpecialTypeMirror(), constructor_arguments: args);
538 } else if (cls.IsNeverClass()) {
539 Array& args = Array::Handle(ptr: Array::New(len: 1));
540 args.SetAt(index: 0, value: Symbols::Never());
541 return CreateMirror(mirror_class_name: Symbols::_SpecialTypeMirror(), constructor_arguments: args);
542 }
543 // TODO(regis): Until mirrors reflect nullability, force kLegacy, except for
544 // Null type, which should remain nullable.
545 if (!type.IsNullType()) {
546 Type& legacy_type = Type::Handle(
547 ptr: Type::Cast(obj: type).ToNullability(value: Nullability::kLegacy, space: Heap::kOld));
548 legacy_type ^= legacy_type.Canonicalize(thread: Thread::Current());
549 return CreateClassMirror(cls, type: legacy_type, is_declaration: Bool::False(),
550 owner_mirror: Object::null_instance());
551 }
552 return CreateClassMirror(cls, type, is_declaration: Bool::False(), owner_mirror: Object::null_instance());
553 } else if (type.IsTypeParameter()) {
554 // TODO(regis): Until mirrors reflect nullability, force kLegacy.
555 TypeParameter& legacy_type =
556 TypeParameter::Handle(ptr: TypeParameter::Cast(obj: type).ToNullability(
557 value: Nullability::kLegacy, space: Heap::kOld));
558 legacy_type ^= legacy_type.Canonicalize(thread: Thread::Current());
559 return CreateTypeVariableMirror(param: legacy_type, owner_mirror: Object::null_instance());
560 }
561 UNREACHABLE();
562 return Instance::null();
563}
564
565static InstancePtr CreateIsolateMirror() {
566 Thread* thread = Thread::Current();
567 Isolate* isolate = thread->isolate();
568 const String& debug_name = String::Handle(ptr: String::New(cstr: isolate->name()));
569 const Library& root_library = Library::Handle(
570 zone: thread->zone(), ptr: isolate->group()->object_store()->root_library());
571 const Instance& root_library_mirror =
572 Instance::Handle(ptr: CreateLibraryMirror(thread, lib: root_library));
573
574 const Array& args = Array::Handle(ptr: Array::New(len: 2));
575 args.SetAt(index: 0, value: debug_name);
576 args.SetAt(index: 1, value: root_library_mirror);
577 return CreateMirror(mirror_class_name: Symbols::_IsolateMirror(), constructor_arguments: args);
578}
579
580static void VerifyMethodKindShifts() {
581#ifdef DEBUG
582 Thread* thread = Thread::Current();
583 Zone* zone = thread->zone();
584 const Library& lib = Library::Handle(zone, Library::MirrorsLibrary());
585 const Class& cls = Class::Handle(
586 zone, lib.LookupClassAllowPrivate(Symbols::_MethodMirror()));
587 Error& error = Error::Handle(zone);
588 error ^= cls.EnsureIsFinalized(thread);
589 ASSERT(error.IsNull());
590
591 Field& field = Field::Handle(zone);
592 Smi& value = Smi::Handle(zone);
593 String& fname = String::Handle(zone);
594
595#define CHECK_KIND_SHIFT(name) \
596 fname ^= String::New(#name); \
597 field = cls.LookupField(fname); \
598 ASSERT(!field.IsNull()); \
599 if (field.IsUninitialized()) { \
600 error ^= field.InitializeStatic(); \
601 ASSERT(error.IsNull()); \
602 } \
603 value ^= field.StaticValue(); \
604 ASSERT(value.Value() == Mirrors::name);
605 MIRRORS_KIND_SHIFT_LIST(CHECK_KIND_SHIFT)
606#undef CHECK_KIND_SHIFT
607#endif
608}
609
610static AbstractTypePtr InstantiateType(const AbstractType& type,
611 const AbstractType& instantiator) {
612 // Generic function type parameters are not reified, but mapped to dynamic,
613 // i.e. all function type parameters are free with a null vector.
614 ASSERT(type.IsFinalized());
615 ASSERT(type.IsCanonical());
616 Thread* thread = Thread::Current();
617
618 if (type.IsInstantiated()) {
619 return type.Canonicalize(thread);
620 }
621 TypeArguments& instantiator_type_args = TypeArguments::Handle();
622 if (!instantiator.IsNull() && instantiator.IsType()) {
623 ASSERT(instantiator.IsFinalized());
624 if (instantiator.type_class_id() == kInstanceCid) {
625 // Handle types created in ClosureMirror_function.
626 instantiator_type_args = instantiator.arguments();
627 } else {
628 instantiator_type_args =
629 Type::Cast(obj: instantiator)
630 .GetInstanceTypeArguments(thread, /*canonicalize=*/false);
631 }
632 }
633 AbstractType& result = AbstractType::Handle(ptr: type.InstantiateFrom(
634 instantiator_type_arguments: instantiator_type_args, function_type_arguments: Object::null_type_arguments(), num_free_fun_type_params: kAllFree,
635 space: Heap::kOld));
636 ASSERT(result.IsFinalized());
637 return result.Canonicalize(thread);
638}
639
640DEFINE_NATIVE_ENTRY(MirrorSystem_libraries, 0, 0) {
641 const GrowableObjectArray& libraries = GrowableObjectArray::Handle(
642 zone, ptr: isolate->group()->object_store()->libraries());
643
644 const intptr_t num_libraries = libraries.Length();
645 const GrowableObjectArray& library_mirrors = GrowableObjectArray::Handle(
646 zone, ptr: GrowableObjectArray::New(capacity: num_libraries));
647 Library& library = Library::Handle(zone);
648 Instance& library_mirror = Instance::Handle(zone);
649
650 for (int i = 0; i < num_libraries; i++) {
651 library ^= libraries.At(index: i);
652 library_mirror = CreateLibraryMirror(thread, lib: library);
653 if (!library_mirror.IsNull() && library.Loaded()) {
654 library_mirrors.Add(value: library_mirror);
655 }
656 }
657 return library_mirrors.ptr();
658}
659
660DEFINE_NATIVE_ENTRY(MirrorSystem_isolate, 0, 0) {
661 VerifyMethodKindShifts();
662
663 return CreateIsolateMirror();
664}
665
666static void ThrowLanguageError(const char* message) {
667 const Error& error =
668 Error::Handle(ptr: LanguageError::New(formatted_message: String::Handle(ptr: String::New(cstr: message))));
669 Exceptions::PropagateError(error);
670}
671
672DEFINE_NATIVE_ENTRY(IsolateMirror_loadUri, 0, 1) {
673 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(0));
674
675 if (!isolate->group()->HasTagHandler()) {
676 ThrowLanguageError(message: "no library handler registered");
677 }
678
679 NoReloadScope no_reload(thread);
680
681 // Canonicalize library URI.
682 String& canonical_uri = String::Handle(zone);
683 if (uri.StartsWith(other: Symbols::DartScheme())) {
684 canonical_uri = uri.ptr();
685 } else {
686 isolate->BlockClassFinalization();
687 const Object& result = Object::Handle(
688 zone, ptr: isolate->group()->CallTagHandler(
689 tag: Dart_kCanonicalizeUrl,
690 arg1: Library::Handle(
691 zone, ptr: isolate->group()->object_store()->root_library()),
692 arg2: uri));
693 isolate->UnblockClassFinalization();
694 if (result.IsError()) {
695 if (result.IsLanguageError()) {
696 Exceptions::ThrowCompileTimeError(error: LanguageError::Cast(obj: result));
697 }
698 Exceptions::PropagateError(error: Error::Cast(obj: result));
699 } else if (!result.IsString()) {
700 ThrowLanguageError(message: "library handler failed URI canonicalization");
701 }
702
703 canonical_uri ^= result.ptr();
704 }
705
706 // Return the existing library if it has already been loaded.
707 Library& library =
708 Library::Handle(zone, ptr: Library::LookupLibrary(thread, url: canonical_uri));
709 if (!library.IsNull()) {
710 return CreateLibraryMirror(thread, lib: library);
711 }
712
713 // Request the embedder to load the library.
714 isolate->BlockClassFinalization();
715 Object& result = Object::Handle(
716 zone, ptr: isolate->group()->CallTagHandler(
717 tag: Dart_kImportTag,
718 arg1: Library::Handle(
719 zone, ptr: isolate->group()->object_store()->root_library()),
720 arg2: canonical_uri));
721 isolate->UnblockClassFinalization();
722 if (result.IsError()) {
723 if (result.IsLanguageError()) {
724 Exceptions::ThrowCompileTimeError(error: LanguageError::Cast(obj: result));
725 }
726 Exceptions::PropagateError(error: Error::Cast(obj: result));
727 }
728
729 // This code assumes a synchronous tag handler (which dart::bin and tonic
730 // provide). Strictly though we should complete a future in response to
731 // Dart_FinalizeLoading.
732
733 if (!ClassFinalizer::ProcessPendingClasses()) {
734 Exceptions::PropagateError(error: Error::Handle(ptr: thread->sticky_error()));
735 }
736
737 // Prefer the tag handler's idea of which library is represented by the URI.
738 if (result.IsLibrary()) {
739 return CreateLibraryMirror(thread, lib: Library::Cast(obj: result));
740 }
741
742 if (result.IsNull()) {
743 library = Library::LookupLibrary(thread, url: canonical_uri);
744 if (!library.IsNull()) {
745 return CreateLibraryMirror(thread, lib: library);
746 }
747 }
748
749 FATAL("Non-library from tag handler");
750}
751
752DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 0, 1) {
753 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
754 ASSERT(type.IsFinalized());
755 const Class& cls = Class::Handle(
756 ptr: type.IsFunctionType()
757 ? IsolateGroup::Current()->object_store()->closure_class()
758 : type.type_class());
759 ASSERT(!cls.IsNull());
760 if (cls.IsDynamicClass() || cls.IsVoidClass() || cls.IsNeverClass()) {
761 Exceptions::ThrowArgumentError(arg: type);
762 UNREACHABLE();
763 }
764 return CreateClassMirror(cls, type: AbstractType::Handle(ptr: cls.DeclarationType()),
765 is_declaration: Bool::True(), // is_declaration
766 owner_mirror: Object::null_instance());
767}
768
769DEFINE_NATIVE_ENTRY(Mirrors_makeLocalTypeMirror, 0, 1) {
770 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
771 return CreateTypeMirror(type);
772}
773
774DEFINE_NATIVE_ENTRY(Mirrors_instantiateGenericType, 0, 2) {
775 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
776 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(1));
777
778 const Class& clz = Class::Handle(
779 ptr: type.IsFunctionType()
780 ? IsolateGroup::Current()->object_store()->closure_class()
781 : type.type_class());
782 if (!clz.IsGeneric()) {
783 const Array& error_args = Array::Handle(ptr: Array::New(len: 3));
784 error_args.SetAt(index: 0, value: type);
785 error_args.SetAt(index: 1, value: String::Handle(ptr: String::New(cstr: "key")));
786 error_args.SetAt(index: 2, value: String::Handle(ptr: String::New(
787 cstr: "Type must be a generic class or function.")));
788 Exceptions::ThrowByType(type: Exceptions::kArgumentValue, arguments: error_args);
789 UNREACHABLE();
790 }
791 if (clz.NumTypeParameters() != args.Length()) {
792 const Array& error_args = Array::Handle(ptr: Array::New(len: 3));
793 error_args.SetAt(index: 0, value: args);
794 error_args.SetAt(index: 1, value: String::Handle(ptr: String::New(cstr: "typeArguments")));
795 error_args.SetAt(index: 2, value: String::Handle(ptr: String::New(
796 cstr: "Number of type arguments does not match.")));
797 Exceptions::ThrowByType(type: Exceptions::kArgumentValue, arguments: error_args);
798 UNREACHABLE();
799 }
800
801 intptr_t num_expected_type_arguments = args.Length();
802 TypeArguments& type_args_obj = TypeArguments::Handle();
803 type_args_obj = TypeArguments::New(len: num_expected_type_arguments);
804 AbstractType& type_arg = AbstractType::Handle();
805 Instance& instance = Instance::Handle();
806 for (intptr_t i = 0; i < args.Length(); i++) {
807 instance ^= args.At(index: i);
808 if (!instance.IsType()) {
809 const Array& error_args = Array::Handle(ptr: Array::New(len: 3));
810 error_args.SetAt(index: 0, value: args);
811 error_args.SetAt(index: 1, value: String::Handle(ptr: String::New(cstr: "typeArguments")));
812 error_args.SetAt(index: 2, value: String::Handle(ptr: String::New(
813 cstr: "Type arguments must be instances of Type.")));
814 Exceptions::ThrowByType(type: Exceptions::kArgumentValue, arguments: error_args);
815 UNREACHABLE();
816 }
817 type_arg ^= args.At(index: i);
818 type_args_obj.SetTypeAt(index: i, value: type_arg);
819 }
820
821 Type& instantiated_type = Type::Handle(ptr: Type::New(clazz: clz, arguments: type_args_obj));
822 instantiated_type ^= ClassFinalizer::FinalizeType(type: instantiated_type);
823 return instantiated_type.ptr();
824}
825
826DEFINE_NATIVE_ENTRY(Mirrors_mangleName, 0, 2) {
827 GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(0));
828 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
829 const Library& lib = Library::Handle(ptr: ref.GetLibraryReferent());
830 return lib.IsPrivate(name) ? lib.PrivateName(name) : name.ptr();
831}
832
833DEFINE_NATIVE_ENTRY(MirrorReference_equals, 0, 2) {
834 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, a, arguments->NativeArgAt(0));
835 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, b, arguments->NativeArgAt(1));
836 return Bool::Get(value: a.referent() == b.referent()).ptr();
837}
838
839DEFINE_NATIVE_ENTRY(DeclarationMirror_metadata, 0, 1) {
840 GET_NON_NULL_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(0));
841 Object& decl = Object::Handle();
842 if (reflectee.IsMirrorReference()) {
843 const MirrorReference& decl_ref = MirrorReference::Cast(obj: reflectee);
844 decl = decl_ref.referent();
845 } else if (reflectee.IsTypeParameter()) {
846 decl = reflectee.ptr();
847 } else {
848 UNREACHABLE();
849 }
850
851 Class& klass = Class::Handle();
852 Library& library = Library::Handle();
853
854 if (decl.IsClass()) {
855 klass ^= decl.ptr();
856 library = klass.library();
857 } else if (decl.IsFunction()) {
858 klass = Function::Cast(obj: decl).Owner();
859 library = klass.library();
860 } else if (decl.IsField()) {
861 klass = Field::Cast(obj: decl).Owner();
862 library = klass.library();
863 } else if (decl.IsLibrary()) {
864 library ^= decl.ptr();
865 } else if (decl.IsTypeParameter()) {
866 // There is no reference from a canonical type parameter to its declaration.
867 return Object::empty_array().ptr();
868 } else {
869 return Object::empty_array().ptr();
870 }
871
872 const Object& metadata = Object::Handle(ptr: library.GetMetadata(declaration: decl));
873 if (metadata.IsError()) {
874 Exceptions::PropagateError(error: Error::Cast(obj: metadata));
875 }
876 return metadata.ptr();
877}
878
879DEFINE_NATIVE_ENTRY(FunctionTypeMirror_call_method, 0, 2) {
880 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner_mirror,
881 arguments->NativeArgAt(0));
882 // Return get:call() method on class _Closure.
883 const auto& getter_name = Symbols::GetCall();
884 const Class& closure_class =
885 Class::Handle(ptr: IsolateGroup::Current()->object_store()->closure_class());
886 const Function& get_call = Function::Handle(
887 ptr: Resolver::ResolveDynamicAnyArgs(zone, receiver_class: closure_class, function_name: getter_name,
888 /*allow_add=*/false));
889 ASSERT(!get_call.IsNull());
890 return CreateMethodMirror(func: get_call, owner_mirror, instantiator: AbstractType::Handle());
891}
892
893DEFINE_NATIVE_ENTRY(FunctionTypeMirror_parameters, 0, 2) {
894 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0));
895 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
896 const FunctionType& sig = FunctionType::Handle(ptr: ref.GetFunctionTypeReferent());
897 return CreateParameterMirrorList(func: Object::null_function(), signature: sig, owner_mirror: owner);
898}
899
900DEFINE_NATIVE_ENTRY(FunctionTypeMirror_return_type, 0, 1) {
901 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
902 const FunctionType& sig = FunctionType::Handle(ptr: ref.GetFunctionTypeReferent());
903 ASSERT(!sig.IsNull());
904 AbstractType& type = AbstractType::Handle(ptr: sig.result_type());
905 // Signatures of function types are instantiated, but not canonical.
906 return type.Canonicalize(thread);
907}
908
909DEFINE_NATIVE_ENTRY(ClassMirror_libraryUri, 0, 1) {
910 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
911 const Class& klass = Class::Handle(ptr: ref.GetClassReferent());
912 const Library& library = Library::Handle(ptr: klass.library());
913 ASSERT(!library.IsNull());
914 return library.url();
915}
916
917DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 0, 1) {
918 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
919 ASSERT(type.IsFinalized());
920 const Class& cls = Class::Handle(
921 ptr: type.IsFunctionType()
922 ? IsolateGroup::Current()->object_store()->closure_class()
923 : type.type_class());
924 const AbstractType& super_type = AbstractType::Handle(ptr: cls.super_type());
925 ASSERT(super_type.IsNull() || super_type.IsFinalized());
926 return super_type.ptr();
927}
928
929DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 0, 1) {
930 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
931 ASSERT(type.IsFinalized());
932 const Class& cls = Class::Handle(
933 ptr: type.IsFunctionType()
934 ? IsolateGroup::Current()->object_store()->closure_class()
935 : type.type_class());
936 const AbstractType& super_type = AbstractType::Handle(ptr: cls.super_type());
937 return InstantiateType(type: super_type, instantiator: type);
938}
939
940DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 0, 1) {
941 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
942 ASSERT(type.IsFinalized());
943 const Class& cls = Class::Handle(
944 ptr: type.IsFunctionType()
945 ? IsolateGroup::Current()->object_store()->closure_class()
946 : type.type_class());
947 const Error& error = Error::Handle(ptr: cls.EnsureIsFinalized(thread));
948 if (!error.IsNull()) {
949 Exceptions::PropagateError(error);
950 }
951
952 return cls.interfaces();
953}
954
955DEFINE_NATIVE_ENTRY(ClassMirror_interfaces_instantiated, 0, 1) {
956 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
957 ASSERT(type.IsFinalized());
958 const Class& cls = Class::Handle(
959 ptr: type.IsFunctionType()
960 ? IsolateGroup::Current()->object_store()->closure_class()
961 : type.type_class());
962 const Error& error = Error::Handle(ptr: cls.EnsureIsFinalized(thread));
963 if (!error.IsNull()) {
964 Exceptions::PropagateError(error);
965 }
966
967 Array& interfaces = Array::Handle(ptr: cls.interfaces());
968 Array& interfaces_inst = Array::Handle(ptr: Array::New(len: interfaces.Length()));
969 AbstractType& interface = AbstractType::Handle();
970
971 for (int i = 0; i < interfaces.Length(); i++) {
972 interface ^= interfaces.At(index: i);
973 interface = InstantiateType(type: interface, instantiator: type);
974 interfaces_inst.SetAt(index: i, value: interface);
975 }
976
977 return interfaces_inst.ptr();
978}
979
980DEFINE_NATIVE_ENTRY(ClassMirror_mixin, 0, 1) {
981 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
982 ASSERT(type.IsFinalized());
983 const Class& cls = Class::Handle(
984 ptr: type.IsFunctionType()
985 ? IsolateGroup::Current()->object_store()->closure_class()
986 : type.type_class());
987 AbstractType& mixin_type = AbstractType::Handle();
988 if (cls.is_transformed_mixin_application()) {
989 const Array& interfaces = Array::Handle(ptr: cls.interfaces());
990 mixin_type ^= interfaces.At(index: interfaces.Length() - 1);
991 }
992 ASSERT(mixin_type.IsNull() || mixin_type.IsFinalized());
993 return mixin_type.ptr();
994}
995
996DEFINE_NATIVE_ENTRY(ClassMirror_mixin_instantiated, 0, 2) {
997 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
998 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, instantiator,
999 arguments->NativeArgAt(1));
1000 ASSERT(type.IsFinalized());
1001 const Class& cls = Class::Handle(
1002 ptr: type.IsFunctionType()
1003 ? IsolateGroup::Current()->object_store()->closure_class()
1004 : type.type_class());
1005 AbstractType& mixin_type = AbstractType::Handle();
1006 if (cls.is_transformed_mixin_application()) {
1007 const Array& interfaces = Array::Handle(ptr: cls.interfaces());
1008 mixin_type ^= interfaces.At(index: interfaces.Length() - 1);
1009 }
1010 if (mixin_type.IsNull()) {
1011 return mixin_type.ptr();
1012 }
1013
1014 return InstantiateType(type: mixin_type, instantiator);
1015}
1016
1017DEFINE_NATIVE_ENTRY(ClassMirror_members, 0, 3) {
1018 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner_mirror,
1019 arguments->NativeArgAt(0));
1020 GET_NATIVE_ARGUMENT(AbstractType, owner_instantiator,
1021 arguments->NativeArgAt(1));
1022 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(2));
1023 const Class& klass = Class::Handle(ptr: ref.GetClassReferent());
1024
1025 const Error& error = Error::Handle(ptr: klass.EnsureIsFinalized(thread));
1026 if (!error.IsNull()) {
1027 Exceptions::PropagateError(error);
1028 }
1029
1030 const Array& fields = Array::Handle(ptr: klass.fields());
1031 const intptr_t num_fields = fields.Length();
1032
1033 const Array& functions = Array::Handle(ptr: klass.current_functions());
1034 const intptr_t num_functions = functions.Length();
1035
1036 Instance& member_mirror = Instance::Handle();
1037 const GrowableObjectArray& member_mirrors = GrowableObjectArray::Handle(
1038 ptr: GrowableObjectArray::New(capacity: num_fields + num_functions));
1039
1040 Field& field = Field::Handle();
1041 for (intptr_t i = 0; i < num_fields; i++) {
1042 field ^= fields.At(index: i);
1043 if (field.is_reflectable()) {
1044 member_mirror = CreateVariableMirror(field, owner_mirror);
1045 member_mirrors.Add(value: member_mirror);
1046 }
1047 }
1048
1049 Function& func = Function::Handle();
1050 for (intptr_t i = 0; i < num_functions; i++) {
1051 func ^= functions.At(index: i);
1052 if (func.is_reflectable() &&
1053 (func.kind() == UntaggedFunction::kRegularFunction ||
1054 func.kind() == UntaggedFunction::kGetterFunction ||
1055 func.kind() == UntaggedFunction::kSetterFunction)) {
1056 member_mirror =
1057 CreateMethodMirror(func, owner_mirror, instantiator: owner_instantiator);
1058 member_mirrors.Add(value: member_mirror);
1059 }
1060 }
1061
1062 return member_mirrors.ptr();
1063}
1064
1065DEFINE_NATIVE_ENTRY(ClassMirror_constructors, 0, 3) {
1066 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner_mirror,
1067 arguments->NativeArgAt(0));
1068 GET_NATIVE_ARGUMENT(AbstractType, owner_instantiator,
1069 arguments->NativeArgAt(1));
1070 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(2));
1071 const Class& klass = Class::Handle(ptr: ref.GetClassReferent());
1072
1073 const Error& error = Error::Handle(ptr: klass.EnsureIsFinalized(thread));
1074 if (!error.IsNull()) {
1075 Exceptions::PropagateError(error);
1076 }
1077
1078 const Array& functions = Array::Handle(ptr: klass.current_functions());
1079 const intptr_t num_functions = functions.Length();
1080
1081 Instance& constructor_mirror = Instance::Handle();
1082 const GrowableObjectArray& constructor_mirrors =
1083 GrowableObjectArray::Handle(ptr: GrowableObjectArray::New(capacity: num_functions));
1084
1085 Function& func = Function::Handle();
1086 for (intptr_t i = 0; i < num_functions; i++) {
1087 func ^= functions.At(index: i);
1088 if (func.is_reflectable() &&
1089 func.kind() == UntaggedFunction::kConstructor) {
1090 constructor_mirror =
1091 CreateMethodMirror(func, owner_mirror, instantiator: owner_instantiator);
1092 constructor_mirrors.Add(value: constructor_mirror);
1093 }
1094 }
1095
1096 return constructor_mirrors.ptr();
1097}
1098
1099DEFINE_NATIVE_ENTRY(LibraryMirror_members, 0, 2) {
1100 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner_mirror,
1101 arguments->NativeArgAt(0));
1102 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
1103 const Library& library = Library::Handle(zone, ptr: ref.GetLibraryReferent());
1104
1105 library.EnsureTopLevelClassIsFinalized();
1106
1107 Instance& member_mirror = Instance::Handle(zone);
1108 const GrowableObjectArray& member_mirrors =
1109 GrowableObjectArray::Handle(zone, ptr: GrowableObjectArray::New());
1110
1111 Object& entry = Object::Handle(zone);
1112 DictionaryIterator entries(library);
1113
1114 Error& error = Error::Handle(zone);
1115 AbstractType& type = AbstractType::Handle(zone);
1116
1117 while (entries.HasNext()) {
1118 entry = entries.GetNext();
1119 if (entry.IsClass()) {
1120 const Class& klass = Class::Cast(obj: entry);
1121 ASSERT(!klass.IsDynamicClass());
1122 ASSERT(!klass.IsVoidClass());
1123 ASSERT(!klass.IsNeverClass());
1124 error = klass.EnsureIsFinalized(thread);
1125 if (!error.IsNull()) {
1126 Exceptions::PropagateError(error);
1127 }
1128 type = klass.DeclarationType();
1129 member_mirror = CreateClassMirror(cls: klass, type,
1130 is_declaration: Bool::True(), // is_declaration
1131 owner_mirror);
1132 member_mirrors.Add(value: member_mirror);
1133 } else if (entry.IsField()) {
1134 const Field& field = Field::Cast(obj: entry);
1135 if (field.is_reflectable()) {
1136 member_mirror = CreateVariableMirror(field, owner_mirror);
1137 member_mirrors.Add(value: member_mirror);
1138 }
1139 } else if (entry.IsFunction()) {
1140 const Function& func = Function::Cast(obj: entry);
1141 if (func.is_reflectable() &&
1142 (func.kind() == UntaggedFunction::kRegularFunction ||
1143 func.kind() == UntaggedFunction::kGetterFunction ||
1144 func.kind() == UntaggedFunction::kSetterFunction)) {
1145 member_mirror =
1146 CreateMethodMirror(func, owner_mirror, instantiator: AbstractType::Handle());
1147 member_mirrors.Add(value: member_mirror);
1148 }
1149 }
1150 }
1151
1152 return member_mirrors.ptr();
1153}
1154
1155DEFINE_NATIVE_ENTRY(ClassMirror_type_variables, 0, 1) {
1156 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
1157 const Class& klass = Class::Handle(ptr: ref.GetClassReferent());
1158 const Error& error = Error::Handle(zone, ptr: klass.EnsureIsFinalized(thread));
1159 if (!error.IsNull()) {
1160 Exceptions::PropagateError(error);
1161 UNREACHABLE();
1162 }
1163 return CreateTypeVariableList(cls: klass);
1164}
1165
1166DEFINE_NATIVE_ENTRY(ClassMirror_type_arguments, 0, 1) {
1167 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
1168
1169 const Class& cls = Class::Handle(
1170 ptr: type.IsFunctionType()
1171 ? IsolateGroup::Current()->object_store()->closure_class()
1172 : type.type_class());
1173 const intptr_t num_params = cls.NumTypeParameters();
1174
1175 if (num_params == 0) {
1176 return Object::empty_array().ptr();
1177 }
1178
1179 const Array& result = Array::Handle(ptr: Array::New(len: num_params));
1180 AbstractType& arg_type = AbstractType::Handle();
1181 Instance& type_mirror = Instance::Handle();
1182 const TypeArguments& args =
1183 TypeArguments::Handle(ptr: Type::Cast(obj: type).arguments());
1184
1185 // Handle argument lists that have been optimized away, because either no
1186 // arguments have been provided, or all arguments are dynamic. Return a list
1187 // of typemirrors on dynamic in this case.
1188 if (args.IsNull()) {
1189 arg_type = Object::dynamic_type().ptr();
1190 type_mirror = CreateTypeMirror(type: arg_type);
1191 for (intptr_t i = 0; i < num_params; i++) {
1192 result.SetAt(index: i, value: type_mirror);
1193 }
1194 return result.ptr();
1195 }
1196
1197 ASSERT(args.Length() == num_params);
1198 for (intptr_t i = 0; i < num_params; i++) {
1199 arg_type = args.TypeAt(index: i);
1200 type_mirror = CreateTypeMirror(type: arg_type);
1201 result.SetAt(index: i, value: type_mirror);
1202 }
1203 return result.ptr();
1204}
1205
1206DEFINE_NATIVE_ENTRY(TypeVariableMirror_owner, 0, 1) {
1207 // Type parameters do not have a reference to their owner anymore.
1208 const AbstractType& type = AbstractType::Handle(ptr: Type::NullType());
1209 Class& owner = Class::Handle(ptr: type.type_class());
1210 return CreateClassMirror(cls: owner, type,
1211 is_declaration: Bool::True(), // is_declaration
1212 owner_mirror: Instance::null_instance());
1213}
1214
1215DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 0, 1) {
1216 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0));
1217 return param.bound();
1218}
1219
1220DEFINE_NATIVE_ENTRY(InstanceMirror_invoke, 0, 5) {
1221 // Argument 0 is the mirror, which is unused by the native. It exists
1222 // because this native is an instance method in order to be polymorphic
1223 // with its cousins.
1224 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1));
1225 GET_NON_NULL_NATIVE_ARGUMENT(String, function_name,
1226 arguments->NativeArgAt(2));
1227 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3));
1228 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4));
1229 RETURN_OR_PROPAGATE(reflectee.Invoke(function_name, args, arg_names));
1230}
1231
1232DEFINE_NATIVE_ENTRY(InstanceMirror_invokeGetter, 0, 3) {
1233 // Argument 0 is the mirror, which is unused by the native. It exists
1234 // because this native is an instance method in order to be polymorphic
1235 // with its cousins.
1236 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1));
1237 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2));
1238 RETURN_OR_PROPAGATE(reflectee.InvokeGetter(getter_name));
1239}
1240
1241DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 0, 4) {
1242 // Argument 0 is the mirror, which is unused by the native. It exists
1243 // because this native is an instance method in order to be polymorphic
1244 // with its cousins.
1245 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1));
1246 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2));
1247 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3));
1248 RETURN_OR_PROPAGATE(reflectee.InvokeSetter(setter_name, value));
1249}
1250
1251DEFINE_NATIVE_ENTRY(InstanceMirror_computeType, 0, 1) {
1252 GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0));
1253 const AbstractType& type = AbstractType::Handle(ptr: instance.GetType(space: Heap::kNew));
1254 // The static type of null is specified to be the bottom type, however, the
1255 // runtime type of null is the Null type, which we correctly return here.
1256 return type.Canonicalize(thread);
1257}
1258
1259DEFINE_NATIVE_ENTRY(ClosureMirror_function, 0, 1) {
1260 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
1261 ASSERT(!closure.IsNull());
1262
1263 Function& function = Function::Handle();
1264 bool callable = closure.IsCallable(function: &function);
1265 if (callable) {
1266 const Function& parent = Function::Handle(ptr: function.parent_function());
1267 if (function.IsImplicitClosureFunction() || parent.is_extension_member()) {
1268 // The VM uses separate Functions for tear-offs, but the mirrors consider
1269 // the tear-offs to be the same as the torn-off methods. Avoid handing out
1270 // a reference to the tear-off here to avoid a special case in the
1271 // the equality test.
1272 // In the case of extension methods also we avoid handing out a reference
1273 // to the tear-off and instead get the parent function of the
1274 // anonymous closure.
1275 function = parent.ptr();
1276 }
1277
1278 Type& instantiator = Type::Handle();
1279 if (closure.IsClosure()) {
1280 const TypeArguments& arguments = TypeArguments::Handle(
1281 ptr: Closure::Cast(obj: closure).instantiator_type_arguments());
1282 // TODO(regis): Mirrors need work to properly support generic functions.
1283 // The 'instantiator' created below should not be a type, but two type
1284 // argument vectors: instantiator_type_arguments and
1285 // function_type_arguments.
1286 const Class& cls = Class::Handle(
1287 ptr: IsolateGroup::Current()->object_store()->object_class());
1288 instantiator = Type::New(clazz: cls, arguments);
1289 instantiator.SetIsFinalized();
1290 }
1291 return CreateMethodMirror(func: function, owner_mirror: Instance::null_instance(),
1292 instantiator);
1293 }
1294 return Instance::null();
1295}
1296
1297DEFINE_NATIVE_ENTRY(ClassMirror_invoke, 0, 5) {
1298 // Argument 0 is the mirror, which is unused by the native. It exists
1299 // because this native is an instance method in order to be polymorphic
1300 // with its cousins.
1301 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
1302 const Class& klass = Class::Handle(ptr: ref.GetClassReferent());
1303 GET_NON_NULL_NATIVE_ARGUMENT(String, function_name,
1304 arguments->NativeArgAt(2));
1305 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3));
1306 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4));
1307 RETURN_OR_PROPAGATE(klass.Invoke(function_name, args, arg_names));
1308}
1309
1310DEFINE_NATIVE_ENTRY(ClassMirror_invokeGetter, 0, 3) {
1311 // Argument 0 is the mirror, which is unused by the native. It exists
1312 // because this native is an instance method in order to be polymorphic
1313 // with its cousins.
1314 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
1315 const Class& klass = Class::Handle(ptr: ref.GetClassReferent());
1316 const Error& error = Error::Handle(zone, ptr: klass.EnsureIsFinalized(thread));
1317 if (!error.IsNull()) {
1318 Exceptions::PropagateError(error);
1319 UNREACHABLE();
1320 }
1321 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2));
1322 RETURN_OR_PROPAGATE(klass.InvokeGetter(getter_name, true));
1323}
1324
1325DEFINE_NATIVE_ENTRY(ClassMirror_invokeSetter, 0, 4) {
1326 // Argument 0 is the mirror, which is unused by the native. It exists
1327 // because this native is an instance method in order to be polymorphic
1328 // with its cousins.
1329 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
1330 const Class& klass = Class::Handle(ptr: ref.GetClassReferent());
1331 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2));
1332 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3));
1333 RETURN_OR_PROPAGATE(klass.InvokeSetter(setter_name, value));
1334}
1335
1336DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 0, 5) {
1337 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
1338 const Class& klass = Class::Handle(ptr: ref.GetClassReferent());
1339 GET_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(1));
1340 GET_NON_NULL_NATIVE_ARGUMENT(String, constructor_name,
1341 arguments->NativeArgAt(2));
1342 GET_NON_NULL_NATIVE_ARGUMENT(Array, explicit_args, arguments->NativeArgAt(3));
1343 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4));
1344
1345 const Error& error =
1346 Error::Handle(zone, ptr: klass.EnsureIsAllocateFinalized(thread));
1347 if (!error.IsNull()) {
1348 Exceptions::PropagateError(error);
1349 UNREACHABLE();
1350 }
1351
1352 // By convention, the static function implementing a named constructor 'C'
1353 // for class 'A' is labeled 'A.C', and the static function implementing the
1354 // unnamed constructor for class 'A' is labeled 'A.'.
1355 // This convention prevents users from explicitly calling constructors.
1356 const String& klass_name = String::Handle(ptr: klass.Name());
1357 String& external_constructor_name = String::Handle(ptr: klass_name.ptr());
1358 String& internal_constructor_name =
1359 String::Handle(ptr: String::Concat(str1: klass_name, str2: Symbols::Dot()));
1360 if (!constructor_name.IsNull() && constructor_name.Length() > 0) {
1361 internal_constructor_name =
1362 String::Concat(str1: internal_constructor_name, str2: constructor_name);
1363 external_constructor_name = internal_constructor_name.ptr();
1364 }
1365
1366 Function& lookup_constructor = Function::Handle(
1367 ptr: Resolver::ResolveFunction(zone, receiver_class: klass, function_name: internal_constructor_name));
1368
1369 if (lookup_constructor.IsNull() ||
1370 (lookup_constructor.kind() != UntaggedFunction::kConstructor) ||
1371 !lookup_constructor.is_reflectable()) {
1372 ThrowNoSuchMethod(receiver: AbstractType::Handle(ptr: klass.RareType()),
1373 function_name: external_constructor_name, arguments: explicit_args, argument_names: arg_names,
1374 level: InvocationMirror::kConstructor,
1375 kind: InvocationMirror::kMethod);
1376 UNREACHABLE();
1377 }
1378
1379 if (klass.is_abstract() && !lookup_constructor.IsFactory()) {
1380 const Array& error_args = Array::Handle(ptr: Array::New(len: 3));
1381 error_args.SetAt(index: 0, value: klass_name);
1382 // 1 = script url
1383 // 2 = token position
1384 Exceptions::ThrowByType(type: Exceptions::kAbstractClassInstantiation,
1385 arguments: error_args);
1386 UNREACHABLE();
1387 }
1388
1389 ASSERT(!type.IsNull());
1390 TypeArguments& type_arguments = TypeArguments::Handle();
1391 if (!type.IsInstantiated()) {
1392 // Must have been a declaration type.
1393 const Type& rare_type = Type::Handle(ptr: klass.RareType());
1394 ASSERT(rare_type.IsInstantiated());
1395 type_arguments = rare_type.GetInstanceTypeArguments(thread);
1396 } else {
1397 type_arguments = type.GetInstanceTypeArguments(thread);
1398 }
1399
1400 Class& redirected_klass = Class::Handle(ptr: klass.ptr());
1401 const intptr_t num_explicit_args = explicit_args.Length();
1402 const intptr_t num_implicit_args = 1;
1403 const Array& args =
1404 Array::Handle(ptr: Array::New(len: num_implicit_args + num_explicit_args));
1405
1406 // Copy over the explicit arguments.
1407 Object& explicit_argument = Object::Handle();
1408 for (int i = 0; i < num_explicit_args; i++) {
1409 explicit_argument = explicit_args.At(index: i);
1410 args.SetAt(index: i + num_implicit_args, value: explicit_argument);
1411 }
1412
1413 const int kTypeArgsLen = 0;
1414 const Array& args_descriptor_array = Array::Handle(
1415 ptr: ArgumentsDescriptor::NewBoxed(type_args_len: kTypeArgsLen, num_arguments: args.Length(), optional_arguments_names: arg_names));
1416
1417 ArgumentsDescriptor args_descriptor(args_descriptor_array);
1418 if (!lookup_constructor.AreValidArguments(args_desc: args_descriptor, error_message: nullptr)) {
1419 external_constructor_name = lookup_constructor.name();
1420 ThrowNoSuchMethod(receiver: AbstractType::Handle(ptr: klass.RareType()),
1421 function_name: external_constructor_name, arguments: explicit_args, argument_names: arg_names,
1422 level: InvocationMirror::kConstructor,
1423 kind: InvocationMirror::kMethod);
1424 UNREACHABLE();
1425 }
1426#if defined(DEBUG)
1427 // Make sure the receiver is the null value, so that DoArgumentTypesMatch does
1428 // not attempt to retrieve the instantiator type arguments from the receiver.
1429 explicit_argument = args.At(args_descriptor.FirstArgIndex());
1430 ASSERT(explicit_argument.IsNull());
1431#endif
1432 const Object& type_error =
1433 Object::Handle(ptr: lookup_constructor.DoArgumentTypesMatch(
1434 args, arg_names: args_descriptor, instantiator_type_args: type_arguments));
1435 if (!type_error.IsNull()) {
1436 Exceptions::PropagateError(error: Error::Cast(obj: type_error));
1437 UNREACHABLE();
1438 }
1439
1440 Instance& new_object = Instance::Handle();
1441 if (lookup_constructor.IsGenerativeConstructor()) {
1442 // Constructors get the uninitialized object.
1443 // Note we have delayed allocation until after the function
1444 // type and argument matching checks.
1445 new_object = Instance::New(cls: redirected_klass);
1446 if (!type_arguments.IsNull()) {
1447 // The type arguments will be null if the class has no type parameters, in
1448 // which case the following call would fail because there is no slot
1449 // reserved in the object for the type vector.
1450 new_object.SetTypeArguments(type_arguments);
1451 }
1452 args.SetAt(index: 0, value: new_object);
1453 } else {
1454 // Factories get type arguments.
1455 args.SetAt(index: 0, value: type_arguments);
1456 }
1457
1458 // Invoke the constructor and return the new object.
1459 const Object& result = Object::Handle(ptr: DartEntry::InvokeFunction(
1460 function: lookup_constructor, arguments: args, arguments_descriptor: args_descriptor_array));
1461 if (result.IsError()) {
1462 Exceptions::PropagateError(error: Error::Cast(obj: result));
1463 UNREACHABLE();
1464 }
1465
1466 // Factories may return null.
1467 ASSERT(result.IsInstance() || result.IsNull());
1468
1469 if (lookup_constructor.IsGenerativeConstructor()) {
1470 return new_object.ptr();
1471 } else {
1472 return result.ptr();
1473 }
1474}
1475
1476DEFINE_NATIVE_ENTRY(LibraryMirror_invoke, 0, 5) {
1477 // Argument 0 is the mirror, which is unused by the native. It exists
1478 // because this native is an instance method in order to be polymorphic
1479 // with its cousins.
1480 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
1481 const Library& library = Library::Handle(ptr: ref.GetLibraryReferent());
1482 GET_NON_NULL_NATIVE_ARGUMENT(String, function_name,
1483 arguments->NativeArgAt(2));
1484 GET_NON_NULL_NATIVE_ARGUMENT(Array, args, arguments->NativeArgAt(3));
1485 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4));
1486 RETURN_OR_PROPAGATE(library.Invoke(function_name, args, arg_names));
1487}
1488
1489DEFINE_NATIVE_ENTRY(LibraryMirror_invokeGetter, 0, 3) {
1490 // Argument 0 is the mirror, which is unused by the native. It exists
1491 // because this native is an instance method in order to be polymorphic
1492 // with its cousins.
1493 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
1494 const Library& library = Library::Handle(ptr: ref.GetLibraryReferent());
1495 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2));
1496 RETURN_OR_PROPAGATE(library.InvokeGetter(getter_name, true));
1497}
1498
1499DEFINE_NATIVE_ENTRY(LibraryMirror_invokeSetter, 0, 4) {
1500 // Argument 0 is the mirror, which is unused by the native. It exists
1501 // because this native is an instance method in order to be polymorphic
1502 // with its cousins.
1503 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
1504 const Library& library = Library::Handle(ptr: ref.GetLibraryReferent());
1505 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2));
1506 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3));
1507 RETURN_OR_PROPAGATE(library.InvokeSetter(setter_name, value));
1508}
1509
1510DEFINE_NATIVE_ENTRY(MethodMirror_owner, 0, 2) {
1511 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
1512 GET_NATIVE_ARGUMENT(AbstractType, instantiator, arguments->NativeArgAt(1));
1513 const Function& func = Function::Handle(ptr: ref.GetFunctionReferent());
1514 if (func.IsNonImplicitClosureFunction()) {
1515 return CreateMethodMirror(func: Function::Handle(ptr: func.parent_function()),
1516 owner_mirror: Object::null_instance(), instantiator);
1517 }
1518 const Class& owner = Class::Handle(ptr: func.Owner());
1519 if (owner.IsTopLevel()) {
1520 return CreateLibraryMirror(thread, lib: Library::Handle(ptr: owner.library()));
1521 }
1522
1523 AbstractType& type = AbstractType::Handle(ptr: owner.DeclarationType());
1524 return CreateClassMirror(cls: owner, type, is_declaration: Bool::True(), owner_mirror: Object::null_instance());
1525}
1526
1527DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 0, 2) {
1528 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0));
1529 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
1530 const Function& func = Function::Handle(ptr: ref.GetFunctionReferent());
1531 const FunctionType& sig = FunctionType::Handle(ptr: func.signature());
1532 return CreateParameterMirrorList(func, signature: sig, owner_mirror: owner);
1533}
1534
1535DEFINE_NATIVE_ENTRY(MethodMirror_return_type, 0, 2) {
1536 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
1537 const Function& func = Function::Handle(ptr: ref.GetFunctionReferent());
1538 GET_NATIVE_ARGUMENT(AbstractType, instantiator, arguments->NativeArgAt(1));
1539 // We handle constructors in Dart code.
1540 ASSERT(!func.IsGenerativeConstructor());
1541 AbstractType& type = AbstractType::Handle(ptr: func.result_type());
1542 type =
1543 type.Canonicalize(thread); // Instantiated signatures are not canonical.
1544 return InstantiateType(type, instantiator);
1545}
1546
1547DEFINE_NATIVE_ENTRY(MethodMirror_source, 0, 1) {
1548 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
1549 const Function& func = Function::Handle(ptr: ref.GetFunctionReferent());
1550 return func.GetSource();
1551}
1552
1553static InstancePtr CreateSourceLocation(const String& uri,
1554 intptr_t line,
1555 intptr_t column) {
1556 const Array& args = Array::Handle(ptr: Array::New(len: 3));
1557 args.SetAt(index: 0, value: uri);
1558 args.SetAt(index: 1, value: Smi::Handle(ptr: Smi::New(value: line)));
1559 args.SetAt(index: 2, value: Smi::Handle(ptr: Smi::New(value: column)));
1560 return CreateMirror(mirror_class_name: Symbols::_SourceLocation(), constructor_arguments: args);
1561}
1562
1563DEFINE_NATIVE_ENTRY(DeclarationMirror_location, 0, 1) {
1564 GET_NON_NULL_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(0));
1565 Object& decl = Object::Handle(zone);
1566 if (reflectee.IsMirrorReference()) {
1567 const MirrorReference& decl_ref = MirrorReference::Cast(obj: reflectee);
1568 decl = decl_ref.referent();
1569 } else if (reflectee.IsTypeParameter()) {
1570 decl = reflectee.ptr();
1571 } else {
1572 UNREACHABLE();
1573 }
1574
1575 Script& script = Script::Handle(zone);
1576 TokenPosition token_pos = TokenPosition::kNoSource;
1577
1578 if (decl.IsFunction()) {
1579 const Function& func = Function::Cast(obj: decl);
1580 if (func.IsImplicitConstructor()) {
1581 // These are synthetic methods; they have no source.
1582 return Instance::null();
1583 }
1584 script = func.script();
1585 token_pos = func.token_pos();
1586 } else if (decl.IsClass()) {
1587 const Class& cls = Class::Cast(obj: decl);
1588 if (cls.is_synthesized_class() && !cls.is_enum_class()) {
1589 return Instance::null(); // Synthetic.
1590 }
1591 script = cls.script();
1592 token_pos = cls.token_pos();
1593 } else if (decl.IsField()) {
1594 const Field& field = Field::Cast(obj: decl);
1595 script = field.Script();
1596 token_pos = field.token_pos();
1597 } else if (decl.IsTypeParameter()) {
1598 return Instance::null();
1599 } else if (decl.IsLibrary()) {
1600 const Library& lib = Library::Cast(obj: decl);
1601 if (lib.ptr() == Library::NativeWrappersLibrary()) {
1602 return Instance::null(); // No source.
1603 }
1604 const Array& scripts = Array::Handle(zone, ptr: lib.LoadedScripts());
1605 ASSERT(scripts.Length() > 0);
1606 script ^= scripts.At(index: scripts.Length() - 1);
1607 ASSERT(!script.IsNull());
1608 const String& uri = String::Handle(zone, ptr: script.url());
1609 return CreateSourceLocation(uri, line: 1, column: 1);
1610 } else {
1611 FATAL("Unexpected declaration type: %s", decl.ToCString());
1612 }
1613
1614 ASSERT(!script.IsNull());
1615 if (token_pos == TokenPosition::kNoSource) {
1616 return Instance::null();
1617 }
1618
1619 const String& uri = String::Handle(zone, ptr: script.url());
1620 intptr_t from_line = 0, from_col = 0;
1621 script.GetTokenLocation(token_pos, line: &from_line, column: &from_col);
1622 return CreateSourceLocation(uri, line: from_line, column: from_col);
1623}
1624
1625DEFINE_NATIVE_ENTRY(ParameterMirror_type, 0, 3) {
1626 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
1627 GET_NON_NULL_NATIVE_ARGUMENT(Smi, pos, arguments->NativeArgAt(1));
1628 GET_NATIVE_ARGUMENT(AbstractType, instantiator, arguments->NativeArgAt(2));
1629 const FunctionType& signature =
1630 FunctionType::Handle(ptr: ref.GetFunctionTypeReferent());
1631 AbstractType& type = AbstractType::Handle(ptr: signature.ParameterTypeAt(
1632 index: signature.num_implicit_parameters() + pos.Value()));
1633 type =
1634 type.Canonicalize(thread); // Instantiated signatures are not canonical.
1635 return InstantiateType(type, instantiator);
1636}
1637
1638DEFINE_NATIVE_ENTRY(VariableMirror_type, 0, 2) {
1639 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
1640 const Field& field = Field::Handle(ptr: ref.GetFieldReferent());
1641 GET_NATIVE_ARGUMENT(AbstractType, instantiator, arguments->NativeArgAt(1));
1642 const AbstractType& type = AbstractType::Handle(ptr: field.type());
1643 return InstantiateType(type, instantiator);
1644}
1645
1646DEFINE_NATIVE_ENTRY(TypeMirror_subtypeTest, 0, 2) {
1647 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, a, arguments->NativeArgAt(0));
1648 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, b, arguments->NativeArgAt(1));
1649 return Bool::Get(value: a.IsSubtypeOf(other: b, space: Heap::kNew)).ptr();
1650}
1651
1652#endif // !DART_PRECOMPILED_RUNTIME
1653
1654} // namespace dart
1655

source code of flutter_engine/third_party/dart/runtime/lib/mirrors.cc