| 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/invocation_mirror.h" | 5 #include "lib/invocation_mirror.h" |
| 6 #include "vm/bootstrap_natives.h" | 6 #include "vm/bootstrap_natives.h" |
| 7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/exceptions.h" | 9 #include "vm/exceptions.h" |
| 10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 const Object& result = Object::Handle( | 22 const Object& result = Object::Handle( |
| 23 DartLibraryCalls::InstanceCreate(mirrors_lib, | 23 DartLibraryCalls::InstanceCreate(mirrors_lib, |
| 24 mirror_class_name, | 24 mirror_class_name, |
| 25 constructor_name, | 25 constructor_name, |
| 26 constructor_arguments)); | 26 constructor_arguments)); |
| 27 ASSERT(!result.IsError()); | 27 ASSERT(!result.IsError()); |
| 28 return Instance::Cast(result).raw(); | 28 return Instance::Cast(result).raw(); |
| 29 } | 29 } |
| 30 | 30 |
| 31 | 31 |
| 32 // Note a "raw type" is not the same as a RawType. | |
| 33 static RawAbstractType* RawTypeOfClass(const Class& cls) { | |
| 34 Type& type = Type::Handle(Type::New(cls, | |
| 35 Object::null_abstract_type_arguments(), | |
| 36 Scanner::kDummyTokenIndex)); | |
| 37 return ClassFinalizer::FinalizeType(cls, type, ClassFinalizer::kCanonicalize); | |
| 38 } | |
| 39 | |
| 40 | |
| 41 static void ThrowMirroredCompilationError(const String& message) { | 32 static void ThrowMirroredCompilationError(const String& message) { |
| 42 Array& args = Array::Handle(Array::New(1)); | 33 Array& args = Array::Handle(Array::New(1)); |
| 43 args.SetAt(0, message); | 34 args.SetAt(0, message); |
| 44 | 35 |
| 45 Exceptions::ThrowByType(Exceptions::kMirroredCompilationError, args); | 36 Exceptions::ThrowByType(Exceptions::kMirroredCompilationError, args); |
| 46 UNREACHABLE(); | 37 UNREACHABLE(); |
| 47 } | 38 } |
| 48 | 39 |
| 49 | 40 |
| 50 static void ThrowInvokeError(const Error& error) { | 41 static void ThrowInvokeError(const Error& error) { |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 if (!call_function.IsNull()) { | 278 if (!call_function.IsNull()) { |
| 288 return call_function.raw(); | 279 return call_function.raw(); |
| 289 } | 280 } |
| 290 lookup_cls = lookup_cls.SuperClass(); | 281 lookup_cls = lookup_cls.SuperClass(); |
| 291 } while (!lookup_cls.IsNull()); | 282 } while (!lookup_cls.IsNull()); |
| 292 return Function::null(); | 283 return Function::null(); |
| 293 } | 284 } |
| 294 | 285 |
| 295 static RawInstance* CreateClassMirror(const Class& cls, | 286 static RawInstance* CreateClassMirror(const Class& cls, |
| 296 const AbstractType& type, | 287 const AbstractType& type, |
| 288 const Bool& is_declaration, |
| 297 const Instance& owner_mirror) { | 289 const Instance& owner_mirror) { |
| 298 ASSERT(!cls.IsDynamicClass() && !cls.IsVoidClass()); | 290 ASSERT(!cls.IsDynamicClass() && !cls.IsVoidClass()); |
| 299 | 291 |
| 300 if (cls.IsSignatureClass()) { | 292 if (cls.IsSignatureClass()) { |
| 301 if (cls.IsCanonicalSignatureClass()) { | 293 if (cls.IsCanonicalSignatureClass()) { |
| 302 // We represent function types as canonical signature classes. | 294 // We represent function types as canonical signature classes. |
| 303 return CreateFunctionTypeMirror(cls, type); | 295 return CreateFunctionTypeMirror(cls, type); |
| 304 } else { | 296 } else { |
| 305 // We represent typedefs as non-canonical signature classes. | 297 // We represent typedefs as non-canonical signature classes. |
| 306 return CreateTypedefMirror(cls, owner_mirror); | 298 return CreateTypedefMirror(cls, owner_mirror); |
| 307 } | 299 } |
| 308 } | 300 } |
| 309 | 301 |
| 302 ASSERT(!type.IsNull()); |
| 303 |
| 310 const Bool& is_generic = Bool::Get(cls.NumTypeParameters() != 0); | 304 const Bool& is_generic = Bool::Get(cls.NumTypeParameters() != 0); |
| 311 const Bool& is_mixin_typedef = Bool::Get(cls.is_mixin_typedef()); | 305 const Bool& is_mixin_typedef = Bool::Get(cls.is_mixin_typedef()); |
| 312 | 306 |
| 313 // If the class is not generic, the mirror must have a non-null runtime type. | 307 const Array& args = Array::Handle(Array::New(6)); |
| 314 // If the class is generic, the mirror will have a null runtime type if it | |
| 315 // represents the declaration or a non-null runtime type if it represents an | |
| 316 // instantiation. | |
| 317 ASSERT(!(cls.NumTypeParameters() == 0) || !type.IsNull()); | |
| 318 | |
| 319 const Array& args = Array::Handle(Array::New(5)); | |
| 320 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); | 308 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls))); |
| 321 args.SetAt(1, type); | 309 args.SetAt(1, type); |
| 322 // We do not set the names of anonymous mixin applications because the mirrors | 310 // We do not set the names of anonymous mixin applications because the mirrors |
| 323 // use a different naming convention than the VM (lib.S with lib.M and S&M | 311 // use a different naming convention than the VM (lib.S with lib.M and S&M |
| 324 // respectively). | 312 // respectively). |
| 325 if (!cls.IsMixinApplication() || cls.is_mixin_typedef()) { | 313 if (!cls.IsMixinApplication() || cls.is_mixin_typedef()) { |
| 326 args.SetAt(2, String::Handle(cls.UserVisibleName())); | 314 args.SetAt(2, String::Handle(cls.UserVisibleName())); |
| 327 } | 315 } |
| 328 args.SetAt(3, is_generic); | 316 args.SetAt(3, is_generic); |
| 329 args.SetAt(4, is_mixin_typedef); | 317 args.SetAt(4, is_mixin_typedef); |
| 318 args.SetAt(5, cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration); |
| 330 return CreateMirror(Symbols::_LocalClassMirrorImpl(), args); | 319 return CreateMirror(Symbols::_LocalClassMirrorImpl(), args); |
| 331 } | 320 } |
| 332 | 321 |
| 333 | 322 |
| 334 static RawInstance* CreateLibraryMirror(const Library& lib) { | 323 static RawInstance* CreateLibraryMirror(const Library& lib) { |
| 335 const Array& args = Array::Handle(Array::New(3)); | 324 const Array& args = Array::Handle(Array::New(3)); |
| 336 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(lib))); | 325 args.SetAt(0, MirrorReference::Handle(MirrorReference::New(lib))); |
| 337 String& str = String::Handle(); | 326 String& str = String::Handle(); |
| 338 str = lib.name(); | 327 str = lib.name(); |
| 339 args.SetAt(1, str); | 328 args.SetAt(1, str); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 352 Array& args = Array::Handle(Array::New(1)); | 341 Array& args = Array::Handle(Array::New(1)); |
| 353 args.SetAt(0, Symbols::Void()); | 342 args.SetAt(0, Symbols::Void()); |
| 354 // TODO(mlippautz): Create once in the VM isolate and retrieve from there. | 343 // TODO(mlippautz): Create once in the VM isolate and retrieve from there. |
| 355 return CreateMirror(Symbols::_SpecialTypeMirrorImpl(), args); | 344 return CreateMirror(Symbols::_SpecialTypeMirrorImpl(), args); |
| 356 } else if (cls.IsDynamicClass()) { | 345 } else if (cls.IsDynamicClass()) { |
| 357 Array& args = Array::Handle(Array::New(1)); | 346 Array& args = Array::Handle(Array::New(1)); |
| 358 args.SetAt(0, Symbols::Dynamic()); | 347 args.SetAt(0, Symbols::Dynamic()); |
| 359 // TODO(mlippautz): Create once in the VM isolate and retrieve from there. | 348 // TODO(mlippautz): Create once in the VM isolate and retrieve from there. |
| 360 return CreateMirror(Symbols::_SpecialTypeMirrorImpl(), args); | 349 return CreateMirror(Symbols::_SpecialTypeMirrorImpl(), args); |
| 361 } | 350 } |
| 362 return CreateClassMirror(cls, type, Object::null_instance()); | 351 return CreateClassMirror(cls, type, Bool::False(), Object::null_instance()); |
| 363 } else if (type.IsTypeParameter()) { | 352 } else if (type.IsTypeParameter()) { |
| 364 return CreateTypeVariableMirror(TypeParameter::Cast(type), | 353 return CreateTypeVariableMirror(TypeParameter::Cast(type), |
| 365 Object::null_instance()); | 354 Object::null_instance()); |
| 366 } | 355 } |
| 367 UNREACHABLE(); | 356 UNREACHABLE(); |
| 368 return Instance::null(); | 357 return Instance::null(); |
| 369 } | 358 } |
| 370 | 359 |
| 371 | 360 |
| 372 static RawInstance* CreateIsolateMirror() { | 361 static RawInstance* CreateIsolateMirror() { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) { | 406 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) { |
| 418 GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0)); | 407 GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0)); |
| 419 const Class& cls = Class::Handle(type.type_class()); | 408 const Class& cls = Class::Handle(type.type_class()); |
| 420 ASSERT(!cls.IsNull()); | 409 ASSERT(!cls.IsNull()); |
| 421 if (cls.IsDynamicClass() || cls.IsVoidClass()) { | 410 if (cls.IsDynamicClass() || cls.IsVoidClass()) { |
| 422 const Array& args = Array::Handle(Array::New(1)); | 411 const Array& args = Array::Handle(Array::New(1)); |
| 423 args.SetAt(0, type); | 412 args.SetAt(0, type); |
| 424 Exceptions::ThrowByType(Exceptions::kArgument, args); | 413 Exceptions::ThrowByType(Exceptions::kArgument, args); |
| 425 UNREACHABLE(); | 414 UNREACHABLE(); |
| 426 } | 415 } |
| 427 // Strip the type for generics only. | 416 const Type& stripped_type = Type::Handle(cls.RareType()); |
| 428 if (cls.NumTypeParameters() == 0) { | 417 return CreateClassMirror(cls, |
| 429 return CreateClassMirror(cls, | 418 stripped_type, |
| 430 type, | 419 Bool::True(), // is_declaration |
| 431 Object::null_instance()); | 420 Object::null_instance()); |
| 432 } else { | |
| 433 return CreateClassMirror(cls, | |
| 434 AbstractType::Handle(), | |
| 435 Object::null_instance()); | |
| 436 } | |
| 437 } | 421 } |
| 438 | 422 |
| 439 | 423 |
| 440 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalTypeMirror, 1) { | 424 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalTypeMirror, 1) { |
| 441 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); | 425 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
| 442 return CreateTypeMirror(type); | 426 return CreateTypeMirror(type); |
| 443 } | 427 } |
| 444 | 428 |
| 445 | 429 |
| 446 DEFINE_NATIVE_ENTRY(MirrorReference_equals, 2) { | 430 DEFINE_NATIVE_ENTRY(MirrorReference_equals, 2) { |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 | 638 |
| 655 while (entries.HasNext()) { | 639 while (entries.HasNext()) { |
| 656 entry = entries.GetNext(); | 640 entry = entries.GetNext(); |
| 657 if (entry.IsClass()) { | 641 if (entry.IsClass()) { |
| 658 const Class& klass = Class::Cast(entry); | 642 const Class& klass = Class::Cast(entry); |
| 659 // We filter out implementation classes like Smi, Mint, Bignum, | 643 // We filter out implementation classes like Smi, Mint, Bignum, |
| 660 // OneByteString; function signature classes; and dynamic. | 644 // OneByteString; function signature classes; and dynamic. |
| 661 if (!klass.IsCanonicalSignatureClass() && | 645 if (!klass.IsCanonicalSignatureClass() && |
| 662 !klass.IsDynamicClass() && | 646 !klass.IsDynamicClass() && |
| 663 !RawObject::IsImplementationClassId(klass.id())) { | 647 !RawObject::IsImplementationClassId(klass.id())) { |
| 664 if (klass.NumTypeParameters() == 0) { | 648 type = klass.RareType(); |
| 665 // Include runtime type for non-generics only. | 649 member_mirror = CreateClassMirror(klass, |
| 666 type = RawTypeOfClass(klass); | 650 type, |
| 667 } else { | 651 Bool::True(), // is_declaration |
| 668 type = AbstractType::null(); | 652 owner_mirror); |
| 669 } | |
| 670 member_mirror = CreateClassMirror(klass, type, owner_mirror); | |
| 671 member_mirrors.Add(member_mirror); | 653 member_mirrors.Add(member_mirror); |
| 672 } | 654 } |
| 673 } else if (entry.IsField()) { | 655 } else if (entry.IsField()) { |
| 674 const Field& field = Field::Cast(entry); | 656 const Field& field = Field::Cast(entry); |
| 675 member_mirror = CreateVariableMirror(field, owner_mirror); | 657 member_mirror = CreateVariableMirror(field, owner_mirror); |
| 676 member_mirrors.Add(member_mirror); | 658 member_mirrors.Add(member_mirror); |
| 677 } else if (entry.IsFunction()) { | 659 } else if (entry.IsFunction()) { |
| 678 const Function& func = Function::Cast(entry); | 660 const Function& func = Function::Cast(entry); |
| 679 if (func.kind() == RawFunction::kRegularFunction || | 661 if (func.kind() == RawFunction::kRegularFunction || |
| 680 func.kind() == RawFunction::kGetterFunction || | 662 func.kind() == RawFunction::kGetterFunction || |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 type_mirror = CreateTypeMirror(arg_type); | 713 type_mirror = CreateTypeMirror(arg_type); |
| 732 result.SetAt(i, type_mirror); | 714 result.SetAt(i, type_mirror); |
| 733 } | 715 } |
| 734 return result.raw(); | 716 return result.raw(); |
| 735 } | 717 } |
| 736 | 718 |
| 737 | 719 |
| 738 DEFINE_NATIVE_ENTRY(TypeVariableMirror_owner, 1) { | 720 DEFINE_NATIVE_ENTRY(TypeVariableMirror_owner, 1) { |
| 739 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0)); | 721 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0)); |
| 740 const Class& owner = Class::Handle(param.parameterized_class()); | 722 const Class& owner = Class::Handle(param.parameterized_class()); |
| 741 // The owner of a type variable must be a generic class: pass a null runtime | 723 const Type& type = Type::Handle(owner.RareType()); |
| 742 // type to get a mirror on the declaration. | |
| 743 ASSERT(owner.NumTypeParameters() != 0); | |
| 744 return CreateClassMirror(owner, | 724 return CreateClassMirror(owner, |
| 745 AbstractType::Handle(), | 725 type, |
| 726 Bool::True(), // is_declaration |
| 746 Instance::null_instance()); | 727 Instance::null_instance()); |
| 747 } | 728 } |
| 748 | 729 |
| 749 | 730 |
| 750 DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 1) { | 731 DEFINE_NATIVE_ENTRY(TypeVariableMirror_upper_bound, 1) { |
| 751 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0)); | 732 GET_NON_NULL_NATIVE_ARGUMENT(TypeParameter, param, arguments->NativeArgAt(0)); |
| 752 return param.bound(); | 733 return param.bound(); |
| 753 } | 734 } |
| 754 | 735 |
| 755 | 736 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 960 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); | 941 Array::Handle(ArgumentsDescriptor::New(args.Length(), arg_names)); |
| 961 | 942 |
| 962 const Function& function = Function::Handle( | 943 const Function& function = Function::Handle( |
| 963 klass.LookupStaticFunctionAllowPrivate(function_name)); | 944 klass.LookupStaticFunctionAllowPrivate(function_name)); |
| 964 | 945 |
| 965 | 946 |
| 966 ArgumentsDescriptor args_descriptor(args_descriptor_array); | 947 ArgumentsDescriptor args_descriptor(args_descriptor_array); |
| 967 if (function.IsNull() || | 948 if (function.IsNull() || |
| 968 !function.AreValidArguments(args_descriptor, NULL) || | 949 !function.AreValidArguments(args_descriptor, NULL) || |
| 969 !function.is_visible()) { | 950 !function.is_visible()) { |
| 970 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 951 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 971 function_name, | 952 function_name, |
| 972 function, | 953 function, |
| 973 InvocationMirror::kStatic, | 954 InvocationMirror::kStatic, |
| 974 InvocationMirror::kMethod); | 955 InvocationMirror::kMethod); |
| 975 UNREACHABLE(); | 956 UNREACHABLE(); |
| 976 } | 957 } |
| 977 | 958 |
| 978 Object& result = Object::Handle( | 959 Object& result = Object::Handle( |
| 979 DartEntry::InvokeFunction(function, args, args_descriptor_array)); | 960 DartEntry::InvokeFunction(function, args, args_descriptor_array)); |
| 980 if (result.IsError()) { | 961 if (result.IsError()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 995 | 976 |
| 996 // Note static fields do not have implicit getters. | 977 // Note static fields do not have implicit getters. |
| 997 const Field& field = Field::Handle(klass.LookupStaticField(getter_name)); | 978 const Field& field = Field::Handle(klass.LookupStaticField(getter_name)); |
| 998 if (field.IsNull() || FieldIsUninitialized(field)) { | 979 if (field.IsNull() || FieldIsUninitialized(field)) { |
| 999 const String& internal_getter_name = String::Handle( | 980 const String& internal_getter_name = String::Handle( |
| 1000 Field::GetterName(getter_name)); | 981 Field::GetterName(getter_name)); |
| 1001 const Function& getter = Function::Handle( | 982 const Function& getter = Function::Handle( |
| 1002 klass.LookupStaticFunctionAllowPrivate(internal_getter_name)); | 983 klass.LookupStaticFunctionAllowPrivate(internal_getter_name)); |
| 1003 | 984 |
| 1004 if (getter.IsNull() || !getter.is_visible()) { | 985 if (getter.IsNull() || !getter.is_visible()) { |
| 1005 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 986 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 1006 getter_name, | 987 getter_name, |
| 1007 getter, | 988 getter, |
| 1008 InvocationMirror::kStatic, | 989 InvocationMirror::kStatic, |
| 1009 InvocationMirror::kGetter); | 990 InvocationMirror::kGetter); |
| 1010 UNREACHABLE(); | 991 UNREACHABLE(); |
| 1011 } | 992 } |
| 1012 | 993 |
| 1013 // Invoke the getter and return the result. | 994 // Invoke the getter and return the result. |
| 1014 Object& result = Object::Handle( | 995 Object& result = Object::Handle( |
| 1015 DartEntry::InvokeFunction(getter, Object::empty_array())); | 996 DartEntry::InvokeFunction(getter, Object::empty_array())); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1034 | 1015 |
| 1035 // Check for real fields and user-defined setters. | 1016 // Check for real fields and user-defined setters. |
| 1036 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); | 1017 const Field& field = Field::Handle(klass.LookupStaticField(setter_name)); |
| 1037 if (field.IsNull()) { | 1018 if (field.IsNull()) { |
| 1038 const String& internal_setter_name = String::Handle( | 1019 const String& internal_setter_name = String::Handle( |
| 1039 Field::SetterName(setter_name)); | 1020 Field::SetterName(setter_name)); |
| 1040 const Function& setter = Function::Handle( | 1021 const Function& setter = Function::Handle( |
| 1041 klass.LookupStaticFunctionAllowPrivate(internal_setter_name)); | 1022 klass.LookupStaticFunctionAllowPrivate(internal_setter_name)); |
| 1042 | 1023 |
| 1043 if (setter.IsNull() || !setter.is_visible()) { | 1024 if (setter.IsNull() || !setter.is_visible()) { |
| 1044 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 1025 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 1045 setter_name, | 1026 setter_name, |
| 1046 setter, | 1027 setter, |
| 1047 InvocationMirror::kStatic, | 1028 InvocationMirror::kStatic, |
| 1048 InvocationMirror::kSetter); | 1029 InvocationMirror::kSetter); |
| 1049 UNREACHABLE(); | 1030 UNREACHABLE(); |
| 1050 } | 1031 } |
| 1051 | 1032 |
| 1052 // Invoke the setter and return the result. | 1033 // Invoke the setter and return the result. |
| 1053 const int kNumArgs = 1; | 1034 const int kNumArgs = 1; |
| 1054 const Array& args = Array::Handle(Array::New(kNumArgs)); | 1035 const Array& args = Array::Handle(Array::New(kNumArgs)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1070 setter_name.ToCString())); | 1051 setter_name.ToCString())); |
| 1071 ThrowMirroredCompilationError(message); | 1052 ThrowMirroredCompilationError(message); |
| 1072 UNREACHABLE(); | 1053 UNREACHABLE(); |
| 1073 } | 1054 } |
| 1074 | 1055 |
| 1075 field.set_value(value); | 1056 field.set_value(value); |
| 1076 return value.raw(); | 1057 return value.raw(); |
| 1077 } | 1058 } |
| 1078 | 1059 |
| 1079 | 1060 |
| 1080 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 4) { | 1061 DEFINE_NATIVE_ENTRY(ClassMirror_invokeConstructor, 5) { |
| 1081 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1062 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| 1082 const Class& klass = Class::Handle(ref.GetClassReferent()); | 1063 const Class& klass = Class::Handle(ref.GetClassReferent()); |
| 1064 GET_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(1)); |
| 1083 GET_NON_NULL_NATIVE_ARGUMENT( | 1065 GET_NON_NULL_NATIVE_ARGUMENT( |
| 1084 String, constructor_name, arguments->NativeArgAt(1)); | 1066 String, constructor_name, arguments->NativeArgAt(2)); |
| 1085 GET_NON_NULL_NATIVE_ARGUMENT(Array, explicit_args, arguments->NativeArgAt(2)); | 1067 GET_NON_NULL_NATIVE_ARGUMENT(Array, explicit_args, arguments->NativeArgAt(3)); |
| 1086 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(3)); | 1068 GET_NON_NULL_NATIVE_ARGUMENT(Array, arg_names, arguments->NativeArgAt(4)); |
| 1087 | 1069 |
| 1088 // By convention, the static function implementing a named constructor 'C' | 1070 // By convention, the static function implementing a named constructor 'C' |
| 1089 // for class 'A' is labeled 'A.C', and the static function implementing the | 1071 // for class 'A' is labeled 'A.C', and the static function implementing the |
| 1090 // unnamed constructor for class 'A' is labeled 'A.'. | 1072 // unnamed constructor for class 'A' is labeled 'A.'. |
| 1091 // This convention prevents users from explicitly calling constructors. | 1073 // This convention prevents users from explicitly calling constructors. |
| 1092 const String& klass_name = String::Handle(klass.Name()); | 1074 const String& klass_name = String::Handle(klass.Name()); |
| 1093 String& internal_constructor_name = | 1075 String& internal_constructor_name = |
| 1094 String::Handle(String::Concat(klass_name, Symbols::Dot())); | 1076 String::Handle(String::Concat(klass_name, Symbols::Dot())); |
| 1095 if (!constructor_name.IsNull()) { | 1077 if (!constructor_name.IsNull()) { |
| 1096 internal_constructor_name = | 1078 internal_constructor_name = |
| 1097 String::Concat(internal_constructor_name, constructor_name); | 1079 String::Concat(internal_constructor_name, constructor_name); |
| 1098 } | 1080 } |
| 1099 | 1081 |
| 1100 Function& lookup_constructor = Function::Handle( | 1082 Function& lookup_constructor = Function::Handle( |
| 1101 klass.LookupFunctionAllowPrivate(internal_constructor_name)); | 1083 klass.LookupFunctionAllowPrivate(internal_constructor_name)); |
| 1102 | 1084 |
| 1103 if (lookup_constructor.IsNull() || | 1085 if (lookup_constructor.IsNull() || |
| 1104 !(lookup_constructor.IsConstructor() || lookup_constructor.IsFactory()) || | 1086 !(lookup_constructor.IsConstructor() || lookup_constructor.IsFactory()) || |
| 1105 !lookup_constructor.is_visible()) { | 1087 !lookup_constructor.is_visible()) { |
| 1106 // Pretend we didn't find the constructor at all when the arity is wrong | 1088 // Pretend we didn't find the constructor at all when the arity is wrong |
| 1107 // so as to produce the same NoSuchMethodError as the non-reflective case. | 1089 // so as to produce the same NoSuchMethodError as the non-reflective case. |
| 1108 lookup_constructor = Function::null(); | 1090 lookup_constructor = Function::null(); |
| 1109 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 1091 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 1110 internal_constructor_name, | 1092 internal_constructor_name, |
| 1111 lookup_constructor, | 1093 lookup_constructor, |
| 1112 InvocationMirror::kConstructor, | 1094 InvocationMirror::kConstructor, |
| 1113 InvocationMirror::kMethod); | 1095 InvocationMirror::kMethod); |
| 1114 UNREACHABLE(); | 1096 UNREACHABLE(); |
| 1115 } | 1097 } |
| 1116 | 1098 |
| 1117 Class& redirected_klass = Class::Handle(klass.raw()); | 1099 Class& redirected_klass = Class::Handle(klass.raw()); |
| 1118 Function& redirected_constructor = Function::Handle(lookup_constructor.raw()); | 1100 Function& redirected_constructor = Function::Handle(lookup_constructor.raw()); |
| 1119 if (lookup_constructor.IsRedirectingFactory()) { | 1101 if (lookup_constructor.IsRedirectingFactory()) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1140 const Array& args_descriptor_array = | 1122 const Array& args_descriptor_array = |
| 1141 Array::Handle(ArgumentsDescriptor::New(args.Length(), | 1123 Array::Handle(ArgumentsDescriptor::New(args.Length(), |
| 1142 arg_names)); | 1124 arg_names)); |
| 1143 | 1125 |
| 1144 ArgumentsDescriptor args_descriptor(args_descriptor_array); | 1126 ArgumentsDescriptor args_descriptor(args_descriptor_array); |
| 1145 if (!redirected_constructor.AreValidArguments(args_descriptor, NULL) || | 1127 if (!redirected_constructor.AreValidArguments(args_descriptor, NULL) || |
| 1146 !redirected_constructor.is_visible()) { | 1128 !redirected_constructor.is_visible()) { |
| 1147 // Pretend we didn't find the constructor at all when the arity is wrong | 1129 // Pretend we didn't find the constructor at all when the arity is wrong |
| 1148 // so as to produce the same NoSuchMethodError as the non-reflective case. | 1130 // so as to produce the same NoSuchMethodError as the non-reflective case. |
| 1149 redirected_constructor = Function::null(); | 1131 redirected_constructor = Function::null(); |
| 1150 ThrowNoSuchMethod(AbstractType::Handle(RawTypeOfClass(klass)), | 1132 ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()), |
| 1151 internal_constructor_name, | 1133 internal_constructor_name, |
| 1152 redirected_constructor, | 1134 redirected_constructor, |
| 1153 InvocationMirror::kConstructor, | 1135 InvocationMirror::kConstructor, |
| 1154 InvocationMirror::kMethod); | 1136 InvocationMirror::kMethod); |
| 1155 UNREACHABLE(); | 1137 UNREACHABLE(); |
| 1156 } | 1138 } |
| 1157 | 1139 |
| 1140 ASSERT(!type.IsNull()); |
| 1141 const AbstractTypeArguments& type_arguments = |
| 1142 AbstractTypeArguments::Handle(type.arguments()); |
| 1143 |
| 1158 Instance& new_object = Instance::Handle(); | 1144 Instance& new_object = Instance::Handle(); |
| 1159 if (redirected_constructor.IsConstructor()) { | 1145 if (redirected_constructor.IsConstructor()) { |
| 1160 // Constructors get the uninitialized object and a constructor phase. Note | 1146 // Constructors get the uninitialized object and a constructor phase. Note |
| 1161 // we have delayed allocation until after the function type and argument | 1147 // we have delayed allocation until after the function type and argument |
| 1162 // matching checks. | 1148 // matching checks. |
| 1163 new_object = Instance::New(redirected_klass); | 1149 new_object = Instance::New(redirected_klass); |
| 1150 if (!type_arguments.IsNull()) { |
| 1151 // The type arguments will be null if the class has no type parameters, in |
| 1152 // which case the following call would fail because there is no slot |
| 1153 // reserved in the object for the type vector. |
| 1154 new_object.SetTypeArguments(type_arguments); |
| 1155 } |
| 1164 args.SetAt(0, new_object); | 1156 args.SetAt(0, new_object); |
| 1165 args.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); | 1157 args.SetAt(1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); |
| 1166 } else { | 1158 } else { |
| 1167 // Factories get type arguments. | 1159 // Factories get type arguments. |
| 1168 // TODO(12921): Should we allow the user to specify type arguments? Use type | 1160 args.SetAt(0, type_arguments); |
| 1169 // arguments from the mirror? | |
| 1170 args.SetAt(0, Object::null_abstract_type_arguments()); | |
| 1171 } | 1161 } |
| 1172 | 1162 |
| 1173 // Invoke the constructor and return the new object. | 1163 // Invoke the constructor and return the new object. |
| 1174 const Object& result = | 1164 const Object& result = |
| 1175 Object::Handle(DartEntry::InvokeFunction(redirected_constructor, | 1165 Object::Handle(DartEntry::InvokeFunction(redirected_constructor, |
| 1176 args, | 1166 args, |
| 1177 args_descriptor_array)); | 1167 args_descriptor_array)); |
| 1178 if (result.IsError()) { | 1168 if (result.IsError()) { |
| 1179 return result.raw(); | 1169 return result.raw(); |
| 1180 } | 1170 } |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1340 const Function& func = Function::Handle(ref.GetFunctionReferent()); | 1330 const Function& func = Function::Handle(ref.GetFunctionReferent()); |
| 1341 if (func.IsNonImplicitClosureFunction()) { | 1331 if (func.IsNonImplicitClosureFunction()) { |
| 1342 return CreateMethodMirror(Function::Handle( | 1332 return CreateMethodMirror(Function::Handle( |
| 1343 func.parent_function()), Object::null_instance()); | 1333 func.parent_function()), Object::null_instance()); |
| 1344 } | 1334 } |
| 1345 const Class& owner = Class::Handle(func.Owner()); | 1335 const Class& owner = Class::Handle(func.Owner()); |
| 1346 if (owner.IsTopLevel()) { | 1336 if (owner.IsTopLevel()) { |
| 1347 return CreateLibraryMirror(Library::Handle(owner.library())); | 1337 return CreateLibraryMirror(Library::Handle(owner.library())); |
| 1348 } | 1338 } |
| 1349 | 1339 |
| 1350 AbstractType& type = AbstractType::Handle(); | 1340 Type& type = Type::Handle(owner.RareType()); |
| 1351 if (owner.NumTypeParameters() == 0) { | 1341 return CreateClassMirror(owner, type, Bool::True(), Object::null_instance()); |
| 1352 // Include runtime type for non-generics only. | |
| 1353 type = RawTypeOfClass(owner); | |
| 1354 } | |
| 1355 return CreateClassMirror(owner, type, Object::null_instance()); | |
| 1356 } | 1342 } |
| 1357 | 1343 |
| 1358 | 1344 |
| 1359 DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 2) { | 1345 DEFINE_NATIVE_ENTRY(MethodMirror_parameters, 2) { |
| 1360 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0)); | 1346 GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0)); |
| 1361 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); | 1347 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); |
| 1362 const Function& func = Function::Handle(ref.GetFunctionReferent()); | 1348 const Function& func = Function::Handle(ref.GetFunctionReferent()); |
| 1363 return CreateParameterMirrorList(func, owner); | 1349 return CreateParameterMirrorList(func, owner); |
| 1364 } | 1350 } |
| 1365 | 1351 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1419 } | 1405 } |
| 1420 | 1406 |
| 1421 | 1407 |
| 1422 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { | 1408 DEFINE_NATIVE_ENTRY(VariableMirror_type, 1) { |
| 1423 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 1409 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| 1424 const Field& field = Field::Handle(ref.GetFieldReferent()); | 1410 const Field& field = Field::Handle(ref.GetFieldReferent()); |
| 1425 return field.type(); | 1411 return field.type(); |
| 1426 } | 1412 } |
| 1427 | 1413 |
| 1428 } // namespace dart | 1414 } // namespace dart |
| OLD | NEW |