| Index: sky/engine/bindings-dart/core/dart/DartService.cpp
|
| diff --git a/sky/engine/bindings-dart/core/dart/DartService.cpp b/sky/engine/bindings-dart/core/dart/DartService.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..53bd812767b20ed516696972e5ba32d9664b8bd6
|
| --- /dev/null
|
| +++ b/sky/engine/bindings-dart/core/dart/DartService.cpp
|
| @@ -0,0 +1,251 @@
|
| +// Copyright (c) 2013, 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 "config.h"
|
| +
|
| +#include "bindings/core/dart/DartService.h"
|
| +
|
| +#include "bindings/core/dart/DartApplicationLoader.h"
|
| +#include "bindings/core/dart/DartController.h"
|
| +#include "bindings/core/dart/DartDocument.h"
|
| +#include "bindings/core/dart/DartUtilities.h"
|
| +#include "bindings/core/dart/DartWindow.h"
|
| +
|
| +
|
| +namespace blink {
|
| +
|
| +// Dartium VM Service embedder glue script source.
|
| +static const char* kScriptChars = "\n"
|
| +"library vmservice_dartium;\n"
|
| +"\n"
|
| +"import 'dart:isolate';\n"
|
| +"import 'dart:vmservice';\n"
|
| +"\n"
|
| +"\n"
|
| +"// The receive port that service request messages are delivered on.\n"
|
| +"SendPort requestPort;\n"
|
| +"\n"
|
| +"// The native method that is called to post the response back to DevTools.\n"
|
| +"void postResponse(String response, int cookie) native \"VMService_PostResponse\";\n"
|
| +"\n"
|
| +"/// Dartium Service receives messages through the requestPort and posts\n"
|
| +"/// responses via postResponse. It has a single persistent client.\n"
|
| +"class DartiumClient extends Client {\n"
|
| +" DartiumClient(port, service) : super(service) {\n"
|
| +" port.listen((message) {\n"
|
| +" if (message == null) {\n"
|
| +" return;\n"
|
| +" }\n"
|
| +" if (message is! List) {\n"
|
| +" return;\n"
|
| +" }\n"
|
| +" if (message.length != 2) {\n"
|
| +" return;\n"
|
| +" }\n"
|
| +" if (message[0] is! String) {\n"
|
| +" return;\n"
|
| +" }\n"
|
| +" var uri = Uri.parse(message[0]);\n"
|
| +" var cookie = message[1];\n"
|
| +" onMessage(cookie, new Message.fromUri(uri));\n"
|
| +" });\n"
|
| +" }\n"
|
| +"\n"
|
| +" void post(var seq, String response) {\n"
|
| +" postResponse(response, seq);\n"
|
| +" }\n"
|
| +"\n"
|
| +" dynamic toJson() {\n"
|
| +" var map = super.toJson();\n"
|
| +" map['type'] = 'DartiumClient';\n"
|
| +" }\n"
|
| +"}\n"
|
| +"\n"
|
| +"\n"
|
| +"vmservice_dartium_main() {\n"
|
| +" // Get VMService.\n"
|
| +" var service = new VMService();\n"
|
| +" var receivePort = new ReceivePort();\n"
|
| +" requestPort = receivePort.sendPort;\n"
|
| +" new DartiumClient(receivePort, service);\n"
|
| +"}\n";
|
| +
|
| +
|
| +#define SHUTDOWN_ON_ERROR(handle) \
|
| + if (Dart_IsError(handle)) { \
|
| + m_errorMsg = strdup(Dart_GetError(handle)); \
|
| + Dart_ExitScope(); \
|
| + Dart_ShutdownIsolate(); \
|
| + return false; \
|
| + }
|
| +
|
| +const char* DartService::m_errorMsg = 0;
|
| +Dart_Isolate DartService::m_isolate = 0;
|
| +
|
| +bool DartService::Start(Document* document)
|
| +{
|
| + if (m_isolate) {
|
| + // Already started.
|
| + return true;
|
| + }
|
| + ASSERT(!Dart_CurrentIsolate());
|
| + Dart_Isolate isolate = Dart_GetServiceIsolate(document);
|
| + if (!isolate) {
|
| + m_errorMsg = "Could not get service isolate from VM.";
|
| + return false;
|
| + }
|
| + Dart_EnterIsolate(isolate);
|
| + Dart_EnterScope();
|
| + Dart_Handle result;
|
| + Dart_Handle library = LoadScript();
|
| + SHUTDOWN_ON_ERROR(library);
|
| + // Expect a library.
|
| + ASSERT(Dart_IsLibrary(library));
|
| + library = Dart_RootLibrary();
|
| + result = Dart_SetNativeResolver(library, NativeResolver, 0);
|
| + SHUTDOWN_ON_ERROR(result);
|
| + result = Dart_Invoke(library, Dart_NewStringFromCString("vmservice_dartium_main"), 0, 0);
|
| + SHUTDOWN_ON_ERROR(result);
|
| + Dart_ExitScope();
|
| + Dart_ExitIsolate();
|
| + m_isolate = isolate;
|
| + return true;
|
| +}
|
| +
|
| +
|
| +const char* DartService::GetErrorMessage()
|
| +{
|
| + return m_errorMsg ? m_errorMsg : "No error.";
|
| +}
|
| +
|
| +
|
| +DartServiceRequest::DartServiceRequest(const String& request) : m_request(request)
|
| +{
|
| +}
|
| +
|
| +DartServiceRequest::~DartServiceRequest()
|
| +{
|
| +}
|
| +
|
| +
|
| +// The format of the message is:
|
| +// [request string, address of DartServiceRequest].
|
| +static Dart_Handle MakeServiceRequestMessage(DartServiceRequest* request)
|
| +{
|
| + intptr_t requestAddress = reinterpret_cast<intptr_t>(request);
|
| + int64_t requestAddress64 = static_cast<int64_t>(requestAddress);
|
| + Dart_Handle ALLOW_UNUSED result;
|
| + Dart_Handle list = Dart_NewList(2);
|
| + ASSERT(!Dart_IsError(list));
|
| + Dart_Handle requestHandle = DartUtilities::stringToDartString(request->GetRequestString());
|
| + ASSERT(!Dart_IsError(requestHandle));
|
| + Dart_Handle addressHandle = Dart_NewInteger(requestAddress64);
|
| + ASSERT(!Dart_IsError(addressHandle));
|
| + result = Dart_ListSetAt(list, 0, requestHandle);
|
| + ASSERT(!Dart_IsError(result));
|
| + result = Dart_ListSetAt(list, 1, addressHandle);
|
| + ASSERT(!Dart_IsError(result));
|
| + return list;
|
| +}
|
| +
|
| +
|
| +void DartService::MakeServiceRequest(DartServiceRequest* request)
|
| +{
|
| + ASSERT(m_isolate);
|
| + // TODO(johnmccutchan): Once the VM service is no longer a DOM isolate,
|
| + // we must be careful about entering the isolate.
|
| + DartIsolateScope isolateScope(m_isolate);
|
| + DartApiScope apiScope;
|
| + Dart_Handle message = MakeServiceRequestMessage(request);
|
| + if (Dart_IsError(message)) {
|
| + return;
|
| + }
|
| + Dart_Handle library = Dart_RootLibrary();
|
| + if (Dart_IsError(library)) {
|
| + return;
|
| + }
|
| + Dart_Handle requestPortFieldName = Dart_NewStringFromCString("requestPort");
|
| + Dart_Handle requestPort = Dart_GetField(library, requestPortFieldName);
|
| + if (Dart_IsError(requestPort)) {
|
| + return;
|
| + }
|
| + Dart_Port portId;
|
| + Dart_Handle result = Dart_SendPortGetId(requestPort, &portId);
|
| + if (Dart_IsError(result)) {
|
| + return;
|
| + }
|
| + Dart_Post(portId, message);
|
| +}
|
| +
|
| +
|
| +Dart_Handle DartService::LoadScript()
|
| +{
|
| + Dart_Handle url = Dart_NewStringFromCString("dart:vmservice_dartium");
|
| + ASSERT(!Dart_IsError(url));
|
| + intptr_t length = strlen(kScriptChars);
|
| + Dart_Handle source = Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(kScriptChars), length);
|
| + ASSERT(!Dart_IsError(source));
|
| + Dart_Handle library = Dart_LoadScript(url, source, 0, 0);
|
| + ASSERT(!Dart_IsError(library));
|
| + Dart_Handle loadingFinalized = Dart_FinalizeLoading(true);
|
| + if (Dart_IsError(loadingFinalized)) {
|
| + return loadingFinalized;
|
| + }
|
| + return library;
|
| +}
|
| +
|
| +
|
| +static void PostResponse(Dart_NativeArguments args)
|
| +{
|
| + Dart_Handle ALLOW_UNUSED result;
|
| + Dart_Handle response = Dart_GetNativeArgument(args, 0);
|
| + ASSERT(!Dart_IsError(response));
|
| + Dart_Handle cookie = Dart_GetNativeArgument(args, 1);
|
| + ASSERT(!Dart_IsError(cookie));
|
| + int64_t requestAddress64 = 0;
|
| + result = Dart_IntegerToInt64(cookie, &requestAddress64);
|
| + ASSERT(!Dart_IsError(result));
|
| + ASSERT(requestAddress64);
|
| + intptr_t requestAddress = static_cast<intptr_t>(requestAddress64);
|
| + ASSERT(requestAddress);
|
| + DartServiceRequest* request = reinterpret_cast<DartServiceRequest*>(requestAddress);
|
| + const char* responseString = 0;
|
| + result = Dart_StringToCString(response, &responseString);
|
| + ASSERT(!Dart_IsError(result));
|
| + ASSERT(responseString);
|
| + request->ResponseReady(responseString);
|
| +}
|
| +
|
| +
|
| +struct VmServiceNativeEntry {
|
| + const char* name;
|
| + int numArguments;
|
| + Dart_NativeFunction function;
|
| +};
|
| +
|
| +
|
| +static VmServiceNativeEntry VmServiceNativeEntries[] = {
|
| + {"VMService_PostResponse", 2, PostResponse}
|
| +};
|
| +
|
| +
|
| +Dart_NativeFunction DartService::NativeResolver(Dart_Handle name, int numArguments, bool* autoScopeSetup)
|
| +{
|
| + const char* functionName = 0;
|
| + Dart_Handle ALLOW_UNUSED result = Dart_StringToCString(name, &functionName);
|
| + ASSERT(!Dart_IsError(result));
|
| + ASSERT(functionName);
|
| + ASSERT(autoScopeSetup);
|
| + *autoScopeSetup = true;
|
| + intptr_t n = sizeof(VmServiceNativeEntries) / sizeof(VmServiceNativeEntries[0]);
|
| + for (intptr_t i = 0; i < n; i++) {
|
| + VmServiceNativeEntry entry = VmServiceNativeEntries[i];
|
| + if (!strcmp(functionName, entry.name) && (numArguments == entry.numArguments)) {
|
| + return entry.function;
|
| + }
|
| + }
|
| + return 0;
|
| +}
|
| +
|
| +}
|
|
|