| Index: runtime/vm/dart_entry.cc
|
| ===================================================================
|
| --- runtime/vm/dart_entry.cc (revision 16173)
|
| +++ runtime/vm/dart_entry.cc (working copy)
|
| @@ -81,16 +81,37 @@
|
| }
|
|
|
|
|
| +// TODO(regis): Pass arguments as an Array including the receiver.
|
| RawObject* DartEntry::InvokeClosure(
|
| - const Instance& closure,
|
| + const Instance& instance,
|
| const GrowableArray<const Object*>& arguments,
|
| const Array& optional_arguments_names) {
|
| - // Get the entrypoint corresponding to the closure specified, this
|
| - // will result in a compilation of the closure if it is not already
|
| - // compiled.
|
| - ASSERT(Class::Handle(closure.clazz()).signature_function() != Object::null());
|
| - const Function& function = Function::Handle(Closure::function(closure));
|
| - const Context& context = Context::Handle(Closure::context(closure));
|
| + // Get the entrypoint corresponding to the closure function or to the call
|
| + // method of the instance. This will result in a compilation of the function
|
| + // if it is not already compiled.
|
| + Function& function = Function::Handle();
|
| + Context& context = Context::Handle();
|
| + if (!instance.IsCallable(&function, &context)) {
|
| + // Set up arguments to include the receiver as the first argument.
|
| + const int num_arguments = arguments.length() + 1;
|
| + const Array& args = Array::Handle(Array::New(num_arguments));
|
| + args.SetAt(0, instance);
|
| + for (int i = 1; i < num_arguments; i++) {
|
| + args.SetAt(i, *arguments[i - 1]);
|
| + }
|
| + const String& call_symbol = String::Handle(Symbols::Call());
|
| + const Object& null_object = Object::Handle();
|
| + GrowableArray<const Object*> dart_arguments(5);
|
| + dart_arguments.Add(&instance);
|
| + dart_arguments.Add(&call_symbol);
|
| + dart_arguments.Add(&args); // Including instance.
|
| + dart_arguments.Add(&null_object); // TODO(regis): Provide names.
|
| + // If a function "call" with different arguments exists, it will have been
|
| + // invoked above, so no need to handle this case here.
|
| + Exceptions::ThrowByType(Exceptions::kNoSuchMethod, dart_arguments);
|
| + UNREACHABLE();
|
| + return Object::null();
|
| + }
|
| ASSERT(!function.IsNull());
|
| if (!function.HasCode()) {
|
| const Error& error = Error::Handle(Compiler::CompileFunction(function));
|
| @@ -98,10 +119,10 @@
|
| return error.raw();
|
| }
|
| }
|
| - // Set up arguments to include the closure as the first argument.
|
| + // Set up arguments to include the receiver as the first argument.
|
| const int num_arguments = arguments.length() + 1;
|
| GrowableArray<const Object*> args(num_arguments);
|
| - const Object& arg0 = Object::ZoneHandle(closure.raw());
|
| + const Object& arg0 = Object::ZoneHandle(instance.raw());
|
| args.Add(&arg0);
|
| for (int i = 1; i < num_arguments; i++) {
|
| args.Add(arguments[i - 1]);
|
|
|