Index: runtime/vm/isolate.cc |
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc |
index cf51a8c2419b83dbb4fe54d443773b9cc097ab7a..7be084e0787e0a3e4c560c29831436a4d09fc845 100644 |
--- a/runtime/vm/isolate.cc |
+++ b/runtime/vm/isolate.cc |
@@ -771,17 +771,28 @@ static bool RunIsolate(uword parameter) { |
func ^= result.raw(); |
func = func.ImplicitClosureFunction(); |
+ const Array& capabilities = Array::Handle(Array::New(2)); |
+ Capability& capability = Capability::Handle(); |
+ capability = Capability::New(isolate->pause_capability()); |
+ capabilities.SetAt(0, capability); |
+ capability = Capability::New(isolate->terminate_capability()); |
+ capabilities.SetAt(1, capability); |
+ |
// Instead of directly invoking the entry point we call '_startIsolate' with |
- // the entry point as argument. The '_startIsolate' function will |
- // communicate with the spawner to receive the initial message before it |
- // executes the real entry point. |
+ // the entry point as argument. |
// Since this function ("RunIsolate") is used for both Isolate.spawn and |
// Isolate.spawnUri we also send a boolean flag as argument so that the |
// "_startIsolate" function can act corresponding to how the isolate was |
// created. |
- const Array& args = Array::Handle(Array::New(2)); |
- args.SetAt(0, Instance::Handle(func.ImplicitStaticClosure())); |
- args.SetAt(1, is_spawn_uri ? Bool::True() : Bool::False()); |
+ const Array& args = Array::Handle(Array::New(7)); |
+ args.SetAt(0, SendPort::Handle(SendPort::New(state->parent_port()))); |
+ args.SetAt(1, Instance::Handle(func.ImplicitStaticClosure())); |
+ args.SetAt(2, Instance::Handle(state->BuildArgs())); |
+ args.SetAt(3, Instance::Handle(state->BuildMessage())); |
+ args.SetAt(4, is_spawn_uri ? Bool::True() : Bool::False()); |
+ args.SetAt(5, ReceivePort::Handle( |
+ ReceivePort::New(isolate->main_port(), true /* control port */))); |
+ args.SetAt(6, capabilities); |
const Library& lib = Library::Handle(Library::IsolateLibrary()); |
const String& entry_name = String::Handle(String::New("_startIsolate")); |
@@ -1109,7 +1120,6 @@ void Isolate::PrintJSON(JSONStream* stream, bool ref) { |
jsobj.AddProperty("depth", (intptr_t)0); |
} |
jsobj.AddProperty("livePorts", message_handler()->live_ports()); |
- jsobj.AddProperty("controlPorts", message_handler()->control_ports()); |
jsobj.AddProperty("pauseOnExit", message_handler()->pause_on_exit()); |
// TODO(turnidge): Make the debugger support paused_on_start/exit. |
@@ -1304,13 +1314,50 @@ T* Isolate::AllocateReusableHandle() { |
} |
-IsolateSpawnState::IsolateSpawnState(const Function& func) |
+static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { |
+ void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); |
+ return reinterpret_cast<uint8_t*>(new_ptr); |
+} |
+ |
+ |
+static void SerializeObject(const Instance& obj, |
+ uint8_t** obj_data, |
+ intptr_t* obj_len) { |
+ MessageWriter writer(obj_data, &allocator); |
+ writer.WriteMessage(obj); |
+ *obj_len = writer.BytesWritten(); |
+} |
+ |
+ |
+static RawInstance* DeserializeObject(Isolate* isolate, |
+ uint8_t* obj_data, |
+ intptr_t obj_len) { |
+ if (obj_data == NULL) { |
+ return Instance::null(); |
+ } |
+ SnapshotReader reader(obj_data, obj_len, Snapshot::kMessage, isolate); |
+ const Object& obj = Object::Handle(isolate, reader.ReadObject()); |
+ ASSERT(!obj.IsError()); |
+ Instance& instance = Instance::Handle(isolate); |
+ instance ^= obj.raw(); // Can't use Instance::Cast because may be null. |
+ return instance.raw(); |
+} |
+ |
+ |
+IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, |
+ const Function& func, |
+ const Instance& message) |
: isolate_(NULL), |
+ parent_port_(parent_port), |
script_url_(NULL), |
library_url_(NULL), |
class_name_(NULL), |
function_name_(NULL), |
- exception_callback_name_(NULL) { |
+ exception_callback_name_(NULL), |
+ serialized_args_(NULL), |
+ serialized_args_len_(0), |
+ serialized_message_(NULL), |
+ serialized_message_len_(0) { |
script_url_ = NULL; |
const Class& cls = Class::Handle(func.Owner()); |
const Library& lib = Library::Handle(cls.library()); |
@@ -1324,19 +1371,30 @@ IsolateSpawnState::IsolateSpawnState(const Function& func) |
class_name_ = strdup(class_name.ToCString()); |
} |
exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
+ SerializeObject(message, &serialized_message_, &serialized_message_len_); |
} |
-IsolateSpawnState::IsolateSpawnState(const char* script_url) |
+IsolateSpawnState::IsolateSpawnState(Dart_Port parent_port, |
+ const char* script_url, |
+ const Instance& args, |
+ const Instance& message) |
: isolate_(NULL), |
+ parent_port_(parent_port), |
library_url_(NULL), |
class_name_(NULL), |
function_name_(NULL), |
- exception_callback_name_(NULL) { |
+ exception_callback_name_(NULL), |
+ serialized_args_(NULL), |
+ serialized_args_len_(0), |
+ serialized_message_(NULL), |
+ serialized_message_len_(0) { |
script_url_ = strdup(script_url); |
library_url_ = NULL; |
function_name_ = strdup("main"); |
exception_callback_name_ = strdup("_unhandledExceptionCallback"); |
+ SerializeObject(args, &serialized_args_, &serialized_args_len_); |
+ SerializeObject(message, &serialized_message_, &serialized_message_len_); |
} |
@@ -1346,6 +1404,8 @@ IsolateSpawnState::~IsolateSpawnState() { |
free(function_name_); |
free(class_name_); |
free(exception_callback_name_); |
+ free(serialized_args_); |
+ free(serialized_message_); |
} |
@@ -1402,6 +1462,17 @@ RawObject* IsolateSpawnState::ResolveFunction() { |
} |
+RawInstance* IsolateSpawnState::BuildArgs() { |
+ return DeserializeObject(isolate_, serialized_args_, serialized_args_len_); |
+} |
+ |
+ |
+RawInstance* IsolateSpawnState::BuildMessage() { |
+ return DeserializeObject(isolate_, |
+ serialized_message_, serialized_message_len_); |
+} |
+ |
+ |
void IsolateSpawnState::Cleanup() { |
SwitchIsolateScope switch_scope(I); |
Dart::ShutdownIsolate(); |