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