2011-10-05 05:20:07 +00:00
|
|
|
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
|
|
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "vm/dart_entry.h"
|
|
|
|
|
|
|
|
#include "vm/code_generator.h"
|
|
|
|
#include "vm/compiler.h"
|
|
|
|
#include "vm/object_store.h"
|
|
|
|
#include "vm/resolver.h"
|
|
|
|
#include "vm/stub_code.h"
|
2012-07-24 00:01:50 +00:00
|
|
|
#include "vm/symbols.h"
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
namespace dart {
|
|
|
|
|
2012-12-18 21:36:01 +00:00
|
|
|
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,
|
2012-12-19 21:26:29 +00:00
|
|
|
const Array& arguments_descriptor) {
|
2011-10-05 05:20:07 +00:00
|
|
|
// Get the entrypoint corresponding to the function specified, this
|
|
|
|
// will result in a compilation of the function if it is not already
|
|
|
|
// compiled.
|
|
|
|
if (!function.HasCode()) {
|
2012-02-02 19:05:06 +00:00
|
|
|
const Error& error = Error::Handle(Compiler::CompileFunction(function));
|
|
|
|
if (!error.IsNull()) {
|
|
|
|
return error.raw();
|
|
|
|
}
|
2011-10-05 05:20:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Now Call the invoke stub which will invoke the dart function.
|
|
|
|
invokestub entrypoint = reinterpret_cast<invokestub>(
|
|
|
|
StubCode::InvokeDartCodeEntryPoint());
|
|
|
|
const Context& context =
|
|
|
|
Context::ZoneHandle(Isolate::Current()->object_store()->empty_context());
|
|
|
|
ASSERT(context.isolate() == Isolate::Current());
|
2012-02-28 01:31:44 +00:00
|
|
|
const Code& code = Code::Handle(function.CurrentCode());
|
|
|
|
ASSERT(!code.IsNull());
|
2012-12-19 21:26:29 +00:00
|
|
|
return entrypoint(code.EntryPoint(),
|
|
|
|
arguments_descriptor,
|
|
|
|
arguments,
|
|
|
|
context);
|
2012-12-18 21:36:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RawObject* DartEntry::InvokeStatic(const Function& function,
|
|
|
|
const Array& arguments) {
|
2012-12-19 21:26:29 +00:00
|
|
|
const Array& arguments_descriptor =
|
2012-12-18 21:36:01 +00:00
|
|
|
Array::Handle(ArgumentsDescriptor::New(arguments.Length()));
|
2012-12-19 21:26:29 +00:00
|
|
|
return InvokeStatic(function, arguments, arguments_descriptor);
|
2011-10-05 05:20:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-18 21:36:01 +00:00
|
|
|
RawObject* DartEntry::InvokeStatic(const Function& function,
|
|
|
|
const Array& arguments,
|
2012-12-19 21:26:29 +00:00
|
|
|
const Array& arguments_descriptor) {
|
2011-10-05 05:20:07 +00:00
|
|
|
// Get the entrypoint corresponding to the function specified, this
|
|
|
|
// will result in a compilation of the function if it is not already
|
|
|
|
// compiled.
|
|
|
|
ASSERT(!function.IsNull());
|
|
|
|
if (!function.HasCode()) {
|
2012-02-02 19:05:06 +00:00
|
|
|
const Error& error = Error::Handle(Compiler::CompileFunction(function));
|
|
|
|
if (!error.IsNull()) {
|
|
|
|
return error.raw();
|
|
|
|
}
|
2011-10-05 05:20:07 +00:00
|
|
|
}
|
|
|
|
// Now Call the invoke stub which will invoke the dart function.
|
|
|
|
invokestub entrypoint = reinterpret_cast<invokestub>(
|
|
|
|
StubCode::InvokeDartCodeEntryPoint());
|
|
|
|
const Context& context =
|
|
|
|
Context::ZoneHandle(Isolate::Current()->object_store()->empty_context());
|
|
|
|
ASSERT(context.isolate() == Isolate::Current());
|
2012-02-28 01:31:44 +00:00
|
|
|
const Code& code = Code::Handle(function.CurrentCode());
|
|
|
|
ASSERT(!code.IsNull());
|
2012-12-19 21:26:29 +00:00
|
|
|
return entrypoint(code.EntryPoint(),
|
|
|
|
arguments_descriptor,
|
|
|
|
arguments,
|
|
|
|
context);
|
2012-12-18 21:36:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RawObject* DartEntry::InvokeClosure(const Instance& closure,
|
|
|
|
const Array& arguments) {
|
2012-12-19 21:26:29 +00:00
|
|
|
const Array& arguments_descriptor =
|
2012-12-18 21:36:01 +00:00
|
|
|
Array::Handle(ArgumentsDescriptor::New(arguments.Length()));
|
2012-12-19 21:26:29 +00:00
|
|
|
return InvokeClosure(closure, arguments, arguments_descriptor);
|
2011-10-05 05:20:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-18 21:36:01 +00:00
|
|
|
RawObject* DartEntry::InvokeClosure(const Instance& instance,
|
|
|
|
const Array& arguments,
|
2012-12-19 21:26:29 +00:00
|
|
|
const Array& arguments_descriptor) {
|
2012-12-18 21:36:01 +00:00
|
|
|
ASSERT(instance.raw() == arguments.At(0));
|
2012-12-14 19:04:01 +00:00
|
|
|
// 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();
|
2012-12-19 21:26:29 +00:00
|
|
|
if (instance.IsCallable(&function, &context)) {
|
|
|
|
// Only invoke the function if its arguments are compatible.
|
|
|
|
const ArgumentsDescriptor args_desc(arguments_descriptor);
|
|
|
|
if (function.AreValidArgumentCounts(args_desc.Count(),
|
|
|
|
args_desc.NamedCount(),
|
|
|
|
NULL)) {
|
|
|
|
if (!function.HasCode()) {
|
|
|
|
const Error& error = Error::Handle(Compiler::CompileFunction(function));
|
|
|
|
if (!error.IsNull()) {
|
|
|
|
return error.raw();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Now call the invoke stub which will invoke the closure function or
|
|
|
|
// 'call' function.
|
|
|
|
// The closure or non-closure object (receiver) is passed as implicit
|
|
|
|
// first argument. It is already included in the arguments array.
|
|
|
|
invokestub entrypoint = reinterpret_cast<invokestub>(
|
|
|
|
StubCode::InvokeDartCodeEntryPoint());
|
|
|
|
ASSERT(context.isolate() == Isolate::Current());
|
|
|
|
const Code& code = Code::Handle(function.CurrentCode());
|
|
|
|
ASSERT(!code.IsNull());
|
|
|
|
return entrypoint(code.EntryPoint(),
|
|
|
|
arguments_descriptor,
|
|
|
|
arguments,
|
|
|
|
context);
|
2012-02-02 19:05:06 +00:00
|
|
|
}
|
2011-10-05 05:20:07 +00:00
|
|
|
}
|
2012-12-19 21:26:29 +00:00
|
|
|
// There is no compatible 'call' method, so invoke noSuchMethod.
|
|
|
|
return InvokeNoSuchMethod(instance,
|
|
|
|
String::Handle(Symbols::Call()),
|
|
|
|
arguments,
|
|
|
|
arguments_descriptor);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RawObject* DartEntry::InvokeNoSuchMethod(const Instance& receiver,
|
|
|
|
const String& target_name,
|
|
|
|
const Array& arguments,
|
|
|
|
const Array& arguments_descriptor) {
|
|
|
|
ASSERT(receiver.raw() == arguments.At(0));
|
|
|
|
// Allocate an InvocationMirror object.
|
|
|
|
const Library& core_lib = Library::Handle(Library::CoreLibrary());
|
|
|
|
const String& invocation_mirror_name =
|
|
|
|
String::Handle(Symbols::InvocationMirror());
|
|
|
|
Class& invocation_mirror_class =
|
|
|
|
Class::Handle(core_lib.LookupClassAllowPrivate(invocation_mirror_name));
|
|
|
|
ASSERT(!invocation_mirror_class.IsNull());
|
|
|
|
const String& allocation_function_name =
|
|
|
|
String::Handle(Symbols::AllocateInvocationMirror());
|
|
|
|
const Function& allocation_function = Function::Handle(
|
|
|
|
Resolver::ResolveStaticByName(invocation_mirror_class,
|
|
|
|
allocation_function_name,
|
|
|
|
Resolver::kIsQualified));
|
|
|
|
ASSERT(!allocation_function.IsNull());
|
|
|
|
const int kNumAllocationArgs = 3;
|
|
|
|
const Array& allocation_args = Array::Handle(Array::New(kNumAllocationArgs));
|
|
|
|
allocation_args.SetAt(0, target_name);
|
|
|
|
allocation_args.SetAt(1, arguments_descriptor);
|
|
|
|
allocation_args.SetAt(2, arguments);
|
|
|
|
const Object& invocation_mirror = Object::Handle(
|
|
|
|
InvokeStatic(allocation_function, allocation_args));
|
|
|
|
|
|
|
|
// Now use the invocation mirror object and invoke NoSuchMethod.
|
|
|
|
const String& function_name = String::Handle(Symbols::NoSuchMethod());
|
|
|
|
const int kNumArguments = 2;
|
|
|
|
const int kNumNamedArguments = 0;
|
|
|
|
const Function& function = Function::Handle(
|
|
|
|
Resolver::ResolveDynamic(receiver,
|
|
|
|
function_name,
|
|
|
|
kNumArguments,
|
|
|
|
kNumNamedArguments));
|
|
|
|
ASSERT(!function.IsNull());
|
|
|
|
const Array& args = Array::Handle(Array::New(kNumArguments));
|
|
|
|
args.SetAt(0, receiver);
|
|
|
|
args.SetAt(1, invocation_mirror);
|
|
|
|
return InvokeDynamic(function, args);
|
2011-10-05 05:20:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-05 19:50:50 +00:00
|
|
|
ArgumentsDescriptor::ArgumentsDescriptor(const Array& array)
|
|
|
|
: array_(array) {
|
2012-12-05 12:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
intptr_t ArgumentsDescriptor::Count() const {
|
|
|
|
return Smi::CheckedHandle(array_.At(kCountIndex)).Value();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
intptr_t ArgumentsDescriptor::PositionalCount() const {
|
|
|
|
return Smi::CheckedHandle(array_.At(kPositionalCountIndex)).Value();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-07 17:59:53 +00:00
|
|
|
bool ArgumentsDescriptor::MatchesNameAt(intptr_t index,
|
|
|
|
const String& other) const {
|
|
|
|
const intptr_t offset = kFirstNamedEntryIndex +
|
|
|
|
(index * kNamedEntrySize) +
|
|
|
|
kNameOffset;
|
|
|
|
return array_.At(offset) == other.raw();
|
2012-12-05 12:05:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
intptr_t ArgumentsDescriptor::count_offset() {
|
|
|
|
return Array::data_offset() + (kCountIndex * kWordSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
intptr_t ArgumentsDescriptor::positional_count_offset() {
|
|
|
|
return Array::data_offset() + (kPositionalCountIndex * kWordSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
intptr_t ArgumentsDescriptor::first_named_entry_offset() {
|
|
|
|
return Array::data_offset() + (kFirstNamedEntryIndex * kWordSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RawArray* ArgumentsDescriptor::New(intptr_t num_arguments,
|
|
|
|
const Array& optional_arguments_names) {
|
2012-06-26 17:43:44 +00:00
|
|
|
const intptr_t num_named_args =
|
|
|
|
optional_arguments_names.IsNull() ? 0 : optional_arguments_names.Length();
|
|
|
|
const intptr_t num_pos_args = num_arguments - num_named_args;
|
|
|
|
|
2012-12-05 12:05:57 +00:00
|
|
|
// Build the arguments descriptor array, which consists of the total
|
|
|
|
// argument count; the positional argument count; a sequence of (name,
|
|
|
|
// position) pairs, sorted by name, for each named optional argument; and
|
|
|
|
// a terminating null to simplify iterating in generated code.
|
|
|
|
const intptr_t descriptor_len = LengthFor(num_named_args);
|
|
|
|
Array& descriptor = Array::Handle(Array::New(descriptor_len, Heap::kOld));
|
2012-06-26 17:43:44 +00:00
|
|
|
|
|
|
|
// Set total number of passed arguments.
|
2012-12-05 12:05:57 +00:00
|
|
|
descriptor.SetAt(kCountIndex, Smi::Handle(Smi::New(num_arguments)));
|
2012-06-26 17:43:44 +00:00
|
|
|
// Set number of positional arguments.
|
2012-12-05 12:05:57 +00:00
|
|
|
descriptor.SetAt(kPositionalCountIndex, Smi::Handle(Smi::New(num_pos_args)));
|
|
|
|
// Set alphabetically sorted entries for named arguments.
|
2012-06-26 17:43:44 +00:00
|
|
|
String& name = String::Handle();
|
|
|
|
Smi& pos = Smi::Handle();
|
2012-12-05 12:05:57 +00:00
|
|
|
for (intptr_t i = 0; i < num_named_args; i++) {
|
2012-06-26 17:43:44 +00:00
|
|
|
name ^= optional_arguments_names.At(i);
|
|
|
|
pos = Smi::New(num_pos_args + i);
|
2012-12-05 12:05:57 +00:00
|
|
|
intptr_t insert_index = kFirstNamedEntryIndex + (kNamedEntrySize * i);
|
2012-06-26 17:43:44 +00:00
|
|
|
// Shift already inserted pairs with "larger" names.
|
2012-12-05 12:05:57 +00:00
|
|
|
String& previous_name = String::Handle();
|
|
|
|
Smi& previous_pos = Smi::Handle();
|
|
|
|
while (insert_index > kFirstNamedEntryIndex) {
|
|
|
|
intptr_t previous_index = insert_index - kNamedEntrySize;
|
|
|
|
previous_name ^= descriptor.At(previous_index + kNameOffset);
|
|
|
|
intptr_t result = name.CompareTo(previous_name);
|
2012-06-26 17:43:44 +00:00
|
|
|
ASSERT(result != 0); // Duplicate argument names checked in parser.
|
|
|
|
if (result > 0) break;
|
2012-12-05 12:05:57 +00:00
|
|
|
previous_pos ^= descriptor.At(previous_index + kPositionOffset);
|
|
|
|
descriptor.SetAt(insert_index + kNameOffset, previous_name);
|
|
|
|
descriptor.SetAt(insert_index + kPositionOffset, previous_pos);
|
|
|
|
insert_index = previous_index;
|
2012-06-26 17:43:44 +00:00
|
|
|
}
|
|
|
|
// Insert pair in descriptor array.
|
2012-12-05 12:05:57 +00:00
|
|
|
descriptor.SetAt(insert_index + kNameOffset, name);
|
|
|
|
descriptor.SetAt(insert_index + kPositionOffset, pos);
|
2012-06-26 17:43:44 +00:00
|
|
|
}
|
|
|
|
// Set terminating null.
|
|
|
|
descriptor.SetAt(descriptor_len - 1, Object::Handle());
|
|
|
|
|
|
|
|
// Share the immutable descriptor when possible by canonicalizing it.
|
|
|
|
descriptor.MakeImmutable();
|
|
|
|
descriptor ^= descriptor.Canonicalize();
|
2012-12-05 12:05:57 +00:00
|
|
|
return descriptor.raw();
|
2012-06-26 17:43:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-18 21:36:01 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-12-18 23:47:35 +00:00
|
|
|
RawObject* DartLibraryCalls::ExceptionCreate(const Library& lib,
|
|
|
|
const String& class_name,
|
|
|
|
const Array& arguments) {
|
2012-10-24 06:17:21 +00:00
|
|
|
const Class& cls = Class::Handle(lib.LookupClassAllowPrivate(class_name));
|
2011-10-05 05:20:07 +00:00
|
|
|
ASSERT(!cls.IsNull());
|
|
|
|
// For now, we only support a non-parameterized or raw type.
|
2012-12-18 21:36:01 +00:00
|
|
|
const int kNumExtraArgs = 2; // implicit rcvr and construction phase args.
|
2011-10-05 05:20:07 +00:00
|
|
|
const Instance& exception_object = Instance::Handle(Instance::New(cls));
|
2012-12-18 21:36:01 +00:00
|
|
|
const Array& constructor_arguments =
|
2012-12-18 23:47:35 +00:00
|
|
|
Array::Handle(Array::New(arguments.Length() + kNumExtraArgs));
|
2012-12-18 21:36:01 +00:00
|
|
|
constructor_arguments.SetAt(0, exception_object);
|
|
|
|
constructor_arguments.SetAt(
|
|
|
|
1, Smi::Handle(Smi::New(Function::kCtorPhaseAll)));
|
2012-12-18 23:47:35 +00:00
|
|
|
Object& obj = Object::Handle();
|
|
|
|
for (intptr_t i = 0; i < arguments.Length(); i++) {
|
|
|
|
obj = arguments.At(i);
|
|
|
|
constructor_arguments.SetAt((i + kNumExtraArgs), obj);
|
2012-12-18 21:36:01 +00:00
|
|
|
}
|
2011-10-05 05:20:07 +00:00
|
|
|
|
2012-12-10 18:24:34 +00:00
|
|
|
String& constructor_name = String::Handle(
|
|
|
|
String::Concat(class_name, Symbols::DotHandle()));
|
2011-10-05 05:20:07 +00:00
|
|
|
Function& constructor =
|
|
|
|
Function::Handle(cls.LookupConstructor(constructor_name));
|
|
|
|
ASSERT(!constructor.IsNull());
|
2012-12-18 21:36:01 +00:00
|
|
|
const Object& retval =
|
|
|
|
Object::Handle(DartEntry::InvokeStatic(constructor, constructor_arguments));
|
2012-02-02 19:05:06 +00:00
|
|
|
ASSERT(retval.IsNull() || retval.IsError());
|
|
|
|
if (retval.IsError()) {
|
|
|
|
return retval.raw();
|
|
|
|
}
|
2011-10-05 05:20:07 +00:00
|
|
|
return exception_object.raw();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-02 19:05:06 +00:00
|
|
|
RawObject* DartLibraryCalls::ToString(const Instance& receiver) {
|
2011-10-05 05:20:07 +00:00
|
|
|
const String& function_name =
|
2012-07-24 00:01:50 +00:00
|
|
|
String::Handle(Symbols::New("toString"));
|
2011-10-05 05:20:07 +00:00
|
|
|
const int kNumArguments = 1; // Receiver.
|
|
|
|
const int kNumNamedArguments = 0; // None.
|
|
|
|
const Function& function = Function::Handle(
|
|
|
|
Resolver::ResolveDynamic(receiver,
|
|
|
|
function_name,
|
|
|
|
kNumArguments,
|
|
|
|
kNumNamedArguments));
|
|
|
|
ASSERT(!function.IsNull());
|
2012-12-18 21:36:01 +00:00
|
|
|
const Array& args = Array::Handle(Array::New(kNumArguments));
|
|
|
|
args.SetAt(0, receiver);
|
|
|
|
const Object& result = Object::Handle(DartEntry::InvokeDynamic(function,
|
|
|
|
args));
|
2012-02-02 19:05:06 +00:00
|
|
|
ASSERT(result.IsInstance() || result.IsError());
|
2011-10-05 05:20:07 +00:00
|
|
|
return result.raw();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-02-02 19:05:06 +00:00
|
|
|
RawObject* DartLibraryCalls::Equals(const Instance& left,
|
|
|
|
const Instance& right) {
|
2011-10-05 05:20:07 +00:00
|
|
|
const int kNumArguments = 2;
|
|
|
|
const int kNumNamedArguments = 0;
|
|
|
|
const Function& function = Function::Handle(
|
|
|
|
Resolver::ResolveDynamic(left,
|
2012-12-11 01:20:02 +00:00
|
|
|
Symbols::EqualOperatorHandle(),
|
2011-10-05 05:20:07 +00:00
|
|
|
kNumArguments,
|
|
|
|
kNumNamedArguments));
|
|
|
|
ASSERT(!function.IsNull());
|
2012-12-18 21:36:01 +00:00
|
|
|
|
|
|
|
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));
|
2012-02-02 19:05:06 +00:00
|
|
|
ASSERT(result.IsInstance() || result.IsError());
|
2011-10-05 05:20:07 +00:00
|
|
|
return result.raw();
|
|
|
|
}
|
|
|
|
|
2011-12-14 18:27:58 +00:00
|
|
|
|
|
|
|
RawObject* DartLibraryCalls::HandleMessage(Dart_Port dest_port_id,
|
|
|
|
Dart_Port reply_port_id,
|
|
|
|
const Instance& message) {
|
2012-02-27 22:50:44 +00:00
|
|
|
Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
|
|
|
|
ASSERT(!isolate_lib.IsNull());
|
2012-03-07 21:15:58 +00:00
|
|
|
const String& public_class_name =
|
2012-07-24 00:01:50 +00:00
|
|
|
String::Handle(Symbols::New("_ReceivePortImpl"));
|
2011-12-14 18:27:58 +00:00
|
|
|
const String& class_name =
|
2012-03-07 21:15:58 +00:00
|
|
|
String::Handle(isolate_lib.PrivateName(public_class_name));
|
2011-12-14 18:27:58 +00:00
|
|
|
const String& function_name =
|
2012-07-24 00:01:50 +00:00
|
|
|
String::Handle(Symbols::New("_handleMessage"));
|
2011-12-14 18:27:58 +00:00
|
|
|
const int kNumArguments = 3;
|
|
|
|
const Array& kNoArgumentNames = Array::Handle();
|
|
|
|
const Function& function = Function::Handle(
|
2012-02-27 22:50:44 +00:00
|
|
|
Resolver::ResolveStatic(isolate_lib,
|
2011-12-14 18:27:58 +00:00
|
|
|
class_name,
|
|
|
|
function_name,
|
|
|
|
kNumArguments,
|
|
|
|
kNoArgumentNames,
|
|
|
|
Resolver::kIsQualified));
|
2012-12-18 21:36:01 +00:00
|
|
|
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));
|
2012-02-02 19:05:06 +00:00
|
|
|
ASSERT(result.IsNull() || result.IsError());
|
2011-12-14 18:27:58 +00:00
|
|
|
return result.raw();
|
|
|
|
}
|
|
|
|
|
2012-03-12 23:51:03 +00:00
|
|
|
|
|
|
|
RawObject* DartLibraryCalls::NewSendPort(intptr_t port_id) {
|
|
|
|
Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
|
|
|
|
ASSERT(!isolate_lib.IsNull());
|
|
|
|
const String& public_class_name =
|
|
|
|
String::Handle(String::New("_SendPortImpl"));
|
|
|
|
const String& class_name =
|
|
|
|
String::Handle(isolate_lib.PrivateName(public_class_name));
|
2012-07-24 00:01:50 +00:00
|
|
|
const String& function_name = String::Handle(Symbols::New("_create"));
|
2012-03-12 23:51:03 +00:00
|
|
|
const int kNumArguments = 1;
|
|
|
|
const Array& kNoArgumentNames = Array::Handle();
|
|
|
|
const Function& function = Function::Handle(
|
|
|
|
Resolver::ResolveStatic(isolate_lib,
|
|
|
|
class_name,
|
|
|
|
function_name,
|
|
|
|
kNumArguments,
|
|
|
|
kNoArgumentNames,
|
|
|
|
Resolver::kIsQualified));
|
2012-12-18 21:36:01 +00:00
|
|
|
const Array& args = Array::Handle(Array::New(kNumArguments));
|
|
|
|
args.SetAt(0, Integer::Handle(Integer::New(port_id)));
|
|
|
|
return DartEntry::InvokeStatic(function, args);
|
2012-03-12 23:51:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RawObject* DartLibraryCalls::MapSetAt(const Instance& map,
|
|
|
|
const Instance& key,
|
|
|
|
const Instance& value) {
|
2012-12-01 00:34:19 +00:00
|
|
|
String& name = String::Handle(Symbols::AssignIndexToken());
|
2012-12-18 21:36:01 +00:00
|
|
|
const int kNumArguments = 3;
|
2012-03-12 23:51:03 +00:00
|
|
|
const Function& function = Function::Handle(
|
2012-12-18 21:36:01 +00:00
|
|
|
Resolver::ResolveDynamic(map, name, kNumArguments, 0));
|
2012-03-12 23:51:03 +00:00
|
|
|
ASSERT(!function.IsNull());
|
2012-12-18 21:36:01 +00:00
|
|
|
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));
|
2012-03-12 23:51:03 +00:00
|
|
|
return result.raw();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
RawObject* DartLibraryCalls::PortGetId(const Instance& port) {
|
2012-07-24 00:01:50 +00:00
|
|
|
const String& field_name = String::Handle(Symbols::New("_id"));
|
2012-03-12 23:51:03 +00:00
|
|
|
const Class& cls = Class::Handle(port.clazz());
|
|
|
|
const String& func_name = String::Handle(Field::GetterName(field_name));
|
|
|
|
const Function& func = Function::Handle(cls.LookupDynamicFunction(func_name));
|
|
|
|
ASSERT(!func.IsNull());
|
2012-12-18 21:36:01 +00:00
|
|
|
const Array& args = Array::Handle(Array::New(1));
|
|
|
|
args.SetAt(0, port);
|
|
|
|
return DartEntry::InvokeDynamic(func, args);
|
2012-03-12 23:51:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
} // namespace dart
|