Index: vm/dart_entry.cc |
=================================================================== |
--- vm/dart_entry.cc (revision 16285) |
+++ vm/dart_entry.cc (working copy) |
@@ -13,11 +13,17 @@ |
namespace dart { |
-RawObject* DartEntry::InvokeDynamic( |
- const Instance& receiver, |
- const Function& function, |
- const GrowableArray<const Object*>& arguments, |
- const Array& optional_arguments_names) { |
+RawObject* DartEntry::InvokeDynamic(const Function& function, |
+ const Array& arguments) { |
+ const Array& arg_desc = |
+ Array::Handle(ArgumentsDescriptor::New(arguments.Length())); |
+ return InvokeDynamic(function, arguments, arg_desc); |
+} |
+ |
+ |
+RawObject* DartEntry::InvokeDynamic(const Function& function, |
+ const Array& arguments, |
+ const Array& arg_descriptor) { |
// Get the entrypoint corresponding to the function specified, this |
// will result in a compilation of the function if it is not already |
// compiled. |
@@ -28,14 +34,6 @@ |
} |
} |
- // 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(receiver.raw()); |
- args.Add(&arg0); |
- for (int i = 1; i < num_arguments; i++) { |
- args.Add(arguments[i - 1]); |
- } |
// Now Call the invoke stub which will invoke the dart function. |
invokestub entrypoint = reinterpret_cast<invokestub>( |
StubCode::InvokeDartCodeEntryPoint()); |
@@ -44,17 +42,21 @@ |
ASSERT(context.isolate() == Isolate::Current()); |
const Code& code = Code::Handle(function.CurrentCode()); |
ASSERT(!code.IsNull()); |
- const Array& arg_descriptor = |
- Array::Handle(ArgumentsDescriptor::New(num_arguments, |
- optional_arguments_names)); |
- return entrypoint(code.EntryPoint(), arg_descriptor, args.data(), context); |
+ return entrypoint(code.EntryPoint(), arg_descriptor, arguments, context); |
} |
-RawObject* DartEntry::InvokeStatic( |
- const Function& function, |
- const GrowableArray<const Object*>& arguments, |
- const Array& optional_arguments_names) { |
+RawObject* DartEntry::InvokeStatic(const Function& function, |
+ const Array& arguments) { |
+ const Array& arg_desc = |
+ Array::Handle(ArgumentsDescriptor::New(arguments.Length())); |
+ return InvokeStatic(function, arguments, arg_desc); |
+} |
+ |
+ |
+RawObject* DartEntry::InvokeStatic(const Function& function, |
+ const Array& arguments, |
+ const Array& arg_descriptor) { |
// Get the entrypoint corresponding to the function specified, this |
// will result in a compilation of the function if it is not already |
// compiled. |
@@ -73,19 +75,22 @@ |
ASSERT(context.isolate() == Isolate::Current()); |
const Code& code = Code::Handle(function.CurrentCode()); |
ASSERT(!code.IsNull()); |
- const Array& arg_descriptor = |
- Array::Handle(ArgumentsDescriptor::New(arguments.length(), |
- optional_arguments_names)); |
- return entrypoint(code.EntryPoint(), arg_descriptor, arguments.data(), |
- context); |
+ return entrypoint(code.EntryPoint(), arg_descriptor, arguments, context); |
} |
-// TODO(regis): Pass arguments as an Array including the receiver. |
-RawObject* DartEntry::InvokeClosure( |
- const Instance& instance, |
- const GrowableArray<const Object*>& arguments, |
- const Array& optional_arguments_names) { |
+RawObject* DartEntry::InvokeClosure(const Instance& closure, |
+ const Array& arguments) { |
+ const Array& arg_desc = |
+ Array::Handle(ArgumentsDescriptor::New(arguments.Length())); |
+ return InvokeClosure(closure, arguments, arg_desc); |
+} |
+ |
+ |
+RawObject* DartEntry::InvokeClosure(const Instance& instance, |
+ const Array& arguments, |
+ const Array& arg_descriptor) { |
+ ASSERT(instance.raw() == arguments.At(0)); |
// 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. |
@@ -93,18 +98,12 @@ |
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(&arguments); // Includes 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. |
@@ -119,24 +118,13 @@ |
return error.raw(); |
} |
} |
- // 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(instance.raw()); |
- args.Add(&arg0); |
- for (int i = 1; i < num_arguments; i++) { |
- args.Add(arguments[i - 1]); |
- } |
// Now call the invoke stub which will invoke the closure. |
invokestub entrypoint = reinterpret_cast<invokestub>( |
StubCode::InvokeDartCodeEntryPoint()); |
ASSERT(context.isolate() == Isolate::Current()); |
const Code& code = Code::Handle(function.CurrentCode()); |
ASSERT(!code.IsNull()); |
- const Array& arg_descriptor = |
- Array::Handle(ArgumentsDescriptor::New(num_arguments, |
- optional_arguments_names)); |
- return entrypoint(code.EntryPoint(), arg_descriptor, args.data(), context); |
+ return entrypoint(code.EntryPoint(), arg_descriptor, arguments, context); |
} |
@@ -231,6 +219,30 @@ |
} |
+RawArray* ArgumentsDescriptor::New(intptr_t num_arguments) { |
+ // Build the arguments descriptor array, which consists of the total |
+ // argument count; the positional argument count; and |
+ // a terminating null to simplify iterating in generated code. |
+ const intptr_t descriptor_len = LengthFor(0); |
+ Array& descriptor = Array::Handle(Array::New(descriptor_len, Heap::kOld)); |
+ const Smi& arg_count = Smi::Handle(Smi::New(num_arguments)); |
+ |
+ // Set total number of passed arguments. |
+ descriptor.SetAt(kCountIndex, arg_count); |
+ |
+ // Set number of positional arguments. |
+ descriptor.SetAt(kPositionalCountIndex, arg_count); |
+ |
+ // Set terminating null. |
+ descriptor.SetAt((descriptor_len - 1), Object::Handle()); |
+ |
+ // Share the immutable descriptor when possible by canonicalizing it. |
+ descriptor.MakeImmutable(); |
+ descriptor ^= descriptor.Canonicalize(); |
+ return descriptor.raw(); |
+} |
+ |
+ |
RawObject* DartLibraryCalls::ExceptionCreate( |
const Library& lib, |
const String& class_name, |
@@ -238,21 +250,24 @@ |
const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name)); |
ASSERT(!cls.IsNull()); |
// For now, we only support a non-parameterized or raw type. |
+ const int kNumExtraArgs = 2; // implicit rcvr and construction phase args. |
const Instance& exception_object = Instance::Handle(Instance::New(cls)); |
- GrowableArray<const Object*> constructor_arguments(arguments.length() + 2); |
- constructor_arguments.Add(&exception_object); |
- constructor_arguments.Add(&Smi::Handle(Smi::New(Function::kCtorPhaseAll))); |
- constructor_arguments.AddArray(arguments); |
+ const Array& constructor_arguments = |
+ Array::Handle(Array::New(arguments.length() + kNumExtraArgs)); |
+ constructor_arguments.SetAt(0, exception_object); |
+ constructor_arguments.SetAt( |
+ 1, Smi::Handle(Smi::New(Function::kCtorPhaseAll))); |
+ for (intptr_t i = 0; i < arguments.length(); i++) { |
+ constructor_arguments.SetAt((i + kNumExtraArgs), *(arguments[i])); |
+ } |
String& constructor_name = String::Handle( |
String::Concat(class_name, Symbols::DotHandle())); |
Function& constructor = |
Function::Handle(cls.LookupConstructor(constructor_name)); |
ASSERT(!constructor.IsNull()); |
- const Array& kNoArgumentNames = Array::Handle(); |
- const Object& retval = Object::Handle( |
- DartEntry::InvokeStatic(constructor, constructor_arguments, |
- kNoArgumentNames)); |
+ const Object& retval = |
+ Object::Handle(DartEntry::InvokeStatic(constructor, constructor_arguments)); |
ASSERT(retval.IsNull() || retval.IsError()); |
if (retval.IsError()) { |
return retval.raw(); |
@@ -264,21 +279,18 @@ |
RawObject* DartLibraryCalls::ToString(const Instance& receiver) { |
const String& function_name = |
String::Handle(Symbols::New("toString")); |
- GrowableArray<const Object*> arguments; |
const int kNumArguments = 1; // Receiver. |
const int kNumNamedArguments = 0; // None. |
- const Array& kNoArgumentNames = Array::Handle(); |
const Function& function = Function::Handle( |
Resolver::ResolveDynamic(receiver, |
function_name, |
kNumArguments, |
kNumNamedArguments)); |
ASSERT(!function.IsNull()); |
- const Object& result = Object::Handle( |
- DartEntry::InvokeDynamic(receiver, |
- function, |
- arguments, |
- kNoArgumentNames)); |
+ const Array& args = Array::Handle(Array::New(kNumArguments)); |
+ args.SetAt(0, receiver); |
+ const Object& result = Object::Handle(DartEntry::InvokeDynamic(function, |
+ args)); |
ASSERT(result.IsInstance() || result.IsError()); |
return result.raw(); |
} |
@@ -286,19 +298,20 @@ |
RawObject* DartLibraryCalls::Equals(const Instance& left, |
const Instance& right) { |
- GrowableArray<const Object*> arguments; |
- arguments.Add(&right); |
const int kNumArguments = 2; |
const int kNumNamedArguments = 0; |
- const Array& kNoArgumentNames = Array::Handle(); |
const Function& function = Function::Handle( |
Resolver::ResolveDynamic(left, |
Symbols::EqualOperatorHandle(), |
kNumArguments, |
kNumNamedArguments)); |
ASSERT(!function.IsNull()); |
- const Object& result = Object::Handle( |
- DartEntry::InvokeDynamic(left, function, arguments, kNoArgumentNames)); |
+ |
+ const Array& args = Array::Handle(Array::New(kNumArguments)); |
+ args.SetAt(0, left); |
+ args.SetAt(1, right); |
+ const Object& result = Object::Handle(DartEntry::InvokeDynamic(function, |
+ args)); |
ASSERT(result.IsInstance() || result.IsError()); |
return result.raw(); |
} |
@@ -324,12 +337,12 @@ |
kNumArguments, |
kNoArgumentNames, |
Resolver::kIsQualified)); |
- GrowableArray<const Object*> arguments(kNumArguments); |
- arguments.Add(&Integer::Handle(Integer::New(dest_port_id))); |
- arguments.Add(&Integer::Handle(Integer::New(reply_port_id))); |
- arguments.Add(&message); |
- const Object& result = Object::Handle( |
- DartEntry::InvokeStatic(function, arguments, kNoArgumentNames)); |
+ const Array& args = Array::Handle(Array::New(kNumArguments)); |
+ args.SetAt(0, Integer::Handle(Integer::New(dest_port_id))); |
+ args.SetAt(1, Integer::Handle(Integer::New(reply_port_id))); |
+ args.SetAt(2, message); |
+ const Object& result = Object::Handle(DartEntry::InvokeStatic(function, |
+ args)); |
ASSERT(result.IsNull() || result.IsError()); |
return result.raw(); |
} |
@@ -352,9 +365,9 @@ |
kNumArguments, |
kNoArgumentNames, |
Resolver::kIsQualified)); |
- GrowableArray<const Object*> arguments(kNumArguments); |
- arguments.Add(&Integer::Handle(Integer::New(port_id))); |
- return DartEntry::InvokeStatic(function, arguments, kNoArgumentNames); |
+ const Array& args = Array::Handle(Array::New(kNumArguments)); |
+ args.SetAt(0, Integer::Handle(Integer::New(port_id))); |
+ return DartEntry::InvokeStatic(function, args); |
} |
@@ -362,15 +375,16 @@ |
const Instance& key, |
const Instance& value) { |
String& name = String::Handle(Symbols::AssignIndexToken()); |
+ const int kNumArguments = 3; |
const Function& function = Function::Handle( |
- Resolver::ResolveDynamic(map, name, 3, 0)); |
+ Resolver::ResolveDynamic(map, name, kNumArguments, 0)); |
ASSERT(!function.IsNull()); |
- GrowableArray<const Object*> args(2); |
- args.Add(&key); |
- args.Add(&value); |
- const Array& kNoArgumentNames = Array::Handle(); |
- const Object& result = Object::Handle( |
- DartEntry::InvokeDynamic(map, function, args, kNoArgumentNames)); |
+ const Array& args = Array::Handle(Array::New(kNumArguments)); |
+ args.SetAt(0, map); |
+ args.SetAt(1, key); |
+ args.SetAt(2, value); |
+ const Object& result = Object::Handle(DartEntry::InvokeDynamic(function, |
+ args)); |
return result.raw(); |
} |
@@ -381,9 +395,9 @@ |
const String& func_name = String::Handle(Field::GetterName(field_name)); |
const Function& func = Function::Handle(cls.LookupDynamicFunction(func_name)); |
ASSERT(!func.IsNull()); |
- GrowableArray<const Object*> arguments; |
- const Array& kNoArgumentNames = Array::Handle(); |
- return DartEntry::InvokeDynamic(port, func, arguments, kNoArgumentNames); |
+ const Array& args = Array::Handle(Array::New(1)); |
+ args.SetAt(0, port); |
+ return DartEntry::InvokeDynamic(func, args); |
} |