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

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

Issue 25675009: Allow invocation of constructors using Dart_Invoke. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 2 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 | « no previous file | 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 2956 matching lines...) Expand 10 before | Expand all | Expand 10 after
2967 if (type_obj.IsNull()) { 2967 if (type_obj.IsNull()) {
2968 RETURN_TYPE_ERROR(isolate, type, Type); 2968 RETURN_TYPE_ERROR(isolate, type, Type);
2969 } 2969 }
2970 const Class& cls = Class::Handle(isolate, type_obj.type_class()); 2970 const Class& cls = Class::Handle(isolate, type_obj.type_class());
2971 2971
2972 // Allocate an object for the given class. 2972 // Allocate an object for the given class.
2973 return Api::NewHandle(isolate, Instance::New(cls)); 2973 return Api::NewHandle(isolate, Instance::New(cls));
2974 } 2974 }
2975 2975
2976 2976
2977 static Dart_Handle SetupArguments(Isolate* isolate,
2978 int num_args,
2979 Dart_Handle* arguments,
2980 int extra_args,
2981 Array* args) {
2982 // Check for malformed arguments in the arguments list.
2983 *args = Array::New(num_args + extra_args);
2984 Object& arg = Object::Handle(isolate);
2985 for (int i = 0; i < num_args; i++) {
2986 arg = Api::UnwrapHandle(arguments[i]);
2987 if (!arg.IsNull() && !arg.IsInstance()) {
2988 *args = Array::null();
2989 if (arg.IsError()) {
2990 return Api::NewHandle(isolate, arg.raw());
2991 } else {
2992 return Api::NewError(
2993 "%s expects arguments[%d] to be an Instance handle.",
2994 "Dart_Invoke", i);
2995 }
2996 }
2997 args->SetAt((i + extra_args), arg);
2998 }
2999 return Api::Success();
3000 }
3001
3002
2977 DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, 3003 DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target,
2978 Dart_Handle name, 3004 Dart_Handle name,
2979 int number_of_arguments, 3005 int number_of_arguments,
2980 Dart_Handle* arguments) { 3006 Dart_Handle* arguments) {
2981 Isolate* isolate = Isolate::Current(); 3007 Isolate* isolate = Isolate::Current();
2982 DARTSCOPE(isolate); 3008 DARTSCOPE(isolate);
2983 CHECK_CALLBACK_STATE(isolate); 3009 CHECK_CALLBACK_STATE(isolate);
2984 3010
2985 const String& function_name = Api::UnwrapStringHandle(isolate, name); 3011 const String& function_name = Api::UnwrapStringHandle(isolate, name);
2986 if (function_name.IsNull()) { 3012 if (function_name.IsNull()) {
2987 RETURN_TYPE_ERROR(isolate, name, String); 3013 RETURN_TYPE_ERROR(isolate, name, String);
2988 } 3014 }
2989 if (number_of_arguments < 0) { 3015 if (number_of_arguments < 0) {
2990 return Api::NewError( 3016 return Api::NewError(
2991 "%s expects argument 'number_of_arguments' to be non-negative.", 3017 "%s expects argument 'number_of_arguments' to be non-negative.",
2992 CURRENT_FUNC); 3018 CURRENT_FUNC);
2993 } 3019 }
2994 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); 3020 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target));
2995 if (obj.IsError()) { 3021 if (obj.IsError()) {
2996 return target; 3022 return target;
2997 } 3023 }
3024 Dart_Handle result;
2998 3025
2999 // Check for malformed arguments in the arguments list. 3026 // Check for malformed arguments in the arguments list.
3000 intptr_t num_receiver = 3027 Array& args = Array::Handle(isolate);
3001 (obj.IsNull() || (obj.IsInstance() && !obj.IsType())) ? 1 : 0;
3002 const Array& args =
3003 Array::Handle(isolate, Array::New(number_of_arguments + num_receiver));
3004 Object& arg = Object::Handle(isolate);
3005 for (int i = 0; i < number_of_arguments; i++) {
3006 arg = Api::UnwrapHandle(arguments[i]);
3007 if (!arg.IsNull() && !arg.IsInstance()) {
3008 if (arg.IsError()) {
3009 return Api::NewHandle(isolate, arg.raw());
3010 } else {
3011 return Api::NewError(
3012 "%s expects arguments[%d] to be an Instance handle.",
3013 CURRENT_FUNC, i);
3014 }
3015 }
3016 args.SetAt((i + num_receiver), arg);
3017 }
3018
3019 if (obj.IsType()) { 3028 if (obj.IsType()) {
3020 // Finalize all classes. 3029 // Finalize all classes.
3021 Dart_Handle state = Api::CheckIsolateState(isolate); 3030 Dart_Handle state = Api::CheckIsolateState(isolate);
3022 if (::Dart_IsError(state)) { 3031 if (::Dart_IsError(state)) {
3023 return state; 3032 return state;
3024 } 3033 }
3025 3034
3026 const Class& cls = Class::Handle(isolate, Type::Cast(obj).type_class()); 3035 const Class& cls = Class::Handle(isolate, Type::Cast(obj).type_class());
regis 2013/10/04 00:03:09 So, target is a type and we use its type class to
siva 2013/10/04 18:32:57 We don't expect to call constructors using this me
3027 const Function& function = Function::Handle( 3036 const Function& function = Function::Handle(
3028 isolate, 3037 isolate,
3029 Resolver::ResolveStatic(cls, 3038 Resolver::ResolveStatic(cls,
3030 function_name, 3039 function_name,
3031 number_of_arguments, 3040 number_of_arguments,
3032 Object::empty_array(), 3041 Object::empty_array(),
3033 Resolver::kIsQualified)); 3042 Resolver::kIsQualified));
3034 if (function.IsNull()) { 3043 if (function.IsNull()) {
3035 const String& cls_name = String::Handle(isolate, cls.Name()); 3044 const String& cls_name = String::Handle(isolate, cls.Name());
3036 return Api::NewError("%s: did not find static method '%s.%s'.", 3045 return Api::NewError("%s: did not find static method '%s.%s'.",
3037 CURRENT_FUNC, 3046 CURRENT_FUNC,
3038 cls_name.ToCString(), 3047 cls_name.ToCString(),
3039 function_name.ToCString()); 3048 function_name.ToCString());
3040 } 3049 }
3041 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); 3050 result = SetupArguments(isolate, number_of_arguments, arguments, 0, &args);
3042 3051 if (!::Dart_IsError(result)) {
3052 result = Api::NewHandle(isolate,
3053 DartEntry::InvokeFunction(function, args));
3054 }
3055 return result;
3043 } else if (obj.IsNull() || obj.IsInstance()) { 3056 } else if (obj.IsNull() || obj.IsInstance()) {
3057 // Since we have allocated an object it would mean that all classes
3058 // are finalized and hence it is not necessary to call
3059 // Api::CheckIsolateState.
3044 Instance& instance = Instance::Handle(isolate); 3060 Instance& instance = Instance::Handle(isolate);
3045 instance ^= obj.raw(); 3061 instance ^= obj.raw();
3046 ArgumentsDescriptor args_desc( 3062 ArgumentsDescriptor args_desc(
3047 Array::Handle(ArgumentsDescriptor::New(number_of_arguments + 1))); 3063 Array::Handle(ArgumentsDescriptor::New(number_of_arguments + 1)));
3048 const Function& function = Function::Handle( 3064 const Function& function = Function::Handle(
3049 isolate, 3065 isolate,
3050 Resolver::ResolveDynamic(instance, function_name, args_desc)); 3066 Resolver::ResolveDynamic(instance, function_name, args_desc));
3051 args.SetAt(0, instance);
3052 if (function.IsNull()) { 3067 if (function.IsNull()) {
3053 const Array& args_descriptor = 3068 // See if we are trying to invoke a constructor here.
regis 2013/10/04 00:03:09 Wouldn't target be a type to call a constructor? O
siva 2013/10/04 18:32:57 Target is an already allocated instance. On 2013/
3054 Array::Handle(ArgumentsDescriptor::New(args.Length())); 3069 if (!instance.IsNull()) {
3055 return Api::NewHandle(isolate, 3070 // Constuct name of the constructor to invoke.
regis 2013/10/04 00:03:09 construct
siva 2013/10/04 18:32:57 Done.
3056 DartEntry::InvokeNoSuchMethod(instance, 3071 const Type& type_obj = Type::Handle(isolate, instance.GetType());
3057 function_name, 3072 const Class& cls = Class::Handle(isolate, type_obj.type_class());
3058 args, 3073 const String& class_name = String::Handle(isolate, cls.Name());
3059 args_descriptor)); 3074 const Array& strings = Array::Handle(Array::New(3));
3075 strings.SetAt(0, class_name);
3076 strings.SetAt(1, Symbols::Dot());
3077 strings.SetAt(2, function_name);
3078 const String& dot_name = String::Handle(isolate,
3079 String::ConcatAll(strings));
3080 const AbstractTypeArguments& type_arguments =
3081 AbstractTypeArguments::Handle(isolate, type_obj.arguments());
3082 const Function& constructor =
3083 Function::Handle(isolate, cls.LookupFunctionAllowPrivate(dot_name));
3084 const int extra_args = 2;
3085 if (!constructor.IsNull() &&
3086 constructor.IsConstructor() &&
3087 constructor.AreValidArgumentCounts(number_of_arguments + extra_args,
3088 0,
3089 NULL)) {
3090 // Create the argument list.
3091 // Constructors get the uninitialized object and a constructor phase.
3092 if (!type_arguments.IsNull()) {
3093 // The type arguments will be null if the class has no type
3094 // parameters, in which case the following call would fail
3095 // because there is no slot reserved in the object for the
3096 // type vector.
3097 instance.SetTypeArguments(type_arguments);
3098 }
3099 result = SetupArguments(isolate,
3100 number_of_arguments,
3101 arguments,
3102 extra_args,
3103 &args);
3104 if (!::Dart_IsError(result)) {
3105 args.SetAt(0, instance);
3106 args.SetAt(1, Smi::Handle(isolate,
3107 Smi::New(Function::kCtorPhaseAll)));
3108 result = Api::NewHandle(
3109 isolate, DartEntry::InvokeFunction(constructor, args));
3110 }
3111 return result;
3112 }
3113 }
3114 result = SetupArguments(isolate,
3115 number_of_arguments,
3116 arguments,
3117 1,
3118 &args);
3119 if (!::Dart_IsError(result)) {
3120 args.SetAt(0, instance);
3121 const Array& args_descriptor =
3122 Array::Handle(ArgumentsDescriptor::New(args.Length()));
3123 result = Api::NewHandle(isolate,
3124 DartEntry::InvokeNoSuchMethod(instance,
3125 function_name,
3126 args,
3127 args_descriptor));
3128 }
3129 return result;
3060 } 3130 }
3061 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); 3131 result = SetupArguments(isolate, number_of_arguments, arguments, 1, &args);
3062 3132 if (!::Dart_IsError(result)) {
3133 args.SetAt(0, instance);
3134 result = Api::NewHandle(isolate,
3135 DartEntry::InvokeFunction(function, args));
3136 }
3137 return result;
3063 } else if (obj.IsLibrary()) { 3138 } else if (obj.IsLibrary()) {
3064 // Check whether class finalization is needed. 3139 // Check whether class finalization is needed.
3065 const Library& lib = Library::Cast(obj); 3140 const Library& lib = Library::Cast(obj);
3066 3141
3067 // Finalize all classes if needed. 3142 // Finalize all classes if needed.
3068 Dart_Handle state = Api::CheckIsolateState(isolate); 3143 Dart_Handle state = Api::CheckIsolateState(isolate);
3069 if (::Dart_IsError(state)) { 3144 if (::Dart_IsError(state)) {
3070 return state; 3145 return state;
3071 } 3146 }
3072 3147
3073 const Function& function = 3148 const Function& function =
3074 Function::Handle(isolate, 3149 Function::Handle(isolate,
3075 lib.LookupFunctionAllowPrivate(function_name)); 3150 lib.LookupFunctionAllowPrivate(function_name));
3076 if (function.IsNull()) { 3151 if (function.IsNull()) {
3077 return Api::NewError("%s: did not find top-level function '%s'.", 3152 return Api::NewError("%s: did not find top-level function '%s'.",
3078 CURRENT_FUNC, 3153 CURRENT_FUNC,
3079 function_name.ToCString()); 3154 function_name.ToCString());
3080 } 3155 }
3081 // LookupFunctionAllowPrivate does not check argument arity, so we 3156 // LookupFunctionAllowPrivate does not check argument arity, so we
3082 // do it here. 3157 // do it here.
3083 String& error_message = String::Handle(); 3158 String& error_message = String::Handle();
3084 if (!function.AreValidArgumentCounts(number_of_arguments, 3159 if (!function.AreValidArgumentCounts(number_of_arguments,
3085 0, 3160 0,
3086 &error_message)) { 3161 &error_message)) {
3087 return Api::NewError("%s: wrong argument count for function '%s': %s.", 3162 return Api::NewError("%s: wrong argument count for function '%s': %s.",
3088 CURRENT_FUNC, 3163 CURRENT_FUNC,
3089 function_name.ToCString(), 3164 function_name.ToCString(),
3090 error_message.ToCString()); 3165 error_message.ToCString());
3091 } 3166 }
3092 return Api::NewHandle(isolate, DartEntry::InvokeFunction(function, args)); 3167 result = SetupArguments(isolate, number_of_arguments, arguments, 0, &args);
3093 3168 if (!::Dart_IsError(result)) {
3169 result = Api::NewHandle(isolate,
3170 DartEntry::InvokeFunction(function, args));
3171 }
3172 return result;
3094 } else { 3173 } else {
3095 return Api::NewError( 3174 return Api::NewError(
3096 "%s expects argument 'target' to be an object, type, or library.", 3175 "%s expects argument 'target' to be an object, type, or library.",
3097 CURRENT_FUNC); 3176 CURRENT_FUNC);
3098 } 3177 }
3099 } 3178 }
3100 3179
3101 3180
3102 DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure, 3181 DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure,
3103 int number_of_arguments, 3182 int number_of_arguments,
(...skipping 1197 matching lines...) Expand 10 before | Expand all | Expand 10 after
4301 } 4380 }
4302 { 4381 {
4303 NoGCScope no_gc; 4382 NoGCScope no_gc;
4304 RawObject* raw_obj = obj.raw(); 4383 RawObject* raw_obj = obj.raw();
4305 isolate->heap()->SetPeer(raw_obj, peer); 4384 isolate->heap()->SetPeer(raw_obj, peer);
4306 } 4385 }
4307 return Api::Success(); 4386 return Api::Success();
4308 } 4387 }
4309 4388
4310 } // namespace dart 4389 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/dart_api_impl_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698