Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Side by Side Diff: Source/bindings/dart/DartService.cpp

Issue 104433004: Enable VM service inside Dartium Renderer processes (Closed) Base URL: svn://svn.chromium.org/multivm/branches/1650/blink
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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/dart/DartService.h"
8
9 #include "DartApplicationLoader.h"
10 #include "DartController.h"
11 #include "DartDocument.h"
12 #include "DartServiceInternal.h"
13 #include "DartUtilities.h"
14 #include "DartWindow.h"
15
16
17 // These must be kept in sync with vmservice/constants.dart
Jacob 2013/12/04 20:39:52 nit: these could be kept in sync automatically by
Cutch 2013/12/04 21:20:50 Done.
18 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
19 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2
20
21 // The following Resources class is used in combination with a generated
22 // source file that expects underscores in names. The NOLINT tags are
23 // used to suppress the errors.
24 namespace dart {
Jacob 2013/12/04 20:39:52 having files with the namespace dart::bin seems st
Cutch 2013/12/04 21:20:50 Added TODO. Moving the namespace requires surgery
25 namespace bin {
26 class Resources {
27 public:
28 static const int kNoSuchInstance = -1;
29
30 static int ResourceLookup(const char* path, const char** resource)
31 {
32 for (int i = 0; i < get_resource_count(); i++) {
33 resource_map_entry* entry = get_resource(i);
34 if (!strcmp(path, entry->path_)) {
35 *resource = entry->resource_;
36 ASSERT(entry->length_ > 0);
37 return entry->length_;
38 }
39 }
40 return kNoSuchInstance;
41 }
42
43 static intptr_t get_resource_count() // NOLINT.
44 {
45 return builtin_resources_count_;
46 }
47
48 static const char* get_resource_path(intptr_t i) // NOLINT.
49 {
50 return get_resource(i)->path_;
51 }
52
53 private:
54 struct resource_map_entry { // NOLINT.
55 const char* path_; // NOLINT.
56 const char* resource_; // NOLINT.
57 intptr_t length_; // NOLINT.
58 };
59
60 // These fields are generated by resources_gen.cc.
61 static resource_map_entry builtin_resources_[]; // NOLINT.
62 static const intptr_t builtin_resources_count_; // NOLINT.
63
64 static resource_map_entry* get_resource(int i) // NOLINT.
65 {
66 ASSERT(i >= 0 && i < builtin_resources_count_);
67 return &builtin_resources_[i];
68 }
69
70 DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
71 };
72
73 }
74 }
75 namespace WebCore {
76
77 #define RETURN_ERROR_HANDLE(handle) \
78 if (Dart_IsError(handle)) { \
79 return handle; \
80 }
81
82 #define SHUTDOWN_ON_ERROR(handle) \
83 if (Dart_IsError(handle)) { \
84 m_errorMsg = strdup(Dart_GetError(handle)); \
85 Dart_ExitScope(); \
86 Dart_ShutdownIsolate(); \
87 return false; \
88 }
89
90 #define kLibraryResourceNamePrefix "/vmservice"
91 static const char* kVMServiceDartiumLibraryScriptResourceName =
92 kLibraryResourceNamePrefix "/vmservice_dartium.dart";
93 static const char* kVMServiceLibraryName =
94 kLibraryResourceNamePrefix "/vmservice.dart";
95
96
97 Dart_Isolate DartService::m_isolate = 0;
98 Dart_Port DartService::m_port = ILLEGAL_PORT;
99 Dart_Port DartService::m_requestPort = ILLEGAL_PORT;
100 const char* DartService::m_errorMsg = 0;
101
102
103 bool DartService::Start(Document* document)
104 {
105 ASSERT(!m_isolate);
106 char* error = 0;
107 const char* scriptUri = "vmservice:";
Jacob 2013/12/04 20:39:52 move this constant outside of the method
Cutch 2013/12/04 21:20:50 Done.
108 m_isolate = DartController::createIsolate(scriptUri, "main", document, true, &error);
109 if (!m_isolate) {
110 m_errorMsg = error;
111 return false;
112 }
113
114
115 Dart_EnterScope();
116
117 // Set up the library tag handler for this isolate.
118 Dart_Handle result = Dart_SetLibraryTagHandler(LibraryTagHandler);
119 SHUTDOWN_ON_ERROR(result);
Jacob 2013/12/04 20:39:52 for consistency use the Scope auto-release helper
Cutch 2013/12/04 21:20:50 Done.
120
121 {
122 // Load source into service isolate.
123 Dart_Handle library =
124 LoadScript(kVMServiceDartiumLibraryScriptResourceName);
125 SHUTDOWN_ON_ERROR(library);
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 _receivePort
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 _receive Port
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 }
179
180
181 bool DartService::Stop()
182 {
183 // TODO: Properly cleanup VM service isolate.
184 m_port = ILLEGAL_PORT;
185 return true;
186 }
187
188
189 const char* DartService::GetErrorMessage()
190 {
191 return m_errorMsg ? m_errorMsg : "No error.";
192 }
193
194
195 Dart_Port DartService::port()
196 {
197 return m_port;
198 }
199
200
201 bool DartService::IsRunning()
202 {
203 return m_port != ILLEGAL_PORT;
204 }
205
206
207 static Dart_Handle MakeServiceControlMessage(Dart_Port portId, intptr_t code, Da rt_Handle name)
208 {
209 Dart_Handle result;
210 Dart_Handle list = Dart_NewList(4);
211 ASSERT(!Dart_IsError(list));
212 Dart_Handle codeHandle = Dart_NewInteger(code);
213 ASSERT(!Dart_IsError(codeHandle));
214 result = Dart_ListSetAt(list, 0, codeHandle);
215 ASSERT(!Dart_IsError(result));
216 Dart_Handle portIdHandle = Dart_NewInteger(portId);
217 ASSERT(!Dart_IsError(portIdHandle));
218 result = Dart_ListSetAt(list, 1, portIdHandle);
219 ASSERT(!Dart_IsError(result));
220 Dart_Handle sendPort = Dart_NewSendPort(portId);
221 ASSERT(!Dart_IsError(sendPort));
222 result = Dart_ListSetAt(list, 2, sendPort);
223 ASSERT(!Dart_IsError(result));
224 result = Dart_ListSetAt(list, 3, name);
225 ASSERT(!Dart_IsError(result));
226 return list;
227 }
228
229
230 bool DartService::SendIsolateStartupMessage()
231 {
232 if (!IsRunning()) {
233 return false;
234 }
235 Dart_Handle name = Dart_DebugName();
236 ASSERT(!Dart_IsError(name));
237 Dart_Handle list = MakeServiceControlMessage(
Jacob 2013/12/04 20:39:52 there isn't an 80 char line limit in this director
Cutch 2013/12/04 21:20:50 Done.
238 Dart_GetMainPortId(),
239 VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID,
240 name);
241 ASSERT(!Dart_IsError(list));
242 return Dart_Post(m_port, list);
243 }
244
245
246 bool DartService::SendIsolateShutdownMessage()
247 {
248 if (!IsRunning()) {
249 return false;
250 }
251 Dart_Handle list = MakeServiceControlMessage(Dart_GetMainPortId(), VM_SERVIC E_ISOLATE_SHUTDOWN_MESSAGE_ID, Dart_Null());
252 ASSERT(!Dart_IsError(list));
253 return Dart_Post(m_port, list);
254 }
255
256
257 Dart_Handle DartService::GetSource(const char* name)
258 {
259 const char* vmserviceSource = 0;
260 int r = dart::bin::Resources::ResourceLookup(name, &vmserviceSource);
261 ASSERT(r != dart::bin::Resources::kNoSuchInstance);
262 return Dart_NewStringFromCString(vmserviceSource);
263 }
264
265
266 Dart_Handle DartService::LoadScript(const char* name)
267 {
268 Dart_Handle url = Dart_NewStringFromCString(name);
269 Dart_Handle source = GetSource(name);
270 return Dart_LoadScript(url, source, 0, 0);
271 }
272
273
274 Dart_Handle DartService::LoadSource(Dart_Handle library, const char* name)
275 {
276 Dart_Handle url = Dart_NewStringFromCString(name);
277 Dart_Handle source = GetSource(name);
278 return Dart_LoadSource(library, url, source);
279 }
280
281
282 Dart_Handle DartService::LoadSources(Dart_Handle library, const char* names[])
283 {
284 Dart_Handle result = Dart_Null();
285 for (int i = 0; names[i]; i++) {
286 result = LoadSource(library, names[i]);
287 if (Dart_IsError(result)) {
288 break;
Jacob 2013/12/04 20:39:52 here and elsewhere, remove { } for single line
Cutch 2013/12/04 21:20:50 Done.
289 }
290 }
291 return result;
292 }
293
294
295 static bool IsVMServiceURL(const char* url)
296 {
297 static const intptr_t kLibraryResourceNamePrefixLen = strlen(kLibraryResourc eNamePrefix);
298 return !strncmp(kLibraryResourceNamePrefix, url, kLibraryResourceNamePrefixL en);
299 }
300
301
302 static bool IsVMServiceLibrary(const char* url)
303 {
304 return !strcmp(kVMServiceLibraryName, url);
305 }
306
307 static bool IsDartLibrary(const char* url)
Jacob 2013/12/04 20:39:52 I assume this is probably defined somewhere else a
Cutch 2013/12/04 21:20:50 It actually is not.
308 {
309 static const char* kDartPrefix = "dart:";
310 static const intptr_t kDartPrefixLen = strlen(kDartPrefix);
311 return !strncmp(kDartPrefix, url, kDartPrefixLen);
312 }
313
314 static Dart_Handle Canonicalize(const char* url)
315 {
316 if (IsVMServiceURL(url)) {
317 // Already canonicalized.
318 return Dart_NewStringFromCString(url);
319 }
320 char buffer[1024];
Jacob 2013/12/04 20:39:52 add FIXME to not hardcode 1024 here.
Cutch 2013/12/04 21:20:50 Done.
321 snprintf(&buffer[0], sizeof(buffer), "%s/%s", kLibraryResourceNamePrefix, ur l);
322 return Dart_NewStringFromCString(buffer);
323 }
324
325
326 Dart_Handle DartService::LibraryTagHandler(Dart_LibraryTag tag, Dart_Handle libr ary, Dart_Handle url)
327 {
328 if (!Dart_IsLibrary(library)) {
329 return Dart_NewApiError("not a library");
330 }
331 if (!Dart_IsString(url)) {
332 return Dart_NewApiError("url is not a string");
333 }
334 const char* urlString = 0;
335 Dart_Handle result = Dart_StringToCString(url, &urlString);
336 if (Dart_IsError(result)) {
337 return result;
338 }
339 Dart_Handle libraryUrl = Dart_LibraryUrl(library);
340 const char* libraryUrlString = 0;
341 result = Dart_StringToCString(libraryUrl, &libraryUrlString);
342 if (Dart_IsError(result)) {
343 return result;
344 }
345 if (IsDartLibrary(urlString)) {
346 return DartApplicationLoader::libraryTagHandlerCallback(tag, library, ur l);
347 }
348 switch (tag) {
349 case Dart_kCanonicalizeUrl:
350 return Canonicalize(urlString);
351 break;
352 case Dart_kImportTag: {
353 Dart_Handle source = GetSource(urlString);
354 if (Dart_IsError(source)) {
355 return source;
356 }
357 Dart_Handle lib = Dart_LoadLibrary(url, source);
358 if (Dart_IsError(lib)) {
359 return lib;
360 }
361 if (IsVMServiceLibrary(urlString)) {
362 // Install native resolver for this library.
363 result = Dart_SetNativeResolver(lib, DartService::NativeResolver);
364 if (Dart_IsError(result)) {
365 return result;
366 }
367 }
368 return lib;
369 }
370 break;
371 case Dart_kSourceTag: {
372 Dart_Handle source = GetSource(urlString);
373 if (Dart_IsError(source)) {
374 return source;
375 }
376 return Dart_LoadSource(library, url, source);
377 }
378 break;
379 default:
380 DART_UNIMPLEMENTED();
381 break;
382 }
383 DART_UNIMPLEMENTED();
Jacob 2013/12/04 20:39:52 DART_UNIMPLEMENTED seems wrong here. this is hitti
Cutch 2013/12/04 21:20:50 Replaced with ASSERT_NOT_REACHED
384 return result;
385 }
386
387
388 void DartService::VmServiceShutdownCallback(void* callbackData)
389 {
390 ASSERT(Dart_CurrentIsolate());
391 Dart_EnterScope();
392 SendIsolateShutdownMessage();
393 Dart_ExitScope();
394 }
395
396 static void SendServiceMessage(Dart_NativeArguments args)
397 {
398 Dart_Handle sp = Dart_GetNativeArgument(args, 0);
399 Dart_Handle rp = Dart_GetNativeArgument(args, 1);
400 Dart_Handle message = Dart_GetNativeArgument(args, 2);
401 DartServiceInternal::PostOOB(sp, rp, message);
402 }
403
404
405 struct VmServiceNativeEntry {
406 const char* name;
407 int numArguments;
408 Dart_NativeFunction function;
409 };
410
411
412 static VmServiceNativeEntry VmServiceNativeEntries[] = {
413 {"SendServiceMessage", 3, SendServiceMessage}
414 };
415
416
417 Dart_NativeFunction DartService::NativeResolver(Dart_Handle name, int numArgumen ts)
418 {
419 const char* functionName = 0;
420 Dart_Handle result = Dart_StringToCString(name, &functionName);
421 ASSERT(!Dart_IsError(result));
422 ASSERT(functionName);
423 intptr_t n = sizeof(VmServiceNativeEntries) / sizeof(VmServiceNativeEntries[ 0]);
424 for (intptr_t i = 0; i < n; i++) {
425 VmServiceNativeEntry entry = VmServiceNativeEntries[i];
426 if (!strcmp(functionName, entry.name) && (numArguments == entry.numArgum ents)) {
427 return entry.function;
428 }
429 }
430 return 0;
431 }
432
433 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698