| 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 #define PROPOGATE_IF_MALFOMRED(type) \ | 21 #define PROPAGATE_IF_MALFORMED(type) \ |
| 22 if (type.IsMalformed()) { \ | 22 if (type.IsMalformed()) { \ |
| 23 Exceptions::PropagateError(Error::Handle(type.error())); \ | 23 Exceptions::PropagateError(Error::Handle(type.error())); \ |
| 24 } \ | 24 } \ |
| 25 | 25 |
| 26 static RawInstance* CreateMirror(const String& mirror_class_name, | 26 static RawInstance* CreateMirror(const String& mirror_class_name, |
| 27 const Array& constructor_arguments) { | 27 const Array& constructor_arguments) { |
| 28 const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary()); | 28 const Library& mirrors_lib = Library::Handle(Library::MirrorsLibrary()); |
| 29 const String& constructor_name = Symbols::Dot(); | 29 const String& constructor_name = Symbols::Dot(); |
| 30 | 30 |
| 31 const Object& result = Object::Handle( | 31 const Object& result = Object::Handle( |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 const TypeArguments& args = TypeArguments::Handle(cls.type_parameters()); | 203 const TypeArguments& args = TypeArguments::Handle(cls.type_parameters()); |
| 204 if (args.IsNull()) { | 204 if (args.IsNull()) { |
| 205 return Object::empty_array().raw(); | 205 return Object::empty_array().raw(); |
| 206 } | 206 } |
| 207 const Array& result = Array::Handle(Array::New(args.Length() * 2)); | 207 const Array& result = Array::Handle(Array::New(args.Length() * 2)); |
| 208 TypeParameter& type = TypeParameter::Handle(); | 208 TypeParameter& type = TypeParameter::Handle(); |
| 209 String& name = String::Handle(); | 209 String& name = String::Handle(); |
| 210 for (intptr_t i = 0; i < args.Length(); i++) { | 210 for (intptr_t i = 0; i < args.Length(); i++) { |
| 211 type ^= args.TypeAt(i); | 211 type ^= args.TypeAt(i); |
| 212 ASSERT(type.IsTypeParameter()); | 212 ASSERT(type.IsTypeParameter()); |
| 213 PROPOGATE_IF_MALFOMRED(type); | 213 PROPAGATE_IF_MALFORMED(type); |
| 214 ASSERT(type.IsFinalized()); | 214 ASSERT(type.IsFinalized()); |
| 215 name ^= type.name(); | 215 name ^= type.name(); |
| 216 result.SetAt(2 * i, name); | 216 result.SetAt(2 * i, name); |
| 217 result.SetAt(2 * i + 1, type); | 217 result.SetAt(2 * i + 1, type); |
| 218 } | 218 } |
| 219 return result.raw(); | 219 return result.raw(); |
| 220 } | 220 } |
| 221 | 221 |
| 222 | 222 |
| 223 static RawInstance* CreateTypedefMirror(const Class& cls, | 223 static RawInstance* CreateTypedefMirror(const Class& cls, |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 | 509 |
| 510 | 510 |
| 511 static RawInstance* CreateTypeMirror(const AbstractType& type) { | 511 static RawInstance* CreateTypeMirror(const AbstractType& type) { |
| 512 if (type.IsTypeRef()) { | 512 if (type.IsTypeRef()) { |
| 513 AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type()); | 513 AbstractType& ref_type = AbstractType::Handle(TypeRef::Cast(type).type()); |
| 514 ASSERT(!ref_type.IsTypeRef()); | 514 ASSERT(!ref_type.IsTypeRef()); |
| 515 ASSERT(ref_type.IsCanonical()); | 515 ASSERT(ref_type.IsCanonical()); |
| 516 return CreateTypeMirror(ref_type); | 516 return CreateTypeMirror(ref_type); |
| 517 } | 517 } |
| 518 ASSERT(type.IsFinalized()); | 518 ASSERT(type.IsFinalized()); |
| 519 PROPOGATE_IF_MALFOMRED(type); | 519 PROPAGATE_IF_MALFORMED(type); |
| 520 ASSERT(type.IsCanonical() || type.IsTypeParameter() || type.IsBoundedType()); |
| 520 | 521 |
| 521 if (type.HasResolvedTypeClass()) { | 522 if (type.HasResolvedTypeClass()) { |
| 522 const Class& cls = Class::Handle(type.type_class()); | 523 const Class& cls = Class::Handle(type.type_class()); |
| 523 // Handle void and dynamic types. | 524 // Handle void and dynamic types. |
| 524 if (cls.IsVoidClass()) { | 525 if (cls.IsVoidClass()) { |
| 525 Array& args = Array::Handle(Array::New(1)); | 526 Array& args = Array::Handle(Array::New(1)); |
| 526 args.SetAt(0, Symbols::Void()); | 527 args.SetAt(0, Symbols::Void()); |
| 527 return CreateMirror(Symbols::_SpecialTypeMirror(), args); | 528 return CreateMirror(Symbols::_SpecialTypeMirror(), args); |
| 528 } else if (cls.IsDynamicClass()) { | 529 } else if (cls.IsDynamicClass()) { |
| 529 Array& args = Array::Handle(Array::New(1)); | 530 Array& args = Array::Handle(Array::New(1)); |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 // Fall through case: Indicate that we didn't find any function or field using | 756 // Fall through case: Indicate that we didn't find any function or field using |
| 756 // a special null instance. This is different from a field being null. Callers | 757 // a special null instance. This is different from a field being null. Callers |
| 757 // make sure that this null does not leak into Dartland. | 758 // make sure that this null does not leak into Dartland. |
| 758 return Object::sentinel().raw(); | 759 return Object::sentinel().raw(); |
| 759 } | 760 } |
| 760 | 761 |
| 761 | 762 |
| 762 static RawAbstractType* InstantiateType(const AbstractType& type, | 763 static RawAbstractType* InstantiateType(const AbstractType& type, |
| 763 const AbstractType& instantiator) { | 764 const AbstractType& instantiator) { |
| 764 ASSERT(type.IsFinalized()); | 765 ASSERT(type.IsFinalized()); |
| 765 PROPOGATE_IF_MALFOMRED(type); | 766 PROPAGATE_IF_MALFORMED(type); |
| 767 ASSERT(type.IsCanonical() || type.IsTypeParameter() || type.IsBoundedType()); |
| 766 | 768 |
| 767 if (type.IsInstantiated() || instantiator.IsNull()) { | 769 if (type.IsInstantiated() || instantiator.IsNull()) { |
| 768 return type.Canonicalize(); | 770 return type.Canonicalize(); |
| 769 } | 771 } |
| 770 | 772 |
| 771 ASSERT(!instantiator.IsNull()); | 773 ASSERT(!instantiator.IsNull()); |
| 772 ASSERT(instantiator.IsFinalized()); | 774 ASSERT(instantiator.IsFinalized()); |
| 773 PROPOGATE_IF_MALFOMRED(instantiator); | 775 PROPAGATE_IF_MALFORMED(instantiator); |
| 774 | 776 |
| 775 const TypeArguments& type_args = | 777 const TypeArguments& type_args = |
| 776 TypeArguments::Handle(instantiator.arguments()); | 778 TypeArguments::Handle(instantiator.arguments()); |
| 777 Error& bound_error = Error::Handle(); | 779 Error& bound_error = Error::Handle(); |
| 778 AbstractType& result = | 780 AbstractType& result = |
| 779 AbstractType::Handle(type.InstantiateFrom(type_args, &bound_error)); | 781 AbstractType::Handle(type.InstantiateFrom(type_args, &bound_error)); |
| 780 if (!bound_error.IsNull()) { | 782 if (!bound_error.IsNull()) { |
| 781 Exceptions::PropagateError(bound_error); | 783 Exceptions::PropagateError(bound_error); |
| 782 UNREACHABLE(); | 784 UNREACHABLE(); |
| 783 } | 785 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 809 | 811 |
| 810 DEFINE_NATIVE_ENTRY(MirrorSystem_isolate, 0) { | 812 DEFINE_NATIVE_ENTRY(MirrorSystem_isolate, 0) { |
| 811 VerifyMethodKindShifts(); | 813 VerifyMethodKindShifts(); |
| 812 | 814 |
| 813 return CreateIsolateMirror(); | 815 return CreateIsolateMirror(); |
| 814 } | 816 } |
| 815 | 817 |
| 816 | 818 |
| 817 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) { | 819 DEFINE_NATIVE_ENTRY(Mirrors_makeLocalClassMirror, 1) { |
| 818 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); | 820 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
| 819 PROPOGATE_IF_MALFOMRED(type); | 821 PROPAGATE_IF_MALFORMED(type); |
| 820 ASSERT(type.IsFinalized()); | 822 ASSERT(type.IsFinalized()); |
| 821 ASSERT(type.HasResolvedTypeClass()); | 823 ASSERT(type.HasResolvedTypeClass()); |
| 822 const Class& cls = Class::Handle(type.type_class()); | 824 const Class& cls = Class::Handle(type.type_class()); |
| 823 ASSERT(!cls.IsNull()); | 825 ASSERT(!cls.IsNull()); |
| 824 if (cls.IsDynamicClass() || | 826 if (cls.IsDynamicClass() || |
| 825 cls.IsVoidClass() || | 827 cls.IsVoidClass() || |
| 826 (cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass())) { | 828 (cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass())) { |
| 827 Exceptions::ThrowArgumentError(type); | 829 Exceptions::ThrowArgumentError(type); |
| 828 UNREACHABLE(); | 830 UNREACHABLE(); |
| 829 } | 831 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 934 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); | 936 GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0)); |
| 935 const Class& klass = Class::Handle(ref.GetClassReferent()); | 937 const Class& klass = Class::Handle(ref.GetClassReferent()); |
| 936 const Library& library = Library::Handle(klass.library()); | 938 const Library& library = Library::Handle(klass.library()); |
| 937 ASSERT(!library.IsNull()); | 939 ASSERT(!library.IsNull()); |
| 938 return library.url(); | 940 return library.url(); |
| 939 } | 941 } |
| 940 | 942 |
| 941 | 943 |
| 942 DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) { | 944 DEFINE_NATIVE_ENTRY(ClassMirror_supertype, 1) { |
| 943 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); | 945 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
| 944 PROPOGATE_IF_MALFOMRED(type); | 946 PROPAGATE_IF_MALFORMED(type); |
| 945 ASSERT(type.IsFinalized()); | 947 ASSERT(type.IsFinalized()); |
| 946 if (!type.HasResolvedTypeClass()) { | 948 if (!type.HasResolvedTypeClass()) { |
| 947 Exceptions::ThrowArgumentError(type); | 949 Exceptions::ThrowArgumentError(type); |
| 948 UNREACHABLE(); | 950 UNREACHABLE(); |
| 949 } | 951 } |
| 950 const Class& cls = Class::Handle(type.type_class()); | 952 const Class& cls = Class::Handle(type.type_class()); |
| 951 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 953 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 952 ASSERT(super_type.IsNull() || super_type.IsFinalized()); | 954 ASSERT(super_type.IsNull() || super_type.IsFinalized()); |
| 953 return super_type.raw(); | 955 return super_type.raw(); |
| 954 } | 956 } |
| 955 | 957 |
| 956 | 958 |
| 957 DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 1) { | 959 DEFINE_NATIVE_ENTRY(ClassMirror_supertype_instantiated, 1) { |
| 958 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); | 960 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
| 959 PROPOGATE_IF_MALFOMRED(type); | 961 PROPAGATE_IF_MALFORMED(type); |
| 960 ASSERT(type.IsFinalized()); | 962 ASSERT(type.IsFinalized()); |
| 961 if (!type.HasResolvedTypeClass()) { | 963 if (!type.HasResolvedTypeClass()) { |
| 962 Exceptions::ThrowArgumentError(type); | 964 Exceptions::ThrowArgumentError(type); |
| 963 UNREACHABLE(); | 965 UNREACHABLE(); |
| 964 } | 966 } |
| 965 const Class& cls = Class::Handle(type.type_class()); | 967 const Class& cls = Class::Handle(type.type_class()); |
| 966 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); | 968 const AbstractType& super_type = AbstractType::Handle(cls.super_type()); |
| 967 return InstantiateType(super_type, type); | 969 return InstantiateType(super_type, type); |
| 968 } | 970 } |
| 969 | 971 |
| 970 | 972 |
| 971 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 1) { | 973 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces, 1) { |
| 972 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); | 974 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
| 973 PROPOGATE_IF_MALFOMRED(type); | 975 PROPAGATE_IF_MALFORMED(type); |
| 974 ASSERT(type.IsFinalized()); | 976 ASSERT(type.IsFinalized()); |
| 975 if (!type.HasResolvedTypeClass()) { | 977 if (!type.HasResolvedTypeClass()) { |
| 976 Exceptions::ThrowArgumentError(type); | 978 Exceptions::ThrowArgumentError(type); |
| 977 UNREACHABLE(); | 979 UNREACHABLE(); |
| 978 } | 980 } |
| 979 const Class& cls = Class::Handle(type.type_class()); | 981 const Class& cls = Class::Handle(type.type_class()); |
| 980 const Error& error = Error::Handle(cls.EnsureIsFinalized(isolate)); | 982 const Error& error = Error::Handle(cls.EnsureIsFinalized(isolate)); |
| 981 if (!error.IsNull()) { | 983 if (!error.IsNull()) { |
| 982 Exceptions::PropagateError(error); | 984 Exceptions::PropagateError(error); |
| 983 } | 985 } |
| 984 | 986 |
| 985 return cls.interfaces(); | 987 return cls.interfaces(); |
| 986 } | 988 } |
| 987 | 989 |
| 988 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces_instantiated, 1) { | 990 DEFINE_NATIVE_ENTRY(ClassMirror_interfaces_instantiated, 1) { |
| 989 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); | 991 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
| 990 PROPOGATE_IF_MALFOMRED(type); | 992 PROPAGATE_IF_MALFORMED(type); |
| 991 ASSERT(type.IsFinalized()); | 993 ASSERT(type.IsFinalized()); |
| 992 if (!type.HasResolvedTypeClass()) { | 994 if (!type.HasResolvedTypeClass()) { |
| 993 Exceptions::ThrowArgumentError(type); | 995 Exceptions::ThrowArgumentError(type); |
| 994 UNREACHABLE(); | 996 UNREACHABLE(); |
| 995 } | 997 } |
| 996 const Class& cls = Class::Handle(type.type_class()); | 998 const Class& cls = Class::Handle(type.type_class()); |
| 997 const Error& error = Error::Handle(cls.EnsureIsFinalized(isolate)); | 999 const Error& error = Error::Handle(cls.EnsureIsFinalized(isolate)); |
| 998 if (!error.IsNull()) { | 1000 if (!error.IsNull()) { |
| 999 Exceptions::PropagateError(error); | 1001 Exceptions::PropagateError(error); |
| 1000 } | 1002 } |
| 1001 | 1003 |
| 1002 Array& interfaces = Array::Handle(cls.interfaces()); | 1004 Array& interfaces = Array::Handle(cls.interfaces()); |
| 1003 Array& interfaces_inst = Array::Handle(Array::New(interfaces.Length())); | 1005 Array& interfaces_inst = Array::Handle(Array::New(interfaces.Length())); |
| 1004 AbstractType& interface = AbstractType::Handle(); | 1006 AbstractType& interface = AbstractType::Handle(); |
| 1005 | 1007 |
| 1006 for (int i = 0; i < interfaces.Length(); i++) { | 1008 for (int i = 0; i < interfaces.Length(); i++) { |
| 1007 interface ^= interfaces.At(i); | 1009 interface ^= interfaces.At(i); |
| 1008 interface = InstantiateType(interface, type); | 1010 interface = InstantiateType(interface, type); |
| 1009 interfaces_inst.SetAt(i, interface); | 1011 interfaces_inst.SetAt(i, interface); |
| 1010 } | 1012 } |
| 1011 | 1013 |
| 1012 return interfaces_inst.raw(); | 1014 return interfaces_inst.raw(); |
| 1013 } | 1015 } |
| 1014 | 1016 |
| 1015 | 1017 |
| 1016 DEFINE_NATIVE_ENTRY(ClassMirror_mixin, 1) { | 1018 DEFINE_NATIVE_ENTRY(ClassMirror_mixin, 1) { |
| 1017 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); | 1019 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
| 1018 PROPOGATE_IF_MALFOMRED(type); | 1020 PROPAGATE_IF_MALFORMED(type); |
| 1019 ASSERT(type.IsFinalized()); | 1021 ASSERT(type.IsFinalized()); |
| 1020 if (!type.HasResolvedTypeClass()) { | 1022 if (!type.HasResolvedTypeClass()) { |
| 1021 Exceptions::ThrowArgumentError(type); | 1023 Exceptions::ThrowArgumentError(type); |
| 1022 UNREACHABLE(); | 1024 UNREACHABLE(); |
| 1023 } | 1025 } |
| 1024 const Class& cls = Class::Handle(type.type_class()); | 1026 const Class& cls = Class::Handle(type.type_class()); |
| 1025 const AbstractType& mixin_type = AbstractType::Handle(cls.mixin()); | 1027 const AbstractType& mixin_type = AbstractType::Handle(cls.mixin()); |
| 1026 ASSERT(mixin_type.IsNull() || mixin_type.IsFinalized()); | 1028 ASSERT(mixin_type.IsNull() || mixin_type.IsFinalized()); |
| 1027 return mixin_type.raw(); | 1029 return mixin_type.raw(); |
| 1028 } | 1030 } |
| 1029 | 1031 |
| 1030 | 1032 |
| 1031 DEFINE_NATIVE_ENTRY(ClassMirror_mixin_instantiated, 2) { | 1033 DEFINE_NATIVE_ENTRY(ClassMirror_mixin_instantiated, 2) { |
| 1032 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); | 1034 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0)); |
| 1033 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, | 1035 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, |
| 1034 instantiator, | 1036 instantiator, |
| 1035 arguments->NativeArgAt(1)); | 1037 arguments->NativeArgAt(1)); |
| 1036 PROPOGATE_IF_MALFOMRED(type); | 1038 PROPAGATE_IF_MALFORMED(type); |
| 1037 ASSERT(type.IsFinalized()); | 1039 ASSERT(type.IsFinalized()); |
| 1038 if (!type.HasResolvedTypeClass()) { | 1040 if (!type.HasResolvedTypeClass()) { |
| 1039 Exceptions::ThrowArgumentError(type); | 1041 Exceptions::ThrowArgumentError(type); |
| 1040 UNREACHABLE(); | 1042 UNREACHABLE(); |
| 1041 } | 1043 } |
| 1042 const Class& cls = Class::Handle(type.type_class()); | 1044 const Class& cls = Class::Handle(type.type_class()); |
| 1043 const AbstractType& mixin_type = AbstractType::Handle(cls.mixin()); | 1045 const AbstractType& mixin_type = AbstractType::Handle(cls.mixin()); |
| 1044 if (mixin_type.IsNull()) { | 1046 if (mixin_type.IsNull()) { |
| 1045 return mixin_type.raw(); | 1047 return mixin_type.raw(); |
| 1046 } | 1048 } |
| (...skipping 1024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2071 } | 2073 } |
| 2072 | 2074 |
| 2073 DEFINE_NATIVE_ENTRY(TypeMirror_moreSpecificTest, 2) { | 2075 DEFINE_NATIVE_ENTRY(TypeMirror_moreSpecificTest, 2) { |
| 2074 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, a, arguments->NativeArgAt(0)); | 2076 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, a, arguments->NativeArgAt(0)); |
| 2075 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, b, arguments->NativeArgAt(1)); | 2077 GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, b, arguments->NativeArgAt(1)); |
| 2076 return Bool::Get(a.IsMoreSpecificThan(b, NULL)).raw(); | 2078 return Bool::Get(a.IsMoreSpecificThan(b, NULL)).raw(); |
| 2077 } | 2079 } |
| 2078 | 2080 |
| 2079 | 2081 |
| 2080 } // namespace dart | 2082 } // namespace dart |
| OLD | NEW |