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

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

Powered by Google App Engine
This is Rietveld 408576698