Index: runtime/bin/vmservice_impl.cc |
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc |
index c31544ad318dde99b8ea7114c92cdd7df93f488a..fba6a98763505fa35a48645980e7e65b862cbf73 100644 |
--- a/runtime/bin/vmservice_impl.cc |
+++ b/runtime/bin/vmservice_impl.cc |
@@ -8,10 +8,19 @@ |
#include "bin/builtin.h" |
#include "bin/dartutils.h" |
+#include "bin/isolate_data.h" |
#include "bin/resources.h" |
#include "bin/thread.h" |
-#include "bin/isolate_data.h" |
+#include "vm/dart_api_impl.h" |
+#include "vm/dart_entry.h" |
+#include "vm/isolate.h" |
+#include "vm/message.h" |
+#include "vm/native_entry.h" |
+#include "vm/native_arguments.h" |
+#include "vm/object.h" |
+#include "vm/port.h" |
+#include "vm/snapshot.h" |
namespace dart { |
namespace bin { |
@@ -36,6 +45,14 @@ extern const uint8_t* snapshot_buffer; |
static const char* kLibraryScriptResourceName = |
kLibraryResourceNamePrefix "/vmservice.dart"; |
static const char* kLibrarySourceResourceNames[] = { |
+ kLibraryResourceNamePrefix "/constants.dart", |
+ kLibraryResourceNamePrefix "/resources.dart", |
+ kLibraryResourceNamePrefix "/running_isolate.dart", |
+ kLibraryResourceNamePrefix "/running_isolates.dart", |
+ kLibraryResourceNamePrefix "/server.dart", |
+ kLibraryResourceNamePrefix "/service_request.dart", |
+ kLibraryResourceNamePrefix "/service_request_router.dart", |
+ kLibraryResourceNamePrefix "/vmservice_io.dart", |
NULL |
}; |
@@ -51,6 +68,10 @@ const char* VmService::error_msg_ = NULL; |
#define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2 |
+static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name, |
+ int num_arguments); |
+ |
+ |
bool VmService::Start(intptr_t server_port) { |
monitor_ = new dart::Monitor(); |
ASSERT(monitor_ != NULL); |
@@ -129,7 +150,13 @@ bool VmService::_Start(intptr_t server_port) { |
Dart_EnterIsolate(isolate_); |
Dart_EnterScope(); |
+ |
Dart_Handle library = Dart_RootLibrary(); |
+ // Set requested port. |
+ DartUtils::SetIntegerField(library, "_port", server_port); |
+ // Install native resolver. |
+ result = Dart_SetNativeResolver(library, VmServiceNativeResolver); |
+ SHUTDOWN_ON_ERROR(result); |
result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL); |
SHUTDOWN_ON_ERROR(result); |
@@ -284,7 +311,7 @@ void VmService::ThreadMain(uword parameters) { |
// Keep handling messages until the last active receive port is closed. |
Dart_Handle result = Dart_RunLoop(); |
if (Dart_IsError(result)) { |
- printf("VmService error %s\n", Dart_GetError(result)); |
+ printf("VmService has exited with an error:\n%s\n", Dart_GetError(result)); |
} |
_Stop(); |
@@ -294,8 +321,6 @@ void VmService::ThreadMain(uword parameters) { |
} |
- |
- |
static Dart_Handle MakeServiceControlMessage(Dart_Port port) { |
Dart_Handle list = Dart_NewList(2); |
ASSERT(!Dart_IsError(list)); |
@@ -334,5 +359,93 @@ bool VmService::SendIsolateShutdownMessage(Dart_Port port) { |
} |
+void VmService::VmServiceShutdownCallback(void* callback_data) { |
+ ASSERT(Dart_CurrentIsolate() != NULL); |
+ Dart_EnterScope(); |
+ VmService::SendIsolateShutdownMessage(Dart_GetMainPortId()); |
+ Dart_ExitScope(); |
+} |
+ |
+ |
+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 SendServiceMessage(Dart_NativeArguments args) { |
+ NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
+ Isolate* isolate = arguments->isolate(); |
+ StackZone zone(isolate); |
+ HANDLESCOPE(isolate); |
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, sp, arguments->NativeArgAt(0)); |
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, rp, arguments->NativeArgAt(1)); |
+ GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(2)); |
+ |
+ // Extract SendPort port id. |
+ const Object& sp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(sp)); |
+ if (sp_id_obj.IsError()) { |
+ Exceptions::PropagateError(Error::Cast(sp_id_obj)); |
+ } |
+ Integer& id = Integer::Handle(); |
+ id ^= sp_id_obj.raw(); |
+ Dart_Port sp_id = static_cast<Dart_Port>(id.AsInt64Value()); |
+ |
+ // Extract ReceivePort port id. |
+ const Object& rp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(rp)); |
+ if (rp_id_obj.IsError()) { |
+ Exceptions::PropagateError(Error::Cast(rp_id_obj)); |
+ } |
+ ASSERT(rp_id_obj.IsSmi() || rp_id_obj.IsMint()); |
+ id ^= rp_id_obj.raw(); |
+ Dart_Port rp_id = static_cast<Dart_Port>(id.AsInt64Value()); |
+ |
+ // Both are valid ports. |
+ ASSERT(sp_id != ILLEGAL_PORT); |
+ ASSERT(rp_id != ILLEGAL_PORT); |
+ |
+ // Serialize message. |
+ uint8_t* data = NULL; |
+ MessageWriter writer(&data, &allocator); |
+ writer.WriteMessage(message); |
+ |
+ // TODO(turnidge): Throw an exception when the return value is false? |
+ PortMap::PostMessage(new Message(sp_id, rp_id, data, writer.BytesWritten(), |
+ Message::kOOBPriority)); |
+} |
+ |
+ |
+struct VmServiceNativeEntry { |
+ const char* name; |
+ int num_arguments; |
+ Dart_NativeFunction function; |
+}; |
+ |
+ |
+static VmServiceNativeEntry _VmServiceNativeEntries[] = { |
+ {"SendServiceMessage", 3, SendServiceMessage} |
+}; |
+ |
+ |
+static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name, |
+ int num_arguments) { |
+ const Object& obj = Object::Handle(Api::UnwrapHandle(name)); |
+ if (!obj.IsString()) { |
+ return NULL; |
+ } |
+ const char* function_name = obj.ToCString(); |
+ ASSERT(function_name != NULL); |
+ intptr_t n = |
+ sizeof(_VmServiceNativeEntries) / sizeof(_VmServiceNativeEntries[0]); |
+ for (intptr_t i = 0; i < n; i++) { |
+ VmServiceNativeEntry entry = _VmServiceNativeEntries[i]; |
+ if (!strcmp(function_name, entry.name) && |
+ (num_arguments == entry.num_arguments)) { |
+ return entry.function; |
+ } |
+ } |
+ return NULL; |
+} |
+ |
} // namespace bin |
} // namespace dart |