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

Side by Side Diff: runtime/lib/isolate.cc

Issue 13452007: Add new Dart API call Dart_MakeIsolateRunnable(). This would allow an (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 "platform/assert.h" 5 #include "platform/assert.h"
6 #include "vm/bootstrap_natives.h" 6 #include "vm/bootstrap_natives.h"
7 #include "vm/class_finalizer.h" 7 #include "vm/class_finalizer.h"
8 #include "vm/dart.h" 8 #include "vm/dart.h"
9 #include "vm/dart_api_impl.h" 9 #include "vm/dart_api_impl.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 24 matching lines...) Expand all
35 intptr_t port_id_; 35 intptr_t port_id_;
36 }; 36 };
37 37
38 38
39 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) { 39 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
40 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size); 40 void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
41 return reinterpret_cast<uint8_t*>(new_ptr); 41 return reinterpret_cast<uint8_t*>(new_ptr);
42 } 42 }
43 43
44 44
45 static void StoreError(Isolate* isolate, const Object& obj) {
46 ASSERT(obj.IsError());
47 isolate->object_store()->set_sticky_error(Error::Cast(obj));
48 }
49
50
51 // TODO(turnidge): Move to DartLibraryCalls. 45 // TODO(turnidge): Move to DartLibraryCalls.
52 static RawObject* ReceivePortCreate(intptr_t port_id) { 46 static RawObject* ReceivePortCreate(intptr_t port_id) {
53 Isolate* isolate = Isolate::Current(); 47 Isolate* isolate = Isolate::Current();
54 Function& func = 48 Function& func =
55 Function::Handle(isolate, 49 Function::Handle(isolate,
56 isolate->object_store()->receive_port_create_function()); 50 isolate->object_store()->receive_port_create_function());
57 const int kNumArguments = 1; 51 const int kNumArguments = 1;
58 if (func.IsNull()) { 52 if (func.IsNull()) {
59 Library& isolate_lib = Library::Handle(Library::IsolateLibrary()); 53 Library& isolate_lib = Library::Handle(Library::IsolateLibrary());
60 ASSERT(!isolate_lib.IsNull()); 54 ASSERT(!isolate_lib.IsNull());
(...skipping 14 matching lines...) Expand all
75 args.SetAt(0, Integer::Handle(isolate, Integer::New(port_id))); 69 args.SetAt(0, Integer::Handle(isolate, Integer::New(port_id)));
76 const Object& result = 70 const Object& result =
77 Object::Handle(isolate, DartEntry::InvokeFunction(func, args)); 71 Object::Handle(isolate, DartEntry::InvokeFunction(func, args));
78 if (!result.IsError()) { 72 if (!result.IsError()) {
79 PortMap::SetLive(port_id); 73 PortMap::SetLive(port_id);
80 } 74 }
81 return result.raw(); 75 return result.raw();
82 } 76 }
83 77
84 78
85 static void ShutdownIsolate(uword parameter) {
86 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
87 {
88 // Print the error if there is one. This may execute dart code to
89 // print the exception object, so we need to use a StartIsolateScope.
90 StartIsolateScope start_scope(isolate);
91 StackZone zone(isolate);
92 HandleScope handle_scope(isolate);
93 Error& error = Error::Handle();
94 error = isolate->object_store()->sticky_error();
95 if (!error.IsNull()) {
96 OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString());
97 }
98 }
99 {
100 // Shut the isolate down.
101 SwitchIsolateScope switch_scope(isolate);
102 Dart::ShutdownIsolate();
103 }
104 }
105
106
107 static char* GetRootScriptUri(Isolate* isolate) {
108 const Library& library =
109 Library::Handle(isolate->object_store()->root_library());
110 ASSERT(!library.IsNull());
111 const String& script_name = String::Handle(library.url());
112 return isolate->current_zone()->MakeCopyOfString(script_name.ToCString());
113 }
114
115
116 DEFINE_NATIVE_ENTRY(ReceivePortImpl_factory, 1) { 79 DEFINE_NATIVE_ENTRY(ReceivePortImpl_factory, 1) {
117 ASSERT(AbstractTypeArguments::CheckedHandle( 80 ASSERT(AbstractTypeArguments::CheckedHandle(
118 arguments->NativeArgAt(0)).IsNull()); 81 arguments->NativeArgAt(0)).IsNull());
119 intptr_t port_id = 82 intptr_t port_id =
120 PortMap::CreatePort(arguments->isolate()->message_handler()); 83 PortMap::CreatePort(arguments->isolate()->message_handler());
121 const Object& port = Object::Handle(ReceivePortCreate(port_id)); 84 const Object& port = Object::Handle(ReceivePortCreate(port_id));
122 if (port.IsError()) { 85 if (port.IsError()) {
123 Exceptions::PropagateError(Error::Cast(port)); 86 Exceptions::PropagateError(Error::Cast(port));
124 } 87 }
125 return port.raw(); 88 return port.raw();
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 Dart_ExitScope(); 158 Dart_ExitScope();
196 } else { 159 } else {
197 *error = zone->PrintToString( 160 *error = zone->PrintToString(
198 "Unable to canonicalize uri '%s': no library tag handler found.", 161 "Unable to canonicalize uri '%s': no library tag handler found.",
199 uri.ToCString()); 162 uri.ToCString());
200 } 163 }
201 return retval; 164 return retval;
202 } 165 }
203 166
204 167
205 class SpawnState { 168 static bool CreateIsolate(IsolateSpawnState* state, char** error) {
206 public:
207 SpawnState(const Function& func, const Function& callback_func)
208 : isolate_(NULL),
209 script_url_(NULL),
210 library_url_(NULL),
211 function_name_(NULL),
212 exception_callback_name_(NULL) {
213 script_url_ = strdup(GetRootScriptUri(Isolate::Current()));
214 const Class& cls = Class::Handle(func.Owner());
215 ASSERT(cls.IsTopLevel());
216 const Library& lib = Library::Handle(cls.library());
217 const String& lib_url = String::Handle(lib.url());
218 library_url_ = strdup(lib_url.ToCString());
219
220 const String& func_name = String::Handle(func.name());
221 function_name_ = strdup(func_name.ToCString());
222 if (!callback_func.IsNull()) {
223 const String& callback_name = String::Handle(callback_func.name());
224 exception_callback_name_ = strdup(callback_name.ToCString());
225 } else {
226 exception_callback_name_ = strdup("_unhandledExceptionCallback");
227 }
228 }
229
230 explicit SpawnState(const char* script_url)
231 : isolate_(NULL),
232 library_url_(NULL),
233 function_name_(NULL),
234 exception_callback_name_(NULL) {
235 script_url_ = strdup(script_url);
236 library_url_ = NULL;
237 function_name_ = strdup("main");
238 exception_callback_name_ = strdup("_unhandledExceptionCallback");
239 }
240
241 ~SpawnState() {
242 free(script_url_);
243 free(library_url_);
244 free(function_name_);
245 free(exception_callback_name_);
246 }
247
248 Isolate* isolate() const { return isolate_; }
249 void set_isolate(Isolate* value) { isolate_ = value; }
250 char* script_url() const { return script_url_; }
251 char* library_url() const { return library_url_; }
252 char* function_name() const { return function_name_; }
253 char* exception_callback_name() const { return exception_callback_name_; }
254
255 RawObject* ResolveFunction() {
256 // Resolve the library.
257 Library& lib = Library::Handle();
258 if (library_url()) {
259 const String& lib_url = String::Handle(String::New(library_url()));
260 lib = Library::LookupLibrary(lib_url);
261 if (lib.IsNull() || lib.IsError()) {
262 const String& msg = String::Handle(String::NewFormatted(
263 "Unable to find library '%s'.", library_url()));
264 return LanguageError::New(msg);
265 }
266 } else {
267 lib = isolate()->object_store()->root_library();
268 }
269 ASSERT(!lib.IsNull());
270
271 // Resolve the function.
272 const String& func_name =
273 String::Handle(String::New(function_name()));
274 const Function& func = Function::Handle(lib.LookupLocalFunction(func_name));
275 if (func.IsNull()) {
276 const String& msg = String::Handle(String::NewFormatted(
277 "Unable to resolve function '%s' in library '%s'.",
278 function_name(), (library_url() ? library_url() : script_url())));
279 return LanguageError::New(msg);
280 }
281 return func.raw();
282 }
283
284 void Cleanup() {
285 SwitchIsolateScope switch_scope(isolate());
286 Dart::ShutdownIsolate();
287 }
288
289 private:
290 Isolate* isolate_;
291 char* script_url_;
292 char* library_url_;
293 char* function_name_;
294 char* exception_callback_name_;
295 };
296
297
298 static bool CreateIsolate(SpawnState* state, char** error) {
299 Isolate* parent_isolate = Isolate::Current(); 169 Isolate* parent_isolate = Isolate::Current();
300 170
301 Dart_IsolateCreateCallback callback = Isolate::CreateCallback(); 171 Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
302 if (callback == NULL) { 172 if (callback == NULL) {
303 *error = strdup("Null callback specified for isolate creation\n"); 173 *error = strdup("Null callback specified for isolate creation\n");
304 Isolate::SetCurrent(parent_isolate); 174 Isolate::SetCurrent(parent_isolate);
305 return false; 175 return false;
306 } 176 }
307 177
308 void* init_data = parent_isolate->init_callback_data(); 178 void* init_data = parent_isolate->init_callback_data();
309 bool retval = (callback)(state->script_url(), 179 Isolate* child_isolate = reinterpret_cast<Isolate*>(
310 state->function_name(), 180 (callback)(state->script_url(),
311 init_data, 181 state->function_name(),
312 error); 182 init_data,
313 if (!retval) { 183 error));
184 if (child_isolate == NULL) {
314 Isolate::SetCurrent(parent_isolate); 185 Isolate::SetCurrent(parent_isolate);
315 return false; 186 return false;
316 } 187 }
317 188 state->set_isolate(reinterpret_cast<Isolate*>(child_isolate));
318 Isolate* child_isolate = Isolate::Current();
319 ASSERT(child_isolate);
320 state->set_isolate(child_isolate);
321
322 // Attempt to resolve the entry function now, so that we fail fast
323 // in the case that the function cannot be resolved.
324 //
325 // TODO(turnidge): Revisit this once we have an isolate death api.
326 bool resolve_error = false;
327 {
328 StackZone zone(child_isolate);
329 HandleScope handle_scope(child_isolate);
330 const Object& result = Object::Handle(state->ResolveFunction());
331 if (result.IsError()) {
332 Error& errobj = Error::Handle();
333 errobj ^= result.raw();
334 *error = strdup(errobj.ToErrorCString());
335 resolve_error = true;
336 } else {
337 const String& callback_name =
338 String::Handle(child_isolate,
339 String::New(state->exception_callback_name()));
340 child_isolate->object_store()->
341 set_unhandled_exception_handler(callback_name);
342 }
343 }
344 if (resolve_error) {
345 Dart::ShutdownIsolate();
346 Isolate::SetCurrent(parent_isolate);
347 return false;
348 }
349 189
350 Isolate::SetCurrent(parent_isolate); 190 Isolate::SetCurrent(parent_isolate);
351 return true; 191 return true;
352 } 192 }
353 193
354 194
355 static bool RunIsolate(uword parameter) { 195 static RawObject* Spawn(NativeArguments* arguments, IsolateSpawnState* state) {
356 Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
357 SpawnState* state = reinterpret_cast<SpawnState*>(isolate->spawn_data());
358 isolate->set_spawn_data(0);
359 {
360 StartIsolateScope start_scope(isolate);
361 StackZone zone(isolate);
362 HandleScope handle_scope(isolate);
363 if (!ClassFinalizer::FinalizePendingClasses()) {
364 // Error is in sticky error already.
365 return false;
366 }
367
368 Object& result = Object::Handle();
369 result = state->ResolveFunction();
370 delete state;
371 state = NULL;
372 if (result.IsError()) {
373 StoreError(isolate, result);
374 return false;
375 }
376 ASSERT(result.IsFunction());
377 Function& func = Function::Handle(isolate);
378 func ^= result.raw();
379 result = DartEntry::InvokeFunction(func, Object::empty_array());
380 if (result.IsError()) {
381 StoreError(isolate, result);
382 return false;
383 }
384 }
385 return true;
386 }
387
388
389 static RawObject* Spawn(NativeArguments* arguments, SpawnState* state) {
390 // Create a new isolate. 196 // Create a new isolate.
391 char* error = NULL; 197 char* error = NULL;
392 if (!CreateIsolate(state, &error)) { 198 if (!CreateIsolate(state, &error)) {
393 delete state; 199 delete state;
394 const String& msg = String::Handle(String::New(error)); 200 const String& msg = String::Handle(String::New(error));
395 free(error); 201 free(error);
396 ThrowIsolateSpawnException(msg); 202 ThrowIsolateSpawnException(msg);
397 } 203 }
398 204
399 // Try to create a SendPort for the new isolate. 205 // Try to create a SendPort for the new isolate.
400 const Object& port = Object::Handle( 206 const Object& port = Object::Handle(
401 DartLibraryCalls::NewSendPort(state->isolate()->main_port())); 207 DartLibraryCalls::NewSendPort(state->isolate()->main_port()));
402 if (port.IsError()) { 208 if (port.IsError()) {
403 state->Cleanup(); 209 state->Cleanup();
404 delete state; 210 delete state;
405 Exceptions::PropagateError(Error::Cast(port)); 211 Exceptions::PropagateError(Error::Cast(port));
406 } 212 }
407 213
408 // Start the new isolate. 214 // Start the new isolate if it is already marked as runnable.
215 MutexLocker ml(state->isolate()->mutex());
409 state->isolate()->set_spawn_data(reinterpret_cast<uword>(state)); 216 state->isolate()->set_spawn_data(reinterpret_cast<uword>(state));
410 state->isolate()->message_handler()->Run( 217 if (state->isolate()->is_runnable()) {
411 Dart::thread_pool(), RunIsolate, ShutdownIsolate, 218 state->isolate()->Run();
412 reinterpret_cast<uword>(state->isolate())); 219 }
413 220
414 return port.raw(); 221 return port.raw();
415 } 222 }
416 223
417 224
418 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 2) { 225 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 2) {
419 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0)); 226 GET_NON_NULL_NATIVE_ARGUMENT(Instance, closure, arguments->NativeArgAt(0));
420 bool throw_exception = false; 227 bool throw_exception = false;
421 Function& func = Function::Handle(); 228 Function& func = Function::Handle();
422 if (closure.IsClosure()) { 229 if (closure.IsClosure()) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 #if defined(DEBUG) 264 #if defined(DEBUG)
458 Context& ctx = Context::Handle(); 265 Context& ctx = Context::Handle();
459 ctx = Closure::context(closure); 266 ctx = Closure::context(closure);
460 ASSERT(ctx.num_variables() == 0); 267 ASSERT(ctx.num_variables() == 0);
461 if (!callback.IsNull()) { 268 if (!callback.IsNull()) {
462 ctx = Closure::context(callback); 269 ctx = Closure::context(callback);
463 ASSERT(ctx.num_variables() == 0); 270 ASSERT(ctx.num_variables() == 0);
464 } 271 }
465 #endif 272 #endif
466 273
467 return Spawn(arguments, new SpawnState(func, callback_func)); 274 return Spawn(arguments, new IsolateSpawnState(func, callback_func));
468 } 275 }
469 276
470 277
471 DEFINE_NATIVE_ENTRY(isolate_spawnUri, 1) { 278 DEFINE_NATIVE_ENTRY(isolate_spawnUri, 1) {
472 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(0)); 279 GET_NON_NULL_NATIVE_ARGUMENT(String, uri, arguments->NativeArgAt(0));
473 280
474 // Canonicalize the uri with respect to the current isolate. 281 // Canonicalize the uri with respect to the current isolate.
475 char* error = NULL; 282 char* error = NULL;
476 char* canonical_uri = NULL; 283 char* canonical_uri = NULL;
477 const Library& root_lib = 284 const Library& root_lib =
478 Library::Handle(arguments->isolate()->object_store()->root_library()); 285 Library::Handle(arguments->isolate()->object_store()->root_library());
479 if (!CanonicalizeUri(arguments->isolate(), root_lib, uri, 286 if (!CanonicalizeUri(arguments->isolate(), root_lib, uri,
480 &canonical_uri, &error)) { 287 &canonical_uri, &error)) {
481 const String& msg = String::Handle(String::New(error)); 288 const String& msg = String::Handle(String::New(error));
482 ThrowIsolateSpawnException(msg); 289 ThrowIsolateSpawnException(msg);
483 } 290 }
484 291
485 return Spawn(arguments, new SpawnState(canonical_uri)); 292 return Spawn(arguments, new IsolateSpawnState(canonical_uri));
486 } 293 }
487 294
488 295
489 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) { 296 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) {
490 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port())); 297 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port()));
491 if (port.IsError()) { 298 if (port.IsError()) {
492 Exceptions::PropagateError(Error::Cast(port)); 299 Exceptions::PropagateError(Error::Cast(port));
493 } 300 }
494 return port.raw(); 301 return port.raw();
495 } 302 }
496 303
497 } // namespace dart 304 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698