| OLD | NEW |
| 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 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1046 | 1046 |
| 1047 | 1047 |
| 1048 // TODO(iposva): This call actually implements IsInstanceOfClass. | 1048 // TODO(iposva): This call actually implements IsInstanceOfClass. |
| 1049 // Do we also need a real Dart_IsInstanceOf, which should take an instance | 1049 // Do we also need a real Dart_IsInstanceOf, which should take an instance |
| 1050 // rather than an object and a type rather than a class? | 1050 // rather than an object and a type rather than a class? |
| 1051 DART_EXPORT Dart_Handle Dart_ObjectIsType(Dart_Handle object, | 1051 DART_EXPORT Dart_Handle Dart_ObjectIsType(Dart_Handle object, |
| 1052 Dart_Handle clazz, | 1052 Dart_Handle clazz, |
| 1053 bool* value) { | 1053 bool* value) { |
| 1054 Isolate* isolate = Isolate::Current(); | 1054 Isolate* isolate = Isolate::Current(); |
| 1055 DARTSCOPE(isolate); | 1055 DARTSCOPE(isolate); |
| 1056 const Class& cls = Class::CheckedHandle(isolate, Api::UnwrapHandle(clazz)); | 1056 |
| 1057 const Class& cls = Api::UnwrapClassHandle(isolate, clazz); |
| 1057 if (cls.IsNull()) { | 1058 if (cls.IsNull()) { |
| 1058 return Api::NewError("instanceof check against null class"); | 1059 RETURN_TYPE_ERROR(isolate, clazz, Class); |
| 1059 } | 1060 } |
| 1060 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); | 1061 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(object)); |
| 1062 if (obj.IsError()) { |
| 1063 return object; |
| 1064 } else if (!obj.IsNull() && !obj.IsInstance()) { |
| 1065 return Api::NewError( |
| 1066 "%s expects argument 'object' to be an instance of Object.", |
| 1067 CURRENT_FUNC); |
| 1068 } |
| 1069 |
| 1061 Instance& instance = Instance::Handle(isolate); | 1070 Instance& instance = Instance::Handle(isolate); |
| 1062 instance ^= obj.raw(); | 1071 instance ^= obj.raw(); |
| 1063 // Finalize all classes. | 1072 // Finalize all classes. |
| 1064 const char* msg = CheckIsolateState(isolate); | 1073 const char* msg = CheckIsolateState(isolate); |
| 1065 if (msg != NULL) { | 1074 if (msg != NULL) { |
| 1066 return Api::NewError(msg); | 1075 return Api::NewError(msg); |
| 1067 } | 1076 } |
| 1068 const Type& type = Type::Handle(isolate, Type::NewNonParameterizedType(cls)); | 1077 const Type& type = Type::Handle(isolate, Type::NewNonParameterizedType(cls)); |
| 1069 Error& malformed_type_error = Error::Handle(isolate); | 1078 Error& malformed_type_error = Error::Handle(isolate); |
| 1070 *value = instance.IsInstanceOf( | 1079 *value = instance.IsInstanceOf( |
| (...skipping 1189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2260 DART_EXPORT void Dart_ClosureSetSmrck(Dart_Handle object, int64_t value) { | 2269 DART_EXPORT void Dart_ClosureSetSmrck(Dart_Handle object, int64_t value) { |
| 2261 Isolate* isolate = Isolate::Current(); | 2270 Isolate* isolate = Isolate::Current(); |
| 2262 DARTSCOPE(isolate); | 2271 DARTSCOPE(isolate); |
| 2263 const Closure& obj = | 2272 const Closure& obj = |
| 2264 Closure::CheckedHandle(isolate, Api::UnwrapHandle(object)); | 2273 Closure::CheckedHandle(isolate, Api::UnwrapHandle(object)); |
| 2265 const Integer& smrck = Integer::Handle(isolate, Integer::New(value)); | 2274 const Integer& smrck = Integer::Handle(isolate, Integer::New(value)); |
| 2266 obj.set_smrck(smrck); | 2275 obj.set_smrck(smrck); |
| 2267 } | 2276 } |
| 2268 | 2277 |
| 2269 | 2278 |
| 2270 // --- Methods and Fields --- | 2279 // --- Constructors, Methods, and Fields --- |
| 2280 |
| 2281 |
| 2282 static RawObject* ResolveConstructor(const char* current_func, |
| 2283 Class& cls, |
| 2284 String& dotted_name, |
| 2285 int num_args) { |
| 2286 // The constructor must be present in the interface. |
| 2287 const String& class_name = String::Handle(cls.Name()); |
| 2288 String& constr_name = String::Handle(String::Concat(class_name, dotted_name)); |
| 2289 const Function& constructor = |
| 2290 Function::Handle(cls.LookupFunction(constr_name)); |
| 2291 if (constructor.IsNull() || |
| 2292 (!constructor.IsConstructor() && !constructor.IsFactory())) { |
| 2293 const String& message = String::Handle( |
| 2294 String::NewFormatted("%s: could not find constructor '%s'.", |
| 2295 current_func, constr_name.ToCString())); |
| 2296 return ApiError::New(message); |
| 2297 } |
| 2298 int extra_args = (constructor.IsConstructor() ? 2 : 1); |
| 2299 if (!constructor.AreValidArgumentCounts(num_args + extra_args, 0)) { |
| 2300 const String& message = String::Handle( |
| 2301 String::NewFormatted("%s: wrong argument count for constructor '%s': " |
| 2302 "expected %d but saw %d.", |
| 2303 current_func, |
| 2304 constr_name.ToCString(), |
| 2305 constructor.num_fixed_parameters() - extra_args, |
| 2306 num_args)); |
| 2307 return ApiError::New(message); |
| 2308 } |
| 2309 return constructor.raw(); |
| 2310 } |
| 2311 |
| 2312 |
| 2313 DART_EXPORT Dart_Handle Dart_New(Dart_Handle clazz, |
| 2314 Dart_Handle constructor_name, |
| 2315 int number_of_arguments, |
| 2316 Dart_Handle* arguments) { |
| 2317 Isolate* isolate = Isolate::Current(); |
| 2318 DARTSCOPE(isolate); |
| 2319 Object& result = Object::Handle(isolate); |
| 2320 |
| 2321 if (number_of_arguments < 0) { |
| 2322 return Api::NewError( |
| 2323 "%s expects argument 'number_of_arguments' to be non-negative.", |
| 2324 CURRENT_FUNC); |
| 2325 } |
| 2326 |
| 2327 // Get the class to instantiate. |
| 2328 Class& cls = Class::Handle(isolate); |
| 2329 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw(); |
| 2330 if (cls.IsNull()) { |
| 2331 RETURN_TYPE_ERROR(isolate, clazz, Class); |
| 2332 } |
| 2333 |
| 2334 // And get the name of the constructor to invoke. |
| 2335 String& dot_name = String::Handle(isolate); |
| 2336 const Object& name_obj = |
| 2337 Object::Handle(isolate, Api::UnwrapHandle(constructor_name)); |
| 2338 if (name_obj.IsNull()) { |
| 2339 dot_name = String::NewSymbol("."); |
| 2340 } else if (name_obj.IsString()) { |
| 2341 const String& dot = String::Handle(isolate, String::NewSymbol(".")); |
| 2342 String& name_str = String::Handle(isolate); |
| 2343 name_str ^= name_obj.raw(); |
| 2344 dot_name ^= String::Concat(dot, name_str); |
| 2345 } else { |
| 2346 return Api::NewError( |
| 2347 "%s expects argument 'constructor_name' to be of type String.", |
| 2348 CURRENT_FUNC); |
| 2349 } |
| 2350 |
| 2351 const char* msg = CheckIsolateState(isolate); |
| 2352 if (msg != NULL) { |
| 2353 return Api::NewError(msg); |
| 2354 } |
| 2355 |
| 2356 // Check for interfaces with default implementations. |
| 2357 if (cls.is_interface()) { |
| 2358 // Make sure that the constructor is found in the interface. |
| 2359 result = ResolveConstructor("Dart_New", cls, dot_name, number_of_arguments); |
| 2360 if (result.IsError()) { |
| 2361 return Api::NewHandle(isolate, result.raw()); |
| 2362 } |
| 2363 |
| 2364 ASSERT(cls.HasResolvedFactoryClass()); |
| 2365 cls ^= cls.FactoryClass(); |
| 2366 } |
| 2367 |
| 2368 // Resolve the constructor. |
| 2369 result = ResolveConstructor("Dart_New", cls, dot_name, number_of_arguments); |
| 2370 if (result.IsError()) { |
| 2371 return Api::NewHandle(isolate, result.raw()); |
| 2372 } |
| 2373 ASSERT(result.IsFunction()); |
| 2374 Function& constructor = Function::Handle(isolate); |
| 2375 constructor ^= result.raw(); |
| 2376 |
| 2377 Instance& new_object = Instance::Handle(isolate); |
| 2378 if (constructor.IsConstructor()) { |
| 2379 // Create the new object. |
| 2380 new_object = Instance::New(cls); |
| 2381 } |
| 2382 |
| 2383 // Create the argument list. |
| 2384 int extra_args = (constructor.IsConstructor() ? 2 : 1); |
| 2385 GrowableArray<const Object*> args(number_of_arguments + extra_args); |
| 2386 if (constructor.IsConstructor()) { |
| 2387 // Constructors get the uninitialized object as an extra arg. |
| 2388 args.Add(&new_object); |
| 2389 } |
| 2390 args.Add(&Smi::Handle(isolate, Smi::New(Function::kCtorPhaseAll))); |
| 2391 for (int i = 0; i < number_of_arguments; i++) { |
| 2392 const Object& arg = |
| 2393 Object::Handle(isolate, Api::UnwrapHandle(arguments[i])); |
| 2394 if (!arg.IsNull() && !arg.IsInstance()) { |
| 2395 if (arg.IsError()) { |
| 2396 return Api::NewHandle(isolate, arg.raw()); |
| 2397 } else { |
| 2398 return Api::NewError( |
| 2399 "%s expects argument %d to be an instance of Object.", |
| 2400 CURRENT_FUNC, i); |
| 2401 } |
| 2402 } |
| 2403 args.Add(&arg); |
| 2404 } |
| 2405 |
| 2406 // Invoke the constructor and return the new object. |
| 2407 const Array& kNoArgNames = Array::Handle(isolate); |
| 2408 result = DartEntry::InvokeStatic(constructor, args, kNoArgNames); |
| 2409 if (result.IsError()) { |
| 2410 return Api::NewHandle(isolate, result.raw()); |
| 2411 } |
| 2412 if (constructor.IsConstructor()) { |
| 2413 ASSERT(result.IsNull()); |
| 2414 } else { |
| 2415 ASSERT(result.IsNull() || result.IsInstance()); |
| 2416 new_object ^= result.raw(); |
| 2417 } |
| 2418 return Api::NewHandle(isolate, new_object.raw()); |
| 2419 } |
| 2271 | 2420 |
| 2272 | 2421 |
| 2273 DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, | 2422 DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, |
| 2274 Dart_Handle name, | 2423 Dart_Handle name, |
| 2275 int number_of_arguments, | 2424 int number_of_arguments, |
| 2276 Dart_Handle* arguments) { | 2425 Dart_Handle* arguments) { |
| 2277 Isolate* isolate = Isolate::Current(); | 2426 Isolate* isolate = Isolate::Current(); |
| 2278 DARTSCOPE(isolate); | 2427 DARTSCOPE(isolate); |
| 2279 | 2428 |
| 2280 const String& function_name = Api::UnwrapStringHandle(isolate, name); | 2429 const String& function_name = Api::UnwrapStringHandle(isolate, name); |
| 2281 if (function_name.IsNull()) { | 2430 if (function_name.IsNull()) { |
| 2282 RETURN_TYPE_ERROR(isolate, name, String); | 2431 RETURN_TYPE_ERROR(isolate, name, String); |
| 2283 } | 2432 } |
| 2284 if (number_of_arguments < 0) { | 2433 if (number_of_arguments < 0) { |
| 2285 return Api::NewError( | 2434 return Api::NewError( |
| 2286 "%s expects argument 'number_of_arguments' to be non-negative.", | 2435 "%s expects argument 'number_of_arguments' to be non-negative.", |
| 2287 CURRENT_FUNC); | 2436 CURRENT_FUNC); |
| 2288 } | 2437 } |
| 2289 | 2438 |
| 2290 // Check for malformed arguments in the arguments list. | 2439 // Check for malformed arguments in the arguments list. |
| 2291 GrowableArray<const Object*> dart_args(number_of_arguments); | 2440 GrowableArray<const Object*> args(number_of_arguments); |
| 2292 for (int i = 0; i < number_of_arguments; i++) { | 2441 for (int i = 0; i < number_of_arguments; i++) { |
| 2293 const Object& arg = | 2442 const Object& arg = |
| 2294 Object::Handle(isolate, Api::UnwrapHandle(arguments[i])); | 2443 Object::Handle(isolate, Api::UnwrapHandle(arguments[i])); |
| 2295 if (!arg.IsNull() && !arg.IsInstance()) { | 2444 if (!arg.IsNull() && !arg.IsInstance()) { |
| 2296 if (arg.IsError()) { | 2445 if (arg.IsError()) { |
| 2297 return Api::NewHandle(isolate, arg.raw()); | 2446 return Api::NewHandle(isolate, arg.raw()); |
| 2298 } else { | 2447 } else { |
| 2299 return Api::NewError( | 2448 return Api::NewError( |
| 2300 "%s expects argument %d to be an instance of Object.", | 2449 "%s expects argument %d to be an instance of Object.", |
| 2301 CURRENT_FUNC, i); | 2450 CURRENT_FUNC, i); |
| 2302 } | 2451 } |
| 2303 } | 2452 } |
| 2304 dart_args.Add(&arg); | 2453 args.Add(&arg); |
| 2305 } | 2454 } |
| 2306 | 2455 |
| 2307 const Array& kNoArgNames = Array::Handle(isolate); | 2456 const Array& kNoArgNames = Array::Handle(isolate); |
| 2308 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); | 2457 const Object& obj = Object::Handle(isolate, Api::UnwrapHandle(target)); |
| 2309 if (obj.IsNull()) { | 2458 if (obj.IsNull()) { |
| 2310 return Api::NewError("%s expects argument 'target' to be non-null.", | 2459 return Api::NewError("%s expects argument 'target' to be non-null.", |
| 2311 CURRENT_FUNC); | 2460 CURRENT_FUNC); |
| 2312 } else if (obj.IsInstance()) { | 2461 } else if (obj.IsInstance()) { |
| 2313 Instance& instance = Instance::Handle(isolate); | 2462 Instance& instance = Instance::Handle(isolate); |
| 2314 instance ^= obj.raw(); | 2463 instance ^= obj.raw(); |
| 2315 const Function& function = Function::Handle( | 2464 const Function& function = Function::Handle( |
| 2316 isolate, | 2465 isolate, |
| 2317 Resolver::ResolveDynamic(instance, | 2466 Resolver::ResolveDynamic(instance, |
| 2318 function_name, | 2467 function_name, |
| 2319 (number_of_arguments + 1), | 2468 (number_of_arguments + 1), |
| 2320 Resolver::kIsQualified)); | 2469 Resolver::kIsQualified)); |
| 2321 if (function.IsNull()) { | 2470 if (function.IsNull()) { |
| 2322 const Type& type = Type::Handle(isolate, instance.GetType()); | 2471 const Type& type = Type::Handle(isolate, instance.GetType()); |
| 2323 const String& cls_name = String::Handle(isolate, type.ClassName()); | 2472 const String& cls_name = String::Handle(isolate, type.ClassName()); |
| 2324 return Api::NewError("%s: did not find instance method '%s.%s'.", | 2473 return Api::NewError("%s: did not find instance method '%s.%s'.", |
| 2325 CURRENT_FUNC, | 2474 CURRENT_FUNC, |
| 2326 cls_name.ToCString(), | 2475 cls_name.ToCString(), |
| 2327 function_name.ToCString()); | 2476 function_name.ToCString()); |
| 2328 } | 2477 } |
| 2329 return Api::NewHandle( | 2478 return Api::NewHandle( |
| 2330 isolate, | 2479 isolate, |
| 2331 DartEntry::InvokeDynamic(instance, function, dart_args, kNoArgNames)); | 2480 DartEntry::InvokeDynamic(instance, function, args, kNoArgNames)); |
| 2332 | 2481 |
| 2333 } else if (obj.IsClass()) { | 2482 } else if (obj.IsClass()) { |
| 2334 // Finalize all classes. | 2483 // Finalize all classes. |
| 2335 const char* msg = CheckIsolateState(isolate); | 2484 const char* msg = CheckIsolateState(isolate); |
| 2336 if (msg != NULL) { | 2485 if (msg != NULL) { |
| 2337 return Api::NewError(msg); | 2486 return Api::NewError(msg); |
| 2338 } | 2487 } |
| 2339 | 2488 |
| 2340 Class& cls = Class::Handle(isolate); | 2489 Class& cls = Class::Handle(isolate); |
| 2341 cls ^= obj.raw(); | 2490 cls ^= obj.raw(); |
| 2342 const Function& function = Function::Handle( | 2491 const Function& function = Function::Handle( |
| 2343 isolate, | 2492 isolate, |
| 2344 Resolver::ResolveStatic(cls, | 2493 Resolver::ResolveStatic(cls, |
| 2345 function_name, | 2494 function_name, |
| 2346 number_of_arguments, | 2495 number_of_arguments, |
| 2347 Array::Handle(isolate), | 2496 Array::Handle(isolate), |
| 2348 Resolver::kIsQualified)); | 2497 Resolver::kIsQualified)); |
| 2349 if (function.IsNull()) { | 2498 if (function.IsNull()) { |
| 2350 const String& cls_name = String::Handle(isolate, cls.Name()); | 2499 const String& cls_name = String::Handle(isolate, cls.Name()); |
| 2351 return Api::NewError("%s: did not find static method '%s.%s'.", | 2500 return Api::NewError("%s: did not find static method '%s.%s'.", |
| 2352 CURRENT_FUNC, | 2501 CURRENT_FUNC, |
| 2353 cls_name.ToCString(), | 2502 cls_name.ToCString(), |
| 2354 function_name.ToCString()); | 2503 function_name.ToCString()); |
| 2355 } | 2504 } |
| 2356 return Api::NewHandle( | 2505 return Api::NewHandle( |
| 2357 isolate, | 2506 isolate, |
| 2358 DartEntry::InvokeStatic(function, dart_args, kNoArgNames)); | 2507 DartEntry::InvokeStatic(function, args, kNoArgNames)); |
| 2359 | 2508 |
| 2360 } else if (obj.IsLibrary()) { | 2509 } else if (obj.IsLibrary()) { |
| 2361 // Check whether class finalization is needed. | 2510 // Check whether class finalization is needed. |
| 2362 bool finalize_classes = true; | 2511 bool finalize_classes = true; |
| 2363 Library& lib = Library::Handle(isolate); | 2512 Library& lib = Library::Handle(isolate); |
| 2364 lib ^= obj.raw(); | 2513 lib ^= obj.raw(); |
| 2365 | 2514 |
| 2366 // When calling functions in the dart:builtin library do not finalize as it | 2515 // When calling functions in the dart:builtin library do not finalize as it |
| 2367 // should have been prefinalized. | 2516 // should have been prefinalized. |
| 2368 Library& builtin = | 2517 Library& builtin = |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2385 if (!function.IsNull() && | 2534 if (!function.IsNull() && |
| 2386 !function.AreValidArgumentCounts(number_of_arguments, 0)) { | 2535 !function.AreValidArgumentCounts(number_of_arguments, 0)) { |
| 2387 function = Function::null(); | 2536 function = Function::null(); |
| 2388 } | 2537 } |
| 2389 if (function.IsNull()) { | 2538 if (function.IsNull()) { |
| 2390 return Api::NewError("%s: did not find top-level function '%s'.", | 2539 return Api::NewError("%s: did not find top-level function '%s'.", |
| 2391 CURRENT_FUNC, | 2540 CURRENT_FUNC, |
| 2392 function_name.ToCString()); | 2541 function_name.ToCString()); |
| 2393 } | 2542 } |
| 2394 return Api::NewHandle( | 2543 return Api::NewHandle( |
| 2395 isolate, DartEntry::InvokeStatic(function, dart_args, kNoArgNames)); | 2544 isolate, DartEntry::InvokeStatic(function, args, kNoArgNames)); |
| 2396 | 2545 |
| 2397 } else { | 2546 } else { |
| 2398 return Api::NewError( | 2547 return Api::NewError( |
| 2399 "%s expects argument 'target' to be an object, class, or library.", | 2548 "%s expects argument 'target' to be an object, class, or library.", |
| 2400 CURRENT_FUNC); | 2549 CURRENT_FUNC); |
| 2401 } | 2550 } |
| 2402 } | 2551 } |
| 2403 | 2552 |
| 2404 | 2553 |
| 2405 DART_EXPORT Dart_Handle Dart_InvokeStatic(Dart_Handle library_in, | 2554 DART_EXPORT Dart_Handle Dart_InvokeStatic(Dart_Handle library_in, |
| (...skipping 1041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3447 *buffer = NULL; | 3596 *buffer = NULL; |
| 3448 } | 3597 } |
| 3449 delete debug_region; | 3598 delete debug_region; |
| 3450 } else { | 3599 } else { |
| 3451 *buffer = NULL; | 3600 *buffer = NULL; |
| 3452 *buffer_size = 0; | 3601 *buffer_size = 0; |
| 3453 } | 3602 } |
| 3454 } | 3603 } |
| 3455 | 3604 |
| 3456 } // namespace dart | 3605 } // namespace dart |
| OLD | NEW |