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

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

Issue 19231005: Initial NOOP VM Service (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 5 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "bin/vmservice_impl.h"
6
7 #include "include/dart_api.h"
8
9 #include "bin/builtin.h"
10 #include "bin/dartutils.h"
11 #include "bin/resources.h"
12 #include "bin/thread.h"
13 #include "bin/isolate_data.h"
14
15
16 namespace dart {
17 namespace bin {
18
19 // snapshot_buffer points to a snapshot if we link in a snapshot otherwise
20 // it is initialized to NULL.
21 extern const uint8_t* snapshot_buffer;
22 #define RETURN_ERROR_HANDLE(handle) \
23 if (Dart_IsError(handle)) { \
24 return handle; \
25 }
26
27 #define SHUTDOWN_ON_ERROR(handle) \
28 if (Dart_IsError(handle)) { \
29 error_msg_ = strdup(Dart_GetError(handle)); \
30 Dart_ExitScope(); \
31 Dart_ShutdownIsolate(); \
32 return false; \
33 }
34
35 #define kLibraryResourceNamePrefix "/vmservice"
36 static const char* kLibraryScriptResourceName =
37 kLibraryResourceNamePrefix "/vmservice.dart";
38 static const char* kLibrarySourceResourceNames[] = {
39 NULL
40 };
41
42 #define kClientResourceNamePrefix "/client/web/out"
43
44 Dart_Isolate VmService::isolate_ = NULL;
45 Dart_Port VmService::port_ = ILLEGAL_PORT;
46 dart::Monitor* VmService::monitor_ = NULL;
47 const char* VmService::error_msg_ = NULL;
48
49 // These must be kept in sync with vmservice/constants.dart
50 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
51 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2
52
53
54 bool VmService::Start(intptr_t server_port) {
55 monitor_ = new dart::Monitor();
56 ASSERT(monitor_ != NULL);
57 error_msg_ = NULL;
58
59
60 {
61 // Take lock before spawning new thread.
62 MonitorLocker ml(monitor_);
63 // Spawn new thread.
64 dart::Thread::Start(ThreadMain, server_port);
65 // Wait until service is running on spawned thread.
66 ml.Wait();
67 }
68 return port_ != ILLEGAL_PORT;
69 }
70
71
72 bool VmService::_Start(intptr_t server_port) {
73 ASSERT(isolate_ == NULL);
74 char* error = NULL;
75 isolate_ = Dart_CreateIsolate("vmservice:", "main", snapshot_buffer,
76 new IsolateData(),
77 &error);
78 if (isolate_ == NULL) {
79 error_msg_ = error;
80 return false;
81 }
82
83 Dart_EnterScope();
84
85 if (snapshot_buffer != NULL) {
86 // Setup the native resolver as the snapshot does not carry it.
87 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
88 Builtin::SetNativeResolver(Builtin::kIOLibrary);
89 }
90
91 // Set up the library tag handler for this isolate.
92 Dart_Handle result = Dart_SetLibraryTagHandler(DartUtils::LibraryTagHandler);
93 SHUTDOWN_ON_ERROR(result);
94
95 // Load the specified application script into the newly created isolate.
96
97 // Prepare builtin and its dependent libraries for use to resolve URIs.
98 // The builtin library is part of the core snapshot and would already be
99 // available here in the case of script snapshot loading.
100 Dart_Handle builtin_lib =
101 Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
102 SHUTDOWN_ON_ERROR(builtin_lib);
103
104 // Prepare for script loading by setting up the 'print' and 'timer'
105 // closures and setting up 'package root' for URI resolution.
106 result = DartUtils::PrepareForScriptLoading("", builtin_lib);
107 SHUTDOWN_ON_ERROR(result);
108
109 {
110 // Load source into service isolate.
111 Dart_Handle library = LoadScript(kLibraryScriptResourceName);
112 SHUTDOWN_ON_ERROR(library);
113 result = LoadSources(library, kLibrarySourceResourceNames);
114 SHUTDOWN_ON_ERROR(result);
115 }
116
117 // Make the isolate runnable so that it is ready to handle messages.
118 Dart_ExitScope();
119 Dart_ExitIsolate();
120
121 bool retval = Dart_IsolateMakeRunnable(isolate_);
122 if (!retval) {
123 Dart_EnterIsolate(isolate_);
124 Dart_ShutdownIsolate();
125 error_msg_ = "Invalid isolate state - Unable to make it runnable.";
126 return false;
127 }
128
129 Dart_EnterIsolate(isolate_);
130 Dart_EnterScope();
131
132 Dart_Handle library = Dart_RootLibrary();
133 result = Dart_Invoke(library, DartUtils::NewString("main"), 0, NULL);
134 SHUTDOWN_ON_ERROR(result);
135
136 result = LoadResources(library);
137 SHUTDOWN_ON_ERROR(result);
138
139 port_ = Dart_GetMainPortId();
140
141 Dart_ExitScope();
142 Dart_ExitIsolate();
143
144 return true;
145 }
146
147
148 void VmService::_Stop() {
149 port_ = ILLEGAL_PORT;
150 }
151
152
153 const char* VmService::GetErrorMessage() {
154 return error_msg_ == NULL ? "No error." : error_msg_;
155 }
156
157
158 Dart_Port VmService::port() {
159 return port_;
160 }
161
162
163 bool VmService::IsRunning() {
164 return port_ != ILLEGAL_PORT;
165 }
166
167
168 Dart_Handle VmService::LoadScript(const char* name) {
169 Dart_Handle url = Dart_NewStringFromCString(name);
170 const char* vmservice_source = NULL;
171 int r = Resources::ResourceLookup(name, &vmservice_source);
172 ASSERT(r != Resources::kNoSuchInstance);
173 Dart_Handle source = Dart_NewStringFromCString(vmservice_source);
174 return Dart_LoadScript(url, source, 0, 0);
175 }
176
177
178 Dart_Handle VmService::LoadSource(Dart_Handle library, const char* name) {
179 Dart_Handle url = Dart_NewStringFromCString(name);
180 const char* vmservice_source = NULL;
181 int r = Resources::ResourceLookup(name, &vmservice_source);
182 if (r == Resources::kNoSuchInstance) {
183 printf("Can't find %s\n", name);
184 }
185 ASSERT(r != Resources::kNoSuchInstance);
186 Dart_Handle source = Dart_NewStringFromCString(vmservice_source);
187 return Dart_LoadSource(library, url, source);
188 }
189
190
191 Dart_Handle VmService::LoadSources(Dart_Handle library, const char* names[]) {
192 Dart_Handle result = Dart_Null();
193 for (int i = 0; names[i] != NULL; i++) {
194 result = LoadSource(library, names[i]);
195 if (Dart_IsError(result)) {
196 break;
197 }
198 }
199 return result;
200 }
201
202
203 Dart_Handle VmService::LoadResource(Dart_Handle library,
204 const char* resource_name,
205 const char* prefix) {
206 intptr_t prefix_len = strlen(prefix);
207 // Prepare for invoke call.
208 Dart_Handle name = Dart_NewStringFromCString(resource_name+prefix_len);
209 RETURN_ERROR_HANDLE(name);
210 const char* data_buffer = NULL;
211 int data_buffer_length = Resources::ResourceLookup(resource_name,
212 &data_buffer);
213 if (data_buffer_length == Resources::kNoSuchInstance) {
214 printf("Could not find %s %s\n", resource_name, resource_name+prefix_len);
215 }
216 ASSERT(data_buffer_length != Resources::kNoSuchInstance);
217 Dart_Handle data_list = Dart_NewTypedData(Dart_TypedData_kUint8,
218 data_buffer_length);
219 RETURN_ERROR_HANDLE(data_list);
220 Dart_TypedData_Type type = Dart_TypedData_kInvalid;
221 void* data_list_buffer = NULL;
222 intptr_t data_list_buffer_length = 0;
223 Dart_Handle result = Dart_TypedDataAcquireData(data_list, &type,
224 &data_list_buffer,
225 &data_list_buffer_length);
226 RETURN_ERROR_HANDLE(result);
227 ASSERT(data_buffer_length == data_list_buffer_length);
228 ASSERT(data_list_buffer != NULL);
229 ASSERT(type = Dart_TypedData_kUint8);
230 memmove(data_list_buffer, &data_buffer[0], data_buffer_length);
231 result = Dart_TypedDataReleaseData(data_list);
232 RETURN_ERROR_HANDLE(result);
233
234 // Make invoke call.
235 const intptr_t kNumArgs = 2;
236 Dart_Handle args[kNumArgs] = { name, data_list };
237 result = Dart_Invoke(library, Dart_NewStringFromCString("_addResource"),
238 kNumArgs, args);
239 return result;
240 }
241
242
243 Dart_Handle VmService::LoadResources(Dart_Handle library) {
244 Dart_Handle result = Dart_Null();
245 intptr_t prefixLen = strlen(kClientResourceNamePrefix);
246 for (intptr_t i = 0; i < Resources::get_resource_count(); i++) {
247 const char* path = Resources::get_resource_path(i);
248 if (!strncmp(path, kClientResourceNamePrefix, prefixLen)) {
249 result = LoadResource(library, path, kClientResourceNamePrefix);
250 if (Dart_IsError(result)) {
251 break;
252 }
253 }
254 }
255 return result;
256 }
257
258
259 void VmService::ThreadMain(uword parameters) {
260 ASSERT(Dart_CurrentIsolate() == NULL);
261 ASSERT(isolate_ == NULL);
262
263 intptr_t server_port = static_cast<intptr_t>(parameters);
264 ASSERT(server_port >= 0);
265
266 // Lock scope.
267 {
268 MonitorLocker ml(monitor_);
269 bool r = _Start(server_port);
270 if (!r) {
271 port_ = ILLEGAL_PORT;
272 monitor_->Notify();
273 return;
274 }
275
276 Dart_EnterIsolate(isolate_);
277 Dart_EnterScope();
278
279 Dart_Handle receievePort = Dart_GetReceivePort(port_);
280 ASSERT(!Dart_IsError(receievePort));
281 monitor_->Notify();
282 }
283
284 // Keep handling messages until the last active receive port is closed.
285 Dart_Handle result = Dart_RunLoop();
286 if (Dart_IsError(result)) {
287 printf("VmService error %s\n", Dart_GetError(result));
288 }
289
290 _Stop();
291
292 Dart_ExitScope();
293 Dart_ExitIsolate();
294 }
295
296
297
298
299 static Dart_Handle MakeServiceControlMessage(Dart_Port port) {
300 Dart_Handle list = Dart_NewList(2);
301 ASSERT(!Dart_IsError(list));
302 Dart_Handle sendPort = Dart_NewSendPort(port);
303 ASSERT(!Dart_IsError(sendPort));
304 Dart_ListSetAt(list, 1, sendPort);
305 return list;
306 }
307
308
309 bool VmService::SendIsolateStartupMessage(Dart_Port port) {
310 if (!IsRunning()) {
311 return false;
312 }
313 Dart_Isolate isolate = Dart_CurrentIsolate();
314 ASSERT(isolate != NULL);
315 ASSERT(Dart_GetMainPortId() == port);
316 Dart_Handle list = MakeServiceControlMessage(port);
317 Dart_ListSetAt(list, 0,
318 Dart_NewInteger(VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID));
319 return Dart_Post(port_, list);
320 }
321
322
323 bool VmService::SendIsolateShutdownMessage(Dart_Port port) {
324 if (!IsRunning()) {
325 return false;
326 }
327 Dart_Isolate isolate = Dart_CurrentIsolate();
328 ASSERT(isolate != NULL);
329 ASSERT(Dart_GetMainPortId() == port);
330 Dart_Handle list = MakeServiceControlMessage(port);
331 Dart_ListSetAt(list, 0,
332 Dart_NewInteger(VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID));
333 return Dart_Post(port_, list);
334 }
335
336
337 } // namespace bin
338 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/bin/vmservice_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698