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

Side by Side Diff: vm/dart_api_impl.cc

Issue 9616044: Adds new apis Dart_GetField/Dart_SetField. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 8 years, 9 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
OLDNEW
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 "include/dart_api.h" 5 #include "include/dart_api.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart.h" 10 #include "vm/dart.h"
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 // TODO(turnidge): Check that the port is native before trying to close. 785 // TODO(turnidge): Check that the port is native before trying to close.
786 return PortMap::ClosePort(native_port_id); 786 return PortMap::ClosePort(native_port_id);
787 } 787 }
788 788
789 789
790 DART_EXPORT Dart_Handle Dart_NewSendPort(Dart_Port port_id) { 790 DART_EXPORT Dart_Handle Dart_NewSendPort(Dart_Port port_id) {
791 Isolate* isolate = Isolate::Current(); 791 Isolate* isolate = Isolate::Current();
792 DARTSCOPE(isolate); 792 DARTSCOPE(isolate);
793 Library& isolate_lib = Library::Handle(Library::IsolateLibrary()); 793 Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
794 ASSERT(!isolate_lib.IsNull()); 794 ASSERT(!isolate_lib.IsNull());
795 const String& public_class_name =
796 String::Handle(String::New("_SendPortImpl"));
795 const String& class_name = 797 const String& class_name =
796 String::Handle(isolate_lib.PrivateName("_SendPortImpl")); 798 String::Handle(isolate_lib.PrivateName(public_class_name));
797 const String& function_name = String::Handle(String::NewSymbol("_create")); 799 const String& function_name = String::Handle(String::NewSymbol("_create"));
798 const int kNumArguments = 1; 800 const int kNumArguments = 1;
799 const Array& kNoArgumentNames = Array::Handle(); 801 const Array& kNoArgumentNames = Array::Handle();
800 // TODO(turnidge): Consider adding a helper function to make 802 // TODO(turnidge): Consider adding a helper function to make
801 // function resolution by class name and function name more concise. 803 // function resolution by class name and function name more concise.
802 const Function& function = Function::Handle( 804 const Function& function = Function::Handle(
803 Resolver::ResolveStatic(isolate_lib, 805 Resolver::ResolveStatic(isolate_lib,
804 class_name, 806 class_name,
805 function_name, 807 function_name,
806 kNumArguments, 808 kNumArguments,
807 kNoArgumentNames, 809 kNoArgumentNames,
808 Resolver::kIsQualified)); 810 Resolver::kIsQualified));
809 GrowableArray<const Object*> arguments(kNumArguments); 811 GrowableArray<const Object*> arguments(kNumArguments);
810 arguments.Add(&Integer::Handle(Integer::New(port_id))); 812 arguments.Add(&Integer::Handle(Integer::New(port_id)));
811 const Object& result = Object::Handle( 813 const Object& result = Object::Handle(
812 DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)); 814 DartEntry::InvokeStatic(function, arguments, kNoArgumentNames));
813 return Api::NewLocalHandle(result); 815 return Api::NewLocalHandle(result);
814 } 816 }
815 817
816 818
817 DART_EXPORT Dart_Handle Dart_GetReceivePort(Dart_Port port_id) { 819 DART_EXPORT Dart_Handle Dart_GetReceivePort(Dart_Port port_id) {
818 Isolate* isolate = Isolate::Current(); 820 Isolate* isolate = Isolate::Current();
819 DARTSCOPE(isolate); 821 DARTSCOPE(isolate);
820 Library& isolate_lib = Library::Handle(Library::IsolateLibrary()); 822 Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
821 ASSERT(!isolate_lib.IsNull()); 823 ASSERT(!isolate_lib.IsNull());
824 const String& public_class_name =
825 String::Handle(String::New("_ReceivePortImpl"));
822 const String& class_name = 826 const String& class_name =
823 String::Handle(isolate_lib.PrivateName("_ReceivePortImpl")); 827 String::Handle(isolate_lib.PrivateName(public_class_name));
824 const String& function_name = 828 const String& function_name =
825 String::Handle(String::NewSymbol("_get_or_create")); 829 String::Handle(String::NewSymbol("_get_or_create"));
826 const int kNumArguments = 1; 830 const int kNumArguments = 1;
827 const Array& kNoArgumentNames = Array::Handle(); 831 const Array& kNoArgumentNames = Array::Handle();
828 const Function& function = Function::Handle( 832 const Function& function = Function::Handle(
829 Resolver::ResolveStatic(isolate_lib, 833 Resolver::ResolveStatic(isolate_lib,
830 class_name, 834 class_name,
831 function_name, 835 function_name,
832 kNumArguments, 836 kNumArguments,
833 kNoArgumentNames, 837 kNoArgumentNames,
(...skipping 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 DartEntry::InvokeDynamic( 2111 DartEntry::InvokeDynamic(
2108 receiver, function, dart_arguments, kNoArgumentNames)); 2112 receiver, function, dart_arguments, kNoArgumentNames));
2109 return Api::NewLocalHandle(result); 2113 return Api::NewLocalHandle(result);
2110 } 2114 }
2111 2115
2112 2116
2113 static const bool kGetter = true; 2117 static const bool kGetter = true;
2114 static const bool kSetter = false; 2118 static const bool kSetter = false;
2115 2119
2116 2120
2117 static bool UseGetterForStaticField(const Field& fld) { 2121 static bool FieldIsUninitialized(const Field& fld) {
2118 if (fld.IsNull()) { 2122 ASSERT(!fld.IsNull());
2119 return true;
2120 }
2121 2123
2122 // Return getter method for uninitialized fields, rather than the 2124 // Return getter method for uninitialized fields, rather than the
2123 // field object, since the value in the field object will not be 2125 // field object, since the value in the field object will not be
2124 // initialized until the first time the getter is invoked. 2126 // initialized until the first time the getter is invoked.
2125 const Instance& value = Instance::Handle(fld.value()); 2127 const Instance& value = Instance::Handle(fld.value());
2126 ASSERT(value.raw() != Object::transition_sentinel()); 2128 ASSERT(value.raw() != Object::transition_sentinel());
2127 return value.raw() == Object::sentinel(); 2129 return value.raw() == Object::sentinel();
2128 } 2130 }
2129 2131
2130 2132
2131 static Dart_Handle LookupStaticField(Dart_Handle clazz, 2133 static Dart_Handle LookupStaticField(Dart_Handle clazz,
2132 Dart_Handle field_name, 2134 Dart_Handle field_name,
2133 bool is_getter) { 2135 bool is_getter) {
2134 const Object& param1 = Object::Handle(Api::UnwrapHandle(clazz)); 2136 const Object& param1 = Object::Handle(Api::UnwrapHandle(clazz));
2135 const Object& param2 = Object::Handle(Api::UnwrapHandle(field_name)); 2137 const Object& param2 = Object::Handle(Api::UnwrapHandle(field_name));
2136 if (param1.IsNull() || !param1.IsClass()) { 2138 if (param1.IsNull() || !param1.IsClass()) {
2137 return Api::NewError("Invalid class specified"); 2139 return Api::NewError("Invalid class specified");
2138 } 2140 }
2139 if (param2.IsNull() || !param2.IsString()) { 2141 if (param2.IsNull() || !param2.IsString()) {
2140 return Api::NewError("Invalid field name specified"); 2142 return Api::NewError("Invalid field name specified");
2141 } 2143 }
2142 Class& cls = Class::Handle(); 2144 Class& cls = Class::Handle();
2143 cls ^= param1.raw(); 2145 cls ^= param1.raw();
2144 String& fld_name = String::Handle(); 2146 String& fld_name = String::Handle();
2145 fld_name ^= param2.raw(); 2147 fld_name ^= param2.raw();
2146 const Field& fld = Field::Handle(cls.LookupStaticField(fld_name)); 2148 const Field& fld = Field::Handle(cls.LookupStaticField(fld_name));
2147 if (is_getter && UseGetterForStaticField(fld)) { 2149 if (is_getter && (fld.IsNull() || FieldIsUninitialized(fld))) {
2148 const String& func_name = String::Handle(Field::GetterName(fld_name)); 2150 const String& func_name = String::Handle(Field::GetterName(fld_name));
2149 const Function& function = 2151 const Function& function =
2150 Function::Handle(cls.LookupStaticFunction(func_name)); 2152 Function::Handle(cls.LookupStaticFunction(func_name));
2151 if (!function.IsNull()) { 2153 if (!function.IsNull()) {
2152 return Api::NewLocalHandle(function); 2154 return Api::NewLocalHandle(function);
2153 } 2155 }
2154 return Api::NewError("Specified field is not found in the class"); 2156 return Api::NewError("Specified field is not found in the class");
2155 } 2157 }
2156 if (fld.IsNull()) { 2158 if (fld.IsNull()) {
2157 return Api::NewError("Specified field is not found in the class"); 2159 return Api::NewError("Specified field is not found in the class");
(...skipping 25 matching lines...) Expand all
2183 : Field::SetterName(field_name)); 2185 : Field::SetterName(field_name));
2184 const Function& function = Function::Handle( 2186 const Function& function = Function::Handle(
2185 cls.LookupDynamicFunction(func_name)); 2187 cls.LookupDynamicFunction(func_name));
2186 if (function.IsNull()) { 2188 if (function.IsNull()) {
2187 return Api::NewError("Unable to find accessor function in the class"); 2189 return Api::NewError("Unable to find accessor function in the class");
2188 } 2190 }
2189 return Api::NewLocalHandle(function); 2191 return Api::NewLocalHandle(function);
2190 } 2192 }
2191 cls = cls.SuperClass(); 2193 cls = cls.SuperClass();
2192 } 2194 }
2193 return Api::NewError("Unable to find field in the class"); 2195 return Api::NewError("Unable to find field '%s'.", field_name.ToCString());
2196 }
2197
2198
2199 DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name) {
2200 Isolate* isolate = Isolate::Current();
2201 DARTSCOPE(isolate);
2202
2203 const String& field_name = Api::UnwrapStringHandle(name);
2204 if (field_name.IsNull()) {
2205 RETURN_TYPE_ERROR(name, String);
2206 }
2207
2208 const Object& obj = Object::Handle(Api::UnwrapHandle(container));
2209
2210 Field& field = Field::Handle();
2211 Function& getter = Function::Handle();
2212 if (obj.IsNull()) {
2213 return Api::NewError("%s expects argument 'container' to be non-null.",
2214 CURRENT_FUNC);
2215 } else if (obj.IsInstance()) {
2216 // Every instance field has a getter Function. Try to find the
2217 // getter in any superclass and use that function to access the
2218 // field.
2219 Instance& instance = Instance::Handle();
2220 instance ^= obj.raw();
2221 Class& cls = Class::Handle(instance.clazz());
2222 while (!cls.IsNull()) {
2223 String& getter_name = String::Handle(Field::GetterName(field_name));
2224 getter = cls.LookupDynamicFunction(getter_name);
2225 if (!getter.IsNull()) {
2226 break;
2227 }
2228 cls = cls.SuperClass();
2229 }
2230
2231 if (getter.IsNull()) {
2232 return Api::NewError("%s: did not find instance field '%s'.",
2233 CURRENT_FUNC, field_name.ToCString());
2234 }
2235
2236 // Invoke the getter and return the result.
2237 GrowableArray<const Object*> args;
2238 const Array& kNoArgNames = Array::Handle();
2239 const Object& result = Object::Handle(
2240 DartEntry::InvokeDynamic(instance, getter, args, kNoArgNames));
2241 return Api::NewLocalHandle(result);
2242
2243 } else if (obj.IsClass()) {
2244 // To access a static field we may need to use the Field or the
2245 // getter Function.
2246 Class& cls = Class::Handle();
2247 cls ^= obj.raw();
2248 field = cls.LookupStaticField(field_name);
2249 if (field.IsNull() || FieldIsUninitialized(field)) {
2250 const String& getter_name = String::Handle(Field::GetterName(field_name));
2251 getter = cls.LookupStaticFunction(getter_name);
2252 }
2253
2254 if (!getter.IsNull()) {
2255 // Invoke the getter and return the result.
2256 GrowableArray<const Object*> args;
2257 const Array& kNoArgNames = Array::Handle();
2258 const Object& result = Object::Handle(
2259 DartEntry::InvokeStatic(getter, args, kNoArgNames));
2260 return Api::NewLocalHandle(result);
2261 } else if (!field.IsNull()) {
2262 const Object& result = Object::Handle(field.value());
2263 return Api::NewLocalHandle(result);
2264 } else {
2265 return Api::NewError("%s: did not find static field '%s'.",
2266 CURRENT_FUNC, field_name.ToCString());
2267 }
2268
2269 } else if (obj.IsLibrary()) {
2270 // To access a top-level we may need to use the Field or the
2271 // getter Function. The getter function may either be in the
2272 // library or in the field's owner class, depending.
2273 Library& lib = Library::Handle();
2274 lib ^= obj.raw();
2275 field = lib.LookupLocalField(field_name);
2276 if (field.IsNull()) {
2277 // No field found. Check for a getter in the lib.
2278 const String& getter_name = String::Handle(Field::GetterName(field_name));
2279 getter = lib.LookupLocalFunction(getter_name);
2280 } else if (FieldIsUninitialized(field)) {
2281 // A field was found. Check for a getter in the field's owner classs.
2282 const Class& cls = Class::Handle(field.owner());
2283 const String& getter_name = String::Handle(Field::GetterName(field_name));
2284 getter = cls.LookupStaticFunction(getter_name);
2285 }
2286
2287 if (!getter.IsNull()) {
2288 // Invoke the getter and return the result.
2289 GrowableArray<const Object*> args;
2290 const Array& kNoArgNames = Array::Handle();
2291 const Object& result = Object::Handle(
2292 DartEntry::InvokeStatic(getter, args, kNoArgNames));
2293 return Api::NewLocalHandle(result);
2294 } else if (!field.IsNull()) {
2295 const Object& result = Object::Handle(field.value());
2296 return Api::NewLocalHandle(result);
2297 } else {
2298 return Api::NewError("%s: did not find top-level variable '%s'.",
2299 CURRENT_FUNC, field_name.ToCString());
2300 }
2301
2302 } else {
2303 return Api::NewError(
2304 "%s expects argument 'container' to be an object, class, or library.",
2305 CURRENT_FUNC);
2306 }
2307 }
2308
2309
2310 DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container,
2311 Dart_Handle name,
2312 Dart_Handle value) {
2313 Isolate* isolate = Isolate::Current();
2314 DARTSCOPE(isolate);
2315
2316 const String& field_name = Api::UnwrapStringHandle(name);
2317 if (field_name.IsNull()) {
2318 RETURN_TYPE_ERROR(name, String);
2319 }
2320 const Instance& value_instance = Api::UnwrapInstanceHandle(value);
2321 if (value_instance.IsNull()) {
2322 RETURN_TYPE_ERROR(value, Instance);
2323 }
2324
2325 Field& field = Field::Handle();
2326 Function& setter = Function::Handle();
2327 const Object& obj = Object::Handle(Api::UnwrapHandle(container));
2328 if (obj.IsNull()) {
2329 return Api::NewError("%s expects argument 'container' to be non-null.",
2330 CURRENT_FUNC);
2331 } else if (obj.IsInstance()) {
2332 // Every instance field has a setter Function. Try to find the
2333 // setter in any superclass and use that function to access the
2334 // field.
2335 Instance& instance = Instance::Handle();
2336 instance ^= obj.raw();
2337 Class& cls = Class::Handle(instance.clazz());
2338 while (!cls.IsNull()) {
2339 field = cls.LookupInstanceField(field_name);
2340 if (!field.IsNull() && field.is_final()) {
2341 return Api::NewError("%s: cannot set final field '%s'.",
2342 CURRENT_FUNC, field_name.ToCString());
2343 }
2344 String& setter_name = String::Handle(Field::SetterName(field_name));
2345 setter = cls.LookupDynamicFunction(setter_name);
2346 if (!setter.IsNull()) {
2347 break;
2348 }
2349 cls = cls.SuperClass();
2350 }
2351
2352 if (setter.IsNull()) {
2353 return Api::NewError("%s: did not find instance field '%s'.",
2354 CURRENT_FUNC, field_name.ToCString());
2355 }
2356
2357 // Invoke the setter and return the result.
2358 GrowableArray<const Object*> args(1);
2359 args.Add(&value_instance);
2360 const Array& kNoArgNames = Array::Handle();
2361 const Object& result = Object::Handle(
2362 DartEntry::InvokeDynamic(instance, setter, args, kNoArgNames));
2363 return Api::NewLocalHandle(result);
2364
2365 } else if (obj.IsClass()) {
2366 // To access a static field we may need to use the Field or the
2367 // setter Function.
2368 Class& cls = Class::Handle();
2369 cls ^= obj.raw();
2370 field = cls.LookupStaticField(field_name);
2371 if (field.IsNull()) {
2372 String& setter_name = String::Handle(Field::SetterName(field_name));
2373 setter = cls.LookupStaticFunction(setter_name);
2374 }
2375
2376 if (!setter.IsNull()) {
2377 // Invoke the setter and return the result.
2378 GrowableArray<const Object*> args(1);
2379 args.Add(&value_instance);
2380 const Array& kNoArgNames = Array::Handle();
2381 const Object& result = Object::Handle(
2382 DartEntry::InvokeStatic(setter, args, kNoArgNames));
2383 if (result.IsError()) {
2384 return Api::NewLocalHandle(result);
2385 } else {
2386 return Api::Success();
2387 }
2388 } else if (!field.IsNull()) {
2389 if (field.is_final()) {
2390 return Api::NewError("%s: cannot set final field '%s'.",
2391 CURRENT_FUNC, field_name.ToCString());
2392 } else {
2393 field.set_value(value_instance);
2394 return Api::Success();
2395 }
2396 } else {
2397 return Api::NewError("%s: did not find static field '%s'.",
2398 CURRENT_FUNC, field_name.ToCString());
2399 }
2400
2401 } else if (obj.IsLibrary()) {
2402 // To access a top-level we may need to use the Field or the
2403 // setter Function. The setter function may either be in the
2404 // library or in the field's owner class, depending.
2405 Library& lib = Library::Handle();
2406 lib ^= obj.raw();
2407 field = lib.LookupLocalField(field_name);
2408 if (field.IsNull()) {
2409 const String& setter_name = String::Handle(Field::SetterName(field_name));
2410 setter ^= lib.LookupLocalFunction(setter_name);
2411 }
2412
2413 if (!setter.IsNull()) {
2414 // Invoke the setter and return the result.
2415 GrowableArray<const Object*> args(1);
2416 args.Add(&value_instance);
2417 const Array& kNoArgNames = Array::Handle();
2418 const Object& result = Object::Handle(
2419 DartEntry::InvokeStatic(setter, args, kNoArgNames));
2420 if (result.IsError()) {
2421 return Api::NewLocalHandle(result);
2422 } else {
2423 return Api::Success();
2424 }
2425 } else if (!field.IsNull()) {
2426 if (field.is_final()) {
2427 return Api::NewError("%s: cannot set final top-level variable '%s'.",
2428 CURRENT_FUNC, field_name.ToCString());
2429 } else {
2430 field.set_value(value_instance);
2431 return Api::Success();
2432 }
2433 } else {
2434 return Api::NewError("%s: did not find top-level variable '%s'.",
2435 CURRENT_FUNC, field_name.ToCString());
2436 }
2437
2438 } else {
2439 return Api::NewError(
2440 "%s expects argument 'container' to be an object, class, or library.",
2441 CURRENT_FUNC);
2442 }
2194 } 2443 }
2195 2444
2196 2445
2197 DART_EXPORT Dart_Handle Dart_GetStaticField(Dart_Handle cls, 2446 DART_EXPORT Dart_Handle Dart_GetStaticField(Dart_Handle cls,
2198 Dart_Handle name) { 2447 Dart_Handle name) {
2199 Isolate* isolate = Isolate::Current(); 2448 Isolate* isolate = Isolate::Current();
2200 DARTSCOPE(isolate); 2449 DARTSCOPE(isolate);
2201 Dart_Handle result = LookupStaticField(cls, name, kGetter); 2450 Dart_Handle result = LookupStaticField(cls, name, kGetter);
2202 if (::Dart_IsError(result)) { 2451 if (::Dart_IsError(result)) {
2203 return result; 2452 return result;
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
2743 *buffer = NULL; 2992 *buffer = NULL;
2744 } 2993 }
2745 delete debug_region; 2994 delete debug_region;
2746 } else { 2995 } else {
2747 *buffer = NULL; 2996 *buffer = NULL;
2748 *buffer_size = 0; 2997 *buffer_size = 0;
2749 } 2998 }
2750 } 2999 }
2751 3000
2752 } // namespace dart 3001 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698