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

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
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 = get_resources_table();
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* get_resource_path(int idx) {
siva 2014/01/10 00:01:54 These are not strictly accessors so you probably n
59 ASSERT(idx >= 0);
60 ResourcesEntry* entry = get_resource_entry(idx);
61 if (entry == NULL) {
62 return NULL;
63 }
64 return entry->path_;
siva 2014/01/10 00:01:54 should we assert that entry_path_ is not NULL ?
65 }
66
67 static const char* get_resource_resource(int idx) {
siva 2014/01/10 00:01:54 How about Resource for this.
Cutch 2014/01/10 21:01:42 Killed it.
68 ASSERT(idx >= 0);
69 ResourcesEntry* entry = get_resource_entry(idx);
70 if (entry == NULL) {
71 return NULL;
72 }
73 return entry->resource_;
74 }
75
76 private:
77 static ResourcesEntry* get_resource_entry(int idx) {
siva 2014/01/10 00:01:54 Ditto Entry?
Cutch 2014/01/10 21:01:42 Renamed to "At".
78 ASSERT(idx >= 0);
79 ResourcesEntry* table = get_resources_table();
80 for (int i = 0; table[i].path_ != NULL; i++) {
81 if (idx == i) {
82 return &table[i];
83 }
84 }
85 return NULL;
86 }
87 static ResourcesEntry* get_resources_table() {
siva 2014/01/10 00:01:54 service_bin_resources() or ResourcesTable for this
Cutch 2014/01/10 21:01:42 Done.
88 return &__service_bin_resources_[0];
89 }
90
91 DISALLOW_ALLOCATION();
92 DISALLOW_IMPLICIT_CONSTRUCTORS(Resources);
93 };
94
55 const char* VmService::error_msg_ = NULL; 95 const char* VmService::error_msg_ = NULL;
56 96
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) { 97 bool VmService::Start(intptr_t server_port) {
68 monitor_ = new dart::Monitor(); 98 bool r = _Start(server_port);
69 ASSERT(monitor_ != NULL); 99 if (!r) {
70 error_msg_ = NULL; 100 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 } 101 }
81 return port_ != ILLEGAL_PORT; 102 // Start processing messages in a new thread.
103 dart::Thread::Start(ThreadMain, NULL);
104 return true;
82 } 105 }
83 106
84 107
85 bool VmService::_Start(intptr_t server_port) { 108 bool VmService::_Start(intptr_t server_port) {
86 ASSERT(isolate_ == NULL); 109 ASSERT(Dart_CurrentIsolate() == NULL);
87 char* error = NULL; 110 Dart_Isolate isolate = Dart_GetServiceIsolate();
siva 2014/01/10 00:01:54 As discussed offline it would be great if we just
Cutch 2014/01/10 21:01:42 Agree that I should follow this cleanup with anoth
88 const char* script_uri = "vmservice:"; 111 if (isolate == NULL) {
89 IsolateData* isolate_data = new IsolateData(script_uri); 112 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; 113 return false;
96 } 114 }
97 115 Dart_EnterIsolate(isolate);
98 Dart_EnterScope(); 116 Dart_EnterScope();
99 117 // Install our own library tag handler.
100 if (snapshot_buffer != NULL) { 118 Dart_SetLibraryTagHandler(LibraryTagHandler);
101 // Setup the native resolver as the snapshot does not carry it. 119 Dart_Handle result;
102 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); 120 Dart_Handle library = LoadScript(kVMServiceIOLibraryScriptResourceName);
103 Builtin::SetNativeResolver(Builtin::kIOLibrary); 121 // Expect a library.
104 } 122 ASSERT(library != Dart_Null());
105 123 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(); 124 Dart_ExitScope();
132 Dart_ExitIsolate(); 125 Dart_ExitIsolate();
133 126 bool retval = Dart_IsolateMakeRunnable(isolate);
134 bool retval = Dart_IsolateMakeRunnable(isolate_);
135 if (!retval) { 127 if (!retval) {
136 Dart_EnterIsolate(isolate_); 128 Dart_EnterIsolate(isolate);
137 Dart_ShutdownIsolate(); 129 Dart_ShutdownIsolate();
138 error_msg_ = "Invalid isolate state - Unable to make it runnable."; 130 error_msg_ = "Invalid isolate state - Unable to make it runnable.";
139 return false; 131 return false;
140 } 132 }
141 133
142 Dart_EnterIsolate(isolate_); 134 Dart_EnterIsolate(isolate);
143 Dart_EnterScope(); 135 Dart_EnterScope();
144 136 library = Dart_RootLibrary();
145
146 Dart_Handle library = Dart_RootLibrary();
147 // Set requested TCP port. 137 // Set requested TCP port.
148 DartUtils::SetIntegerField(library, "_port", server_port); 138 DartUtils::SetIntegerField(library, "_port", server_port);
149 result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL); 139 result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
150 SHUTDOWN_ON_ERROR(result); 140 SHUTDOWN_ON_ERROR(result);
151 141 // 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); 142 result = LoadResources(library);
182 SHUTDOWN_ON_ERROR(result); 143 SHUTDOWN_ON_ERROR(result);
183 144
184 Dart_ExitScope(); 145 Dart_ExitScope();
185 Dart_ExitIsolate(); 146 Dart_ExitIsolate();
186 147
187 return true; 148 return true;
188 } 149 }
189 150
190 151
191 void VmService::_Stop() {
192 port_ = ILLEGAL_PORT;
193 }
194
195
196 const char* VmService::GetErrorMessage() { 152 const char* VmService::GetErrorMessage() {
197 return error_msg_ == NULL ? "No error." : error_msg_; 153 return error_msg_ == NULL ? "No error." : error_msg_;
198 } 154 }
199 155
200 156
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) { 157 Dart_Handle VmService::GetSource(const char* name) {
158 const intptr_t kBufferSize = 512;
159 char buffer[kBufferSize];
160 snprintf(&buffer[0], kBufferSize-1, "%s/%s", kLibrarySourceNamePrefix, name);
212 const char* vmservice_source = NULL; 161 const char* vmservice_source = NULL;
213 int r = Resources::ResourceLookup(name, &vmservice_source); 162 int r = Resources::ResourceLookup(buffer, &vmservice_source);
214 ASSERT(r != Resources::kNoSuchInstance); 163 ASSERT(r != Resources::kNoSuchInstance);
215 return Dart_NewStringFromCString(vmservice_source); 164 return Dart_NewStringFromCString(vmservice_source);
216 } 165 }
217 166
218 167
219 Dart_Handle VmService::LoadScript(const char* name) { 168 Dart_Handle VmService::LoadScript(const char* name) {
220 Dart_Handle url = Dart_NewStringFromCString(name); 169 Dart_Handle url = Dart_NewStringFromCString("dart:vmservice_io");
221 Dart_Handle source = GetSource(name); 170 Dart_Handle source = GetSource(name);
222 return Dart_LoadScript(url, source, 0, 0); 171 return Dart_LoadScript(url, source, 0, 0);
223 } 172 }
224 173
225 174
226 Dart_Handle VmService::LoadSource(Dart_Handle library, const char* name) { 175 Dart_Handle VmService::LoadSource(Dart_Handle library, const char* name) {
227 Dart_Handle url = Dart_NewStringFromCString(name); 176 Dart_Handle url = Dart_NewStringFromCString(name);
228 Dart_Handle source = GetSource(name); 177 Dart_Handle source = GetSource(name);
229 return Dart_LoadSource(library, url, source); 178 return Dart_LoadSource(library, url, source);
230 } 179 }
231 180
232 181
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, 182 Dart_Handle VmService::LoadResource(Dart_Handle library,
246 const char* resource_name, 183 const char* resource_name,
247 const char* prefix) { 184 const char* prefix) {
248 intptr_t prefix_len = strlen(prefix); 185 intptr_t prefix_len = strlen(prefix);
249 // Prepare for invoke call. 186 // Prepare for invoke call.
250 Dart_Handle name = Dart_NewStringFromCString(resource_name+prefix_len); 187 Dart_Handle name = Dart_NewStringFromCString(resource_name+prefix_len);
251 RETURN_ERROR_HANDLE(name); 188 RETURN_ERROR_HANDLE(name);
252 const char* data_buffer = NULL; 189 const char* data_buffer = NULL;
253 int data_buffer_length = Resources::ResourceLookup(resource_name, 190 int data_buffer_length = Resources::ResourceLookup(resource_name,
254 &data_buffer); 191 &data_buffer);
(...skipping 23 matching lines...) Expand all
278 Dart_Handle args[kNumArgs] = { name, data_list }; 215 Dart_Handle args[kNumArgs] = { name, data_list };
279 result = Dart_Invoke(library, Dart_NewStringFromCString("_addResource"), 216 result = Dart_Invoke(library, Dart_NewStringFromCString("_addResource"),
280 kNumArgs, args); 217 kNumArgs, args);
281 return result; 218 return result;
282 } 219 }
283 220
284 221
285 Dart_Handle VmService::LoadResources(Dart_Handle library) { 222 Dart_Handle VmService::LoadResources(Dart_Handle library) {
286 Dart_Handle result = Dart_Null(); 223 Dart_Handle result = Dart_Null();
287 intptr_t prefixLen = strlen(kClientResourceNamePrefix); 224 intptr_t prefixLen = strlen(kClientResourceNamePrefix);
288 for (intptr_t i = 0; i < Resources::get_resource_count(); i++) { 225 for (intptr_t i = 0; Resources::get_resource_path(i) != NULL; i++) {
289 const char* path = Resources::get_resource_path(i); 226 const char* path = Resources::get_resource_path(i);
290 if (!strncmp(path, kClientResourceNamePrefix, prefixLen)) { 227 if (!strncmp(path, kClientResourceNamePrefix, prefixLen)) {
291 result = LoadResource(library, path, kClientResourceNamePrefix); 228 result = LoadResource(library, path, kClientResourceNamePrefix);
292 if (Dart_IsError(result)) { 229 if (Dart_IsError(result)) {
293 break; 230 break;
294 } 231 }
295 } 232 }
296 } 233 }
297 return result; 234 return result;
298 } 235 }
299 236
300 237
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, 238 Dart_Handle VmService::LibraryTagHandler(Dart_LibraryTag tag,
315 Dart_Handle library, 239 Dart_Handle library,
316 Dart_Handle url) { 240 Dart_Handle url) {
317 if (!Dart_IsLibrary(library)) { 241 if (!Dart_IsLibrary(library)) {
318 return Dart_NewApiError("not a library"); 242 return Dart_NewApiError("not a library");
319 } 243 }
320 if (!Dart_IsString(url)) { 244 if (!Dart_IsString(url)) {
321 return Dart_NewApiError("url is not a string"); 245 return Dart_NewApiError("url is not a string");
322 } 246 }
323 const char* url_string = NULL; 247 const char* url_string = NULL;
324 Dart_Handle result = Dart_StringToCString(url, &url_string); 248 Dart_Handle result = Dart_StringToCString(url, &url_string);
325 if (Dart_IsError(result)) { 249 if (Dart_IsError(result)) {
326 return result; 250 return result;
327 } 251 }
328 Dart_Handle library_url = Dart_LibraryUrl(library); 252 Dart_Handle library_url = Dart_LibraryUrl(library);
329 const char* library_url_string = NULL; 253 const char* library_url_string = NULL;
330 result = Dart_StringToCString(library_url, &library_url_string); 254 result = Dart_StringToCString(library_url, &library_url_string);
331 if (Dart_IsError(result)) { 255 if (Dart_IsError(result)) {
332 return result; 256 return result;
333 } 257 }
334 bool is_vm_service_url = IsVMServiceURL(url_string); 258 if (tag == Dart_kImportTag) {
335 if (!is_vm_service_url) { 259 // Embedder handles all requests for external libraries.
336 // Pass to DartUtils.
337 return DartUtils::LibraryTagHandler(tag, library, url); 260 return DartUtils::LibraryTagHandler(tag, library, url);
338 } 261 }
339 switch (tag) { 262 ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl));
340 case Dart_kCanonicalizeUrl: 263 if (tag == Dart_kCanonicalizeUrl) {
341 // The URL is already canonicalized. 264 // url is already canonicalized.
342 return url; 265 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 } 266 }
375 UNREACHABLE(); 267 Dart_Handle source = GetSource(url_string);
376 return result; 268 if (Dart_IsError(source)) {
269 return source;
270 }
271 return Dart_LoadSource(library, url, source);
377 } 272 }
378 273
379 274
380 void VmService::ThreadMain(uword parameters) { 275 void VmService::ThreadMain(uword parameters) {
381 ASSERT(Dart_CurrentIsolate() == NULL); 276 ASSERT(Dart_CurrentIsolate() == NULL);
382 ASSERT(isolate_ == NULL); 277 Dart_Isolate service_isolate = Dart_GetServiceIsolate();
383 278 Dart_EnterIsolate(service_isolate);
384 intptr_t server_port = static_cast<intptr_t>(parameters); 279 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(); 280 Dart_Handle result = Dart_RunLoop();
407 if (Dart_IsError(result)) { 281 if (Dart_IsError(result)) {
408 printf("VmService has exited with an error:\n%s\n", Dart_GetError(result)); 282 printf("Service exited with an error:\n%s\n", Dart_GetError(result));
409 } 283 }
410
411 _Stop();
412
413 Dart_ExitScope(); 284 Dart_ExitScope();
414 Dart_ExitIsolate(); 285 Dart_ExitIsolate();
415 } 286 }
416 287
417 288
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 289
553 } // namespace bin 290 } // namespace bin
554 } // namespace dart 291 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698