Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "bindings/dart/DartService.h" | 7 #include "bindings/dart/DartService.h" |
| 8 | 8 |
| 9 #include "DartApplicationLoader.h" | 9 #include "DartApplicationLoader.h" |
| 10 #include "DartController.h" | 10 #include "DartController.h" |
| 11 #include "DartDocument.h" | 11 #include "DartDocument.h" |
| 12 #include "DartServiceInternal.h" | |
| 13 #include "DartUtilities.h" | 12 #include "DartUtilities.h" |
| 14 #include "DartWindow.h" | 13 #include "DartWindow.h" |
| 15 | 14 |
| 16 | 15 |
| 17 // These must be kept in sync with vmservice/constants.dart | 16 namespace WebCore { |
| 18 // TODO(johnmccutchan): Put these constants in one place. | |
| 19 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1 | |
| 20 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2 | |
| 21 | 17 |
| 22 // The following Resources class is used in combination with a generated | 18 #define SHUTDOWN_ON_ERROR(handle) \ |
|
Jacob
2014/01/08 18:47:10
Consider moving this to DartUtils or using existin
Cutch
2014/01/10 21:34:26
This code is specific to the service startup code.
| |
| 23 // source file that expects underscores in names. The NOLINT tags are | 19 if (Dart_IsError(handle)) { \ |
| 24 // used to suppress the errors. | 20 m_errorMsg = strdup(Dart_GetError(handle)); \ |
| 25 // TODO(johnmccutchan): Move VM service source into runtime and out of bin. | 21 Dart_ExitScope(); \ |
| 26 namespace dart { | 22 Dart_ShutdownIsolate(); \ |
| 27 namespace bin { | 23 return false; \ |
| 28 class Resources { | |
| 29 public: | |
| 30 static const int kNoSuchInstance = -1; | |
| 31 | |
| 32 static int ResourceLookup(const char* path, const char** resource) | |
| 33 { | |
| 34 for (int i = 0; i < get_resource_count(); i++) { | |
| 35 resource_map_entry* entry = get_resource(i); | |
| 36 if (!strcmp(path, entry->path_)) { | |
| 37 *resource = entry->resource_; | |
| 38 ASSERT(entry->length_ > 0); | |
| 39 return entry->length_; | |
| 40 } | |
| 41 } | |
| 42 return kNoSuchInstance; | |
| 43 } | 24 } |
| 44 | 25 |
| 45 static intptr_t get_resource_count() // NOLINT. | 26 const char* DartService::m_errorMsg = 0; |
| 46 { | |
| 47 return builtin_resources_count_; | |
| 48 } | |
| 49 | |
| 50 static const char* get_resource_path(intptr_t i) // NOLINT. | |
| 51 { | |
| 52 return get_resource(i)->path_; | |
| 53 } | |
| 54 | |
| 55 private: | |
| 56 struct resource_map_entry { // NOLINT. | |
| 57 const char* path_; // NOLINT. | |
| 58 const char* resource_; // NOLINT. | |
| 59 intptr_t length_; // NOLINT. | |
| 60 }; | |
| 61 | |
| 62 // These fields are generated by resources_gen.cc. | |
| 63 static resource_map_entry builtin_resources_[]; // NOLINT. | |
| 64 static const intptr_t builtin_resources_count_; // NOLINT. | |
| 65 | |
| 66 static resource_map_entry* get_resource(int i) // NOLINT. | |
| 67 { | |
| 68 ASSERT(i >= 0 && i < builtin_resources_count_); | |
| 69 return &builtin_resources_[i]; | |
| 70 } | |
| 71 | |
| 72 DISALLOW_IMPLICIT_CONSTRUCTORS(Resources); | |
| 73 }; | |
| 74 | |
| 75 } | |
| 76 } | |
| 77 namespace WebCore { | |
| 78 | |
| 79 #define SHUTDOWN_ON_ERROR(handle) \ | |
| 80 if (Dart_IsError(handle)) { \ | |
| 81 m_errorMsg = strdup(Dart_GetError(handle)); \ | |
| 82 goto error; \ | |
| 83 } | |
| 84 | |
| 85 static const char* kScriptUri = "vmservice:"; | |
| 86 #define kLibraryResourceNamePrefix "/vmservice" | |
| 87 static const char* kVMServiceDartiumLibraryScriptResourceName = | |
| 88 kLibraryResourceNamePrefix "/vmservice_dartium.dart"; | |
| 89 static const char* kVMServiceLibraryName = | |
| 90 kLibraryResourceNamePrefix "/vmservice.dart"; | |
| 91 | |
| 92 | |
| 93 Dart_Isolate DartService::m_isolate = 0; | 27 Dart_Isolate DartService::m_isolate = 0; |
| 94 Dart_Port DartService::m_port = ILLEGAL_PORT; | |
| 95 Dart_Port DartService::m_requestPort = ILLEGAL_PORT; | |
| 96 const char* DartService::m_errorMsg = 0; | |
| 97 | |
| 98 | 28 |
| 99 bool DartService::Start(Document* document) | 29 bool DartService::Start(Document* document) |
| 100 { | 30 { |
| 101 if (m_isolate) { | 31 if (m_isolate) { |
| 102 // Already running. | 32 // Already started. |
| 103 return true; | 33 return true; |
| 104 } | 34 } |
| 105 { | 35 ASSERT(!Dart_CurrentIsolate()); |
| 106 char* error = 0; | 36 Dart_Isolate isolate = Dart_GetServiceIsolate(document); |
|
siva
2014/01/10 00:10:13
As discussed offline we should see if it is possib
| |
| 107 | 37 if (!isolate) { |
| 108 m_isolate = DartController::createIsolate(kScriptUri, "main", document, true, &error); | 38 m_errorMsg = "Internal error."; |
|
Jacob
2014/01/08 18:47:10
add a better error message
Cutch
2014/01/10 21:34:26
Done.
| |
| 109 if (!m_isolate) { | 39 return false; |
| 110 m_errorMsg = error; | |
| 111 return false; | |
| 112 } | |
| 113 | |
| 114 Dart_EnterScope(); | |
| 115 // Set up the library tag handler for this isolate. | |
| 116 Dart_Handle result = Dart_SetLibraryTagHandler(LibraryTagHandler); | |
| 117 SHUTDOWN_ON_ERROR(result); | |
| 118 | |
| 119 { | |
| 120 // Load source into service isolate. | |
| 121 Dart_Handle library = | |
| 122 LoadScript(kVMServiceDartiumLibraryScriptResourceName); | |
| 123 SHUTDOWN_ON_ERROR(library); | |
| 124 result = Dart_SetNativeResolver(library, DartService::NativeResolver ); | |
| 125 SHUTDOWN_ON_ERROR(result); | |
| 126 } | |
| 127 // Make the isolate runnable so that it is ready to handle messages. | |
| 128 Dart_ExitScope(); | |
| 129 Dart_ExitIsolate(); | |
| 130 | |
| 131 bool retval = Dart_IsolateMakeRunnable(m_isolate); | |
| 132 if (!retval) { | |
| 133 Dart_EnterIsolate(m_isolate); | |
| 134 Dart_ShutdownIsolate(); | |
| 135 m_errorMsg = "Invalid isolate state - Unable to make it runnable."; | |
| 136 return false; | |
| 137 } | |
| 138 | |
| 139 Dart_EnterIsolate(m_isolate); | |
| 140 Dart_EnterScope(); | |
| 141 | |
| 142 // Invoke main. | |
| 143 Dart_Handle library = Dart_RootLibrary(); | |
| 144 Dart_Handle entryFunctioName = Dart_NewStringFromCString("main"); | |
| 145 SHUTDOWN_ON_ERROR(entryFunctioName); | |
| 146 result = Dart_Invoke(library, entryFunctioName, 0, 0); | |
| 147 SHUTDOWN_ON_ERROR(result); | |
| 148 | |
| 149 // Retrieve the ReceivePort that the service is waiting on. The _receive Port | |
| 150 // variable is setup in the call to main. | |
| 151 Dart_Handle portFieldName = Dart_NewStringFromCString("_receivePort"); | |
| 152 SHUTDOWN_ON_ERROR(portFieldName); | |
| 153 Dart_Handle receivePort = Dart_GetField(library, portFieldName); | |
| 154 SHUTDOWN_ON_ERROR(receivePort); | |
| 155 | |
| 156 m_port = DartServiceInternal::GetPortIdFromPort(receivePort); | |
| 157 if (m_port == ILLEGAL_PORT) { | |
| 158 Dart_ExitScope(); | |
| 159 Dart_ShutdownIsolate(); | |
| 160 m_errorMsg = "Invalid isolate state - Unable to get receivePort"; | |
| 161 return false; | |
| 162 } | |
| 163 | |
| 164 { | |
| 165 // Retrieve the ReceivePort that the service is waiting on. The _rec eivePort | |
| 166 // variable is setup in the call to main. | |
| 167 Dart_Handle portFieldName = Dart_NewStringFromCString("_requestPort" ); | |
| 168 SHUTDOWN_ON_ERROR(portFieldName); | |
| 169 Dart_Handle receivePort = Dart_GetField(library, portFieldName); | |
| 170 SHUTDOWN_ON_ERROR(receivePort); | |
| 171 m_requestPort = DartServiceInternal::GetPortIdFromPort(receivePort); | |
| 172 ASSERT(m_requestPort != ILLEGAL_PORT); | |
| 173 } | |
| 174 | |
| 175 Dart_ExitScope(); | |
| 176 Dart_ExitIsolate(); | |
| 177 return true; | |
| 178 } | 40 } |
| 179 error: | 41 Dart_EnterIsolate(isolate); |
| 42 Dart_EnterScope(); | |
| 43 Dart_Handle result; | |
| 44 Dart_Handle library = LoadScript(); | |
| 45 // Expect a library. | |
| 46 ASSERT(library != Dart_Null()); | |
|
Jacob
2014/01/08 18:47:10
why not assert that this is a library?
Cutch
2014/01/10 21:34:26
Done.
| |
| 47 SHUTDOWN_ON_ERROR(library); | |
| 48 library = Dart_RootLibrary(); | |
| 49 result = Dart_SetNativeResolver(library, NativeResolver); | |
| 50 SHUTDOWN_ON_ERROR(result); | |
| 51 result = Dart_Invoke(library, Dart_NewStringFromCString("main"), 0, 0); | |
| 52 SHUTDOWN_ON_ERROR(result); | |
| 180 Dart_ExitScope(); | 53 Dart_ExitScope(); |
| 181 Dart_ShutdownIsolate(); | 54 Dart_ExitIsolate(); |
| 182 m_isolate = 0; | 55 m_isolate = isolate; |
| 183 m_port = ILLEGAL_PORT; | |
| 184 m_requestPort = ILLEGAL_PORT; | |
| 185 return false; | |
| 186 } | |
| 187 | |
| 188 | |
| 189 bool DartService::Stop() | |
| 190 { | |
| 191 if (!m_isolate) { | |
| 192 // Already shutdown. | |
| 193 return true; | |
| 194 } | |
| 195 m_port = ILLEGAL_PORT; | |
| 196 m_requestPort = ILLEGAL_PORT; | |
| 197 Dart_Isolate isolate = m_isolate; | |
| 198 m_isolate = 0; | |
| 199 Dart_EnterIsolate(isolate); | |
| 200 DartController::shutdownIsolate(isolate); | |
| 201 return true; | 56 return true; |
| 202 } | 57 } |
| 203 | 58 |
| 204 | 59 |
| 205 const char* DartService::GetErrorMessage() | 60 const char* DartService::GetErrorMessage() |
| 206 { | 61 { |
| 207 return m_errorMsg ? m_errorMsg : "No error."; | 62 return m_errorMsg ? m_errorMsg : "No error."; |
| 208 } | 63 } |
| 209 | 64 |
| 210 | 65 |
| 211 Dart_Port DartService::port() | |
| 212 { | |
| 213 return m_port; | |
| 214 } | |
| 215 | |
| 216 | |
| 217 bool DartService::IsRunning() | |
| 218 { | |
| 219 return m_port != ILLEGAL_PORT; | |
| 220 } | |
| 221 | |
| 222 | |
| 223 static Dart_Handle MakeServiceControlMessage(Dart_Port portId, intptr_t code, Da rt_Handle name) | |
| 224 { | |
| 225 Dart_Handle result; | |
| 226 UNUSED_PARAM(result); | |
| 227 Dart_Handle list = Dart_NewList(4); | |
| 228 ASSERT(!Dart_IsError(list)); | |
| 229 Dart_Handle codeHandle = Dart_NewInteger(code); | |
| 230 ASSERT(!Dart_IsError(codeHandle)); | |
| 231 result = Dart_ListSetAt(list, 0, codeHandle); | |
| 232 ASSERT(!Dart_IsError(result)); | |
| 233 Dart_Handle portIdHandle = Dart_NewInteger(portId); | |
| 234 ASSERT(!Dart_IsError(portIdHandle)); | |
| 235 result = Dart_ListSetAt(list, 1, portIdHandle); | |
| 236 ASSERT(!Dart_IsError(result)); | |
| 237 Dart_Handle sendPort = Dart_NewSendPort(portId); | |
| 238 ASSERT(!Dart_IsError(sendPort)); | |
| 239 result = Dart_ListSetAt(list, 2, sendPort); | |
| 240 ASSERT(!Dart_IsError(result)); | |
| 241 result = Dart_ListSetAt(list, 3, name); | |
| 242 ASSERT(!Dart_IsError(result)); | |
| 243 return list; | |
| 244 } | |
| 245 | |
| 246 | |
| 247 bool DartService::SendIsolateStartupMessage() | |
| 248 { | |
| 249 if (!IsRunning()) { | |
| 250 return false; | |
| 251 } | |
| 252 Dart_Handle name = Dart_DebugName(); | |
| 253 ASSERT(!Dart_IsError(name)); | |
| 254 Dart_Handle list = MakeServiceControlMessage(Dart_GetMainPortId(), VM_SERVIC E_ISOLATE_STARTUP_MESSAGE_ID, name); | |
| 255 ASSERT(!Dart_IsError(list)); | |
| 256 return Dart_Post(m_port, list); | |
| 257 } | |
| 258 | |
| 259 | |
| 260 bool DartService::SendIsolateShutdownMessage() | |
| 261 { | |
| 262 if (!IsRunning()) | |
| 263 return false; | |
| 264 Dart_Handle list = MakeServiceControlMessage(Dart_GetMainPortId(), VM_SERVIC E_ISOLATE_SHUTDOWN_MESSAGE_ID, Dart_Null()); | |
| 265 ASSERT(!Dart_IsError(list)); | |
| 266 return Dart_Post(m_port, list); | |
| 267 } | |
| 268 | |
| 269 | |
| 270 DartServiceRequest::DartServiceRequest(const String& request) : m_request(reques t) | 66 DartServiceRequest::DartServiceRequest(const String& request) : m_request(reques t) |
| 271 { | 67 { |
| 272 } | 68 } |
| 273 | 69 |
| 274 DartServiceRequest::~DartServiceRequest() | 70 DartServiceRequest::~DartServiceRequest() |
| 275 { | 71 { |
| 276 } | 72 } |
| 277 | 73 |
| 278 | 74 |
| 279 | |
| 280 // The format of the message is: | 75 // The format of the message is: |
| 281 // [request string, address of DartServiceRequest]. | 76 // [request string, address of DartServiceRequest]. |
| 282 static Dart_Handle MakeServiceRequestMessage(DartServiceRequest* request) | 77 static Dart_Handle MakeServiceRequestMessage(DartServiceRequest* request) |
| 283 { | 78 { |
| 284 intptr_t requestAddress = reinterpret_cast<intptr_t>(request); | 79 intptr_t requestAddress = reinterpret_cast<intptr_t>(request); |
| 285 int64_t requestAddress64 = static_cast<int64_t>(requestAddress); | 80 int64_t requestAddress64 = static_cast<int64_t>(requestAddress); |
| 286 Dart_Handle result; | 81 Dart_Handle result; |
| 287 UNUSED_PARAM(result); | 82 UNUSED_PARAM(result); |
| 288 Dart_Handle list = Dart_NewList(2); | 83 Dart_Handle list = Dart_NewList(2); |
| 289 ASSERT(!Dart_IsError(list)); | 84 ASSERT(!Dart_IsError(list)); |
| 290 Dart_Handle requestHandle = DartUtilities::stringToDartString(request->GetRe questString()); | 85 Dart_Handle requestHandle = DartUtilities::stringToDartString(request->GetRe questString()); |
| 291 ASSERT(!Dart_IsError(requestHandle)); | 86 ASSERT(!Dart_IsError(requestHandle)); |
| 292 Dart_Handle addressHandle = Dart_NewInteger(requestAddress64); | 87 Dart_Handle addressHandle = Dart_NewInteger(requestAddress64); |
| 293 ASSERT(!Dart_IsError(addressHandle)); | 88 ASSERT(!Dart_IsError(addressHandle)); |
| 294 result = Dart_ListSetAt(list, 0, requestHandle); | 89 result = Dart_ListSetAt(list, 0, requestHandle); |
| 295 ASSERT(!Dart_IsError(result)); | 90 ASSERT(!Dart_IsError(result)); |
| 296 result = Dart_ListSetAt(list, 1, addressHandle); | 91 result = Dart_ListSetAt(list, 1, addressHandle); |
| 297 ASSERT(!Dart_IsError(result)); | 92 ASSERT(!Dart_IsError(result)); |
| 298 return list; | 93 return list; |
| 299 } | 94 } |
| 300 | 95 |
| 301 | 96 |
| 302 void DartService::MakeServiceRequest(DartServiceRequest* request) | 97 void DartService::MakeServiceRequest(DartServiceRequest* request) |
| 303 { | 98 { |
| 304 ASSERT(m_isolate); | 99 ASSERT(m_isolate); |
| 305 // TODO(johnmccutchan): Once the VM service is no longer a DOM isolate, | 100 // TODO(johnmccutchan): Once the VM service is no longer a DOM isolate, |
| 306 // we must be careful about entering the isolate. | 101 // we must be careful about entering the isolate. |
|
siva
2014/01/10 00:10:13
Is this comment valid? You indicated that the serv
Cutch
2014/01/10 21:34:26
The comment was optimistic that one day the servic
| |
| 307 DartIsolateScope isolateScope(m_isolate); | 102 DartIsolateScope isolateScope(m_isolate); |
| 308 DartApiScope apiScope; | 103 DartApiScope apiScope; |
| 309 Dart_Handle message = MakeServiceRequestMessage(request); | 104 Dart_Handle message = MakeServiceRequestMessage(request); |
| 310 Dart_Post(m_requestPort, message); | 105 if (Dart_IsError(message)) { |
| 106 return; | |
| 107 } | |
| 108 Dart_Handle library = Dart_RootLibrary(); | |
| 109 if (Dart_IsError(library)) { | |
| 110 return; | |
| 111 } | |
| 112 Dart_Handle requestPortFieldName = Dart_NewStringFromCString("requestPort"); | |
| 113 Dart_Handle requestPort = Dart_GetField(library, requestPortFieldName); | |
| 114 if (Dart_IsError(requestPort)) { | |
| 115 return; | |
| 116 } | |
|
siva
2014/01/10 00:10:13
If the API handed back the service request port th
| |
| 117 Dart_SendPortSend(requestPort, message); | |
| 311 } | 118 } |
| 312 | 119 |
| 313 | 120 |
| 314 Dart_Handle DartService::GetSource(const char* name) | 121 Dart_Handle DartService::LoadScript() |
| 315 { | 122 { |
| 316 const char* vmserviceSource = 0; | 123 const char* kScriptChars = "\n" |
| 317 int result = dart::bin::Resources::ResourceLookup(name, &vmserviceSource); | 124 "library vmservice_dartium;\n" |
|
Jacob
2014/01/08 18:47:10
this script should be moved to an internal library
Cutch
2014/01/10 21:34:26
We do not want to add the VM service glue script t
| |
| 318 UNUSED_PARAM(result); | 125 "\n" |
| 319 ASSERT(result != dart::bin::Resources::kNoSuchInstance); | 126 "import 'dart:isolate';\n" |
| 320 return Dart_NewStringFromCString(vmserviceSource); | 127 "import 'dart:vmservice';\n" |
| 128 "\n" | |
| 129 "\n" | |
| 130 "// The receive port that service request messages are delivered on.\n" | |
| 131 "SendPort requestPort;\n" | |
| 132 "\n" | |
| 133 "// The native method that is called to post the response back to DevTools.\n" | |
| 134 "void postResponse(String response, int cookie) native \"VMService_PostResponse\ ";\n" | |
| 135 "\n" | |
| 136 "/// Dartium Service receives messages through the requestPort and posts\n" | |
| 137 "/// responses via postResponse. It has a single persistent client.\n" | |
| 138 "class DartiumClient extends Client {\n" | |
| 139 " DartiumClient(port, service) : super(service) {\n" | |
| 140 " port.listen((message) {\n" | |
| 141 " if (message == null) {\n" | |
| 142 " return;\n" | |
| 143 " }\n" | |
| 144 " if (message is! List) {\n" | |
| 145 " return;\n" | |
| 146 " }\n" | |
| 147 " if (message.length != 2) {\n" | |
| 148 " return;\n" | |
| 149 " }\n" | |
| 150 " if (message[0] is! String) {\n" | |
| 151 " return;\n" | |
| 152 " }\n" | |
| 153 " var uri = Uri.parse(message[0]);\n" | |
| 154 " var cookie = message[1];\n" | |
| 155 " onMessage(cookie, new Message.fromUri(uri));\n" | |
| 156 " });\n" | |
| 157 " }\n" | |
| 158 "\n" | |
| 159 " void post(var seq, String response) {\n" | |
| 160 " postResponse(response, seq);\n" | |
| 161 " }\n" | |
| 162 "\n" | |
| 163 " dynamic toJson() {\n" | |
| 164 " var map = super.toJson();\n" | |
| 165 " map['type'] = 'DartiumClient';\n" | |
| 166 " }\n" | |
| 167 "}\n" | |
| 168 "\n" | |
| 169 "\n" | |
| 170 "main() {\n" | |
| 171 " // Get VMService.\n" | |
| 172 " var service = new VMService();\n" | |
| 173 " var receivePort = new ReceivePort();\n" | |
| 174 " requestPort = receivePort.sendPort;\n" | |
| 175 " new DartiumClient(receivePort, service);\n" | |
| 176 "}\n"; | |
| 177 Dart_Handle url = Dart_NewStringFromCString("dart:vmservice_dartium"); | |
| 178 ASSERT(!Dart_IsError(url)); | |
| 179 Dart_Handle source = Dart_NewStringFromCString(kScriptChars); | |
| 180 ASSERT(!Dart_IsError(source)); | |
| 181 Dart_Handle library = Dart_LoadScript(url, source, 0, 0); | |
| 182 return library; | |
| 321 } | 183 } |
| 322 | 184 |
| 323 | 185 |
| 324 Dart_Handle DartService::LoadScript(const char* name) | |
| 325 { | |
| 326 Dart_Handle url = Dart_NewStringFromCString(name); | |
| 327 Dart_Handle source = GetSource(name); | |
| 328 return Dart_LoadScript(url, source, 0, 0); | |
| 329 } | |
| 330 | |
| 331 | |
| 332 Dart_Handle DartService::LoadSource(Dart_Handle library, const char* name) | |
| 333 { | |
| 334 Dart_Handle url = Dart_NewStringFromCString(name); | |
| 335 Dart_Handle source = GetSource(name); | |
| 336 return Dart_LoadSource(library, url, source); | |
| 337 } | |
| 338 | |
| 339 | |
| 340 Dart_Handle DartService::LoadSources(Dart_Handle library, const char* names[]) | |
| 341 { | |
| 342 Dart_Handle result = Dart_Null(); | |
| 343 for (int i = 0; names[i]; i++) { | |
| 344 result = LoadSource(library, names[i]); | |
| 345 if (Dart_IsError(result)) | |
| 346 break; | |
| 347 } | |
| 348 return result; | |
| 349 } | |
| 350 | |
| 351 | |
| 352 static bool IsVMServiceURL(const char* url) | |
| 353 { | |
| 354 static const intptr_t kLibraryResourceNamePrefixLen = strlen(kLibraryResourc eNamePrefix); | |
| 355 return !strncmp(kLibraryResourceNamePrefix, url, kLibraryResourceNamePrefixL en); | |
| 356 } | |
| 357 | |
| 358 | |
| 359 static bool IsVMServiceLibrary(const char* url) | |
| 360 { | |
| 361 return !strcmp(kVMServiceLibraryName, url); | |
| 362 } | |
| 363 | |
| 364 static bool IsDartLibrary(const char* url) | |
| 365 { | |
| 366 static const char* kDartPrefix = "dart:"; | |
| 367 static const intptr_t kDartPrefixLen = strlen(kDartPrefix); | |
| 368 return !strncmp(kDartPrefix, url, kDartPrefixLen); | |
| 369 } | |
| 370 | |
| 371 static Dart_Handle Canonicalize(const char* url) | |
| 372 { | |
| 373 if (IsVMServiceURL(url)) { | |
| 374 // Already canonicalized. | |
| 375 return Dart_NewStringFromCString(url); | |
| 376 } | |
| 377 String path = String(kLibraryResourceNamePrefix) + String("/") + String(url) ; | |
| 378 return DartUtilities::stringToDartString(path); | |
| 379 } | |
| 380 | |
| 381 | |
| 382 Dart_Handle DartService::LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle libr ary, Dart_Handle url) | |
| 383 { | |
| 384 if (!Dart_IsLibrary(library)) | |
| 385 return Dart_NewApiError("not a library"); | |
| 386 if (!Dart_IsString(url)) | |
| 387 return Dart_NewApiError("url is not a string"); | |
| 388 const char* urlString = 0; | |
| 389 Dart_Handle result = Dart_StringToCString(url, &urlString); | |
| 390 if (Dart_IsError(result)) | |
| 391 return result; | |
| 392 Dart_Handle libraryUrl = Dart_LibraryUrl(library); | |
| 393 const char* libraryUrlString = 0; | |
| 394 result = Dart_StringToCString(libraryUrl, &libraryUrlString); | |
| 395 if (Dart_IsError(result)) | |
| 396 return result; | |
| 397 if (IsDartLibrary(urlString)) | |
| 398 return DartApplicationLoader::libraryTagHandlerCallback(tag, library, ur l); | |
| 399 switch (tag) { | |
| 400 case Dart_kCanonicalizeUrl: | |
| 401 return Canonicalize(urlString); | |
| 402 break; | |
| 403 case Dart_kImportTag: { | |
| 404 Dart_Handle source = GetSource(urlString); | |
| 405 if (Dart_IsError(source)) | |
| 406 return source; | |
| 407 Dart_Handle lib = Dart_LoadLibrary(url, source); | |
| 408 if (Dart_IsError(lib)) | |
| 409 return lib; | |
| 410 if (IsVMServiceLibrary(urlString)) { | |
| 411 // Install native resolver for this library. | |
| 412 result = Dart_SetNativeResolver(lib, DartService::NativeResolver); | |
| 413 if (Dart_IsError(result)) | |
| 414 return result; | |
| 415 } | |
| 416 return lib; | |
| 417 } | |
| 418 break; | |
| 419 case Dart_kSourceTag: { | |
| 420 Dart_Handle source = GetSource(urlString); | |
| 421 if (Dart_IsError(source)) | |
| 422 return source; | |
| 423 return Dart_LoadSource(library, url, source); | |
| 424 } | |
| 425 break; | |
| 426 default: | |
| 427 DART_UNIMPLEMENTED(); | |
| 428 break; | |
| 429 } | |
| 430 ASSERT_NOT_REACHED(); | |
| 431 return result; | |
| 432 } | |
| 433 | |
| 434 | |
| 435 void DartService::VmServiceShutdownCallback(void* callbackData) | |
| 436 { | |
| 437 ASSERT(Dart_CurrentIsolate()); | |
| 438 DartApiScope apiScope; | |
| 439 SendIsolateShutdownMessage(); | |
| 440 } | |
| 441 | |
| 442 static void SendServiceMessage(Dart_NativeArguments args) | |
| 443 { | |
| 444 Dart_Handle sp = Dart_GetNativeArgument(args, 0); | |
| 445 Dart_Handle message = Dart_GetNativeArgument(args, 1); | |
| 446 DartServiceInternal::PostOOB(sp, message); | |
| 447 } | |
| 448 | |
| 449 static void PostResponse(Dart_NativeArguments args) | 186 static void PostResponse(Dart_NativeArguments args) |
| 450 { | 187 { |
| 451 Dart_Handle result; | 188 Dart_Handle result; |
| 452 UNUSED_PARAM(result); | 189 UNUSED_PARAM(result); |
| 453 Dart_Handle response = Dart_GetNativeArgument(args, 0); | 190 Dart_Handle response = Dart_GetNativeArgument(args, 0); |
| 454 ASSERT(!Dart_IsError(response)); | 191 ASSERT(!Dart_IsError(response)); |
| 455 Dart_Handle cookie = Dart_GetNativeArgument(args, 1); | 192 Dart_Handle cookie = Dart_GetNativeArgument(args, 1); |
| 456 ASSERT(!Dart_IsError(cookie)); | 193 ASSERT(!Dart_IsError(cookie)); |
| 457 int64_t requestAddress64 = 0; | 194 int64_t requestAddress64 = 0; |
| 458 result = Dart_IntegerToInt64(cookie, &requestAddress64); | 195 result = Dart_IntegerToInt64(cookie, &requestAddress64); |
| 459 ASSERT(!Dart_IsError(result)); | 196 ASSERT(!Dart_IsError(result)); |
| 460 ASSERT(requestAddress64); | 197 ASSERT(requestAddress64); |
| 461 intptr_t requestAddress = static_cast<intptr_t>(requestAddress64); | 198 intptr_t requestAddress = static_cast<intptr_t>(requestAddress64); |
| 462 ASSERT(requestAddress); | 199 ASSERT(requestAddress); |
| 463 DartServiceRequest* request = reinterpret_cast<DartServiceRequest*>(requestA ddress); | 200 DartServiceRequest* request = reinterpret_cast<DartServiceRequest*>(requestA ddress); |
| 464 const char* responseString = 0; | 201 const char* responseString = 0; |
| 465 result = Dart_StringToCString(response, &responseString); | 202 result = Dart_StringToCString(response, &responseString); |
| 466 ASSERT(!Dart_IsError(result)); | 203 ASSERT(!Dart_IsError(result)); |
| 467 ASSERT(responseString); | 204 ASSERT(responseString); |
| 468 request->ResponseReady(responseString); | 205 request->ResponseReady(responseString); |
| 469 } | 206 } |
| 470 | 207 |
| 208 | |
| 471 struct VmServiceNativeEntry { | 209 struct VmServiceNativeEntry { |
| 472 const char* name; | 210 const char* name; |
| 473 int numArguments; | 211 int numArguments; |
| 474 Dart_NativeFunction function; | 212 Dart_NativeFunction function; |
| 475 }; | 213 }; |
| 476 | 214 |
| 477 | 215 |
| 478 static VmServiceNativeEntry VmServiceNativeEntries[] = { | 216 static VmServiceNativeEntry VmServiceNativeEntries[] = { |
| 479 {"VMService_SendServiceMessage", 2, SendServiceMessage}, | |
| 480 {"VMService_PostResponse", 2, PostResponse} | 217 {"VMService_PostResponse", 2, PostResponse} |
| 481 }; | 218 }; |
| 482 | 219 |
| 483 | 220 |
| 484 Dart_NativeFunction DartService::NativeResolver(Dart_Handle name, int numArgumen ts, bool* autoScopeSetup) | 221 Dart_NativeFunction DartService::NativeResolver(Dart_Handle name, int numArgumen ts, bool* autoScopeSetup) |
| 485 { | 222 { |
| 486 const char* functionName = 0; | 223 const char* functionName = 0; |
| 487 Dart_Handle result = Dart_StringToCString(name, &functionName); | 224 Dart_Handle result = Dart_StringToCString(name, &functionName); |
| 488 UNUSED_PARAM(result); | 225 UNUSED_PARAM(result); |
| 489 ASSERT(!Dart_IsError(result)); | 226 ASSERT(!Dart_IsError(result)); |
| 490 ASSERT(functionName); | 227 ASSERT(functionName); |
| 491 ASSERT(autoScopeSetup); | 228 ASSERT(autoScopeSetup); |
| 492 *autoScopeSetup = true; | 229 *autoScopeSetup = true; |
| 493 intptr_t n = sizeof(VmServiceNativeEntries) / sizeof(VmServiceNativeEntries[ 0]); | 230 intptr_t n = sizeof(VmServiceNativeEntries) / sizeof(VmServiceNativeEntries[ 0]); |
| 494 for (intptr_t i = 0; i < n; i++) { | 231 for (intptr_t i = 0; i < n; i++) { |
| 495 VmServiceNativeEntry entry = VmServiceNativeEntries[i]; | 232 VmServiceNativeEntry entry = VmServiceNativeEntries[i]; |
| 496 if (!strcmp(functionName, entry.name) && (numArguments == entry.numArgum ents)) { | 233 if (!strcmp(functionName, entry.name) && (numArguments == entry.numArgum ents)) { |
| 497 return entry.function; | 234 return entry.function; |
| 498 } | 235 } |
| 499 } | 236 } |
| 500 return 0; | 237 return 0; |
| 501 } | 238 } |
| 502 | 239 |
| 503 } | 240 } |
| OLD | NEW |