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

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
« no previous file with comments | « lib/isolate.cc ('k') | 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) 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 1280 matching lines...) Expand 10 before | Expand all | Expand 10 after
2114 DartEntry::InvokeDynamic( 2118 DartEntry::InvokeDynamic(
2115 receiver, function, dart_arguments, kNoArgumentNames)); 2119 receiver, function, dart_arguments, kNoArgumentNames));
2116 return Api::NewLocalHandle(result); 2120 return Api::NewLocalHandle(result);
2117 } 2121 }
2118 2122
2119 2123
2120 static const bool kGetter = true; 2124 static const bool kGetter = true;
2121 static const bool kSetter = false; 2125 static const bool kSetter = false;
2122 2126
2123 2127
2124 static bool UseGetterForStaticField(const Field& fld) { 2128 static bool FieldIsUninitialized(const Field& fld) {
2125 if (fld.IsNull()) { 2129 ASSERT(!fld.IsNull());
2126 return true;
2127 }
2128 2130
2129 // Return getter method for uninitialized fields, rather than the 2131 // Return getter method for uninitialized fields, rather than the
2130 // field object, since the value in the field object will not be 2132 // field object, since the value in the field object will not be
2131 // initialized until the first time the getter is invoked. 2133 // initialized until the first time the getter is invoked.
2132 const Instance& value = Instance::Handle(fld.value()); 2134 const Instance& value = Instance::Handle(fld.value());
2133 ASSERT(value.raw() != Object::transition_sentinel()); 2135 ASSERT(value.raw() != Object::transition_sentinel());
2134 return value.raw() == Object::sentinel(); 2136 return value.raw() == Object::sentinel();
2135 } 2137 }
2136 2138
2137 2139
2138 static Dart_Handle LookupStaticField(Dart_Handle clazz, 2140 static Dart_Handle LookupStaticField(Dart_Handle clazz,
2139 Dart_Handle field_name, 2141 Dart_Handle field_name,
2140 bool is_getter) { 2142 bool is_getter) {
2141 const Object& param1 = Object::Handle(Api::UnwrapHandle(clazz)); 2143 const Object& param1 = Object::Handle(Api::UnwrapHandle(clazz));
2142 const Object& param2 = Object::Handle(Api::UnwrapHandle(field_name)); 2144 const Object& param2 = Object::Handle(Api::UnwrapHandle(field_name));
2143 if (param1.IsNull() || !param1.IsClass()) { 2145 if (param1.IsNull() || !param1.IsClass()) {
2144 return Api::NewError("Invalid class specified"); 2146 return Api::NewError("Invalid class specified");
2145 } 2147 }
2146 if (param2.IsNull() || !param2.IsString()) { 2148 if (param2.IsNull() || !param2.IsString()) {
2147 return Api::NewError("Invalid field name specified"); 2149 return Api::NewError("Invalid field name specified");
2148 } 2150 }
2149 Class& cls = Class::Handle(); 2151 Class& cls = Class::Handle();
2150 cls ^= param1.raw(); 2152 cls ^= param1.raw();
2151 String& fld_name = String::Handle(); 2153 String& fld_name = String::Handle();
2152 fld_name ^= param2.raw(); 2154 fld_name ^= param2.raw();
2153 const Field& fld = Field::Handle(cls.LookupStaticField(fld_name)); 2155 const Field& fld = Field::Handle(cls.LookupStaticField(fld_name));
2154 if (is_getter && UseGetterForStaticField(fld)) { 2156 if (is_getter && (fld.IsNull() || FieldIsUninitialized(fld))) {
2155 const String& func_name = String::Handle(Field::GetterName(fld_name)); 2157 const String& func_name = String::Handle(Field::GetterName(fld_name));
2156 const Function& function = 2158 const Function& function =
2157 Function::Handle(cls.LookupStaticFunction(func_name)); 2159 Function::Handle(cls.LookupStaticFunction(func_name));
2158 if (!function.IsNull()) { 2160 if (!function.IsNull()) {
2159 return Api::NewLocalHandle(function); 2161 return Api::NewLocalHandle(function);
2160 } 2162 }
2161 return Api::NewError("Specified field is not found in the class"); 2163 return Api::NewError("Specified field is not found in the class");
2162 } 2164 }
2163 if (fld.IsNull()) { 2165 if (fld.IsNull()) {
2164 return Api::NewError("Specified field is not found in the class"); 2166 return Api::NewError("Specified field is not found in the class");
(...skipping 25 matching lines...) Expand all
2190 : Field::SetterName(field_name)); 2192 : Field::SetterName(field_name));
2191 const Function& function = Function::Handle( 2193 const Function& function = Function::Handle(
2192 cls.LookupDynamicFunction(func_name)); 2194 cls.LookupDynamicFunction(func_name));
2193 if (function.IsNull()) { 2195 if (function.IsNull()) {
2194 return Api::NewError("Unable to find accessor function in the class"); 2196 return Api::NewError("Unable to find accessor function in the class");
2195 } 2197 }
2196 return Api::NewLocalHandle(function); 2198 return Api::NewLocalHandle(function);
2197 } 2199 }
2198 cls = cls.SuperClass(); 2200 cls = cls.SuperClass();
2199 } 2201 }
2200 return Api::NewError("Unable to find field in the class"); 2202 return Api::NewError("Unable to find field '%s'.", field_name.ToCString());
2203 }
2204
2205
2206 DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name) {
2207 Isolate* isolate = Isolate::Current();
2208 DARTSCOPE(isolate);
2209
2210 const String& field_name = Api::UnwrapStringHandle(name);
2211 if (field_name.IsNull()) {
2212 RETURN_TYPE_ERROR(name, String);
2213 }
2214
2215 const Object& obj = Object::Handle(Api::UnwrapHandle(container));
2216
2217 Field& field = Field::Handle();
2218 Function& getter = Function::Handle();
2219 if (obj.IsNull()) {
2220 return Api::NewError("%s expects argument 'container' to be non-null.",
2221 CURRENT_FUNC);
2222 } else if (obj.IsInstance()) {
2223 // Every instance field has a getter Function. Try to find the
2224 // getter in any superclass and use that function to access the
2225 // field.
2226 Instance& instance = Instance::Handle();
2227 instance ^= obj.raw();
2228 Class& cls = Class::Handle(instance.clazz());
2229 while (!cls.IsNull()) {
2230 String& getter_name = String::Handle(Field::GetterName(field_name));
2231 getter = cls.LookupDynamicFunction(getter_name);
2232 if (!getter.IsNull()) {
2233 break;
2234 }
2235 cls = cls.SuperClass();
2236 }
2237
2238 if (getter.IsNull()) {
2239 return Api::NewError("%s: did not find instance field '%s'.",
2240 CURRENT_FUNC, field_name.ToCString());
2241 }
2242
2243 // Invoke the getter and return the result.
2244 GrowableArray<const Object*> args;
2245 const Array& kNoArgNames = Array::Handle();
2246 const Object& result = Object::Handle(
2247 DartEntry::InvokeDynamic(instance, getter, args, kNoArgNames));
2248 return Api::NewLocalHandle(result);
2249
2250 } else if (obj.IsClass()) {
2251 // To access a static field we may need to use the Field or the
2252 // getter Function.
2253 Class& cls = Class::Handle();
2254 cls ^= obj.raw();
2255 field = cls.LookupStaticField(field_name);
2256 if (field.IsNull() || FieldIsUninitialized(field)) {
2257 const String& getter_name = String::Handle(Field::GetterName(field_name));
2258 getter = cls.LookupStaticFunction(getter_name);
2259 }
2260
2261 if (!getter.IsNull()) {
2262 // Invoke the getter and return the result.
2263 GrowableArray<const Object*> args;
2264 const Array& kNoArgNames = Array::Handle();
2265 const Object& result = Object::Handle(
2266 DartEntry::InvokeStatic(getter, args, kNoArgNames));
2267 return Api::NewLocalHandle(result);
2268 } else if (!field.IsNull()) {
2269 const Object& result = Object::Handle(field.value());
2270 return Api::NewLocalHandle(result);
2271 } else {
2272 return Api::NewError("%s: did not find static field '%s'.",
2273 CURRENT_FUNC, field_name.ToCString());
2274 }
2275
2276 } else if (obj.IsLibrary()) {
2277 // To access a top-level we may need to use the Field or the
2278 // getter Function. The getter function may either be in the
2279 // library or in the field's owner class, depending.
2280 Library& lib = Library::Handle();
2281 lib ^= obj.raw();
2282 field = lib.LookupLocalField(field_name);
2283 if (field.IsNull()) {
2284 // No field found. Check for a getter in the lib.
2285 const String& getter_name = String::Handle(Field::GetterName(field_name));
2286 getter = lib.LookupLocalFunction(getter_name);
2287 } else if (FieldIsUninitialized(field)) {
2288 // A field was found. Check for a getter in the field's owner classs.
2289 const Class& cls = Class::Handle(field.owner());
2290 const String& getter_name = String::Handle(Field::GetterName(field_name));
2291 getter = cls.LookupStaticFunction(getter_name);
2292 }
2293
2294 if (!getter.IsNull()) {
2295 // Invoke the getter and return the result.
2296 GrowableArray<const Object*> args;
2297 const Array& kNoArgNames = Array::Handle();
2298 const Object& result = Object::Handle(
2299 DartEntry::InvokeStatic(getter, args, kNoArgNames));
2300 return Api::NewLocalHandle(result);
2301 } else if (!field.IsNull()) {
2302 const Object& result = Object::Handle(field.value());
2303 return Api::NewLocalHandle(result);
2304 } else {
2305 return Api::NewError("%s: did not find top-level variable '%s'.",
2306 CURRENT_FUNC, field_name.ToCString());
2307 }
2308
2309 } else {
2310 return Api::NewError(
2311 "%s expects argument 'container' to be an object, class, or library.",
2312 CURRENT_FUNC);
2313 }
2314 }
2315
2316
2317 DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container,
2318 Dart_Handle name,
2319 Dart_Handle value) {
2320 Isolate* isolate = Isolate::Current();
2321 DARTSCOPE(isolate);
2322
2323 const String& field_name = Api::UnwrapStringHandle(name);
2324 if (field_name.IsNull()) {
2325 RETURN_TYPE_ERROR(name, String);
2326 }
2327 const Instance& value_instance = Api::UnwrapInstanceHandle(value);
2328 if (value_instance.IsNull()) {
2329 RETURN_TYPE_ERROR(value, Instance);
2330 }
2331
2332 Field& field = Field::Handle();
2333 Function& setter = Function::Handle();
2334 const Object& obj = Object::Handle(Api::UnwrapHandle(container));
2335 if (obj.IsNull()) {
2336 return Api::NewError("%s expects argument 'container' to be non-null.",
2337 CURRENT_FUNC);
2338 } else if (obj.IsInstance()) {
2339 // Every instance field has a setter Function. Try to find the
2340 // setter in any superclass and use that function to access the
2341 // field.
2342 Instance& instance = Instance::Handle();
2343 instance ^= obj.raw();
2344 Class& cls = Class::Handle(instance.clazz());
2345 while (!cls.IsNull()) {
2346 field = cls.LookupInstanceField(field_name);
2347 if (!field.IsNull() && field.is_final()) {
2348 return Api::NewError("%s: cannot set final field '%s'.",
2349 CURRENT_FUNC, field_name.ToCString());
2350 }
2351 String& setter_name = String::Handle(Field::SetterName(field_name));
2352 setter = cls.LookupDynamicFunction(setter_name);
2353 if (!setter.IsNull()) {
2354 break;
2355 }
2356 cls = cls.SuperClass();
2357 }
2358
2359 if (setter.IsNull()) {
2360 return Api::NewError("%s: did not find instance field '%s'.",
2361 CURRENT_FUNC, field_name.ToCString());
2362 }
2363
2364 // Invoke the setter and return the result.
2365 GrowableArray<const Object*> args(1);
2366 args.Add(&value_instance);
2367 const Array& kNoArgNames = Array::Handle();
2368 const Object& result = Object::Handle(
2369 DartEntry::InvokeDynamic(instance, setter, args, kNoArgNames));
2370 return Api::NewLocalHandle(result);
2371
2372 } else if (obj.IsClass()) {
2373 // To access a static field we may need to use the Field or the
2374 // setter Function.
2375 Class& cls = Class::Handle();
2376 cls ^= obj.raw();
2377 field = cls.LookupStaticField(field_name);
2378 if (field.IsNull()) {
2379 String& setter_name = String::Handle(Field::SetterName(field_name));
2380 setter = cls.LookupStaticFunction(setter_name);
2381 }
2382
2383 if (!setter.IsNull()) {
2384 // Invoke the setter and return the result.
2385 GrowableArray<const Object*> args(1);
2386 args.Add(&value_instance);
2387 const Array& kNoArgNames = Array::Handle();
2388 const Object& result = Object::Handle(
2389 DartEntry::InvokeStatic(setter, args, kNoArgNames));
2390 if (result.IsError()) {
2391 return Api::NewLocalHandle(result);
2392 } else {
2393 return Api::Success();
2394 }
2395 } else if (!field.IsNull()) {
2396 if (field.is_final()) {
2397 return Api::NewError("%s: cannot set final field '%s'.",
2398 CURRENT_FUNC, field_name.ToCString());
2399 } else {
2400 field.set_value(value_instance);
2401 return Api::Success();
2402 }
2403 } else {
2404 return Api::NewError("%s: did not find static field '%s'.",
2405 CURRENT_FUNC, field_name.ToCString());
2406 }
2407
2408 } else if (obj.IsLibrary()) {
2409 // To access a top-level we may need to use the Field or the
2410 // setter Function. The setter function may either be in the
2411 // library or in the field's owner class, depending.
2412 Library& lib = Library::Handle();
2413 lib ^= obj.raw();
2414 field = lib.LookupLocalField(field_name);
2415 if (field.IsNull()) {
2416 const String& setter_name = String::Handle(Field::SetterName(field_name));
2417 setter ^= lib.LookupLocalFunction(setter_name);
2418 }
2419
2420 if (!setter.IsNull()) {
2421 // Invoke the setter and return the result.
2422 GrowableArray<const Object*> args(1);
2423 args.Add(&value_instance);
2424 const Array& kNoArgNames = Array::Handle();
2425 const Object& result = Object::Handle(
2426 DartEntry::InvokeStatic(setter, args, kNoArgNames));
2427 if (result.IsError()) {
2428 return Api::NewLocalHandle(result);
2429 } else {
2430 return Api::Success();
2431 }
2432 } else if (!field.IsNull()) {
2433 if (field.is_final()) {
2434 return Api::NewError("%s: cannot set final top-level variable '%s'.",
2435 CURRENT_FUNC, field_name.ToCString());
2436 } else {
2437 field.set_value(value_instance);
2438 return Api::Success();
2439 }
2440 } else {
2441 return Api::NewError("%s: did not find top-level variable '%s'.",
2442 CURRENT_FUNC, field_name.ToCString());
2443 }
2444
2445 } else {
2446 return Api::NewError(
2447 "%s expects argument 'container' to be an object, class, or library.",
2448 CURRENT_FUNC);
2449 }
2201 } 2450 }
2202 2451
2203 2452
2204 DART_EXPORT Dart_Handle Dart_GetStaticField(Dart_Handle cls, 2453 DART_EXPORT Dart_Handle Dart_GetStaticField(Dart_Handle cls,
2205 Dart_Handle name) { 2454 Dart_Handle name) {
2206 Isolate* isolate = Isolate::Current(); 2455 Isolate* isolate = Isolate::Current();
2207 DARTSCOPE(isolate); 2456 DARTSCOPE(isolate);
2208 Dart_Handle result = LookupStaticField(cls, name, kGetter); 2457 Dart_Handle result = LookupStaticField(cls, name, kGetter);
2209 if (::Dart_IsError(result)) { 2458 if (::Dart_IsError(result)) {
2210 return result; 2459 return result;
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after
2750 *buffer = NULL; 2999 *buffer = NULL;
2751 } 3000 }
2752 delete debug_region; 3001 delete debug_region;
2753 } else { 3002 } else {
2754 *buffer = NULL; 3003 *buffer = NULL;
2755 *buffer_size = 0; 3004 *buffer_size = 0;
2756 } 3005 }
2757 } 3006 }
2758 3007
2759 } // namespace dart 3008 } // namespace dart
OLDNEW
« no previous file with comments | « lib/isolate.cc ('k') | vm/dart_api_impl_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698