OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "lib/mirrors.h" | 5 #include "lib/mirrors.h" |
6 | 6 |
7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "vm/bootstrap_natives.h" | 8 #include "vm/bootstrap_natives.h" |
9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
11 #include "vm/dart_entry.h" | 11 #include "vm/dart_entry.h" |
12 #include "vm/exceptions.h" | 12 #include "vm/exceptions.h" |
13 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
14 #include "vm/parser.h" | 14 #include "vm/parser.h" |
15 #include "vm/port.h" | 15 #include "vm/port.h" |
16 #include "vm/resolver.h" | 16 #include "vm/resolver.h" |
17 #include "vm/symbols.h" | 17 #include "vm/symbols.h" |
18 | 18 |
19 namespace dart { | 19 namespace dart { |
20 | 20 |
| 21 DECLARE_FLAG(bool, lazy_dispatchers); |
| 22 |
21 #define PROPAGATE_IF_MALFORMED(type) \ | 23 #define PROPAGATE_IF_MALFORMED(type) \ |
22 if (type.IsMalformed()) { \ | 24 if (type.IsMalformed()) { \ |
23 Exceptions::PropagateError(Error::Handle(type.error())); \ | 25 Exceptions::PropagateError(Error::Handle(type.error())); \ |
24 } \ | 26 } \ |
25 | 27 |
26 static RawInstance* CreateMirror(const String& mirror_class_name, | 28 static RawInstance* CreateMirror(const String& mirror_class_name, |
27 const Array& constructor_arguments) { | 29 const Array& constructor_arguments) { |
28 const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary()); | 30 const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary()); |
29 const String& constructor_name = Symbols::Dot(); | 31 const String& constructor_name = Symbols::Dot(); |
30 | 32 |
(...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 | 734 |
733 // Invoke the getter and return the result. | 735 // Invoke the getter and return the result. |
734 const Object& result = Object::Handle( | 736 const Object& result = Object::Handle( |
735 DartEntry::InvokeFunction(getter, Object::empty_array())); | 737 DartEntry::InvokeFunction(getter, Object::empty_array())); |
736 return ReturnResult(result); | 738 return ReturnResult(result); |
737 } | 739 } |
738 return field.value(); | 740 return field.value(); |
739 } | 741 } |
740 | 742 |
741 | 743 |
742 static RawInstance* InvokeInstanceGetter(const Class& klass, | |
743 const Instance& reflectee, | |
744 const String& getter_name, | |
745 const bool throw_nsm_if_absent) { | |
746 const String& internal_getter_name = String::Handle( | |
747 Field::GetterName(getter_name)); | |
748 Function& function = Function::Handle( | |
749 Resolver::ResolveDynamicAnyArgs(klass, internal_getter_name)); | |
750 | |
751 if (!function.IsNull() || throw_nsm_if_absent) { | |
752 const int kNumArgs = 1; | |
753 const Array& args = Array::Handle(Array::New(kNumArgs)); | |
754 args.SetAt(0, reflectee); | |
755 const Array& args_descriptor = | |
756 Array::Handle(ArgumentsDescriptor::New(args.Length())); | |
757 | |
758 // InvokeDynamic invokes NoSuchMethod if the provided function is null. | |
759 return InvokeDynamicFunction(reflectee, | |
760 function, | |
761 internal_getter_name, | |
762 args, | |
763 args_descriptor); | |
764 } | |
765 | |
766 // Fall through case: Indicate that we didn't find any function or field using | |
767 // a special null instance. This is different from a field being null. Callers | |
768 // make sure that this null does not leak into Dartland. | |
769 return Object::sentinel().raw(); | |
770 } | |
771 | |
772 | |
773 static RawAbstractType* InstantiateType(const AbstractType& type, | 744 static RawAbstractType* InstantiateType(const AbstractType& type, |
774 const AbstractType& instantiator) { | 745 const AbstractType& instantiator) { |
775 ASSERT(type.IsFinalized()); | 746 ASSERT(type.IsFinalized()); |
776 PROPAGATE_IF_MALFORMED(type); | 747 PROPAGATE_IF_MALFORMED(type); |
777 ASSERT(type.IsCanonical() || type.IsTypeParameter() || type.IsBoundedType()); | 748 ASSERT(type.IsCanonical() || type.IsTypeParameter() || type.IsBoundedType()); |
778 | 749 |
779 if (type.IsInstantiated() || instantiator.IsNull()) { | 750 if (type.IsInstantiated() || instantiator.IsNull()) { |
780 return type.Canonicalize(); | 751 return type.Canonicalize(); |
781 } | 752 } |
782 | 753 |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 } | 1353 } |
1383 | 1354 |
1384 | 1355 |
1385 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeGetter, 3) { | 1356 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeGetter, 3) { |
1386 // Argument 0 is the mirror, which is unused by the native. It exists | 1357 // Argument 0 is the mirror, which is unused by the native. It exists |
1387 // because this native is an instance method in order to be polymorphic | 1358 // because this native is an instance method in order to be polymorphic |
1388 // with its cousins. | 1359 // with its cousins. |
1389 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); | 1360 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); |
1390 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2)); | 1361 GET_NON_NULL_NATIVE_ARGUMENT(String, getter_name, arguments->NativeArgAt(2)); |
1391 Class& klass = Class::Handle(reflectee.clazz()); | 1362 Class& klass = Class::Handle(reflectee.clazz()); |
1392 return InvokeInstanceGetter(klass, reflectee, getter_name, true); | 1363 |
| 1364 const String& internal_getter_name = String::Handle( |
| 1365 Field::GetterName(getter_name)); |
| 1366 Function& function = Function::Handle( |
| 1367 Resolver::ResolveDynamicAnyArgs(klass, internal_getter_name)); |
| 1368 |
| 1369 // Check for method extraction when method extractors are not created. |
| 1370 if (function.IsNull() && !FLAG_lazy_dispatchers) { |
| 1371 function = Resolver::ResolveDynamicAnyArgs(klass, getter_name); |
| 1372 if (!function.IsNull()) { |
| 1373 const Function& closure_function = |
| 1374 Function::Handle(function.ImplicitClosureFunction()); |
| 1375 return closure_function.ImplicitInstanceClosure(reflectee); |
| 1376 } |
| 1377 } |
| 1378 |
| 1379 const int kNumArgs = 1; |
| 1380 const Array& args = Array::Handle(Array::New(kNumArgs)); |
| 1381 args.SetAt(0, reflectee); |
| 1382 const Array& args_descriptor = |
| 1383 Array::Handle(ArgumentsDescriptor::New(args.Length())); |
| 1384 |
| 1385 // InvokeDynamic invokes NoSuchMethod if the provided function is null. |
| 1386 return InvokeDynamicFunction(reflectee, |
| 1387 function, |
| 1388 internal_getter_name, |
| 1389 args, |
| 1390 args_descriptor); |
1393 } | 1391 } |
1394 | 1392 |
1395 | 1393 |
1396 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) { | 1394 DEFINE_NATIVE_ENTRY(InstanceMirror_invokeSetter, 4) { |
1397 // Argument 0 is the mirror, which is unused by the native. It exists | 1395 // Argument 0 is the mirror, which is unused by the native. It exists |
1398 // because this native is an instance method in order to be polymorphic | 1396 // because this native is an instance method in order to be polymorphic |
1399 // with its cousins. | 1397 // with its cousins. |
1400 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); | 1398 GET_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(1)); |
1401 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); | 1399 GET_NON_NULL_NATIVE_ARGUMENT(String, setter_name, arguments->NativeArgAt(2)); |
1402 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); | 1400 GET_NATIVE_ARGUMENT(Instance, value, arguments->NativeArgAt(3)); |
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2082 } | 2080 } |
2083 | 2081 |
2084 DEFINE_NATIVE_ENTRY(TypeMirror_subtypeTest, 2) { | 2082 DEFINE_NATIVE_ENTRY(TypeMirror_subtypeTest, 2) { |
2085 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, a, arguments->NativeArgAt(0)); | 2083 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, a, arguments->NativeArgAt(0)); |
2086 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, b, arguments->NativeArgAt(1)); | 2084 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, b, arguments->NativeArgAt(1)); |
2087 return Bool::Get(a.IsSubtypeOf(b, NULL)).raw(); | 2085 return Bool::Get(a.IsSubtypeOf(b, NULL)).raw(); |
2088 } | 2086 } |
2089 | 2087 |
2090 | 2088 |
2091 } // namespace dart | 2089 } // namespace dart |
OLD | NEW |