| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 #include "config.h" | |
| 6 | |
| 7 #include "bindings/core/dart/DartService.h" | |
| 8 | |
| 9 #include "bindings/core/dart/DartApplicationLoader.h" | |
| 10 #include "bindings/core/dart/DartController.h" | |
| 11 #include "bindings/core/dart/DartDocument.h" | |
| 12 #include "bindings/core/dart/DartUtilities.h" | |
| 13 #include "bindings/core/dart/DartWindow.h" | |
| 14 | |
| 15 | |
| 16 namespace blink { | |
| 17 | |
| 18 // Dartium VM Service embedder glue script source. | |
| 19 static const char* kScriptChars = "\n" | |
| 20 "library vmservice_dartium;\n" | |
| 21 "\n" | |
| 22 "import 'dart:isolate';\n" | |
| 23 "import 'dart:vmservice';\n" | |
| 24 "\n" | |
| 25 "\n" | |
| 26 "// The receive port that service request messages are delivered on.\n" | |
| 27 "SendPort requestPort;\n" | |
| 28 "\n" | |
| 29 "// The native method that is called to post the response back to DevTools.\n" | |
| 30 "void postResponse(String response, int cookie) native \"VMService_PostResponse\
";\n" | |
| 31 "\n" | |
| 32 "/// Dartium Service receives messages through the requestPort and posts\n" | |
| 33 "/// responses via postResponse. It has a single persistent client.\n" | |
| 34 "class DartiumClient extends Client {\n" | |
| 35 " DartiumClient(port, service) : super(service) {\n" | |
| 36 " port.listen((message) {\n" | |
| 37 " if (message == null) {\n" | |
| 38 " return;\n" | |
| 39 " }\n" | |
| 40 " if (message is! List) {\n" | |
| 41 " return;\n" | |
| 42 " }\n" | |
| 43 " if (message.length != 2) {\n" | |
| 44 " return;\n" | |
| 45 " }\n" | |
| 46 " if (message[0] is! String) {\n" | |
| 47 " return;\n" | |
| 48 " }\n" | |
| 49 " var uri = Uri.parse(message[0]);\n" | |
| 50 " var cookie = message[1];\n" | |
| 51 " onMessage(cookie, new Message.fromUri(uri));\n" | |
| 52 " });\n" | |
| 53 " }\n" | |
| 54 "\n" | |
| 55 " void post(var seq, String response) {\n" | |
| 56 " postResponse(response, seq);\n" | |
| 57 " }\n" | |
| 58 "\n" | |
| 59 " dynamic toJson() {\n" | |
| 60 " var map = super.toJson();\n" | |
| 61 " map['type'] = 'DartiumClient';\n" | |
| 62 " }\n" | |
| 63 "}\n" | |
| 64 "\n" | |
| 65 "\n" | |
| 66 "vmservice_dartium_main() {\n" | |
| 67 " // Get VMService.\n" | |
| 68 " var service = new VMService();\n" | |
| 69 " var receivePort = new ReceivePort();\n" | |
| 70 " requestPort = receivePort.sendPort;\n" | |
| 71 " new DartiumClient(receivePort, service);\n" | |
| 72 "}\n"; | |
| 73 | |
| 74 | |
| 75 #define SHUTDOWN_ON_ERROR(handle) \ | |
| 76 if (Dart_IsError(handle)) { \ | |
| 77 m_errorMsg = strdup(Dart_GetError(handle)); \ | |
| 78 Dart_ExitScope(); \ | |
| 79 Dart_ShutdownIsolate(); \ | |
| 80 return false; \ | |
| 81 } | |
| 82 | |
| 83 const char* DartService::m_errorMsg = 0; | |
| 84 Dart_Isolate DartService::m_isolate = 0; | |
| 85 | |
| 86 bool DartService::Start(Document* document) | |
| 87 { | |
| 88 if (m_isolate) { | |
| 89 // Already started. | |
| 90 return true; | |
| 91 } | |
| 92 ASSERT(!Dart_CurrentIsolate()); | |
| 93 Dart_Isolate isolate = Dart_GetServiceIsolate(document); | |
| 94 if (!isolate) { | |
| 95 m_errorMsg = "Could not get service isolate from VM."; | |
| 96 return false; | |
| 97 } | |
| 98 Dart_EnterIsolate(isolate); | |
| 99 Dart_EnterScope(); | |
| 100 Dart_Handle result; | |
| 101 Dart_Handle library = LoadScript(); | |
| 102 SHUTDOWN_ON_ERROR(library); | |
| 103 // Expect a library. | |
| 104 ASSERT(Dart_IsLibrary(library)); | |
| 105 library = Dart_RootLibrary(); | |
| 106 result = Dart_SetNativeResolver(library, NativeResolver, 0); | |
| 107 SHUTDOWN_ON_ERROR(result); | |
| 108 result = Dart_Invoke(library, Dart_NewStringFromCString("vmservice_dartium_m
ain"), 0, 0); | |
| 109 SHUTDOWN_ON_ERROR(result); | |
| 110 Dart_ExitScope(); | |
| 111 Dart_ExitIsolate(); | |
| 112 m_isolate = isolate; | |
| 113 return true; | |
| 114 } | |
| 115 | |
| 116 | |
| 117 const char* DartService::GetErrorMessage() | |
| 118 { | |
| 119 return m_errorMsg ? m_errorMsg : "No error."; | |
| 120 } | |
| 121 | |
| 122 | |
| 123 DartServiceRequest::DartServiceRequest(const String& request) : m_request(reques
t) | |
| 124 { | |
| 125 } | |
| 126 | |
| 127 DartServiceRequest::~DartServiceRequest() | |
| 128 { | |
| 129 } | |
| 130 | |
| 131 | |
| 132 // The format of the message is: | |
| 133 // [request string, address of DartServiceRequest]. | |
| 134 static Dart_Handle MakeServiceRequestMessage(DartServiceRequest* request) | |
| 135 { | |
| 136 intptr_t requestAddress = reinterpret_cast<intptr_t>(request); | |
| 137 int64_t requestAddress64 = static_cast<int64_t>(requestAddress); | |
| 138 Dart_Handle ALLOW_UNUSED result; | |
| 139 Dart_Handle list = Dart_NewList(2); | |
| 140 ASSERT(!Dart_IsError(list)); | |
| 141 Dart_Handle requestHandle = DartUtilities::stringToDartString(request->GetRe
questString()); | |
| 142 ASSERT(!Dart_IsError(requestHandle)); | |
| 143 Dart_Handle addressHandle = Dart_NewInteger(requestAddress64); | |
| 144 ASSERT(!Dart_IsError(addressHandle)); | |
| 145 result = Dart_ListSetAt(list, 0, requestHandle); | |
| 146 ASSERT(!Dart_IsError(result)); | |
| 147 result = Dart_ListSetAt(list, 1, addressHandle); | |
| 148 ASSERT(!Dart_IsError(result)); | |
| 149 return list; | |
| 150 } | |
| 151 | |
| 152 | |
| 153 void DartService::MakeServiceRequest(DartServiceRequest* request) | |
| 154 { | |
| 155 ASSERT(m_isolate); | |
| 156 // TODO(johnmccutchan): Once the VM service is no longer a DOM isolate, | |
| 157 // we must be careful about entering the isolate. | |
| 158 DartIsolateScope isolateScope(m_isolate); | |
| 159 DartApiScope apiScope; | |
| 160 Dart_Handle message = MakeServiceRequestMessage(request); | |
| 161 if (Dart_IsError(message)) { | |
| 162 return; | |
| 163 } | |
| 164 Dart_Handle library = Dart_RootLibrary(); | |
| 165 if (Dart_IsError(library)) { | |
| 166 return; | |
| 167 } | |
| 168 Dart_Handle requestPortFieldName = Dart_NewStringFromCString("requestPort"); | |
| 169 Dart_Handle requestPort = Dart_GetField(library, requestPortFieldName); | |
| 170 if (Dart_IsError(requestPort)) { | |
| 171 return; | |
| 172 } | |
| 173 Dart_Port portId; | |
| 174 Dart_Handle result = Dart_SendPortGetId(requestPort, &portId); | |
| 175 if (Dart_IsError(result)) { | |
| 176 return; | |
| 177 } | |
| 178 Dart_Post(portId, message); | |
| 179 } | |
| 180 | |
| 181 | |
| 182 Dart_Handle DartService::LoadScript() | |
| 183 { | |
| 184 Dart_Handle url = Dart_NewStringFromCString("dart:vmservice_dartium"); | |
| 185 ASSERT(!Dart_IsError(url)); | |
| 186 intptr_t length = strlen(kScriptChars); | |
| 187 Dart_Handle source = Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>
(kScriptChars), length); | |
| 188 ASSERT(!Dart_IsError(source)); | |
| 189 Dart_Handle library = Dart_LoadScript(url, source, 0, 0); | |
| 190 ASSERT(!Dart_IsError(library)); | |
| 191 Dart_Handle loadingFinalized = Dart_FinalizeLoading(true); | |
| 192 if (Dart_IsError(loadingFinalized)) { | |
| 193 return loadingFinalized; | |
| 194 } | |
| 195 return library; | |
| 196 } | |
| 197 | |
| 198 | |
| 199 static void PostResponse(Dart_NativeArguments args) | |
| 200 { | |
| 201 Dart_Handle ALLOW_UNUSED result; | |
| 202 Dart_Handle response = Dart_GetNativeArgument(args, 0); | |
| 203 ASSERT(!Dart_IsError(response)); | |
| 204 Dart_Handle cookie = Dart_GetNativeArgument(args, 1); | |
| 205 ASSERT(!Dart_IsError(cookie)); | |
| 206 int64_t requestAddress64 = 0; | |
| 207 result = Dart_IntegerToInt64(cookie, &requestAddress64); | |
| 208 ASSERT(!Dart_IsError(result)); | |
| 209 ASSERT(requestAddress64); | |
| 210 intptr_t requestAddress = static_cast<intptr_t>(requestAddress64); | |
| 211 ASSERT(requestAddress); | |
| 212 DartServiceRequest* request = reinterpret_cast<DartServiceRequest*>(requestA
ddress); | |
| 213 const char* responseString = 0; | |
| 214 result = Dart_StringToCString(response, &responseString); | |
| 215 ASSERT(!Dart_IsError(result)); | |
| 216 ASSERT(responseString); | |
| 217 request->ResponseReady(responseString); | |
| 218 } | |
| 219 | |
| 220 | |
| 221 struct VmServiceNativeEntry { | |
| 222 const char* name; | |
| 223 int numArguments; | |
| 224 Dart_NativeFunction function; | |
| 225 }; | |
| 226 | |
| 227 | |
| 228 static VmServiceNativeEntry VmServiceNativeEntries[] = { | |
| 229 {"VMService_PostResponse", 2, PostResponse} | |
| 230 }; | |
| 231 | |
| 232 | |
| 233 Dart_NativeFunction DartService::NativeResolver(Dart_Handle name, int numArgumen
ts, bool* autoScopeSetup) | |
| 234 { | |
| 235 const char* functionName = 0; | |
| 236 Dart_Handle ALLOW_UNUSED result = Dart_StringToCString(name, &functionName); | |
| 237 ASSERT(!Dart_IsError(result)); | |
| 238 ASSERT(functionName); | |
| 239 ASSERT(autoScopeSetup); | |
| 240 *autoScopeSetup = true; | |
| 241 intptr_t n = sizeof(VmServiceNativeEntries) / sizeof(VmServiceNativeEntries[
0]); | |
| 242 for (intptr_t i = 0; i < n; i++) { | |
| 243 VmServiceNativeEntry entry = VmServiceNativeEntries[i]; | |
| 244 if (!strcmp(functionName, entry.name) && (numArguments == entry.numArgum
ents)) { | |
| 245 return entry.function; | |
| 246 } | |
| 247 } | |
| 248 return 0; | |
| 249 } | |
| 250 | |
| 251 } | |
| OLD | NEW |