| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_mirrors_api.h" | 6 #include "include/dart_mirrors_api.h" |
| 7 #include "include/dart_native_api.h" | 7 #include "include/dart_native_api.h" |
| 8 | 8 |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 #include "vm/bigint_operations.h" | 10 #include "vm/bigint_operations.h" |
| (...skipping 1223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1234 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | 1234 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); |
| 1235 return GetListInstance(isolate, obj) != Instance::null(); | 1235 return GetListInstance(isolate, obj) != Instance::null(); |
| 1236 } | 1236 } |
| 1237 | 1237 |
| 1238 | 1238 |
| 1239 DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) { | 1239 DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) { |
| 1240 return Api::ClassId(object) == kLibraryCid; | 1240 return Api::ClassId(object) == kLibraryCid; |
| 1241 } | 1241 } |
| 1242 | 1242 |
| 1243 | 1243 |
| 1244 DART_EXPORT bool Dart_IsType(Dart_Handle handle) { |
| 1245 return Api::ClassId(handle) == kTypeCid; |
| 1246 } |
| 1247 |
| 1248 |
| 1244 DART_EXPORT bool Dart_IsClass(Dart_Handle handle) { | 1249 DART_EXPORT bool Dart_IsClass(Dart_Handle handle) { |
| 1245 Isolate* isolate = Isolate::Current(); | 1250 Isolate* isolate = Isolate::Current(); |
| 1246 DARTSCOPE(isolate); | 1251 DARTSCOPE(isolate); |
| 1247 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); | 1252 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); |
| 1248 return obj.IsClass(); | 1253 return obj.IsClass(); |
| 1249 } | 1254 } |
| 1250 | 1255 |
| 1251 | 1256 |
| 1252 DART_EXPORT bool Dart_IsAbstractClass(Dart_Handle handle) { | |
| 1253 Isolate* isolate = Isolate::Current(); | |
| 1254 DARTSCOPE(isolate); | |
| 1255 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(handle)); | |
| 1256 if (obj.IsClass()) { | |
| 1257 return Class::Cast(obj).is_abstract(); | |
| 1258 } | |
| 1259 return false; | |
| 1260 } | |
| 1261 | |
| 1262 | |
| 1263 DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) { | 1257 DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) { |
| 1264 return Api::ClassId(handle) == kFunctionCid; | 1258 return Api::ClassId(handle) == kFunctionCid; |
| 1265 } | 1259 } |
| 1266 | 1260 |
| 1267 | 1261 |
| 1268 DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) { | 1262 DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) { |
| 1269 return Api::ClassId(handle) == kFieldCid; | 1263 return Api::ClassId(handle) == kFieldCid; |
| 1270 } | 1264 } |
| 1271 | 1265 |
| 1272 | 1266 |
| 1273 DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle) { | 1267 DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle) { |
| 1274 return Api::ClassId(handle) == kTypeParameterCid; | 1268 return Api::ClassId(handle) == kTypeParameterCid; |
| 1275 } | 1269 } |
| 1276 | 1270 |
| 1277 | 1271 |
| 1278 DART_EXPORT bool Dart_IsClosure(Dart_Handle object) { | 1272 DART_EXPORT bool Dart_IsClosure(Dart_Handle object) { |
| 1279 // We can't use a fast class index check here because there are many | 1273 // We can't use a fast class index check here because there are many |
| 1280 // different signature classes for closures. | 1274 // different signature classes for closures. |
| 1281 Isolate* isolate = Isolate::Current(); | 1275 Isolate* isolate = Isolate::Current(); |
| 1282 DARTSCOPE(isolate); | 1276 DARTSCOPE(isolate); |
| 1283 const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, object); | 1277 const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, object); |
| 1284 return (!closure_obj.IsNull() && closure_obj.IsClosure()); | 1278 return (!closure_obj.IsNull() && closure_obj.IsClosure()); |
| 1285 } | 1279 } |
| 1286 | 1280 |
| 1287 | 1281 |
| 1288 // --- Instances ---- | 1282 // --- Instances ---- |
| 1289 | 1283 |
| 1290 // TODO(turnidge): Technically, null has a class. Should we allow it? | 1284 DART_EXPORT Dart_Handle Dart_InstanceGetType(Dart_Handle instance) { |
| 1285 Isolate* isolate = Isolate::Current(); |
| 1286 DARTSCOPE(isolate); |
| 1287 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(instance)); |
| 1288 if (obj.IsNull()) { |
| 1289 return Api::NewHandle(isolate, isolate->object_store()->null_type()); |
| 1290 } |
| 1291 if (!obj.IsInstance()) { |
| 1292 RETURN_TYPE_ERROR(isolate, instance, Instance); |
| 1293 } |
| 1294 const Type& type = Type::Handle(Instance::Cast(obj).GetType()); |
| 1295 return Api::NewHandle(isolate, type.Canonicalize()); |
| 1296 } |
| 1297 |
| 1298 // TODO(asiva): Deprecate this method. |
| 1291 DART_EXPORT Dart_Handle Dart_InstanceGetClass(Dart_Handle instance) { | 1299 DART_EXPORT Dart_Handle Dart_InstanceGetClass(Dart_Handle instance) { |
| 1292 Isolate* isolate = Isolate::Current(); | 1300 Isolate* isolate = Isolate::Current(); |
| 1293 DARTSCOPE(isolate); | 1301 DARTSCOPE(isolate); |
| 1294 const Instance& obj = Api::UnwrapInstanceHandle(isolate, instance); | 1302 const Instance& obj = Api::UnwrapInstanceHandle(isolate, instance); |
| 1295 if (obj.IsNull()) { | 1303 if (obj.IsNull()) { |
| 1296 RETURN_TYPE_ERROR(isolate, instance, Instance); | 1304 RETURN_TYPE_ERROR(isolate, instance, Instance); |
| 1297 } | 1305 } |
| 1298 return Api::NewHandle(isolate, obj.clazz()); | 1306 return Api::NewHandle(isolate, obj.clazz()); |
| 1299 } | 1307 } |
| 1300 | 1308 |
| (...skipping 1406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2707 "constructor '%s': %s.", | 2715 "constructor '%s': %s.", |
| 2708 current_func, | 2716 current_func, |
| 2709 constr_name.ToCString(), | 2717 constr_name.ToCString(), |
| 2710 error_message.ToCString())); | 2718 error_message.ToCString())); |
| 2711 return ApiError::New(message); | 2719 return ApiError::New(message); |
| 2712 } | 2720 } |
| 2713 return constructor.raw(); | 2721 return constructor.raw(); |
| 2714 } | 2722 } |
| 2715 | 2723 |
| 2716 | 2724 |
| 2717 DART_EXPORT Dart_Handle Dart_New(Dart_Handle clazz, | 2725 DART_EXPORT Dart_Handle Dart_New(Dart_Handle type, |
| 2718 Dart_Handle constructor_name, | 2726 Dart_Handle constructor_name, |
| 2719 int number_of_arguments, | 2727 int number_of_arguments, |
| 2720 Dart_Handle* arguments) { | 2728 Dart_Handle* arguments) { |
| 2721 Isolate* isolate = Isolate::Current(); | 2729 Isolate* isolate = Isolate::Current(); |
| 2722 DARTSCOPE(isolate); | 2730 DARTSCOPE(isolate); |
| 2723 CHECK_CALLBACK_STATE(isolate); | 2731 CHECK_CALLBACK_STATE(isolate); |
| 2724 Object& result = Object::Handle(isolate); | 2732 Object& result = Object::Handle(isolate); |
| 2725 | 2733 |
| 2726 if (number_of_arguments < 0) { | 2734 if (number_of_arguments < 0) { |
| 2727 return Api::NewError( | 2735 return Api::NewError( |
| 2728 "%s expects argument 'number_of_arguments' to be non-negative.", | 2736 "%s expects argument 'number_of_arguments' to be non-negative.", |
| 2729 CURRENT_FUNC); | 2737 CURRENT_FUNC); |
| 2730 } | 2738 } |
| 2731 | 2739 |
| 2732 // Get the class to instantiate. | 2740 // Get the class to instantiate. |
| 2733 Class& cls = | 2741 result = Api::UnwrapHandle(type); |
| 2734 Class::Handle(isolate, Api::UnwrapClassHandle(isolate, clazz).raw()); | 2742 if (result.IsNull()) { |
| 2735 if (cls.IsNull()) { | 2743 RETURN_TYPE_ERROR(isolate, type, Type); |
| 2736 RETURN_TYPE_ERROR(isolate, clazz, Class); | 2744 } |
| 2745 Class& cls = Class::Handle(isolate); |
| 2746 if (result.IsType()) { |
| 2747 cls = Type::Cast(result).type_class(); |
| 2748 } else if (result.IsClass()) { |
| 2749 // For backwards compatibility we allow class objects to be passed in |
| 2750 // for now. This needs to be removed once all code that uses class |
| 2751 // objects to invoke Dart_New is removed. |
| 2752 cls ^= result.raw(); |
| 2753 } else { |
| 2754 RETURN_TYPE_ERROR(isolate, type, Type); |
| 2737 } | 2755 } |
| 2738 | 2756 |
| 2739 String& base_constructor_name = String::Handle(); | 2757 String& base_constructor_name = String::Handle(); |
| 2740 base_constructor_name = cls.Name(); | 2758 base_constructor_name = cls.Name(); |
| 2741 | 2759 |
| 2742 // And get the name of the constructor to invoke. | 2760 // And get the name of the constructor to invoke. |
| 2743 String& dot_name = String::Handle(isolate); | 2761 String& dot_name = String::Handle(isolate); |
| 2744 const Object& name_obj = | 2762 result = Api::UnwrapHandle(constructor_name); |
| 2745 Object::Handle(isolate, Api::UnwrapHandle(constructor_name)); | 2763 if (result.IsNull()) { |
| 2746 if (name_obj.IsNull()) { | |
| 2747 dot_name = Symbols::Dot().raw(); | 2764 dot_name = Symbols::Dot().raw(); |
| 2748 } else if (name_obj.IsString()) { | 2765 } else if (result.IsString()) { |
| 2749 dot_name = String::Concat(Symbols::Dot(), String::Cast(name_obj)); | 2766 dot_name = String::Concat(Symbols::Dot(), String::Cast(result)); |
| 2750 } else { | 2767 } else { |
| 2751 RETURN_TYPE_ERROR(isolate, constructor_name, String); | 2768 RETURN_TYPE_ERROR(isolate, constructor_name, String); |
| 2752 } | 2769 } |
| 2753 Dart_Handle state = Api::CheckIsolateState(isolate); | 2770 Dart_Handle state = Api::CheckIsolateState(isolate); |
| 2754 if (::Dart_IsError(state)) { | 2771 if (::Dart_IsError(state)) { |
| 2755 return state; | 2772 return state; |
| 2756 } | 2773 } |
| 2757 | 2774 |
| 2758 // Resolve the constructor. | 2775 // Resolve the constructor. |
| 2759 String& constr_name = | 2776 String& constr_name = |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2841 return Api::NewError( | 2858 return Api::NewError( |
| 2842 "%s expects argument 'number_of_arguments' to be non-negative.", | 2859 "%s expects argument 'number_of_arguments' to be non-negative.", |
| 2843 CURRENT_FUNC); | 2860 CURRENT_FUNC); |
| 2844 } | 2861 } |
| 2845 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | 2862 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); |
| 2846 if (obj.IsError()) { | 2863 if (obj.IsError()) { |
| 2847 return target; | 2864 return target; |
| 2848 } | 2865 } |
| 2849 | 2866 |
| 2850 // Check for malformed arguments in the arguments list. | 2867 // Check for malformed arguments in the arguments list. |
| 2851 intptr_t num_receiver = (obj.IsNull() || obj.IsInstance()) ? 1 : 0; | 2868 intptr_t num_receiver = |
| 2869 (obj.IsNull() || (obj.IsInstance() && !obj.IsType())) ? 1 : 0; |
| 2852 const Array& args = | 2870 const Array& args = |
| 2853 Array::Handle(isolate, Array::New(number_of_arguments + num_receiver)); | 2871 Array::Handle(isolate, Array::New(number_of_arguments + num_receiver)); |
| 2854 Object& arg = Object::Handle(isolate); | 2872 Object& arg = Object::Handle(isolate); |
| 2855 for (int i = 0; i < number_of_arguments; i++) { | 2873 for (int i = 0; i < number_of_arguments; i++) { |
| 2856 arg = Api::UnwrapHandle(arguments[i]); | 2874 arg = Api::UnwrapHandle(arguments[i]); |
| 2857 if (!arg.IsNull() && !arg.IsInstance()) { | 2875 if (!arg.IsNull() && !arg.IsInstance()) { |
| 2858 if (arg.IsError()) { | 2876 if (arg.IsError()) { |
| 2859 return Api::NewHandle(isolate, arg.raw()); | 2877 return Api::NewHandle(isolate, arg.raw()); |
| 2860 } else { | 2878 } else { |
| 2861 return Api::NewError( | 2879 return Api::NewError( |
| 2862 "%s expects arguments[%d] to be an Instance handle.", | 2880 "%s expects arguments[%d] to be an Instance handle.", |
| 2863 CURRENT_FUNC, i); | 2881 CURRENT_FUNC, i); |
| 2864 } | 2882 } |
| 2865 } | 2883 } |
| 2866 args.SetAt((i + num_receiver), arg); | 2884 args.SetAt((i + num_receiver), arg); |
| 2867 } | 2885 } |
| 2868 | 2886 |
| 2869 if (obj.IsNull() || obj.IsInstance()) { | 2887 if (obj.IsType() || obj.IsClass()) { |
| 2870 Instance& instance = Instance::Handle(isolate); | |
| 2871 instance ^= obj.raw(); | |
| 2872 const Function& function = Function::Handle( | |
| 2873 isolate, | |
| 2874 Resolver::ResolveDynamic(instance, | |
| 2875 function_name, | |
| 2876 (number_of_arguments + 1), | |
| 2877 Resolver::kIsQualified)); | |
| 2878 args.SetAt(0, instance); | |
| 2879 if (function.IsNull()) { | |
| 2880 const Array& args_descriptor = | |
| 2881 Array::Handle(ArgumentsDescriptor::New(args.Length())); | |
| 2882 return Api::NewHandle(isolate, | |
| 2883 DartEntry::InvokeNoSuchMethod(instance, | |
| 2884 function_name, | |
| 2885 args, | |
| 2886 args_descriptor)); | |
| 2887 } | |
| 2888 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); | |
| 2889 | |
| 2890 } else if (obj.IsClass()) { | |
| 2891 // Finalize all classes. | 2888 // Finalize all classes. |
| 2892 Dart_Handle state = Api::CheckIsolateState(isolate); | 2889 Dart_Handle state = Api::CheckIsolateState(isolate); |
| 2893 if (::Dart_IsError(state)) { | 2890 if (::Dart_IsError(state)) { |
| 2894 return state; | 2891 return state; |
| 2895 } | 2892 } |
| 2896 | 2893 |
| 2897 const Class& cls = Class::Cast(obj); | 2894 Class& cls = Class::Handle(); |
| 2895 if (obj.IsType()) { |
| 2896 cls = Type::Cast(obj).type_class(); |
| 2897 } else { |
| 2898 cls = Class::Cast(obj).raw(); |
| 2899 } |
| 2898 const Function& function = Function::Handle( | 2900 const Function& function = Function::Handle( |
| 2899 isolate, | 2901 isolate, |
| 2900 Resolver::ResolveStatic(cls, | 2902 Resolver::ResolveStatic(cls, |
| 2901 function_name, | 2903 function_name, |
| 2902 number_of_arguments, | 2904 number_of_arguments, |
| 2903 Object::empty_array(), | 2905 Object::empty_array(), |
| 2904 Resolver::kIsQualified)); | 2906 Resolver::kIsQualified)); |
| 2905 if (function.IsNull()) { | 2907 if (function.IsNull()) { |
| 2906 const String& cls_name = String::Handle(isolate, cls.Name()); | 2908 const String& cls_name = String::Handle(isolate, cls.Name()); |
| 2907 return Api::NewError("%s: did not find static method '%s.%s'.", | 2909 return Api::NewError("%s: did not find static method '%s.%s'.", |
| 2908 CURRENT_FUNC, | 2910 CURRENT_FUNC, |
| 2909 cls_name.ToCString(), | 2911 cls_name.ToCString(), |
| 2910 function_name.ToCString()); | 2912 function_name.ToCString()); |
| 2911 } | 2913 } |
| 2912 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); | 2914 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); |
| 2913 | 2915 |
| 2916 } else if (obj.IsNull() || obj.IsInstance()) { |
| 2917 Instance& instance = Instance::Handle(isolate); |
| 2918 instance ^= obj.raw(); |
| 2919 const Function& function = Function::Handle( |
| 2920 isolate, |
| 2921 Resolver::ResolveDynamic(instance, |
| 2922 function_name, |
| 2923 (number_of_arguments + 1), |
| 2924 Resolver::kIsQualified)); |
| 2925 args.SetAt(0, instance); |
| 2926 if (function.IsNull()) { |
| 2927 const Array& args_descriptor = |
| 2928 Array::Handle(ArgumentsDescriptor::New(args.Length())); |
| 2929 return Api::NewHandle(isolate, |
| 2930 DartEntry::InvokeNoSuchMethod(instance, |
| 2931 function_name, |
| 2932 args, |
| 2933 args_descriptor)); |
| 2934 } |
| 2935 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); |
| 2936 |
| 2914 } else if (obj.IsLibrary()) { | 2937 } else if (obj.IsLibrary()) { |
| 2915 // Check whether class finalization is needed. | 2938 // Check whether class finalization is needed. |
| 2916 bool finalize_classes = true; | 2939 bool finalize_classes = true; |
| 2917 const Library& lib = Library::Cast(obj); | 2940 const Library& lib = Library::Cast(obj); |
| 2918 | 2941 |
| 2919 // When calling functions in the dart:builtin library do not finalize as it | 2942 // When calling functions in the dart:builtin library do not finalize as it |
| 2920 // should have been prefinalized. | 2943 // should have been prefinalized. |
| 2921 Library& builtin = | 2944 Library& builtin = |
| 2922 Library::Handle(isolate, isolate->object_store()->builtin_library()); | 2945 Library::Handle(isolate, isolate->object_store()->builtin_library()); |
| 2923 if (builtin.raw() == lib.raw()) { | 2946 if (builtin.raw() == lib.raw()) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2947 &error_message)) { | 2970 &error_message)) { |
| 2948 return Api::NewError("%s: wrong argument count for function '%s': %s.", | 2971 return Api::NewError("%s: wrong argument count for function '%s': %s.", |
| 2949 CURRENT_FUNC, | 2972 CURRENT_FUNC, |
| 2950 function_name.ToCString(), | 2973 function_name.ToCString(), |
| 2951 error_message.ToCString()); | 2974 error_message.ToCString()); |
| 2952 } | 2975 } |
| 2953 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); | 2976 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); |
| 2954 | 2977 |
| 2955 } else { | 2978 } else { |
| 2956 return Api::NewError( | 2979 return Api::NewError( |
| 2957 "%s expects argument 'target' to be an object, class, or library.", | 2980 "%s expects argument 'target' to be an object, type, or library.", |
| 2958 CURRENT_FUNC); | 2981 CURRENT_FUNC); |
| 2959 } | 2982 } |
| 2960 } | 2983 } |
| 2961 | 2984 |
| 2962 | 2985 |
| 2963 DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure, | 2986 DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure, |
| 2964 int number_of_arguments, | 2987 int number_of_arguments, |
| 2965 Dart_Handle* arguments) { | 2988 Dart_Handle* arguments) { |
| 2966 Isolate* isolate = Isolate::Current(); | 2989 Isolate* isolate = Isolate::Current(); |
| 2967 DARTSCOPE(isolate); | 2990 DARTSCOPE(isolate); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3020 Dart_Handle state = Api::CheckIsolateState(isolate); | 3043 Dart_Handle state = Api::CheckIsolateState(isolate); |
| 3021 if (::Dart_IsError(state)) { | 3044 if (::Dart_IsError(state)) { |
| 3022 return state; | 3045 return state; |
| 3023 } | 3046 } |
| 3024 Field& field = Field::Handle(isolate); | 3047 Field& field = Field::Handle(isolate); |
| 3025 Function& getter = Function::Handle(isolate); | 3048 Function& getter = Function::Handle(isolate); |
| 3026 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(container)); | 3049 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(container)); |
| 3027 if (obj.IsNull()) { | 3050 if (obj.IsNull()) { |
| 3028 return Api::NewError("%s expects argument 'container' to be non-null.", | 3051 return Api::NewError("%s expects argument 'container' to be non-null.", |
| 3029 CURRENT_FUNC); | 3052 CURRENT_FUNC); |
| 3053 } else if (obj.IsType() || obj.IsClass()) { |
| 3054 // To access a static field we may need to use the Field or the |
| 3055 // getter Function. |
| 3056 Class& cls = Class::Handle(); |
| 3057 if (obj.IsType()) { |
| 3058 cls = Type::Cast(obj).type_class(); |
| 3059 } else { |
| 3060 cls = Class::Cast(obj).raw(); |
| 3061 } |
| 3062 field = cls.LookupStaticField(field_name); |
| 3063 if (field.IsNull() || FieldIsUninitialized(isolate, field)) { |
| 3064 const String& getter_name = |
| 3065 String::Handle(isolate, Field::GetterName(field_name)); |
| 3066 getter = cls.LookupStaticFunctionAllowPrivate(getter_name); |
| 3067 } |
| 3068 |
| 3069 if (!getter.IsNull()) { |
| 3070 // Invoke the getter and return the result. |
| 3071 return Api::NewHandle( |
| 3072 isolate, DartEntry::InvokeFunction(getter, Object::empty_array())); |
| 3073 } else if (!field.IsNull()) { |
| 3074 return Api::NewHandle(isolate, field.value()); |
| 3075 } else { |
| 3076 return Api::NewError("%s: did not find static field '%s'.", |
| 3077 CURRENT_FUNC, field_name.ToCString()); |
| 3078 } |
| 3079 |
| 3030 } else if (obj.IsInstance()) { | 3080 } else if (obj.IsInstance()) { |
| 3031 // Every instance field has a getter Function. Try to find the | 3081 // Every instance field has a getter Function. Try to find the |
| 3032 // getter in any superclass and use that function to access the | 3082 // getter in any superclass and use that function to access the |
| 3033 // field. | 3083 // field. |
| 3034 const Instance& instance = Instance::Cast(obj); | 3084 const Instance& instance = Instance::Cast(obj); |
| 3035 Class& cls = Class::Handle(isolate, instance.clazz()); | 3085 Class& cls = Class::Handle(isolate, instance.clazz()); |
| 3036 String& getter_name = | 3086 String& getter_name = |
| 3037 String::Handle(isolate, Field::GetterName(field_name)); | 3087 String::Handle(isolate, Field::GetterName(field_name)); |
| 3038 while (!cls.IsNull()) { | 3088 while (!cls.IsNull()) { |
| 3039 getter = cls.LookupDynamicFunctionAllowPrivate(getter_name); | 3089 getter = cls.LookupDynamicFunctionAllowPrivate(getter_name); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3051 const Array& args_descriptor = | 3101 const Array& args_descriptor = |
| 3052 Array::Handle(ArgumentsDescriptor::New(args.Length())); | 3102 Array::Handle(ArgumentsDescriptor::New(args.Length())); |
| 3053 return Api::NewHandle(isolate, | 3103 return Api::NewHandle(isolate, |
| 3054 DartEntry::InvokeNoSuchMethod(instance, | 3104 DartEntry::InvokeNoSuchMethod(instance, |
| 3055 getter_name, | 3105 getter_name, |
| 3056 args, | 3106 args, |
| 3057 args_descriptor)); | 3107 args_descriptor)); |
| 3058 } | 3108 } |
| 3059 return Api::NewHandle(isolate, DartEntry::InvokeFunction(getter, args)); | 3109 return Api::NewHandle(isolate, DartEntry::InvokeFunction(getter, args)); |
| 3060 | 3110 |
| 3061 } else if (obj.IsClass()) { | |
| 3062 // To access a static field we may need to use the Field or the | |
| 3063 // getter Function. | |
| 3064 const Class& cls = Class::Cast(obj); | |
| 3065 field = cls.LookupStaticField(field_name); | |
| 3066 if (field.IsNull() || FieldIsUninitialized(isolate, field)) { | |
| 3067 const String& getter_name = | |
| 3068 String::Handle(isolate, Field::GetterName(field_name)); | |
| 3069 getter = cls.LookupStaticFunctionAllowPrivate(getter_name); | |
| 3070 } | |
| 3071 | |
| 3072 if (!getter.IsNull()) { | |
| 3073 // Invoke the getter and return the result. | |
| 3074 return Api::NewHandle( | |
| 3075 isolate, DartEntry::InvokeFunction(getter, Object::empty_array())); | |
| 3076 } else if (!field.IsNull()) { | |
| 3077 return Api::NewHandle(isolate, field.value()); | |
| 3078 } else { | |
| 3079 return Api::NewError("%s: did not find static field '%s'.", | |
| 3080 CURRENT_FUNC, field_name.ToCString()); | |
| 3081 } | |
| 3082 | |
| 3083 } else if (obj.IsLibrary()) { | 3111 } else if (obj.IsLibrary()) { |
| 3084 // To access a top-level we may need to use the Field or the | 3112 // To access a top-level we may need to use the Field or the |
| 3085 // getter Function. The getter function may either be in the | 3113 // getter Function. The getter function may either be in the |
| 3086 // library or in the field's owner class, depending. | 3114 // library or in the field's owner class, depending. |
| 3087 const Library& lib = Library::Cast(obj); | 3115 const Library& lib = Library::Cast(obj); |
| 3088 field = lib.LookupFieldAllowPrivate(field_name); | 3116 field = lib.LookupFieldAllowPrivate(field_name); |
| 3089 if (field.IsNull()) { | 3117 if (field.IsNull()) { |
| 3090 // No field found. Check for a getter in the lib. | 3118 // No field found. Check for a getter in the lib. |
| 3091 const String& getter_name = | 3119 const String& getter_name = |
| 3092 String::Handle(isolate, Field::GetterName(field_name)); | 3120 String::Handle(isolate, Field::GetterName(field_name)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3107 return Api::NewHandle(isolate, field.value()); | 3135 return Api::NewHandle(isolate, field.value()); |
| 3108 } else { | 3136 } else { |
| 3109 return Api::NewError("%s: did not find top-level variable '%s'.", | 3137 return Api::NewError("%s: did not find top-level variable '%s'.", |
| 3110 CURRENT_FUNC, field_name.ToCString()); | 3138 CURRENT_FUNC, field_name.ToCString()); |
| 3111 } | 3139 } |
| 3112 | 3140 |
| 3113 } else if (obj.IsError()) { | 3141 } else if (obj.IsError()) { |
| 3114 return container; | 3142 return container; |
| 3115 } else { | 3143 } else { |
| 3116 return Api::NewError( | 3144 return Api::NewError( |
| 3117 "%s expects argument 'container' to be an object, class, or library.", | 3145 "%s expects argument 'container' to be an object, type, or library.", |
| 3118 CURRENT_FUNC); | 3146 CURRENT_FUNC); |
| 3119 } | 3147 } |
| 3120 } | 3148 } |
| 3121 | 3149 |
| 3122 | 3150 |
| 3123 DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container, | 3151 DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container, |
| 3124 Dart_Handle name, | 3152 Dart_Handle name, |
| 3125 Dart_Handle value) { | 3153 Dart_Handle value) { |
| 3126 Isolate* isolate = Isolate::Current(); | 3154 Isolate* isolate = Isolate::Current(); |
| 3127 DARTSCOPE(isolate); | 3155 DARTSCOPE(isolate); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3144 Dart_Handle state = Api::CheckIsolateState(isolate); | 3172 Dart_Handle state = Api::CheckIsolateState(isolate); |
| 3145 if (::Dart_IsError(state)) { | 3173 if (::Dart_IsError(state)) { |
| 3146 return state; | 3174 return state; |
| 3147 } | 3175 } |
| 3148 Field& field = Field::Handle(isolate); | 3176 Field& field = Field::Handle(isolate); |
| 3149 Function& setter = Function::Handle(isolate); | 3177 Function& setter = Function::Handle(isolate); |
| 3150 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(container)); | 3178 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(container)); |
| 3151 if (obj.IsNull()) { | 3179 if (obj.IsNull()) { |
| 3152 return Api::NewError("%s expects argument 'container' to be non-null.", | 3180 return Api::NewError("%s expects argument 'container' to be non-null.", |
| 3153 CURRENT_FUNC); | 3181 CURRENT_FUNC); |
| 3182 } else if (obj.IsType() || obj.IsClass()) { |
| 3183 // To access a static field we may need to use the Field or the |
| 3184 // setter Function. |
| 3185 Class& cls = Class::Handle(); |
| 3186 if (obj.IsType()) { |
| 3187 cls = Type::Cast(obj).type_class(); |
| 3188 } else { |
| 3189 cls = Class::Cast(obj).raw(); |
| 3190 } |
| 3191 field = cls.LookupStaticField(field_name); |
| 3192 if (field.IsNull()) { |
| 3193 String& setter_name = |
| 3194 String::Handle(isolate, Field::SetterName(field_name)); |
| 3195 setter = cls.LookupStaticFunctionAllowPrivate(setter_name); |
| 3196 } |
| 3197 |
| 3198 if (!setter.IsNull()) { |
| 3199 // Invoke the setter and return the result. |
| 3200 const int kNumArgs = 1; |
| 3201 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); |
| 3202 args.SetAt(0, value_instance); |
| 3203 const Object& result = |
| 3204 Object::Handle(isolate, DartEntry::InvokeFunction(setter, args)); |
| 3205 if (result.IsError()) { |
| 3206 return Api::NewHandle(isolate, result.raw()); |
| 3207 } else { |
| 3208 return Api::Success(); |
| 3209 } |
| 3210 } else if (!field.IsNull()) { |
| 3211 if (field.is_final()) { |
| 3212 return Api::NewError("%s: cannot set final field '%s'.", |
| 3213 CURRENT_FUNC, field_name.ToCString()); |
| 3214 } else { |
| 3215 field.set_value(value_instance); |
| 3216 return Api::Success(); |
| 3217 } |
| 3218 } else { |
| 3219 return Api::NewError("%s: did not find static field '%s'.", |
| 3220 CURRENT_FUNC, field_name.ToCString()); |
| 3221 } |
| 3222 |
| 3154 } else if (obj.IsInstance()) { | 3223 } else if (obj.IsInstance()) { |
| 3155 // Every instance field has a setter Function. Try to find the | 3224 // Every instance field has a setter Function. Try to find the |
| 3156 // setter in any superclass and use that function to access the | 3225 // setter in any superclass and use that function to access the |
| 3157 // field. | 3226 // field. |
| 3158 const Instance& instance = Instance::Cast(obj); | 3227 const Instance& instance = Instance::Cast(obj); |
| 3159 Class& cls = Class::Handle(isolate, instance.clazz()); | 3228 Class& cls = Class::Handle(isolate, instance.clazz()); |
| 3160 String& setter_name = | 3229 String& setter_name = |
| 3161 String::Handle(isolate, Field::SetterName(field_name)); | 3230 String::Handle(isolate, Field::SetterName(field_name)); |
| 3162 while (!cls.IsNull()) { | 3231 while (!cls.IsNull()) { |
| 3163 field = cls.LookupInstanceField(field_name); | 3232 field = cls.LookupInstanceField(field_name); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3181 const Array& args_descriptor = | 3250 const Array& args_descriptor = |
| 3182 Array::Handle(ArgumentsDescriptor::New(args.Length())); | 3251 Array::Handle(ArgumentsDescriptor::New(args.Length())); |
| 3183 return Api::NewHandle(isolate, | 3252 return Api::NewHandle(isolate, |
| 3184 DartEntry::InvokeNoSuchMethod(instance, | 3253 DartEntry::InvokeNoSuchMethod(instance, |
| 3185 setter_name, | 3254 setter_name, |
| 3186 args, | 3255 args, |
| 3187 args_descriptor)); | 3256 args_descriptor)); |
| 3188 } | 3257 } |
| 3189 return Api::NewHandle(isolate, DartEntry::InvokeFunction(setter, args)); | 3258 return Api::NewHandle(isolate, DartEntry::InvokeFunction(setter, args)); |
| 3190 | 3259 |
| 3191 } else if (obj.IsClass()) { | |
| 3192 // To access a static field we may need to use the Field or the | |
| 3193 // setter Function. | |
| 3194 const Class& cls = Class::Cast(obj); | |
| 3195 field = cls.LookupStaticField(field_name); | |
| 3196 if (field.IsNull()) { | |
| 3197 String& setter_name = | |
| 3198 String::Handle(isolate, Field::SetterName(field_name)); | |
| 3199 setter = cls.LookupStaticFunctionAllowPrivate(setter_name); | |
| 3200 } | |
| 3201 | |
| 3202 if (!setter.IsNull()) { | |
| 3203 // Invoke the setter and return the result. | |
| 3204 const int kNumArgs = 1; | |
| 3205 const Array& args = Array::Handle(isolate, Array::New(kNumArgs)); | |
| 3206 args.SetAt(0, value_instance); | |
| 3207 const Object& result = | |
| 3208 Object::Handle(isolate, DartEntry::InvokeFunction(setter, args)); | |
| 3209 if (result.IsError()) { | |
| 3210 return Api::NewHandle(isolate, result.raw()); | |
| 3211 } else { | |
| 3212 return Api::Success(); | |
| 3213 } | |
| 3214 } else if (!field.IsNull()) { | |
| 3215 if (field.is_final()) { | |
| 3216 return Api::NewError("%s: cannot set final field '%s'.", | |
| 3217 CURRENT_FUNC, field_name.ToCString()); | |
| 3218 } else { | |
| 3219 field.set_value(value_instance); | |
| 3220 return Api::Success(); | |
| 3221 } | |
| 3222 } else { | |
| 3223 return Api::NewError("%s: did not find static field '%s'.", | |
| 3224 CURRENT_FUNC, field_name.ToCString()); | |
| 3225 } | |
| 3226 | |
| 3227 } else if (obj.IsLibrary()) { | 3260 } else if (obj.IsLibrary()) { |
| 3228 // To access a top-level we may need to use the Field or the | 3261 // To access a top-level we may need to use the Field or the |
| 3229 // setter Function. The setter function may either be in the | 3262 // setter Function. The setter function may either be in the |
| 3230 // library or in the field's owner class, depending. | 3263 // library or in the field's owner class, depending. |
| 3231 const Library& lib = Library::Cast(obj); | 3264 const Library& lib = Library::Cast(obj); |
| 3232 field = lib.LookupFieldAllowPrivate(field_name); | 3265 field = lib.LookupFieldAllowPrivate(field_name); |
| 3233 if (field.IsNull()) { | 3266 if (field.IsNull()) { |
| 3234 const String& setter_name = | 3267 const String& setter_name = |
| 3235 String::Handle(isolate, Field::SetterName(field_name)); | 3268 String::Handle(isolate, Field::SetterName(field_name)); |
| 3236 setter ^= lib.LookupFunctionAllowPrivate(setter_name); | 3269 setter ^= lib.LookupFunctionAllowPrivate(setter_name); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3258 } | 3291 } |
| 3259 } else { | 3292 } else { |
| 3260 return Api::NewError("%s: did not find top-level variable '%s'.", | 3293 return Api::NewError("%s: did not find top-level variable '%s'.", |
| 3261 CURRENT_FUNC, field_name.ToCString()); | 3294 CURRENT_FUNC, field_name.ToCString()); |
| 3262 } | 3295 } |
| 3263 | 3296 |
| 3264 } else if (obj.IsError()) { | 3297 } else if (obj.IsError()) { |
| 3265 return container; | 3298 return container; |
| 3266 } else { | 3299 } else { |
| 3267 return Api::NewError( | 3300 return Api::NewError( |
| 3268 "%s expects argument 'container' to be an object, class, or library.", | 3301 "%s expects argument 'container' to be an object, type, or library.", |
| 3269 CURRENT_FUNC); | 3302 CURRENT_FUNC); |
| 3270 } | 3303 } |
| 3271 } | 3304 } |
| 3272 | 3305 |
| 3273 | 3306 |
| 3274 // --- Exceptions ---- | 3307 // --- Exceptions ---- |
| 3275 | 3308 |
| 3276 DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) { | 3309 DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) { |
| 3277 Isolate* isolate = Isolate::Current(); | 3310 Isolate* isolate = Isolate::Current(); |
| 3278 CHECK_ISOLATE(isolate); | 3311 CHECK_ISOLATE(isolate); |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3923 } | 3956 } |
| 3924 { | 3957 { |
| 3925 NoGCScope no_gc; | 3958 NoGCScope no_gc; |
| 3926 RawObject* raw_obj = obj.raw(); | 3959 RawObject* raw_obj = obj.raw(); |
| 3927 isolate->heap()->SetPeer(raw_obj, peer); | 3960 isolate->heap()->SetPeer(raw_obj, peer); |
| 3928 } | 3961 } |
| 3929 return Api::Success(); | 3962 return Api::Success(); |
| 3930 } | 3963 } |
| 3931 | 3964 |
| 3932 } // namespace dart | 3965 } // namespace dart |
| OLD | NEW |