| 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 2265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2276 Closure::CheckedHandle(isolate, Api::UnwrapHandle(object)); | 2276 Closure::CheckedHandle(isolate, Api::UnwrapHandle(object)); |
| 2277 const Integer& smrck = Integer::Handle(isolate, Integer::New(value)); | 2277 const Integer& smrck = Integer::Handle(isolate, Integer::New(value)); |
| 2278 obj.set_smrck(smrck); | 2278 obj.set_smrck(smrck); |
| 2279 } | 2279 } |
| 2280 | 2280 |
| 2281 | 2281 |
| 2282 // --- Constructors, Methods, and Fields --- | 2282 // --- Constructors, Methods, and Fields --- |
| 2283 | 2283 |
| 2284 | 2284 |
| 2285 static RawObject* ResolveConstructor(const char* current_func, | 2285 static RawObject* ResolveConstructor(const char* current_func, |
| 2286 Class& cls, | 2286 const Class& cls, |
| 2287 String& dotted_name, | 2287 const String& class_name, |
| 2288 const String& dotted_name, |
| 2288 int num_args) { | 2289 int num_args) { |
| 2289 // The constructor must be present in the interface. | 2290 // The constructor must be present in the interface. |
| 2290 const String& class_name = String::Handle(cls.Name()); | |
| 2291 String& constr_name = String::Handle(String::Concat(class_name, dotted_name)); | 2291 String& constr_name = String::Handle(String::Concat(class_name, dotted_name)); |
| 2292 const Function& constructor = | 2292 const Function& constructor = |
| 2293 Function::Handle(cls.LookupFunction(constr_name)); | 2293 Function::Handle(cls.LookupFunction(constr_name)); |
| 2294 if (constructor.IsNull() || | 2294 if (constructor.IsNull() || |
| 2295 (!constructor.IsConstructor() && !constructor.IsFactory())) { | 2295 (!constructor.IsConstructor() && !constructor.IsFactory())) { |
| 2296 const String& message = String::Handle( | 2296 const String& lookup_class_name = String::Handle(cls.Name()); |
| 2297 String::NewFormatted("%s: could not find constructor '%s'.", | 2297 if (!class_name.Equals(lookup_class_name)) { |
| 2298 current_func, constr_name.ToCString())); | 2298 // When the class name used to build the constructor name is |
| 2299 return ApiError::New(message); | 2299 // different than the name of the class in which we are doing |
| 2300 // the lookup, it can be confusing to the user to figure out |
| 2301 // what's going on. Be a little more explicit for these error |
| 2302 // messages. |
| 2303 const String& message = String::Handle( |
| 2304 String::NewFormatted( |
| 2305 "%s: could not find factory '%s' in class '%s'.", |
| 2306 current_func, |
| 2307 constr_name.ToCString(), |
| 2308 lookup_class_name.ToCString())); |
| 2309 return ApiError::New(message); |
| 2310 } else { |
| 2311 const String& message = String::Handle( |
| 2312 String::NewFormatted("%s: could not find constructor '%s'.", |
| 2313 current_func, constr_name.ToCString())); |
| 2314 return ApiError::New(message); |
| 2315 } |
| 2300 } | 2316 } |
| 2301 int extra_args = (constructor.IsConstructor() ? 2 : 1); | 2317 int extra_args = (constructor.IsConstructor() ? 2 : 1); |
| 2302 if (!constructor.AreValidArgumentCounts(num_args + extra_args, 0)) { | 2318 if (!constructor.AreValidArgumentCounts(num_args + extra_args, 0)) { |
| 2303 const String& message = String::Handle( | 2319 const String& message = String::Handle( |
| 2304 String::NewFormatted("%s: wrong argument count for constructor '%s': " | 2320 String::NewFormatted("%s: wrong argument count for constructor '%s': " |
| 2305 "expected %d but saw %d.", | 2321 "expected %d but saw %d.", |
| 2306 current_func, | 2322 current_func, |
| 2307 constr_name.ToCString(), | 2323 constr_name.ToCString(), |
| 2308 constructor.num_fixed_parameters() - extra_args, | 2324 constructor.num_fixed_parameters() - extra_args, |
| 2309 num_args)); | 2325 num_args)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2326 "%s expects argument 'number_of_arguments' to be non-negative.", | 2342 "%s expects argument 'number_of_arguments' to be non-negative.", |
| 2327 CURRENT_FUNC); | 2343 CURRENT_FUNC); |
| 2328 } | 2344 } |
| 2329 | 2345 |
| 2330 // Get the class to instantiate. | 2346 // Get the class to instantiate. |
| 2331 Class& cls = Class::Handle(isolate); | 2347 Class& cls = Class::Handle(isolate); |
| 2332 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw(); | 2348 cls ^= Api::UnwrapClassHandle(isolate, clazz).raw(); |
| 2333 if (cls.IsNull()) { | 2349 if (cls.IsNull()) { |
| 2334 RETURN_TYPE_ERROR(isolate, clazz, Class); | 2350 RETURN_TYPE_ERROR(isolate, clazz, Class); |
| 2335 } | 2351 } |
| 2352 String& base_constructor_name = String::Handle(); |
| 2353 base_constructor_name = cls.Name(); |
| 2336 | 2354 |
| 2337 // And get the name of the constructor to invoke. | 2355 // And get the name of the constructor to invoke. |
| 2338 String& dot_name = String::Handle(isolate); | 2356 String& dot_name = String::Handle(isolate); |
| 2339 const Object& name_obj = | 2357 const Object& name_obj = |
| 2340 Object::Handle(isolate, Api::UnwrapHandle(constructor_name)); | 2358 Object::Handle(isolate, Api::UnwrapHandle(constructor_name)); |
| 2341 if (name_obj.IsNull()) { | 2359 if (name_obj.IsNull()) { |
| 2342 dot_name = String::NewSymbol("."); | 2360 dot_name = String::NewSymbol("."); |
| 2343 } else if (name_obj.IsString()) { | 2361 } else if (name_obj.IsString()) { |
| 2344 const String& dot = String::Handle(isolate, String::NewSymbol(".")); | 2362 const String& dot = String::Handle(isolate, String::NewSymbol(".")); |
| 2345 String& name_str = String::Handle(isolate); | 2363 String& name_str = String::Handle(isolate); |
| 2346 name_str ^= name_obj.raw(); | 2364 name_str ^= name_obj.raw(); |
| 2347 dot_name ^= String::Concat(dot, name_str); | 2365 dot_name ^= String::Concat(dot, name_str); |
| 2348 } else { | 2366 } else { |
| 2349 return Api::NewError( | 2367 return Api::NewError( |
| 2350 "%s expects argument 'constructor_name' to be of type String.", | 2368 "%s expects argument 'constructor_name' to be of type String.", |
| 2351 CURRENT_FUNC); | 2369 CURRENT_FUNC); |
| 2352 } | 2370 } |
| 2353 | 2371 |
| 2354 const char* msg = CheckIsolateState(isolate); | 2372 const char* msg = CheckIsolateState(isolate); |
| 2355 if (msg != NULL) { | 2373 if (msg != NULL) { |
| 2356 return Api::NewError(msg); | 2374 return Api::NewError(msg); |
| 2357 } | 2375 } |
| 2358 | 2376 |
| 2359 // Check for interfaces with default implementations. | 2377 // Check for interfaces with default implementations. |
| 2360 if (cls.is_interface()) { | 2378 if (cls.is_interface()) { |
| 2361 // Make sure that the constructor is found in the interface. | 2379 // Make sure that the constructor is found in the interface. |
| 2362 result = ResolveConstructor("Dart_New", cls, dot_name, number_of_arguments); | 2380 result = ResolveConstructor( |
| 2381 "Dart_New", cls, base_constructor_name, dot_name, number_of_arguments); |
| 2363 if (result.IsError()) { | 2382 if (result.IsError()) { |
| 2364 return Api::NewHandle(isolate, result.raw()); | 2383 return Api::NewHandle(isolate, result.raw()); |
| 2365 } | 2384 } |
| 2366 | 2385 |
| 2367 ASSERT(cls.HasResolvedFactoryClass()); | 2386 ASSERT(cls.HasResolvedFactoryClass()); |
| 2387 const Class& factory_class = Class::Handle(cls.FactoryClass()); |
| 2388 |
| 2389 // If the factory class implements the requested interface, then |
| 2390 // we use the name of the factory class when looking up the |
| 2391 // constructor. Otherwise we use the original interface name when |
| 2392 // looking up the constructor. |
| 2393 const TypeArguments& no_type_args = TypeArguments::Handle(isolate); |
| 2394 Error& error = Error::Handle(); |
| 2395 if (factory_class.IsSubtypeOf(no_type_args, cls, no_type_args, &error)) { |
| 2396 base_constructor_name = factory_class.Name(); |
| 2397 } |
| 2398 if (!error.IsNull()) { |
| 2399 return Api::NewHandle(isolate, error.raw()); |
| 2400 } |
| 2401 |
| 2368 cls ^= cls.FactoryClass(); | 2402 cls ^= cls.FactoryClass(); |
| 2369 } | 2403 } |
| 2370 | 2404 |
| 2371 // Resolve the constructor. | 2405 // Resolve the constructor. |
| 2372 result = ResolveConstructor("Dart_New", cls, dot_name, number_of_arguments); | 2406 result = ResolveConstructor( |
| 2407 "Dart_New", cls, base_constructor_name, dot_name, number_of_arguments); |
| 2373 if (result.IsError()) { | 2408 if (result.IsError()) { |
| 2374 return Api::NewHandle(isolate, result.raw()); | 2409 return Api::NewHandle(isolate, result.raw()); |
| 2375 } | 2410 } |
| 2376 ASSERT(result.IsFunction()); | 2411 ASSERT(result.IsFunction()); |
| 2377 Function& constructor = Function::Handle(isolate); | 2412 Function& constructor = Function::Handle(isolate); |
| 2378 constructor ^= result.raw(); | 2413 constructor ^= result.raw(); |
| 2379 | 2414 |
| 2380 Instance& new_object = Instance::Handle(isolate); | 2415 Instance& new_object = Instance::Handle(isolate); |
| 2381 if (constructor.IsConstructor()) { | 2416 if (constructor.IsConstructor()) { |
| 2382 // Create the new object. | 2417 // Create the new object. |
| 2383 new_object = Instance::New(cls); | 2418 new_object = Instance::New(cls); |
| 2384 } | 2419 } |
| 2385 | 2420 |
| 2386 // Create the argument list. | 2421 // Create the argument list. |
| 2387 int extra_args = (constructor.IsConstructor() ? 2 : 1); | 2422 int extra_args = (constructor.IsConstructor() ? 2 : 1); |
| 2388 GrowableArray<const Object*> args(number_of_arguments + extra_args); | 2423 GrowableArray<const Object*> args(number_of_arguments + extra_args); |
| 2389 if (constructor.IsConstructor()) { | 2424 if (constructor.IsConstructor()) { |
| 2390 // Constructors get the uninitialized object as an extra arg. | 2425 // Constructors get the uninitialized object and a constructor phase. |
| 2391 args.Add(&new_object); | 2426 args.Add(&new_object); |
| 2427 args.Add(&Smi::Handle(isolate, Smi::New(Function::kCtorPhaseAll))); |
| 2428 } else { |
| 2429 // Factories get type arguments. |
| 2430 args.Add(&TypeArguments::Handle(isolate)); |
| 2392 } | 2431 } |
| 2393 args.Add(&Smi::Handle(isolate, Smi::New(Function::kCtorPhaseAll))); | |
| 2394 for (int i = 0; i < number_of_arguments; i++) { | 2432 for (int i = 0; i < number_of_arguments; i++) { |
| 2395 const Object& arg = | 2433 const Object& arg = |
| 2396 Object::Handle(isolate, Api::UnwrapHandle(arguments[i])); | 2434 Object::Handle(isolate, Api::UnwrapHandle(arguments[i])); |
| 2397 if (!arg.IsNull() && !arg.IsInstance()) { | 2435 if (!arg.IsNull() && !arg.IsInstance()) { |
| 2398 if (arg.IsError()) { | 2436 if (arg.IsError()) { |
| 2399 return Api::NewHandle(isolate, arg.raw()); | 2437 return Api::NewHandle(isolate, arg.raw()); |
| 2400 } else { | 2438 } else { |
| 2401 return Api::NewError( | 2439 return Api::NewError( |
| 2402 "%s expects argument %d to be an instance of Object.", | 2440 "%s expects argument %d to be an instance of Object.", |
| 2403 CURRENT_FUNC, i); | 2441 CURRENT_FUNC, i); |
| (...skipping 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3313 *buffer = NULL; | 3351 *buffer = NULL; |
| 3314 } | 3352 } |
| 3315 delete debug_region; | 3353 delete debug_region; |
| 3316 } else { | 3354 } else { |
| 3317 *buffer = NULL; | 3355 *buffer = NULL; |
| 3318 *buffer_size = 0; | 3356 *buffer_size = 0; |
| 3319 } | 3357 } |
| 3320 } | 3358 } |
| 3321 | 3359 |
| 3322 } // namespace dart | 3360 } // namespace dart |
| OLD | NEW |