Chromium Code Reviews| 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 "include/dart_api.h" | 5 #include "include/dart_api.h" |
| 6 #include "include/dart_debugger_api.h" | 6 #include "include/dart_debugger_api.h" |
| 7 #include "include/dart_mirrors_api.h" | 7 #include "include/dart_mirrors_api.h" |
| 8 #include "vm/dart_api_impl.h" | 8 #include "vm/dart_api_impl.h" |
| 9 #include "vm/dart_api_state.h" // TODO(11742): Remove with CreateMirrorRef. | 9 #include "vm/dart_api_state.h" // TODO(11742): Remove with CreateMirrorRef. |
| 10 #include "vm/bootstrap_natives.h" | 10 #include "vm/bootstrap_natives.h" |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 cls_name, | 498 cls_name, |
| 499 owner_mirror, | 499 owner_mirror, |
| 500 CreateLazyMirror(referent), | 500 CreateLazyMirror(referent), |
| 501 }; | 501 }; |
| 502 Dart_Handle mirror = | 502 Dart_Handle mirror = |
| 503 Dart_New(mirror_type, Dart_Null(), ARRAY_SIZE(args), args); | 503 Dart_New(mirror_type, Dart_Null(), ARRAY_SIZE(args), args); |
| 504 return mirror; | 504 return mirror; |
| 505 } | 505 } |
| 506 | 506 |
| 507 | 507 |
| 508 static Dart_Handle CreateMemberMap(Dart_Handle owner, Dart_Handle owner_mirror); | |
| 509 static Dart_Handle CreateConstructorMap(Dart_Handle owner, | 508 static Dart_Handle CreateConstructorMap(Dart_Handle owner, |
| 510 Dart_Handle owner_mirror); | 509 Dart_Handle owner_mirror); |
| 511 | 510 |
| 512 static Dart_Handle CreateClassMirrorUsingApi(Dart_Handle intf, | 511 static Dart_Handle CreateClassMirrorUsingApi(Dart_Handle intf, |
| 513 Dart_Handle intf_name, | 512 Dart_Handle intf_name, |
| 514 Dart_Handle lib_mirror) { | 513 Dart_Handle lib_mirror) { |
| 515 ASSERT(Dart_IsClass(intf)); | 514 ASSERT(Dart_IsClass(intf)); |
| 516 if (Dart_ClassIsTypedef(intf)) { | 515 if (Dart_ClassIsTypedef(intf)) { |
| 517 // This class is actually a typedef. Represent it specially in | 516 // This class is actually a typedef. Represent it specially in |
| 518 // reflection. | 517 // reflection. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 608 args.SetAt(1, name); | 607 args.SetAt(1, name); |
| 609 args.SetAt(2, owner_mirror); | 608 args.SetAt(2, owner_mirror); |
| 610 args.SetAt(3, Instance::Handle()); // Null for type. | 609 args.SetAt(3, Instance::Handle()); // Null for type. |
| 611 args.SetAt(4, field.is_static() ? Bool::True() : Bool::False()); | 610 args.SetAt(4, field.is_static() ? Bool::True() : Bool::False()); |
| 612 args.SetAt(5, field.is_final() ? Bool::True() : Bool::False()); | 611 args.SetAt(5, field.is_final() ? Bool::True() : Bool::False()); |
| 613 | 612 |
| 614 return CreateMirror(Symbols::_LocalVariableMirrorImpl(), args); | 613 return CreateMirror(Symbols::_LocalVariableMirrorImpl(), args); |
| 615 } | 614 } |
| 616 | 615 |
| 617 | 616 |
| 618 static Dart_Handle AddMemberClasses(Dart_Handle map, | |
| 619 Dart_Handle owner, | |
| 620 Dart_Handle owner_mirror) { | |
| 621 ASSERT(Dart_IsLibrary(owner)); | |
| 622 Dart_Handle result; | |
| 623 Dart_Handle names = Dart_LibraryGetClassNames(owner); | |
| 624 if (Dart_IsError(names)) { | |
| 625 return names; | |
| 626 } | |
| 627 intptr_t len; | |
| 628 result = Dart_ListLength(names, &len); | |
| 629 if (Dart_IsError(result)) { | |
| 630 return result; | |
| 631 } | |
| 632 for (intptr_t i = 0; i < len; i++) { | |
| 633 Dart_Handle intf_name = Dart_ListGetAt(names, i); | |
| 634 Dart_Handle intf = Dart_GetClass(owner, intf_name); | |
| 635 if (Dart_IsError(intf)) { | |
| 636 return intf; | |
| 637 } | |
| 638 Dart_Handle intf_mirror = | |
| 639 CreateClassMirrorUsingApi(intf, intf_name, owner_mirror); | |
| 640 if (Dart_IsError(intf_mirror)) { | |
| 641 return intf_mirror; | |
| 642 } | |
| 643 result = MapAdd(map, intf_name, intf_mirror); | |
| 644 if (Dart_IsError(result)) { | |
| 645 return result; | |
| 646 } | |
| 647 } | |
| 648 return Dart_True(); | |
| 649 } | |
| 650 | |
| 651 | |
| 652 static Dart_Handle AddMemberFunctions(Dart_Handle map, | |
| 653 Dart_Handle owner, | |
| 654 Dart_Handle owner_mirror) { | |
| 655 Dart_Handle result; | |
| 656 Dart_Handle names = Dart_GetFunctionNames(owner); | |
| 657 if (Dart_IsError(names)) { | |
| 658 return names; | |
| 659 } | |
| 660 intptr_t len; | |
| 661 result = Dart_ListLength(names, &len); | |
| 662 if (Dart_IsError(result)) { | |
| 663 return result; | |
| 664 } | |
| 665 for (intptr_t i = 0; i < len; i++) { | |
| 666 Dart_Handle func_name = Dart_ListGetAt(names, i); | |
| 667 Dart_Handle func = Dart_LookupFunction(owner, func_name); | |
| 668 if (Dart_IsError(func)) { | |
| 669 return func; | |
| 670 } | |
| 671 ASSERT(!Dart_IsNull(func)); | |
| 672 | |
| 673 bool is_constructor = false; | |
| 674 result = Dart_FunctionIsConstructor(func, &is_constructor); | |
| 675 if (Dart_IsError(result)) { | |
| 676 return result; | |
| 677 } | |
| 678 if (is_constructor) { | |
| 679 // Skip constructors. | |
| 680 continue; | |
| 681 } | |
| 682 | |
| 683 Dart_Handle func_mirror = CreateMethodMirrorUsingApi(func, owner_mirror); | |
| 684 if (Dart_IsError(func_mirror)) { | |
| 685 return func_mirror; | |
| 686 } | |
| 687 result = MapAdd(map, func_name, func_mirror); | |
| 688 if (Dart_IsError(result)) { | |
| 689 return result; | |
| 690 } | |
| 691 } | |
| 692 return Dart_True(); | |
| 693 } | |
| 694 | |
| 695 | |
| 696 static Dart_Handle AddConstructors(Dart_Handle map, | 617 static Dart_Handle AddConstructors(Dart_Handle map, |
| 697 Dart_Handle owner, | 618 Dart_Handle owner, |
| 698 Dart_Handle owner_mirror) { | 619 Dart_Handle owner_mirror) { |
| 699 Dart_Handle result; | 620 Dart_Handle result; |
| 700 Dart_Handle names = Dart_GetFunctionNames(owner); | 621 Dart_Handle names = Dart_GetFunctionNames(owner); |
| 701 if (Dart_IsError(names)) { | 622 if (Dart_IsError(names)) { |
| 702 return names; | 623 return names; |
| 703 } | 624 } |
| 704 intptr_t len; | 625 intptr_t len; |
| 705 result = Dart_ListLength(names, &len); | 626 result = Dart_ListLength(names, &len); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 730 } | 651 } |
| 731 result = MapAdd(map, func_name, func_mirror); | 652 result = MapAdd(map, func_name, func_mirror); |
| 732 if (Dart_IsError(result)) { | 653 if (Dart_IsError(result)) { |
| 733 return result; | 654 return result; |
| 734 } | 655 } |
| 735 } | 656 } |
| 736 return Dart_True(); | 657 return Dart_True(); |
| 737 } | 658 } |
| 738 | 659 |
| 739 | 660 |
| 740 static Dart_Handle AddMemberVariables(Dart_Handle map, | |
| 741 Dart_Handle owner, | |
| 742 Dart_Handle owner_mirror) { | |
| 743 Isolate* isolate = Isolate::Current(); | |
| 744 Dart_Handle result; | |
| 745 Dart_Handle names = Dart_GetVariableNames(owner); | |
| 746 if (Dart_IsError(names)) { | |
| 747 return names; | |
| 748 } | |
| 749 intptr_t len; | |
| 750 result = Dart_ListLength(names, &len); | |
| 751 if (Dart_IsError(result)) { | |
| 752 return result; | |
| 753 } | |
| 754 for (intptr_t i = 0; i < len; i++) { | |
| 755 Dart_Handle var_name = Dart_ListGetAt(names, i); | |
| 756 Dart_Handle var = Dart_LookupVariable(owner, var_name); | |
| 757 if (Dart_IsError(var)) { | |
| 758 return var; | |
| 759 } | |
| 760 ASSERT(!Dart_IsNull(var)); | |
| 761 ASSERT(Dart_IsVariable(var)); | |
| 762 const Field& field = Api::UnwrapFieldHandle(isolate, var); | |
| 763 const Instance& owner_mirror_inst = | |
| 764 Api::UnwrapInstanceHandle(isolate, owner_mirror); | |
| 765 const Instance& var_mirror_inst = | |
| 766 Instance::Handle(CreateVariableMirror(field, owner_mirror_inst)); | |
| 767 Dart_Handle var_mirror = Api::NewHandle(isolate, var_mirror_inst.raw()); | |
| 768 | |
| 769 result = MapAdd(map, var_name, var_mirror); | |
| 770 if (Dart_IsError(result)) { | |
| 771 return result; | |
| 772 } | |
| 773 } | |
| 774 return Dart_True(); | |
| 775 } | |
| 776 | |
| 777 | |
| 778 static Dart_Handle CreateMemberMap(Dart_Handle owner, | |
| 779 Dart_Handle owner_mirror) { | |
| 780 // TODO(turnidge): This should be an immutable map. | |
| 781 if (Dart_IsError(owner_mirror)) { | |
| 782 return owner_mirror; | |
| 783 } | |
| 784 Dart_Handle result; | |
| 785 Dart_Handle map = MapNew(); | |
| 786 if (Dart_IsLibrary(owner)) { | |
| 787 result = AddMemberClasses(map, owner, owner_mirror); | |
| 788 if (Dart_IsError(result)) { | |
| 789 return result; | |
| 790 } | |
| 791 } | |
| 792 result = AddMemberFunctions(map, owner, owner_mirror); | |
| 793 if (Dart_IsError(result)) { | |
| 794 return result; | |
| 795 } | |
| 796 result = AddMemberVariables(map, owner, owner_mirror); | |
| 797 if (Dart_IsError(result)) { | |
| 798 return result; | |
| 799 } | |
| 800 return map; | |
| 801 } | |
| 802 | |
| 803 | |
| 804 static Dart_Handle CreateConstructorMap(Dart_Handle owner, | 661 static Dart_Handle CreateConstructorMap(Dart_Handle owner, |
| 805 Dart_Handle owner_mirror) { | 662 Dart_Handle owner_mirror) { |
| 806 // TODO(turnidge): This should be an immutable map. | 663 // TODO(turnidge): This should be an immutable map. |
| 807 if (Dart_IsError(owner_mirror)) { | 664 if (Dart_IsError(owner_mirror)) { |
| 808 return owner_mirror; | 665 return owner_mirror; |
| 809 } | 666 } |
| 810 Dart_Handle result; | 667 Dart_Handle result; |
| 811 Dart_Handle map = MapNew(); | 668 Dart_Handle map = MapNew(); |
| 812 result = AddConstructors(map, owner, owner_mirror); | 669 result = AddConstructors(map, owner, owner_mirror); |
| 813 if (Dart_IsError(result)) { | 670 if (Dart_IsError(result)) { |
| 814 return result; | 671 return result; |
| 815 } | 672 } |
| 816 return map; | 673 return map; |
| 817 } | 674 } |
| 818 | 675 |
| 819 | 676 |
| 820 static Dart_Handle CreateLibraryMirrorUsingApi(Dart_Handle lib) { | 677 static Dart_Handle CreateLibraryMirrorUsingApi(Dart_Handle lib) { |
| 821 Dart_Handle cls_name = NewString("_LocalLibraryMirrorImpl"); | 678 Dart_Handle cls_name = NewString("_LocalLibraryMirrorImpl"); |
| 822 Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL); | 679 Dart_Handle type = Dart_GetType(MirrorLib(), cls_name, 0, NULL); |
| 823 if (Dart_IsError(type)) { | 680 if (Dart_IsError(type)) { |
| 824 return type; | 681 return type; |
| 825 } | 682 } |
| 826 Dart_Handle lazy_lib_mirror = CreateLazyMirror(lib); | 683 Dart_Handle lazy_lib_mirror = CreateLazyMirror(lib); |
| 827 if (Dart_IsError(lazy_lib_mirror)) { | 684 if (Dart_IsError(lazy_lib_mirror)) { |
| 828 return lazy_lib_mirror; | 685 return lazy_lib_mirror; |
| 829 } | 686 } |
| 830 Dart_Handle member_map = CreateMemberMap(lib, lazy_lib_mirror); | |
| 831 if (Dart_IsError(member_map)) { | |
| 832 return member_map; | |
| 833 } | |
| 834 Dart_Handle args[] = { | 687 Dart_Handle args[] = { |
| 835 CreateMirrorReference(lib), | 688 CreateMirrorReference(lib), |
| 836 Dart_LibraryName(lib), | 689 Dart_LibraryName(lib), |
| 837 Dart_LibraryUrl(lib), | 690 Dart_LibraryUrl(lib), |
| 838 member_map, | |
| 839 }; | 691 }; |
| 840 Dart_Handle lib_mirror = Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args); | 692 Dart_Handle lib_mirror = Dart_New(type, Dart_Null(), ARRAY_SIZE(args), args); |
| 841 if (Dart_IsError(lib_mirror)) { | 693 if (Dart_IsError(lib_mirror)) { |
| 842 return lib_mirror; | 694 return lib_mirror; |
| 843 } | 695 } |
| 844 | 696 |
| 845 return lib_mirror; | 697 return lib_mirror; |
| 846 } | 698 } |
| 847 | 699 |
| 848 | 700 |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1240 // initialized until the first time the getter is invoked. | 1092 // initialized until the first time the getter is invoked. |
| 1241 const Instance& value = Instance::Handle(field.value()); | 1093 const Instance& value = Instance::Handle(field.value()); |
| 1242 ASSERT(value.raw() != Object::transition_sentinel().raw()); | 1094 ASSERT(value.raw() != Object::transition_sentinel().raw()); |
| 1243 return value.raw() == Object::sentinel().raw(); | 1095 return value.raw() == Object::sentinel().raw(); |
| 1244 } | 1096 } |
| 1245 | 1097 |
| 1246 | 1098 |
| 1247 DEFINE_NATIVE_ENTRY(ClassMirror_name, 1) { | 1099 DEFINE_NATIVE_ENTRY(ClassMirror_name, 1) { |
| 1248 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1100 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| 1249 const Class& klass = Class::Handle(ref.GetClassReferent()); | 1101 const Class& klass = Class::Handle(ref.GetClassReferent()); |
| 1250 return klass.Name(); | 1102 return klass.UserVisibleName(); |
| 1251 } | 1103 } |
| 1252 | 1104 |
| 1253 | 1105 |
| 1254 DEFINE_NATIVE_ENTRY(ClassMirror_library, 1) { | 1106 DEFINE_NATIVE_ENTRY(ClassMirror_library, 1) { |
| 1255 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1107 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| 1256 const Class& klass = Class::Handle(ref.GetClassReferent()); | 1108 const Class& klass = Class::Handle(ref.GetClassReferent()); |
| 1257 return CreateLibraryMirror(Library::Handle(klass.library())); | 1109 return CreateLibraryMirror(Library::Handle(klass.library())); |
| 1258 } | 1110 } |
| 1259 | 1111 |
| 1260 | 1112 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1296 func.kind() == RawFunction::kSetterFunction) { | 1148 func.kind() == RawFunction::kSetterFunction) { |
| 1297 member_mirror = CreateMethodMirror(func, owner_mirror); | 1149 member_mirror = CreateMethodMirror(func, owner_mirror); |
| 1298 member_mirrors.Add(member_mirror); | 1150 member_mirrors.Add(member_mirror); |
| 1299 } | 1151 } |
| 1300 } | 1152 } |
| 1301 | 1153 |
| 1302 return member_mirrors.raw(); | 1154 return member_mirrors.raw(); |
| 1303 } | 1155 } |
| 1304 | 1156 |
| 1305 | 1157 |
| 1158 DEFINE_NATIVE_ENTRY(LibraryMirror_members, 2) { | |
| 1159 GET_NON_NULL_NATIVE_ARGUMENT(Instance, | |
| 1160 owner_mirror, | |
| 1161 arguments->NativeArgAt(0)); | |
| 1162 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | |
| 1163 const Library& library = Library::Handle(ref.GetLibraryReferent()); | |
| 1164 | |
| 1165 Instance& member_mirror = Instance::Handle(); | |
| 1166 const GrowableObjectArray& member_mirrors = | |
| 1167 GrowableObjectArray::Handle(GrowableObjectArray::New()); | |
| 1168 | |
| 1169 Field& field = Field::Handle(); | |
| 1170 Class& klass = Class::Handle(); | |
| 1171 Function& func = Function::Handle(); | |
|
siva
2013/07/24 22:41:35
You don't need these 3 handles, see comment below.
| |
| 1172 | |
| 1173 Object& entry = Object::Handle(); | |
| 1174 DictionaryIterator entries(library); | |
| 1175 | |
| 1176 String& user_visible_name = String::Handle(); | |
| 1177 Class& lookup_class = Class::Handle(); | |
| 1178 | |
| 1179 while (entries.HasNext()) { | |
| 1180 entry = entries.GetNext(); | |
| 1181 if (entry.IsClass()) { | |
| 1182 klass ^= entry.raw(); | |
|
siva
2013/07/24 22:41:35
you could replace this with the Cast operator:
rmacnak
2013/07/24 22:51:43
Done.
| |
| 1183 if (!klass.IsCanonicalSignatureClass()) { | |
| 1184 // The various implementations of public classes don't always have the | |
| 1185 // expected superinterfaces or other properties, so we filter them out | |
| 1186 // (e.g., ObjectArray would displace the abstract class List but doesn't | |
| 1187 // answer [Iterable] as its superinterfaces). Checking that the normal | |
| 1188 // and user-visible names match does not work because it excludes | |
| 1189 // private members. | |
| 1190 user_visible_name = klass.UserVisibleName(); | |
| 1191 lookup_class = library.LookupClassAllowPrivate(user_visible_name, NULL); | |
| 1192 bool is_lookup_class; | |
| 1193 { | |
| 1194 NoGCScope(); | |
| 1195 is_lookup_class = klass.raw() == lookup_class.raw(); | |
| 1196 } | |
|
siva
2013/07/24 22:41:35
Replace this with the internal class id check as d
rmacnak
2013/07/24 22:51:43
Done.
| |
| 1197 if (is_lookup_class) { | |
| 1198 member_mirror = CreateClassMirror(klass, owner_mirror); | |
| 1199 member_mirrors.Add(member_mirror); | |
| 1200 } | |
| 1201 } | |
| 1202 } else if (entry.IsField()) { | |
| 1203 field ^= entry.raw(); | |
| 1204 member_mirror = CreateVariableMirror(field, owner_mirror); | |
| 1205 member_mirrors.Add(member_mirror); | |
| 1206 } else if (entry.IsFunction()) { | |
| 1207 func ^= entry.raw(); | |
| 1208 if (func.kind() == RawFunction::kRegularFunction || | |
| 1209 func.kind() == RawFunction::kGetterFunction || | |
| 1210 func.kind() == RawFunction::kSetterFunction) { | |
| 1211 member_mirror = CreateMethodMirror(func, owner_mirror); | |
| 1212 member_mirrors.Add(member_mirror); | |
| 1213 } | |
| 1214 } | |
| 1215 } | |
| 1216 | |
| 1217 return member_mirrors.raw(); | |
| 1218 } | |
| 1219 | |
| 1220 | |
| 1306 // Invoke the function, or noSuchMethod if it is null. Propagate any unhandled | 1221 // Invoke the function, or noSuchMethod if it is null. Propagate any unhandled |
| 1307 // exceptions. Wrap and propagate any compilation errors. | 1222 // exceptions. Wrap and propagate any compilation errors. |
| 1308 static RawObject* ReflectivelyInvokeDynamicFunction(const Instance& receiver, | 1223 static RawObject* ReflectivelyInvokeDynamicFunction(const Instance& receiver, |
| 1309 const Function& function, | 1224 const Function& function, |
| 1310 const String& target_name, | 1225 const String& target_name, |
| 1311 const Array& arguments) { | 1226 const Array& arguments) { |
| 1312 // Note "arguments" is already the internal arguments with the receiver as | 1227 // Note "arguments" is already the internal arguments with the receiver as |
| 1313 // the first element. | 1228 // the first element. |
| 1314 Object& result = Object::Handle(); | 1229 Object& result = Object::Handle(); |
| 1315 if (function.IsNull()) { | 1230 if (function.IsNull()) { |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1926 | 1841 |
| 1927 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { | 1842 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { |
| 1928 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1843 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| 1929 const Field& field = Field::Handle(ref.GetFieldReferent()); | 1844 const Field& field = Field::Handle(ref.GetFieldReferent()); |
| 1930 | 1845 |
| 1931 const AbstractType& type = AbstractType::Handle(field.type()); | 1846 const AbstractType& type = AbstractType::Handle(field.type()); |
| 1932 return CreateTypeMirror(type); | 1847 return CreateTypeMirror(type); |
| 1933 } | 1848 } |
| 1934 | 1849 |
| 1935 } // namespace dart | 1850 } // namespace dart |
| OLD | NEW |