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

Unified Diff: runtime/vm/code_generator.cc

Issue 11316343: Support call operator in the vm. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/dart_entry.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/code_generator.cc
===================================================================
--- runtime/vm/code_generator.cc (revision 16007)
+++ runtime/vm/code_generator.cc (working copy)
@@ -1264,7 +1264,7 @@
ASSERT(arguments.ArgCount() ==
kInvokeImplicitClosureFunctionRuntimeEntry.argument_count());
const Instance& closure = Instance::CheckedHandle(arguments.ArgAt(0));
- const Array& arg_descriptor = Array::CheckedHandle(arguments.ArgAt(1));
+ const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(1));
const Array& func_arguments = Array::CheckedHandle(arguments.ArgAt(2));
const Function& function = Function::Handle(Closure::function(closure));
ASSERT(!function.IsNull());
@@ -1291,13 +1291,13 @@
invoke_arguments.Add(&value);
}
- // Now Call the invoke stub which will invoke the closure.
+ // Now call the invoke stub which will invoke the closure.
DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>(
StubCode::InvokeDartCodeEntryPoint());
ASSERT(context.isolate() == Isolate::Current());
const Object& result = Object::Handle(
entrypoint(instrs.EntryPoint(),
- arg_descriptor,
+ args_descriptor,
invoke_arguments.data(),
context));
CheckResultError(result);
@@ -1366,25 +1366,17 @@
// A non-closure object was invoked as a closure, so call the "call" method
// on it.
// Arg0: non-closure object.
-// Arg1: arguments array, including non-closure object.
-// TODO(regis): Rename this entry?
-DEFINE_RUNTIME_ENTRY(ReportObjectNotClosure, 2) {
+// Arg1: arguments descriptor.
+// Arg2: arguments array, including non-closure object.
+DEFINE_RUNTIME_ENTRY(InvokeNonClosure, 3) {
ASSERT(arguments.ArgCount() ==
- kReportObjectNotClosureRuntimeEntry.argument_count());
+ kInvokeNonClosureRuntimeEntry.argument_count());
const Instance& instance = Instance::CheckedHandle(arguments.ArgAt(0));
- const Array& function_args = Array::CheckedHandle(arguments.ArgAt(1));
+ const Array& args_descriptor = Array::CheckedHandle(arguments.ArgAt(1));
+ const Array& function_args = Array::CheckedHandle(arguments.ArgAt(2));
+
+ // Resolve and invoke "call" method, if existing.
const String& function_name = String::Handle(Symbols::Call());
- GrowableArray<const Object*> dart_arguments(5);
-
- // TODO(regis): Resolve and invoke "call" method, if existing.
-
- const Object& null_object = Object::Handle();
- dart_arguments.Add(&instance);
- dart_arguments.Add(&function_name);
- dart_arguments.Add(&function_args);
- dart_arguments.Add(&null_object);
-
- // Report if a function "call" with different arguments has been found.
Class& instance_class = Class::Handle(instance.clazz());
Function& function =
Function::Handle(instance_class.LookupDynamicFunction(function_name));
@@ -1394,14 +1386,47 @@
function = instance_class.LookupDynamicFunction(function_name);
}
if (!function.IsNull()) {
- const int total_num_parameters = function.NumParameters();
- const Array& array = Array::Handle(Array::New(total_num_parameters - 1));
- // Skip receiver.
- for (int i = 1; i < total_num_parameters; i++) {
- array.SetAt(i - 1, String::Handle(function.ParameterNameAt(i)));
+ if (!function.HasCode()) {
+ const Error& error = Error::Handle(Compiler::CompileFunction(function));
+ if (!error.IsNull()) {
+ Exceptions::PropagateError(error);
+ }
}
- dart_arguments.Add(&array);
+ const Code& code = Code::Handle(function.CurrentCode());
+ ASSERT(!code.IsNull());
+ const Instructions& instrs = Instructions::Handle(code.instructions());
+ ASSERT(!instrs.IsNull());
+
+ // The non-closure object is passed as implicit first argument (receiver).
+ // It is already included in the arguments array.
+ GrowableArray<const Object*> invoke_arguments(function_args.Length());
+ for (intptr_t i = 0; i < function_args.Length(); i++) {
+ const Object& value = Object::Handle(function_args.At(i));
+ invoke_arguments.Add(&value);
+ }
+
+ // Now call the invoke stub which will invoke the call method.
+ DartEntry::invokestub entrypoint = reinterpret_cast<DartEntry::invokestub>(
+ StubCode::InvokeDartCodeEntryPoint());
+ const Context& context = Context::ZoneHandle(
+ Isolate::Current()->object_store()->empty_context());
+ const Object& result = Object::Handle(
+ entrypoint(instrs.EntryPoint(),
+ args_descriptor,
+ invoke_arguments.data(),
+ context));
+ CheckResultError(result);
+ arguments.SetReturn(result);
+ return;
}
+ const Object& null_object = Object::Handle();
+ GrowableArray<const Object*> dart_arguments(5);
+ dart_arguments.Add(&instance);
+ dart_arguments.Add(&function_name);
+ dart_arguments.Add(&function_args);
+ dart_arguments.Add(&null_object);
+ // 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();
}
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/dart_entry.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698