| 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 |