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

Side by Side Diff: runtime/bin/vmservice_impl.cc

Issue 125103004: Move service into VM (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 months 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
« no previous file with comments | « runtime/bin/vmservice_impl.h ('k') | runtime/include/dart_api.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "bin/vmservice_impl.h" 5 #include "bin/vmservice_impl.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 8
9 #include "bin/builtin.h" 9 #include "bin/builtin.h"
10 #include "bin/dartutils.h" 10 #include "bin/dartutils.h"
11 #include "bin/isolate_data.h" 11 #include "bin/isolate_data.h"
12 #include "bin/resources.h"
13 #include "bin/thread.h" 12 #include "bin/thread.h"
14 13
15 #include "vm/dart_api_impl.h"
16 #include "vm/dart_entry.h"
17 #include "vm/isolate.h"
18 #include "vm/message.h"
19 #include "vm/native_entry.h"
20 #include "vm/native_arguments.h"
21 #include "vm/object.h"
22 #include "vm/port.h"
23 #include "vm/snapshot.h"
24
25 namespace dart { 14 namespace dart {
26 namespace bin { 15 namespace bin {
27 16
28 // snapshot_buffer points to a snapshot if we link in a snapshot otherwise
29 // it is initialized to NULL.
30 extern const uint8_t* snapshot_buffer;
31 #define RETURN_ERROR_HANDLE(handle) \ 17 #define RETURN_ERROR_HANDLE(handle) \
32 if (Dart_IsError(handle)) { \ 18 if (Dart_IsError(handle)) { \
33 return handle; \ 19 return handle; \
34 } 20 }
35 21
36 #define SHUTDOWN_ON_ERROR(handle) \ 22 #define SHUTDOWN_ON_ERROR(handle) \
37 if (Dart_IsError(handle)) { \ 23 if (Dart_IsError(handle)) { \
38 error_msg_ = strdup(Dart_GetError(handle)); \ 24 error_msg_ = strdup(Dart_GetError(handle)); \
39 Dart_ExitScope(); \ 25 Dart_ExitScope(); \
40 Dart_ShutdownIsolate(); \ 26 Dart_ShutdownIsolate(); \
41 return false; \ 27 return false; \
42 } 28 }
43 29
44 #define kLibraryResourceNamePrefix "/vmservice" 30 #define kLibrarySourceNamePrefix "/vmservice"
45 static const char* kVMServiceIOLibraryScriptResourceName = 31 static const char* kVMServiceIOLibraryScriptResourceName = "vmservice_io.dart";
46 kLibraryResourceNamePrefix "/vmservice_io.dart";
47 static const char* kVMServiceLibraryName =
48 kLibraryResourceNamePrefix "/vmservice.dart";
49
50 #define kClientResourceNamePrefix "/vmservice/client/deployed/web" 32 #define kClientResourceNamePrefix "/vmservice/client/deployed/web"
51 33
52 Dart_Isolate VmService::isolate_ = NULL; 34 struct ResourcesEntry {
53 Dart_Port VmService::port_ = ILLEGAL_PORT; 35 const char* path_;
54 dart::Monitor* VmService::monitor_ = NULL; 36 const char* resource_;
37 int length_;
38 };
39
40 extern ResourcesEntry __service_bin_resources_[];
41
42 class Resources {
43 public:
44 static const int kNoSuchInstance = -1;
45 static int ResourceLookup(const char* path, const char** resource) {
46 ResourcesEntry* table = ResourcesTable();
47 for (int i = 0; table[i].path_ != NULL; i++) {
48 const ResourcesEntry& entry = table[i];
49 if (strcmp(path, entry.path_) == 0) {
50 *resource = entry.resource_;
51 ASSERT(entry.length_ > 0);
52 return entry.length_;
53 }
54 }
55 return kNoSuchInstance;
56 }
57
58 static const char* Path(int idx) {
59 ASSERT(idx >= 0);
60 ResourcesEntry* entry = At(idx);
61 if (entry == NULL) {
62 return NULL;
63 }
64 ASSERT(entry->path_ != NULL);
65 return entry->path_;
66 }
67
68 private:
69 static ResourcesEntry* At(int idx) {
70 ASSERT(idx >= 0);
71 ResourcesEntry* table = ResourcesTable();
72 for (int i = 0; table[i].path_ != NULL; i++) {
73 if (idx == i) {
74 return &table[i];
75 }
76 }
77 return NULL;
78 }
79 static ResourcesEntry* ResourcesTable() {
80 return &__service_bin_resources_[0];
81 }
82
83 DISALLOW_ALLOCATION();
84 DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
85 };
86
55 const char* VmService::error_msg_ = NULL; 87 const char* VmService::error_msg_ = NULL;
56 88
57 // These must be kept in sync with vmservice/constants.dart
58 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
59 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2
60
61
62 static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name,
63 int num_arguments,
64 bool* auto_setup_scope);
65
66
67 bool VmService::Start(intptr_t server_port) { 89 bool VmService::Start(intptr_t server_port) {
68 monitor_ = new dart::Monitor(); 90 bool r = _Start(server_port);
69 ASSERT(monitor_ != NULL); 91 if (!r) {
70 error_msg_ = NULL; 92 return r;
71
72
73 {
74 // Take lock before spawning new thread.
75 MonitorLocker ml(monitor_);
76 // Spawn new thread.
77 dart::Thread::Start(ThreadMain, server_port);
78 // Wait until service is running on spawned thread.
79 ml.Wait();
80 } 93 }
81 return port_ != ILLEGAL_PORT; 94 // Start processing messages in a new thread.
95 dart::Thread::Start(ThreadMain, NULL);
96 return true;
82 } 97 }
83 98
84 99
85 bool VmService::_Start(intptr_t server_port) { 100 bool VmService::_Start(intptr_t server_port) {
86 ASSERT(isolate_ == NULL); 101 ASSERT(Dart_CurrentIsolate() == NULL);
87 char* error = NULL; 102 Dart_Isolate isolate = Dart_GetServiceIsolate(NULL);
88 const char* script_uri = "vmservice:"; 103 if (isolate == NULL) {
89 IsolateData* isolate_data = new IsolateData(script_uri); 104 error_msg_ = "Internal error.";
90 isolate_ = Dart_CreateIsolate(script_uri, "main", snapshot_buffer,
91 isolate_data,
92 &error);
93 if (isolate_ == NULL) {
94 error_msg_ = error;
95 return false; 105 return false;
96 } 106 }
97 107 Dart_EnterIsolate(isolate);
98 Dart_EnterScope(); 108 Dart_EnterScope();
99 109 // Install our own library tag handler.
100 if (snapshot_buffer != NULL) { 110 Dart_SetLibraryTagHandler(LibraryTagHandler);
101 // Setup the native resolver as the snapshot does not carry it. 111 Dart_Handle result;
102 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); 112 Dart_Handle library = LoadScript(kVMServiceIOLibraryScriptResourceName);
103 Builtin::SetNativeResolver(Builtin::kIOLibrary); 113 // Expect a library.
104 } 114 ASSERT(library != Dart_Null());
105 115 SHUTDOWN_ON_ERROR(library);
106 // Set up the library tag handler for this isolate.
107 Dart_Handle result = Dart_SetLibraryTagHandler(LibraryTagHandler);
108 SHUTDOWN_ON_ERROR(result);
109
110 // Load the specified application script into the newly created isolate.
111
112 // Prepare builtin and its dependent libraries for use to resolve URIs.
113 // The builtin library is part of the core snapshot and would already be
114 // available here in the case of script snapshot loading.
115 Dart_Handle builtin_lib =
116 Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
117 SHUTDOWN_ON_ERROR(builtin_lib);
118
119 // Prepare for script loading by setting up the 'print' and 'timer'
120 // closures and setting up 'package root' for URI resolution.
121 result = DartUtils::PrepareForScriptLoading("", builtin_lib);
122 SHUTDOWN_ON_ERROR(result);
123
124 {
125 // Load source into service isolate.
126 Dart_Handle library = LoadScript(kVMServiceIOLibraryScriptResourceName);
127 SHUTDOWN_ON_ERROR(library);
128 }
129
130 // Make the isolate runnable so that it is ready to handle messages.
131 Dart_ExitScope(); 116 Dart_ExitScope();
132 Dart_ExitIsolate(); 117 Dart_ExitIsolate();
133 118 bool retval = Dart_IsolateMakeRunnable(isolate);
134 bool retval = Dart_IsolateMakeRunnable(isolate_);
135 if (!retval) { 119 if (!retval) {
136 Dart_EnterIsolate(isolate_); 120 Dart_EnterIsolate(isolate);
137 Dart_ShutdownIsolate(); 121 Dart_ShutdownIsolate();
138 error_msg_ = "Invalid isolate state - Unable to make it runnable."; 122 error_msg_ = "Invalid isolate state - Unable to make it runnable.";
139 return false; 123 return false;
140 } 124 }
141 125
142 Dart_EnterIsolate(isolate_); 126 Dart_EnterIsolate(isolate);
143 Dart_EnterScope(); 127 Dart_EnterScope();
144 128 library = Dart_RootLibrary();
145
146 Dart_Handle library = Dart_RootLibrary();
147 // Set requested TCP port. 129 // Set requested TCP port.
148 DartUtils::SetIntegerField(library, "_port", server_port); 130 DartUtils::SetIntegerField(library, "_port", server_port);
149 result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL); 131 result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
150 SHUTDOWN_ON_ERROR(result); 132 SHUTDOWN_ON_ERROR(result);
151 133 // Load resources.
152 // Retrieve the ReceivePort that the service is waiting on. The _receivePort
153 // variable is setup in the call to main.
154 Dart_Handle receivePort = Dart_GetField(library,
155 DartUtils::NewString("_receivePort"));
156 SHUTDOWN_ON_ERROR(receivePort);
157
158 {
159 // Extract the Dart_Port from the receive port.
160 HANDLESCOPE(Isolate::Current());
161 const Object& unwrapped_rp = Object::Handle(Api::UnwrapHandle(receivePort));
162 const Instance& rp = Instance::Cast(unwrapped_rp);
163 // Extract ReceivePort port id.
164 const Object& rp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(rp));
165 if (rp_id_obj.IsError()) {
166 const Error& error = Error::Cast(rp_id_obj);
167 error_msg_ = strdup(error.ToErrorCString());
168 Dart_ExitScope();
169 Dart_ShutdownIsolate();
170 return false;
171 }
172 ASSERT(rp_id_obj.IsSmi() || rp_id_obj.IsMint());
173 Integer& id = Integer::Handle();
174 id ^= rp_id_obj.raw();
175 port_ = static_cast<Dart_Port>(id.AsInt64Value());
176 }
177
178 Dart_Handle library_name = Dart_NewStringFromCString(kVMServiceLibraryName);
179 library = Dart_LookupLibrary(library_name);
180 SHUTDOWN_ON_ERROR(library);
181 result = LoadResources(library); 134 result = LoadResources(library);
182 SHUTDOWN_ON_ERROR(result); 135 SHUTDOWN_ON_ERROR(result);
183 136
184 Dart_ExitScope(); 137 Dart_ExitScope();
185 Dart_ExitIsolate(); 138 Dart_ExitIsolate();
186 139
187 return true; 140 return true;
188 } 141 }
189 142
190 143
191 void VmService::_Stop() {
192 port_ = ILLEGAL_PORT;
193 }
194
195
196 const char* VmService::GetErrorMessage() { 144 const char* VmService::GetErrorMessage() {
197 return error_msg_ == NULL ? "No error." : error_msg_; 145 return error_msg_ == NULL ? "No error." : error_msg_;
198 } 146 }
199 147
200 148
201 Dart_Port VmService::port() {
202 return port_;
203 }
204
205
206 bool VmService::IsRunning() {
207 return port_ != ILLEGAL_PORT;
208 }
209
210
211 Dart_Handle VmService::GetSource(const char* name) { 149 Dart_Handle VmService::GetSource(const char* name) {
150 const intptr_t kBufferSize = 512;
151 char buffer[kBufferSize];
152 snprintf(&buffer[0], kBufferSize-1, "%s/%s", kLibrarySourceNamePrefix, name);
212 const char* vmservice_source = NULL; 153 const char* vmservice_source = NULL;
213 int r = Resources::ResourceLookup(name, &vmservice_source); 154 int r = Resources::ResourceLookup(buffer, &vmservice_source);
214 ASSERT(r != Resources::kNoSuchInstance); 155 ASSERT(r != Resources::kNoSuchInstance);
215 return Dart_NewStringFromCString(vmservice_source); 156 return Dart_NewStringFromCString(vmservice_source);
216 } 157 }
217 158
218 159
219 Dart_Handle VmService::LoadScript(const char* name) { 160 Dart_Handle VmService::LoadScript(const char* name) {
220 Dart_Handle url = Dart_NewStringFromCString(name); 161 Dart_Handle url = Dart_NewStringFromCString("dart:vmservice_io");
221 Dart_Handle source = GetSource(name); 162 Dart_Handle source = GetSource(name);
222 return Dart_LoadScript(url, source, 0, 0); 163 return Dart_LoadScript(url, source, 0, 0);
223 } 164 }
224 165
225 166
226 Dart_Handle VmService::LoadSource(Dart_Handle library, const char* name) { 167 Dart_Handle VmService::LoadSource(Dart_Handle library, const char* name) {
227 Dart_Handle url = Dart_NewStringFromCString(name); 168 Dart_Handle url = Dart_NewStringFromCString(name);
228 Dart_Handle source = GetSource(name); 169 Dart_Handle source = GetSource(name);
229 return Dart_LoadSource(library, url, source); 170 return Dart_LoadSource(library, url, source);
230 } 171 }
231 172
232 173
233 Dart_Handle VmService::LoadSources(Dart_Handle library, const char* names[]) {
234 Dart_Handle result = Dart_Null();
235 for (int i = 0; names[i] != NULL; i++) {
236 result = LoadSource(library, names[i]);
237 if (Dart_IsError(result)) {
238 break;
239 }
240 }
241 return result;
242 }
243
244
245 Dart_Handle VmService::LoadResource(Dart_Handle library, 174 Dart_Handle VmService::LoadResource(Dart_Handle library,
246 const char* resource_name, 175 const char* resource_name,
247 const char* prefix) { 176 const char* prefix) {
248 intptr_t prefix_len = strlen(prefix); 177 intptr_t prefix_len = strlen(prefix);
249 // Prepare for invoke call. 178 // Prepare for invoke call.
250 Dart_Handle name = Dart_NewStringFromCString(resource_name+prefix_len); 179 Dart_Handle name = Dart_NewStringFromCString(resource_name+prefix_len);
251 RETURN_ERROR_HANDLE(name); 180 RETURN_ERROR_HANDLE(name);
252 const char* data_buffer = NULL; 181 const char* data_buffer = NULL;
253 int data_buffer_length = Resources::ResourceLookup(resource_name, 182 int data_buffer_length = Resources::ResourceLookup(resource_name,
254 &data_buffer); 183 &data_buffer);
(...skipping 23 matching lines...) Expand all
278 Dart_Handle args[kNumArgs] = { name, data_list }; 207 Dart_Handle args[kNumArgs] = { name, data_list };
279 result = Dart_Invoke(library, Dart_NewStringFromCString("_addResource"), 208 result = Dart_Invoke(library, Dart_NewStringFromCString("_addResource"),
280 kNumArgs, args); 209 kNumArgs, args);
281 return result; 210 return result;
282 } 211 }
283 212
284 213
285 Dart_Handle VmService::LoadResources(Dart_Handle library) { 214 Dart_Handle VmService::LoadResources(Dart_Handle library) {
286 Dart_Handle result = Dart_Null(); 215 Dart_Handle result = Dart_Null();
287 intptr_t prefixLen = strlen(kClientResourceNamePrefix); 216 intptr_t prefixLen = strlen(kClientResourceNamePrefix);
288 for (intptr_t i = 0; i < Resources::get_resource_count(); i++) { 217 for (intptr_t i = 0; Resources::Path(i) != NULL; i++) {
289 const char* path = Resources::get_resource_path(i); 218 const char* path = Resources::Path(i);
290 if (!strncmp(path, kClientResourceNamePrefix, prefixLen)) { 219 if (!strncmp(path, kClientResourceNamePrefix, prefixLen)) {
291 result = LoadResource(library, path, kClientResourceNamePrefix); 220 result = LoadResource(library, path, kClientResourceNamePrefix);
292 if (Dart_IsError(result)) { 221 if (Dart_IsError(result)) {
293 break; 222 break;
294 } 223 }
295 } 224 }
296 } 225 }
297 return result; 226 return result;
298 } 227 }
299 228
300 229
301 static bool IsVMServiceURL(const char* url) {
302 static const intptr_t kLibraryResourceNamePrefixLen =
303 strlen(kLibraryResourceNamePrefix);
304 return 0 == strncmp(kLibraryResourceNamePrefix, url,
305 kLibraryResourceNamePrefixLen);
306 }
307
308
309 static bool IsVMServiceLibrary(const char* url) {
310 return 0 == strcmp(kVMServiceLibraryName, url);
311 }
312
313
314 Dart_Handle VmService::LibraryTagHandler(Dart_LibraryTag tag, 230 Dart_Handle VmService::LibraryTagHandler(Dart_LibraryTag tag,
315 Dart_Handle library, 231 Dart_Handle library,
316 Dart_Handle url) { 232 Dart_Handle url) {
317 if (!Dart_IsLibrary(library)) { 233 if (!Dart_IsLibrary(library)) {
318 return Dart_NewApiError("not a library"); 234 return Dart_NewApiError("not a library");
319 } 235 }
320 if (!Dart_IsString(url)) { 236 if (!Dart_IsString(url)) {
321 return Dart_NewApiError("url is not a string"); 237 return Dart_NewApiError("url is not a string");
322 } 238 }
323 const char* url_string = NULL; 239 const char* url_string = NULL;
324 Dart_Handle result = Dart_StringToCString(url, &url_string); 240 Dart_Handle result = Dart_StringToCString(url, &url_string);
325 if (Dart_IsError(result)) { 241 if (Dart_IsError(result)) {
326 return result; 242 return result;
327 } 243 }
328 Dart_Handle library_url = Dart_LibraryUrl(library); 244 Dart_Handle library_url = Dart_LibraryUrl(library);
329 const char* library_url_string = NULL; 245 const char* library_url_string = NULL;
330 result = Dart_StringToCString(library_url, &library_url_string); 246 result = Dart_StringToCString(library_url, &library_url_string);
331 if (Dart_IsError(result)) { 247 if (Dart_IsError(result)) {
332 return result; 248 return result;
333 } 249 }
334 bool is_vm_service_url = IsVMServiceURL(url_string); 250 if (tag == Dart_kImportTag) {
335 if (!is_vm_service_url) { 251 // Embedder handles all requests for external libraries.
336 // Pass to DartUtils.
337 return DartUtils::LibraryTagHandler(tag, library, url); 252 return DartUtils::LibraryTagHandler(tag, library, url);
338 } 253 }
339 switch (tag) { 254 ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl));
340 case Dart_kCanonicalizeUrl: 255 if (tag == Dart_kCanonicalizeUrl) {
341 // The URL is already canonicalized. 256 // url is already canonicalized.
342 return url; 257 return url;
343 break;
344 case Dart_kImportTag: {
345 Dart_Handle source = GetSource(url_string);
346 if (Dart_IsError(source)) {
347 return source;
348 }
349 Dart_Handle lib = Dart_LoadLibrary(url, source);
350 if (Dart_IsError(lib)) {
351 return lib;
352 }
353 if (IsVMServiceLibrary(url_string)) {
354 // Install native resolver for this library.
355 result = Dart_SetNativeResolver(lib, VmServiceNativeResolver);
356 if (Dart_IsError(result)) {
357 return result;
358 }
359 }
360 return lib;
361 }
362 break;
363 case Dart_kSourceTag: {
364 Dart_Handle source = GetSource(url_string);
365 if (Dart_IsError(source)) {
366 return source;
367 }
368 return Dart_LoadSource(library, url, source);
369 }
370 break;
371 default:
372 UNIMPLEMENTED();
373 break;
374 } 258 }
375 UNREACHABLE(); 259 Dart_Handle source = GetSource(url_string);
376 return result; 260 if (Dart_IsError(source)) {
261 return source;
262 }
263 return Dart_LoadSource(library, url, source);
377 } 264 }
378 265
379 266
380 void VmService::ThreadMain(uword parameters) { 267 void VmService::ThreadMain(uword parameters) {
381 ASSERT(Dart_CurrentIsolate() == NULL); 268 ASSERT(Dart_CurrentIsolate() == NULL);
382 ASSERT(isolate_ == NULL); 269 Dart_Isolate service_isolate = Dart_GetServiceIsolate(NULL);
383 270 Dart_EnterIsolate(service_isolate);
384 intptr_t server_port = static_cast<intptr_t>(parameters); 271 Dart_EnterScope();
385 ASSERT(server_port >= 0);
386
387 // Lock scope.
388 {
389 MonitorLocker ml(monitor_);
390 bool r = _Start(server_port);
391 if (!r) {
392 port_ = ILLEGAL_PORT;
393 monitor_->Notify();
394 return;
395 }
396
397 Dart_EnterIsolate(isolate_);
398 Dart_EnterScope();
399
400 Dart_Handle receievePort = Dart_GetReceivePort(port_);
401 ASSERT(!Dart_IsError(receievePort));
402 monitor_->Notify();
403 }
404
405 // Keep handling messages until the last active receive port is closed.
406 Dart_Handle result = Dart_RunLoop(); 272 Dart_Handle result = Dart_RunLoop();
407 if (Dart_IsError(result)) { 273 if (Dart_IsError(result)) {
408 printf("VmService has exited with an error:\n%s\n", Dart_GetError(result)); 274 printf("Service exited with an error:\n%s\n", Dart_GetError(result));
409 } 275 }
410
411 _Stop();
412
413 Dart_ExitScope(); 276 Dart_ExitScope();
414 Dart_ExitIsolate(); 277 Dart_ExitIsolate();
415 } 278 }
416 279
417 280
418 static Dart_Handle MakeServiceControlMessage(Dart_Port port_id, intptr_t code,
419 Dart_Handle name) {
420 Dart_Handle result;
421 Dart_Handle list = Dart_NewList(4);
422 ASSERT(!Dart_IsError(list));
423 Dart_Handle code_handle = Dart_NewInteger(code);
424 ASSERT(!Dart_IsError(code_handle));
425 result = Dart_ListSetAt(list, 0, code_handle);
426 ASSERT(!Dart_IsError(result));
427 Dart_Handle port_id_handle = Dart_NewInteger(port_id);
428 ASSERT(!Dart_IsError(port_id_handle));
429 result = Dart_ListSetAt(list, 1, port_id_handle);
430 ASSERT(!Dart_IsError(result));
431 Dart_Handle sendPort = Dart_NewSendPort(port_id);
432 ASSERT(!Dart_IsError(sendPort));
433 result = Dart_ListSetAt(list, 2, sendPort);
434 ASSERT(!Dart_IsError(result));
435 result = Dart_ListSetAt(list, 3, name);
436 ASSERT(!Dart_IsError(result));
437 return list;
438 }
439
440
441 bool VmService::SendIsolateStartupMessage() {
442 if (!IsRunning()) {
443 return false;
444 }
445 Isolate* isolate = Isolate::Current();
446 ASSERT(isolate != NULL);
447 HANDLESCOPE(isolate);
448 Dart_Handle name = Api::NewHandle(isolate, String::New(isolate->name()));
449 ASSERT(!Dart_IsError(name));
450 Dart_Handle list =
451 MakeServiceControlMessage(Dart_GetMainPortId(),
452 VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID,
453 name);
454 ASSERT(!Dart_IsError(list));
455 return Dart_Post(port_, list);
456 }
457
458
459 bool VmService::SendIsolateShutdownMessage() {
460 if (!IsRunning()) {
461 return false;
462 }
463 Isolate* isolate = Isolate::Current();
464 ASSERT(isolate != NULL);
465 HANDLESCOPE(isolate);
466 Dart_Handle list =
467 MakeServiceControlMessage(Dart_GetMainPortId(),
468 VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID,
469 Dart_Null());
470 ASSERT(!Dart_IsError(list));
471 return Dart_Post(port_, list);
472 }
473
474
475 void VmService::VmServiceShutdownCallback(void* callback_data) {
476 ASSERT(Dart_CurrentIsolate() != NULL);
477 Dart_EnterScope();
478 VmService::SendIsolateShutdownMessage();
479 Dart_ExitScope();
480 }
481
482
483 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
484 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
485 return reinterpret_cast<uint8_t*>(new_ptr);
486 }
487
488
489 static void SendServiceMessage(Dart_NativeArguments args) {
490 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
491 Isolate* isolate = arguments->isolate();
492 StackZone zone(isolate);
493 HANDLESCOPE(isolate);
494 GET_NON_NULL_NATIVE_ARGUMENT(Instance, sp, arguments->NativeArgAt(0));
495 GET_NON_NULL_NATIVE_ARGUMENT(Instance, message, arguments->NativeArgAt(1));
496
497 // Extract SendPort port id.
498 const Object& sp_id_obj = Object::Handle(DartLibraryCalls::PortGetId(sp));
499 if (sp_id_obj.IsError()) {
500 Exceptions::PropagateError(Error::Cast(sp_id_obj));
501 }
502 Integer& id = Integer::Handle();
503 id ^= sp_id_obj.raw();
504 Dart_Port sp_id = static_cast<Dart_Port>(id.AsInt64Value());
505 ASSERT(sp_id != ILLEGAL_PORT);
506
507 // Serialize message.
508 uint8_t* data = NULL;
509 MessageWriter writer(&data, &allocator);
510 writer.WriteMessage(message);
511
512 // TODO(turnidge): Throw an exception when the return value is false?
513 PortMap::PostMessage(new Message(sp_id, data, writer.BytesWritten(),
514 Message::kOOBPriority));
515 }
516
517
518 struct VmServiceNativeEntry {
519 const char* name;
520 int num_arguments;
521 Dart_NativeFunction function;
522 };
523
524
525 static VmServiceNativeEntry _VmServiceNativeEntries[] = {
526 {"VMService_SendServiceMessage", 2, SendServiceMessage}
527 };
528
529
530 static Dart_NativeFunction VmServiceNativeResolver(Dart_Handle name,
531 int num_arguments,
532 bool* auto_setup_scope) {
533 const Object& obj = Object::Handle(Api::UnwrapHandle(name));
534 if (!obj.IsString()) {
535 return NULL;
536 }
537 const char* function_name = obj.ToCString();
538 ASSERT(function_name != NULL);
539 ASSERT(auto_setup_scope != NULL);
540 *auto_setup_scope = true;
541 intptr_t n =
542 sizeof(_VmServiceNativeEntries) / sizeof(_VmServiceNativeEntries[0]);
543 for (intptr_t i = 0; i < n; i++) {
544 VmServiceNativeEntry entry = _VmServiceNativeEntries[i];
545 if (!strcmp(function_name, entry.name) &&
546 (num_arguments == entry.num_arguments)) {
547 return entry.function;
548 }
549 }
550 return NULL;
551 }
552 281
553 } // namespace bin 282 } // namespace bin
554 } // namespace dart 283 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/bin/vmservice_impl.h ('k') | runtime/include/dart_api.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698