| Index: runtime/vm/kernel_isolate.cc
|
| diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
|
| index 8d682ab2cd786aa1a299925801b3a6d94dce674e..a4af37fa4bdc33c1a8146ae0087bbd4eb3cc8511 100644
|
| --- a/runtime/vm/kernel_isolate.cc
|
| +++ b/runtime/vm/kernel_isolate.cc
|
| @@ -5,6 +5,7 @@
|
| #include "vm/kernel_isolate.h"
|
|
|
| #include "vm/compiler.h"
|
| +#include "include/dart_native_api.h"
|
| #include "vm/dart_api_impl.h"
|
| #include "vm/dart_entry.h"
|
| #include "vm/isolate.h"
|
| @@ -33,7 +34,7 @@ DEFINE_FLAG(bool,
|
| false,
|
| "Parse scripts with Dart-to-Kernel parser");
|
|
|
| -const char* KernelIsolate::kName = "kernel-service";
|
| +const char* KernelIsolate::kName = DART_KERNEL_ISOLATE_NAME;
|
| Dart_IsolateCreateCallback KernelIsolate::create_callback_ = NULL;
|
| Monitor* KernelIsolate::monitor_ = new Monitor();
|
| Isolate* KernelIsolate::isolate_ = NULL;
|
| @@ -74,7 +75,8 @@ class RunKernelTask : public ThreadPool::Task {
|
| KernelIsolate::kName, NULL, NULL, NULL, &api_flags, NULL, &error));
|
| if (isolate == NULL) {
|
| if (FLAG_trace_kernel) {
|
| - OS::PrintErr("kernel-service: Isolate creation error: %s\n", error);
|
| + OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Isolate creation error: %s\n",
|
| + error);
|
| }
|
| KernelIsolate::SetKernelIsolate(NULL);
|
| KernelIsolate::FinishedInitializing();
|
| @@ -104,7 +106,7 @@ class RunKernelTask : public ThreadPool::Task {
|
| protected:
|
| static void ShutdownIsolate(uword parameter) {
|
| if (FLAG_trace_kernel) {
|
| - OS::Print("kernel-service: ShutdownIsolate\n");
|
| + OS::Print(DART_KERNEL_ISOLATE_NAME ": ShutdownIsolate\n");
|
| }
|
| Isolate* I = reinterpret_cast<Isolate*>(parameter);
|
| ASSERT(KernelIsolate::IsKernelIsolate(I));
|
| @@ -123,18 +125,20 @@ class RunKernelTask : public ThreadPool::Task {
|
| Error& error = Error::Handle(Z);
|
| error = T->sticky_error();
|
| if (!error.IsNull() && !error.IsUnwindError()) {
|
| - OS::PrintErr("kernel-service: Error: %s\n", error.ToErrorCString());
|
| + OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Error: %s\n",
|
| + error.ToErrorCString());
|
| }
|
| error = I->sticky_error();
|
| if (!error.IsNull() && !error.IsUnwindError()) {
|
| - OS::PrintErr("kernel-service: Error: %s\n", error.ToErrorCString());
|
| + OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Error: %s\n",
|
| + error.ToErrorCString());
|
| }
|
| Dart::RunShutdownCallback();
|
| }
|
| // Shut the isolate down.
|
| Dart::ShutdownIsolate(I);
|
| if (FLAG_trace_kernel) {
|
| - OS::Print("kernel-service: Shutdown.\n");
|
| + OS::Print(DART_KERNEL_ISOLATE_NAME ": Shutdown.\n");
|
| }
|
| }
|
|
|
| @@ -148,7 +152,8 @@ class RunKernelTask : public ThreadPool::Task {
|
| Library::Handle(Z, I->object_store()->root_library());
|
| if (root_library.IsNull()) {
|
| if (FLAG_trace_kernel) {
|
| - OS::Print("kernel-service: Embedder did not install a script.");
|
| + OS::Print(DART_KERNEL_ISOLATE_NAME
|
| + ": Embedder did not install a script.");
|
| }
|
| // Kernel isolate is not supported by embedder.
|
| return false;
|
| @@ -161,7 +166,8 @@ class RunKernelTask : public ThreadPool::Task {
|
| if (entry.IsNull()) {
|
| // Kernel isolate is not supported by embedder.
|
| if (FLAG_trace_kernel) {
|
| - OS::Print("kernel-service: Embedder did not provide a main function.");
|
| + OS::Print(DART_KERNEL_ISOLATE_NAME
|
| + ": Embedder did not provide a main function.");
|
| }
|
| return false;
|
| }
|
| @@ -173,7 +179,8 @@ class RunKernelTask : public ThreadPool::Task {
|
| // Kernel isolate did not initialize properly.
|
| if (FLAG_trace_kernel) {
|
| const Error& error = Error::Cast(result);
|
| - OS::Print("kernel-service: Calling main resulted in an error: %s",
|
| + OS::Print(DART_KERNEL_ISOLATE_NAME
|
| + ": Calling main resulted in an error: %s",
|
| error.ToErrorCString());
|
| }
|
| return false;
|
| @@ -203,13 +210,13 @@ void KernelIsolate::InitCallback(Isolate* I) {
|
| ASSERT(I != NULL);
|
| ASSERT(I->name() != NULL);
|
| if (!FLAG_use_dart_frontend ||
|
| - (strstr(I->name(), "kernel-service") == NULL)) {
|
| + (strstr(I->name(), DART_KERNEL_ISOLATE_NAME) == NULL)) {
|
| // Not kernel isolate.
|
| return;
|
| }
|
| ASSERT(!Exists());
|
| if (FLAG_trace_kernel) {
|
| - OS::Print("kernel-service: InitCallback for %s.\n", I->name());
|
| + OS::Print(DART_KERNEL_ISOLATE_NAME ": InitCallback for %s.\n", I->name());
|
| }
|
| SetKernelIsolate(I);
|
| }
|
| @@ -238,11 +245,13 @@ void KernelIsolate::SetKernelIsolate(Isolate* isolate) {
|
| isolate_ = isolate;
|
| }
|
|
|
| +
|
| void KernelIsolate::SetLoadPort(Dart_Port port) {
|
| MonitorLocker ml(monitor_);
|
| kernel_port_ = port;
|
| }
|
|
|
| +
|
| void KernelIsolate::FinishedInitializing() {
|
| MonitorLocker ml(monitor_);
|
| initializing_ = false;
|
| @@ -261,6 +270,130 @@ Dart_Port KernelIsolate::WaitForKernelPort() {
|
| return kernel_port_;
|
| }
|
|
|
| +
|
| +class KernelCompilationRequest : public ValueObject {
|
| + public:
|
| + KernelCompilationRequest()
|
| + : monitor_(new Monitor()),
|
| + port_(Dart_NewNativePort("kernel-compilation-port",
|
| + &HandleResponse,
|
| + false,
|
| + this)) {
|
| + result_.status = Dart_KernelCompilationStatus_Unknown;
|
| + result_.error = NULL;
|
| + result_.kernel = NULL;
|
| + result_.kernel_size = 0;
|
| + }
|
| +
|
| + ~KernelCompilationRequest() {
|
| + Dart_CloseNativePort(port_);
|
| + delete monitor_;
|
| + }
|
| +
|
| + Dart_KernelCompilationResult SendAndWaitForResponse(Dart_Port kernel_port,
|
| + const char* script_uri) {
|
| + // Build the [null, send_port, script_uri] message for the Kernel isolate:
|
| + // null tag tells it that request came from this code, instead of Loader
|
| + // so that it can given a more informative response.
|
| + Dart_CObject tag;
|
| + tag.type = Dart_CObject_kNull;
|
| +
|
| + Dart_CObject send_port;
|
| + send_port.type = Dart_CObject_kSendPort;
|
| + send_port.value.as_send_port.id = port_;
|
| + send_port.value.as_send_port.origin_id = ILLEGAL_PORT;
|
| +
|
| + Dart_CObject uri;
|
| + uri.type = Dart_CObject_kString;
|
| + uri.value.as_string = const_cast<char*>(script_uri);
|
| +
|
| + static const intptr_t kMessageLen = 3;
|
| + Dart_CObject* message_arr[kMessageLen] = {&tag, &send_port, &uri};
|
| +
|
| + Dart_CObject message;
|
| + message.type = Dart_CObject_kArray;
|
| + message.value.as_array.length = kMessageLen;
|
| + message.value.as_array.values = message_arr;
|
| +
|
| + // Send the message.
|
| + Dart_PostCObject(kernel_port, &message);
|
| +
|
| + // Wait for reply to arrive.
|
| + MonitorLocker ml(monitor_);
|
| + while (result_.status == Dart_KernelCompilationStatus_Unknown) {
|
| + ml.Wait();
|
| + }
|
| +
|
| + return result_;
|
| + }
|
| +
|
| + private:
|
| + // Possible responses from the Kernel isolate:
|
| + //
|
| + // [Ok, Uint8List KernelBinary]
|
| + // [Error, String error]
|
| + // [Crash, String error]
|
| + //
|
| + void HandleResponseImpl(Dart_CObject* message) {
|
| + ASSERT(message->type == Dart_CObject_kArray);
|
| + ASSERT(message->value.as_array.length >= 1);
|
| +
|
| + Dart_CObject** response = message->value.as_array.values;
|
| +
|
| + MonitorLocker ml(monitor_);
|
| +
|
| + ASSERT(response[0]->type == Dart_CObject_kInt32);
|
| + result_.status = static_cast<Dart_KernelCompilationStatus>(
|
| + message->value.as_array.values[0]->value.as_int32);
|
| +
|
| + if (result_.status == Dart_KernelCompilationStatus_Ok) {
|
| + ASSERT(response[1]->type == Dart_CObject_kTypedData);
|
| + ASSERT(response[1]->value.as_typed_data.type == Dart_TypedData_kUint8);
|
| +
|
| + result_.kernel_size = response[1]->value.as_typed_data.length;
|
| + result_.kernel = static_cast<uint8_t*>(malloc(result_.kernel_size));
|
| + memmove(result_.kernel, response[1]->value.as_typed_data.values,
|
| + result_.kernel_size);
|
| + } else {
|
| + ASSERT(result_.status == Dart_KernelCompilationStatus_Crash ||
|
| + result_.status == Dart_KernelCompilationStatus_Error);
|
| + // This is an error.
|
| + ASSERT(response[1]->type == Dart_CObject_kString);
|
| + result_.error = strdup(response[1]->value.as_string);
|
| + }
|
| + ml.Notify();
|
| + }
|
| +
|
| + static void HandleResponse(Dart_Port dest_port_id,
|
| + Dart_CObject* message,
|
| + void* peer) {
|
| + static_cast<KernelCompilationRequest*>(peer)->HandleResponseImpl(message);
|
| + }
|
| +
|
| + Monitor* monitor_;
|
| + Dart_Port port_;
|
| +
|
| + Dart_KernelCompilationResult result_;
|
| +};
|
| +
|
| +
|
| +Dart_KernelCompilationResult KernelIsolate::CompileToKernel(
|
| + const char* script_uri) {
|
| + // This must be the main script to be loaded. Wait for Kernel isolate
|
| + // to finish initialization.
|
| + Dart_Port kernel_port = WaitForKernelPort();
|
| + if (kernel_port == ILLEGAL_PORT) {
|
| + Dart_KernelCompilationResult result;
|
| + result.status = Dart_KernelCompilationStatus_Unknown;
|
| + result.error = strdup("Error while initializing Kernel isolate");
|
| + return result;
|
| + }
|
| +
|
| + KernelCompilationRequest request;
|
| + return request.SendAndWaitForResponse(kernel_port, script_uri);
|
| +}
|
| +
|
| +
|
| #endif // DART_PRECOMPILED_RUNTIME
|
|
|
| } // namespace dart
|
|
|