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

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

Issue 9691005: Implement spawnFunction from the new isolate api. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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 | « no previous file | runtime/lib/isolate.dart » ('j') | runtime/lib/isolate.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 46
47 static uint8_t* SerializeObject(const Instance& obj) { 47 static uint8_t* SerializeObject(const Instance& obj) {
48 uint8_t* result = NULL; 48 uint8_t* result = NULL;
49 SnapshotWriter writer(Snapshot::kMessage, &result, &allocator); 49 SnapshotWriter writer(Snapshot::kMessage, &result, &allocator);
50 writer.WriteObject(obj.raw()); 50 writer.WriteObject(obj.raw());
51 writer.FinalizeBuffer(); 51 writer.FinalizeBuffer();
52 return result; 52 return result;
53 } 53 }
54 54
55 55
56 // TODO(turnidge): Taking down the whole vm when an isolate fails is
57 // bad. Change this.
56 static void ProcessError(const Object& obj) { 58 static void ProcessError(const Object& obj) {
57 ASSERT(obj.IsError()); 59 ASSERT(obj.IsError());
58 Error& error = Error::Handle(); 60 Error& error = Error::Handle();
59 error ^= obj.raw(); 61 error ^= obj.raw();
60 OS::PrintErr("%s\n", error.ToErrorCString()); 62 OS::PrintErr("%s\n", error.ToErrorCString());
61 exit(255); 63 exit(255);
62 } 64 }
63 65
64 66
65 static void ThrowErrorException(Exceptions::ExceptionType type, 67 static void ThrowErrorException(Exceptions::ExceptionType type,
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 intptr_t send_id = Smi::CheckedHandle(arguments->At(0)).Value(); 378 intptr_t send_id = Smi::CheckedHandle(arguments->At(0)).Value();
377 intptr_t reply_id = Smi::CheckedHandle(arguments->At(1)).Value(); 379 intptr_t reply_id = Smi::CheckedHandle(arguments->At(1)).Value();
378 // TODO(iposva): Allow for arbitrary messages to be sent. 380 // TODO(iposva): Allow for arbitrary messages to be sent.
379 uint8_t* data = SerializeObject(Instance::CheckedHandle(arguments->At(2))); 381 uint8_t* data = SerializeObject(Instance::CheckedHandle(arguments->At(2)));
380 382
381 // TODO(turnidge): Throw an exception when the return value is false? 383 // TODO(turnidge): Throw an exception when the return value is false?
382 PortMap::PostMessage(new Message( 384 PortMap::PostMessage(new Message(
383 send_id, reply_id, data, Message::kNormalPriority)); 385 send_id, reply_id, data, Message::kNormalPriority));
384 } 386 }
385 387
388
389 static void ThrowIllegalArgException(const char* message) {
390 const String& message_str = String::Handle(String::New(message));
391 GrowableArray<const Object*> args(1);
392 args.Add(&message_str);
393 Exceptions::ThrowByType(Exceptions::kIllegalArgument, args);
394 }
395
396
397 class SpawnState {
398 public:
399 explicit SpawnState(const Function& func)
400 : isolate_(NULL),
401 library_url_(NULL),
402 function_name_(NULL) {
403 const Class& cls = Class::Handle(func.owner());
404 const Library& lib = Library::Handle(cls.library());
siva 2012/03/12 23:25:41 Assert cls represents implicit top level in 'lib'
turnidge 2012/03/13 18:13:48 Added an assert that cls.IsTopLevel().
405 const String& lib_url = String::Handle(lib.url());
406 library_url_ = strdup(lib_url.ToCString());
407
408 const String& func_name = String::Handle(func.name());
409 function_name_ = strdup(func_name.ToCString());
410 }
411
412 ~SpawnState() {
413 free(library_url_);
414 free(function_name_);
415 }
416
417 Isolate* isolate() const { return isolate_; }
418 void set_isolate(Isolate* value) { isolate_ = value; }
419 char* library_url() const { return library_url_; }
420 char* function_name() const { return function_name_; }
421
422 private:
423 Isolate* isolate_;
424 char* library_url_;
425 char* function_name_;
426 };
427
428
429 static bool CreateIsolate(SpawnState* state, char** error) {
430 Isolate* parent_isolate = Isolate::Current();
431
432 Dart_IsolateCreateCallback callback = Isolate::CreateCallback();
433 ASSERT(callback);
434 const char* isolate_name = BuildIsolateName(state->library_url(),
435 "",
436 state->function_name());
437 void* init_data = parent_isolate->init_callback_data();
438 bool retval = (callback)(isolate_name, init_data, error);
439 if (retval) {
440 Isolate* child_isolate = Isolate::Current();
441 ASSERT(child_isolate);
442 state->set_isolate(child_isolate);
siva 2012/03/12 23:25:41 We are assuming that the callback will load up the
turnidge 2012/03/13 18:13:48 It seems to me that if this occurs, it is an inter
siva 2012/03/13 19:45:21 Since the callback is something that the embedder
443 } else {
444 Dart::ShutdownIsolate();
445 }
446 Isolate::SetCurrent(parent_isolate);
447 return retval;
448 }
449
450
451 static void RunIsolate2(uword parameter) {
452 SpawnState* state = reinterpret_cast<SpawnState*>(parameter);
453 Isolate* isolate = state->isolate();
454
455 Isolate::SetCurrent(isolate);
456 // Intialize stack limit in case we are running isolate in a
457 // different thread than in which it was initialized.
458 isolate->SetStackLimitFromCurrentTOS(reinterpret_cast<uword>(&isolate));
459
460 {
461 Zone zone(isolate);
462 HandleScope handle_scope(isolate);
463 ASSERT(ClassFinalizer::FinalizePendingClasses());
464 Object& result = Object::Handle();
465
466 const String& lib_url =
467 String::Handle(String::NewSymbol(state->library_url()));
468 const String& func_name =
469 String::Handle(String::NewSymbol(state->function_name()));
470 delete state;
471 state = NULL;
472
473 const Library& lib = Library::Handle(Library::LookupLibrary(lib_url));
474 ASSERT(!lib.IsNull() && !lib.IsError());
475 GrowableArray<const Object*> args(0);
476 const Function& func =
477 Function::Handle(lib.LookupLocalFunction(func_name));
siva 2012/03/12 23:25:41 ASSERT(!func.IsNull());
turnidge 2012/03/13 18:13:48 Done.
478 const Array& kNoArgNames = Array::Handle();
479 result = DartEntry::InvokeStatic(func, args, kNoArgNames);
480 if (result.IsError()) {
481 ProcessError(result);
482 }
483
484 result = isolate->StandardRunLoop();
485 if (result.IsError()) {
486 ProcessError(result);
487 }
488 ASSERT(result.IsNull());
489 }
490 Dart::ShutdownIsolate();
491 }
492
493
494 DEFINE_NATIVE_ENTRY(isolate_spawnFunction, 1) {
495 const Closure& closure = Closure::CheckedHandle(arguments->At(0));
siva 2012/03/12 23:25:41 This should be GET_NATIVE_ARGUMENT(Closure, closur
turnidge 2012/03/13 18:13:48 Done.
496 const Function& func = Function::Handle(closure.function());
497 const Context& ctx = Context::Handle(closure.context());
498
499 if (!func.IsClosureFunction() || !func.is_static()) {
500 ThrowIllegalArgException(
501 "spawnFunction expects to be passed a closure to a static function");
502 }
siva 2012/03/12 23:25:41 Don't we also have to check that it is a top level
turnidge 2012/03/13 18:13:48 Done.
503 if (ctx.num_variables() > 0) {
Siggi Cherem (dart-lang) 2012/03/12 22:57:44 is this check redundant with the check above for i
turnidge 2012/03/13 18:13:48 I believe it is. Made it an ASSERT.
504 ThrowIllegalArgException(
505 "spawnFunction expects to be passed a closure with no bound variables");
506 }
507
508 // Create a new isolate.
509 char* error = NULL;
510 SpawnState* state = new SpawnState(func);
511 if (!CreateIsolate(state, &error)) {
512 // TODO(turnidge): Throw a different exception type here.
turnidge 2012/03/12 22:38:48 Siggi -- what type of exception do we want to thro
Siggi Cherem (dart-lang) 2012/03/12 22:57:44 How about we introduce 'IsolateSpawnException' (ma
turnidge 2012/03/13 18:13:48 I've added IsolateSpawnException as part of this c
513 delete state;
514 ThrowIllegalArgException(error);
515 }
516
517 // Try to create a SendPort for the new isolate.
518 const Object& port =
519 Object::Handle(SendPortCreate(state->isolate()->main_port()));
520 if (port.IsError()) {
521 Isolate* saved = Isolate::Current();
522 Isolate::SetCurrent(state->isolate());
523 Dart::ShutdownIsolate();
524 Isolate::SetCurrent(saved);
525 delete state;
526 Exceptions::PropagateError(port);
527 }
528
529 // Start the new isolate.
530 int result = Thread::Start(RunIsolate2, reinterpret_cast<uword>(state));
531 if (result != 0) {
532 FATAL1("Failed to start isolate thread: error %d", result);
Siggi Cherem (dart-lang) 2012/03/12 22:57:44 should this be fatal or also throw the IsolateSpaw
siva 2012/03/12 23:25:41 Why does this have to be a Fatal and not an except
turnidge 2012/03/13 18:13:48 I was just cribbing from the existing code. Chang
533 }
534
535 arguments->SetReturn(port);
536 }
537
538
539 DEFINE_NATIVE_ENTRY(isolate_getPortInternal, 0) {
540 const Object& port = Object::Handle(ReceivePortCreate(isolate->main_port()));
541 if (port.IsError()) {
542 Exceptions::PropagateError(port);
543 }
544 arguments->SetReturn(port);
545 }
546
386 } // namespace dart 547 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/lib/isolate.dart » ('j') | runtime/lib/isolate.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698