Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: runtime/vm/dart_api_impl.cc

Issue 17390008: Fix for issue 11262. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/include/dart_api.h ('k') | runtime/vm/dart_api_impl_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 // For backwards compatibility we allow class objects to be passed in
2895 // for now. This needs to be removed once all code that uses class
2896 // objects to invoke Dart_Invoke is removed.
2897 Class& cls = Class::Handle();
2898 if (obj.IsType()) {
2899 cls = Type::Cast(obj).type_class();
2900 } else {
2901 cls = Class::Cast(obj).raw();
2902 }
2898 const Function& function = Function::Handle( 2903 const Function& function = Function::Handle(
2899 isolate, 2904 isolate,
2900 Resolver::ResolveStatic(cls, 2905 Resolver::ResolveStatic(cls,
2901 function_name, 2906 function_name,
2902 number_of_arguments, 2907 number_of_arguments,
2903 Object::empty_array(), 2908 Object::empty_array(),
2904 Resolver::kIsQualified)); 2909 Resolver::kIsQualified));
2905 if (function.IsNull()) { 2910 if (function.IsNull()) {
2906 const String& cls_name = String::Handle(isolate, cls.Name()); 2911 const String& cls_name = String::Handle(isolate, cls.Name());
2907 return Api::NewError("%s: did not find static method '%s.%s'.", 2912 return Api::NewError("%s: did not find static method '%s.%s'.",
2908 CURRENT_FUNC, 2913 CURRENT_FUNC,
2909 cls_name.ToCString(), 2914 cls_name.ToCString(),
2910 function_name.ToCString()); 2915 function_name.ToCString());
2911 } 2916 }
2912 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); 2917 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args));
2913 2918
2919 } else if (obj.IsNull() || obj.IsInstance()) {
2920 Instance& instance = Instance::Handle(isolate);
2921 instance ^= obj.raw();
2922 const Function& function = Function::Handle(
2923 isolate,
2924 Resolver::ResolveDynamic(instance,
2925 function_name,
2926 (number_of_arguments + 1),
2927 Resolver::kIsQualified));
2928 args.SetAt(0, instance);
2929 if (function.IsNull()) {
2930 const Array& args_descriptor =
2931 Array::Handle(ArgumentsDescriptor::New(args.Length()));
2932 return Api::NewHandle(isolate,
2933 DartEntry::InvokeNoSuchMethod(instance,
2934 function_name,
2935 args,
2936 args_descriptor));
2937 }
2938 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args));
2939
2914 } else if (obj.IsLibrary()) { 2940 } else if (obj.IsLibrary()) {
2915 // Check whether class finalization is needed. 2941 // Check whether class finalization is needed.
2916 bool finalize_classes = true; 2942 bool finalize_classes = true;
2917 const Library& lib = Library::Cast(obj); 2943 const Library& lib = Library::Cast(obj);
2918 2944
2919 // When calling functions in the dart:builtin library do not finalize as it 2945 // When calling functions in the dart:builtin library do not finalize as it
2920 // should have been prefinalized. 2946 // should have been prefinalized.
2921 Library& builtin = 2947 Library& builtin =
2922 Library::Handle(isolate, isolate->object_store()->builtin_library()); 2948 Library::Handle(isolate, isolate->object_store()->builtin_library());
2923 if (builtin.raw() == lib.raw()) { 2949 if (builtin.raw() == lib.raw()) {
(...skipping 23 matching lines...) Expand all
2947 &error_message)) { 2973 &error_message)) {
2948 return Api::NewError("%s: wrong argument count for function '%s': %s.", 2974 return Api::NewError("%s: wrong argument count for function '%s': %s.",
2949 CURRENT_FUNC, 2975 CURRENT_FUNC,
2950 function_name.ToCString(), 2976 function_name.ToCString(),
2951 error_message.ToCString()); 2977 error_message.ToCString());
2952 } 2978 }
2953 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); 2979 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args));
2954 2980
2955 } else { 2981 } else {
2956 return Api::NewError( 2982 return Api::NewError(
2957 "%s expects argument 'target' to be an object, class, or library.", 2983 "%s expects argument 'target' to be an object, type, or library.",
2958 CURRENT_FUNC); 2984 CURRENT_FUNC);
2959 } 2985 }
2960 } 2986 }
2961 2987
2962 2988
2963 DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure, 2989 DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure,
2964 int number_of_arguments, 2990 int number_of_arguments,
2965 Dart_Handle* arguments) { 2991 Dart_Handle* arguments) {
2966 Isolate* isolate = Isolate::Current(); 2992 Isolate* isolate = Isolate::Current();
2967 DARTSCOPE(isolate); 2993 DARTSCOPE(isolate);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3020 Dart_Handle state = Api::CheckIsolateState(isolate); 3046 Dart_Handle state = Api::CheckIsolateState(isolate);
3021 if (::Dart_IsError(state)) { 3047 if (::Dart_IsError(state)) {
3022 return state; 3048 return state;
3023 } 3049 }
3024 Field& field = Field::Handle(isolate); 3050 Field& field = Field::Handle(isolate);
3025 Function& getter = Function::Handle(isolate); 3051 Function& getter = Function::Handle(isolate);
3026 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(container)); 3052 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(container));
3027 if (obj.IsNull()) { 3053 if (obj.IsNull()) {
3028 return Api::NewError("%s expects argument 'container' to be non-null.", 3054 return Api::NewError("%s expects argument 'container' to be non-null.",
3029 CURRENT_FUNC); 3055 CURRENT_FUNC);
3056 } else if (obj.IsType() || obj.IsClass()) {
3057 // To access a static field we may need to use the Field or the
3058 // getter Function.
3059 // For backwards compatibility we allow class objects to be passed in
3060 // for now. This needs to be removed once all code that uses class
3061 // objects to invoke Dart_GetField is removed.
3062 Class& cls = Class::Handle();
3063 if (obj.IsType()) {
3064 cls = Type::Cast(obj).type_class();
3065 } else {
3066 cls = Class::Cast(obj).raw();
3067 }
3068 field = cls.LookupStaticField(field_name);
3069 if (field.IsNull() || FieldIsUninitialized(isolate, field)) {
3070 const String& getter_name =
3071 String::Handle(isolate, Field::GetterName(field_name));
3072 getter = cls.LookupStaticFunctionAllowPrivate(getter_name);
3073 }
3074
3075 if (!getter.IsNull()) {
3076 // Invoke the getter and return the result.
3077 return Api::NewHandle(
3078 isolate, DartEntry::InvokeFunction(getter, Object::empty_array()));
3079 } else if (!field.IsNull()) {
3080 return Api::NewHandle(isolate, field.value());
3081 } else {
3082 return Api::NewError("%s: did not find static field '%s'.",
3083 CURRENT_FUNC, field_name.ToCString());
3084 }
3085
3030 } else if (obj.IsInstance()) { 3086 } else if (obj.IsInstance()) {
3031 // Every instance field has a getter Function. Try to find the 3087 // Every instance field has a getter Function. Try to find the
3032 // getter in any superclass and use that function to access the 3088 // getter in any superclass and use that function to access the
3033 // field. 3089 // field.
3034 const Instance& instance = Instance::Cast(obj); 3090 const Instance& instance = Instance::Cast(obj);
3035 Class& cls = Class::Handle(isolate, instance.clazz()); 3091 Class& cls = Class::Handle(isolate, instance.clazz());
3036 String& getter_name = 3092 String& getter_name =
3037 String::Handle(isolate, Field::GetterName(field_name)); 3093 String::Handle(isolate, Field::GetterName(field_name));
3038 while (!cls.IsNull()) { 3094 while (!cls.IsNull()) {
3039 getter = cls.LookupDynamicFunctionAllowPrivate(getter_name); 3095 getter = cls.LookupDynamicFunctionAllowPrivate(getter_name);
(...skipping 11 matching lines...) Expand all
3051 const Array& args_descriptor = 3107 const Array& args_descriptor =
3052 Array::Handle(ArgumentsDescriptor::New(args.Length())); 3108 Array::Handle(ArgumentsDescriptor::New(args.Length()));
3053 return Api::NewHandle(isolate, 3109 return Api::NewHandle(isolate,
3054 DartEntry::InvokeNoSuchMethod(instance, 3110 DartEntry::InvokeNoSuchMethod(instance,
3055 getter_name, 3111 getter_name,
3056 args, 3112 args,
3057 args_descriptor)); 3113 args_descriptor));
3058 } 3114 }
3059 return Api::NewHandle(isolate, DartEntry::InvokeFunction(getter, args)); 3115 return Api::NewHandle(isolate, DartEntry::InvokeFunction(getter, args));
3060 3116
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()) { 3117 } else if (obj.IsLibrary()) {
3084 // To access a top-level we may need to use the Field or the 3118 // 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 3119 // getter Function. The getter function may either be in the
3086 // library or in the field's owner class, depending. 3120 // library or in the field's owner class, depending.
3087 const Library& lib = Library::Cast(obj); 3121 const Library& lib = Library::Cast(obj);
3088 field = lib.LookupFieldAllowPrivate(field_name); 3122 field = lib.LookupFieldAllowPrivate(field_name);
3089 if (field.IsNull()) { 3123 if (field.IsNull()) {
3090 // No field found. Check for a getter in the lib. 3124 // No field found. Check for a getter in the lib.
3091 const String& getter_name = 3125 const String& getter_name =
3092 String::Handle(isolate, Field::GetterName(field_name)); 3126 String::Handle(isolate, Field::GetterName(field_name));
(...skipping 14 matching lines...) Expand all
3107 return Api::NewHandle(isolate, field.value()); 3141 return Api::NewHandle(isolate, field.value());
3108 } else { 3142 } else {
3109 return Api::NewError("%s: did not find top-level variable '%s'.", 3143 return Api::NewError("%s: did not find top-level variable '%s'.",
3110 CURRENT_FUNC, field_name.ToCString()); 3144 CURRENT_FUNC, field_name.ToCString());
3111 } 3145 }
3112 3146
3113 } else if (obj.IsError()) { 3147 } else if (obj.IsError()) {
3114 return container; 3148 return container;
3115 } else { 3149 } else {
3116 return Api::NewError( 3150 return Api::NewError(
3117 "%s expects argument 'container' to be an object, class, or library.", 3151 "%s expects argument 'container' to be an object, type, or library.",
3118 CURRENT_FUNC); 3152 CURRENT_FUNC);
3119 } 3153 }
3120 } 3154 }
3121 3155
3122 3156
3123 DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container, 3157 DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container,
3124 Dart_Handle name, 3158 Dart_Handle name,
3125 Dart_Handle value) { 3159 Dart_Handle value) {
3126 Isolate* isolate = Isolate::Current(); 3160 Isolate* isolate = Isolate::Current();
3127 DARTSCOPE(isolate); 3161 DARTSCOPE(isolate);
(...skipping 16 matching lines...) Expand all
3144 Dart_Handle state = Api::CheckIsolateState(isolate); 3178 Dart_Handle state = Api::CheckIsolateState(isolate);
3145 if (::Dart_IsError(state)) { 3179 if (::Dart_IsError(state)) {
3146 return state; 3180 return state;
3147 } 3181 }
3148 Field& field = Field::Handle(isolate); 3182 Field& field = Field::Handle(isolate);
3149 Function& setter = Function::Handle(isolate); 3183 Function& setter = Function::Handle(isolate);
3150 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(container)); 3184 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(container));
3151 if (obj.IsNull()) { 3185 if (obj.IsNull()) {
3152 return Api::NewError("%s expects argument 'container' to be non-null.", 3186 return Api::NewError("%s expects argument 'container' to be non-null.",
3153 CURRENT_FUNC); 3187 CURRENT_FUNC);
3188 } else if (obj.IsType() || obj.IsClass()) {
3189 // To access a static field we may need to use the Field or the
3190 // setter Function.
3191 // For backwards compatibility we allow class objects to be passed in
3192 // for now. This needs to be removed once all code that uses class
3193 // objects to invoke Dart_SetField is removed.
3194 Class& cls = Class::Handle();
3195 if (obj.IsType()) {
3196 cls = Type::Cast(obj).type_class();
3197 } else {
3198 cls = Class::Cast(obj).raw();
3199 }
3200 field = cls.LookupStaticField(field_name);
3201 if (field.IsNull()) {
3202 String& setter_name =
3203 String::Handle(isolate, Field::SetterName(field_name));
3204 setter = cls.LookupStaticFunctionAllowPrivate(setter_name);
3205 }
3206
3207 if (!setter.IsNull()) {
3208 // Invoke the setter and return the result.
3209 const int kNumArgs = 1;
3210 const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
3211 args.SetAt(0, value_instance);
3212 const Object& result =
3213 Object::Handle(isolate, DartEntry::InvokeFunction(setter, args));
3214 if (result.IsError()) {
3215 return Api::NewHandle(isolate, result.raw());
3216 } else {
3217 return Api::Success();
3218 }
3219 } else if (!field.IsNull()) {
3220 if (field.is_final()) {
3221 return Api::NewError("%s: cannot set final field '%s'.",
3222 CURRENT_FUNC, field_name.ToCString());
3223 } else {
3224 field.set_value(value_instance);
3225 return Api::Success();
3226 }
3227 } else {
3228 return Api::NewError("%s: did not find static field '%s'.",
3229 CURRENT_FUNC, field_name.ToCString());
3230 }
3231
3154 } else if (obj.IsInstance()) { 3232 } else if (obj.IsInstance()) {
3155 // Every instance field has a setter Function. Try to find the 3233 // Every instance field has a setter Function. Try to find the
3156 // setter in any superclass and use that function to access the 3234 // setter in any superclass and use that function to access the
3157 // field. 3235 // field.
3158 const Instance& instance = Instance::Cast(obj); 3236 const Instance& instance = Instance::Cast(obj);
3159 Class& cls = Class::Handle(isolate, instance.clazz()); 3237 Class& cls = Class::Handle(isolate, instance.clazz());
3160 String& setter_name = 3238 String& setter_name =
3161 String::Handle(isolate, Field::SetterName(field_name)); 3239 String::Handle(isolate, Field::SetterName(field_name));
3162 while (!cls.IsNull()) { 3240 while (!cls.IsNull()) {
3163 field = cls.LookupInstanceField(field_name); 3241 field = cls.LookupInstanceField(field_name);
(...skipping 17 matching lines...) Expand all
3181 const Array& args_descriptor = 3259 const Array& args_descriptor =
3182 Array::Handle(ArgumentsDescriptor::New(args.Length())); 3260 Array::Handle(ArgumentsDescriptor::New(args.Length()));
3183 return Api::NewHandle(isolate, 3261 return Api::NewHandle(isolate,
3184 DartEntry::InvokeNoSuchMethod(instance, 3262 DartEntry::InvokeNoSuchMethod(instance,
3185 setter_name, 3263 setter_name,
3186 args, 3264 args,
3187 args_descriptor)); 3265 args_descriptor));
3188 } 3266 }
3189 return Api::NewHandle(isolate, DartEntry::InvokeFunction(setter, args)); 3267 return Api::NewHandle(isolate, DartEntry::InvokeFunction(setter, args));
3190 3268
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()) { 3269 } else if (obj.IsLibrary()) {
3228 // To access a top-level we may need to use the Field or the 3270 // 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 3271 // setter Function. The setter function may either be in the
3230 // library or in the field's owner class, depending. 3272 // library or in the field's owner class, depending.
3231 const Library& lib = Library::Cast(obj); 3273 const Library& lib = Library::Cast(obj);
3232 field = lib.LookupFieldAllowPrivate(field_name); 3274 field = lib.LookupFieldAllowPrivate(field_name);
3233 if (field.IsNull()) { 3275 if (field.IsNull()) {
3234 const String& setter_name = 3276 const String& setter_name =
3235 String::Handle(isolate, Field::SetterName(field_name)); 3277 String::Handle(isolate, Field::SetterName(field_name));
3236 setter ^= lib.LookupFunctionAllowPrivate(setter_name); 3278 setter ^= lib.LookupFunctionAllowPrivate(setter_name);
(...skipping 21 matching lines...) Expand all
3258 } 3300 }
3259 } else { 3301 } else {
3260 return Api::NewError("%s: did not find top-level variable '%s'.", 3302 return Api::NewError("%s: did not find top-level variable '%s'.",
3261 CURRENT_FUNC, field_name.ToCString()); 3303 CURRENT_FUNC, field_name.ToCString());
3262 } 3304 }
3263 3305
3264 } else if (obj.IsError()) { 3306 } else if (obj.IsError()) {
3265 return container; 3307 return container;
3266 } else { 3308 } else {
3267 return Api::NewError( 3309 return Api::NewError(
3268 "%s expects argument 'container' to be an object, class, or library.", 3310 "%s expects argument 'container' to be an object, type, or library.",
3269 CURRENT_FUNC); 3311 CURRENT_FUNC);
3270 } 3312 }
3271 } 3313 }
3272 3314
3273 3315
3274 // --- Exceptions ---- 3316 // --- Exceptions ----
3275 3317
3276 DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) { 3318 DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) {
3277 Isolate* isolate = Isolate::Current(); 3319 Isolate* isolate = Isolate::Current();
3278 CHECK_ISOLATE(isolate); 3320 CHECK_ISOLATE(isolate);
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
3923 } 3965 }
3924 { 3966 {
3925 NoGCScope no_gc; 3967 NoGCScope no_gc;
3926 RawObject* raw_obj = obj.raw(); 3968 RawObject* raw_obj = obj.raw();
3927 isolate->heap()->SetPeer(raw_obj, peer); 3969 isolate->heap()->SetPeer(raw_obj, peer);
3928 } 3970 }
3929 return Api::Success(); 3971 return Api::Success();
3930 } 3972 }
3931 3973
3932 } // namespace dart 3974 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/include/dart_api.h ('k') | runtime/vm/dart_api_impl_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698