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