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

Unified Diff: runtime/vm/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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/isolate.cc
===================================================================
--- runtime/vm/isolate.cc (revision 20976)
+++ runtime/vm/isolate.cc (working copy)
@@ -337,6 +337,7 @@
saved_stack_limit_(0),
message_handler_(NULL),
spawn_data_(0),
+ is_runnable_(false),
gc_prologue_callbacks_(),
gc_epilogue_callbacks_(),
deopt_cpu_registers_copy_(NULL),
@@ -480,6 +481,109 @@
}
+bool Isolate::MakeRunnable() {
+ ASSERT(Isolate::Current() == NULL);
+ // Can't use MutexLocker here because MutexLocker is
+ // a StackResource, which requires a current isolate.
+ mutex_->Lock();
+ // Check if we are in a valid state to make the isolate runnable.
+ if (is_runnable_ == true) {
+ mutex_->Unlock();
+ return false; // Already runnable.
+ }
+ // Set the isolate as runnable and if we are being spawned schedule
+ // isolate on thread pool for execution.
+ is_runnable_ = true;
+ IsolateSpawnState* state = reinterpret_cast<IsolateSpawnState*>(spawn_data());
+ if (state != NULL) {
+ ASSERT(this == state->isolate());
+ Run();
+ }
+ mutex_->Unlock();
+ return true;
+}
+
+
+static void StoreError(Isolate* isolate, const Object& obj) {
+ ASSERT(obj.IsError());
+ isolate->object_store()->set_sticky_error(Error::Cast(obj));
+}
+
+
+static bool RunIsolate(uword parameter) {
+ Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
+ IsolateSpawnState* state = NULL;
+ {
+ MutexLocker ml(isolate->mutex());
+ state = reinterpret_cast<IsolateSpawnState*>(isolate->spawn_data());
+ isolate->set_spawn_data(0);
+ }
+ {
+ StartIsolateScope start_scope(isolate);
+ StackZone zone(isolate);
+ HandleScope handle_scope(isolate);
+ if (!ClassFinalizer::FinalizePendingClasses()) {
+ // Error is in sticky error already.
+ return false;
+ }
+
+ // Set up specific unhandled exception handler.
+ const String& callback_name = String::Handle(
+ isolate, String::New(state->exception_callback_name()));
+ isolate->object_store()->
+ set_unhandled_exception_handler(callback_name);
+
+ Object& result = Object::Handle();
+ result = state->ResolveFunction();
+ delete state;
+ state = NULL;
+ if (result.IsError()) {
+ StoreError(isolate, result);
+ return false;
+ }
+ ASSERT(result.IsFunction());
+ Function& func = Function::Handle(isolate);
+ func ^= result.raw();
+ result = DartEntry::InvokeFunction(func, Object::empty_array());
+ if (result.IsError()) {
+ StoreError(isolate, result);
+ return false;
+ }
+ }
+ return true;
+}
+
+
+static void ShutdownIsolate(uword parameter) {
+ Isolate* isolate = reinterpret_cast<Isolate*>(parameter);
+ {
+ // Print the error if there is one. This may execute dart code to
+ // print the exception object, so we need to use a StartIsolateScope.
+ StartIsolateScope start_scope(isolate);
+ StackZone zone(isolate);
+ HandleScope handle_scope(isolate);
+ Error& error = Error::Handle();
+ error = isolate->object_store()->sticky_error();
+ if (!error.IsNull()) {
+ OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString());
+ }
+ }
+ {
+ // Shut the isolate down.
+ SwitchIsolateScope switch_scope(isolate);
+ Dart::ShutdownIsolate();
+ }
+}
+
+
+void Isolate::Run() {
+ message_handler()->Run(Dart::thread_pool(),
+ RunIsolate,
+ ShutdownIsolate,
+ reinterpret_cast<uword>(this));
+}
+
+
uword Isolate::GetAndClearInterrupts() {
MutexLocker ml(mutex_);
if (stack_limit_ == saved_stack_limit_) {
@@ -878,4 +982,94 @@
return NULL; // Unimplemented query.
}
+
+static char* GetRootScriptUri(Isolate* isolate) {
+ const Library& library =
+ Library::Handle(isolate->object_store()->root_library());
+ ASSERT(!library.IsNull());
+ const String& script_name = String::Handle(library.url());
+ return isolate->current_zone()->MakeCopyOfString(script_name.ToCString());
+}
+
+
+IsolateSpawnState::IsolateSpawnState(const Function& func,
+ const Function& callback_func)
+ : isolate_(NULL),
+ script_url_(NULL),
+ library_url_(NULL),
+ function_name_(NULL),
+ exception_callback_name_(NULL) {
+ script_url_ = strdup(GetRootScriptUri(Isolate::Current()));
+ const Class& cls = Class::Handle(func.Owner());
+ ASSERT(cls.IsTopLevel());
+ const Library& lib = Library::Handle(cls.library());
+ const String& lib_url = String::Handle(lib.url());
+ library_url_ = strdup(lib_url.ToCString());
+
+ const String& func_name = String::Handle(func.name());
+ function_name_ = strdup(func_name.ToCString());
+ if (!callback_func.IsNull()) {
+ const String& callback_name = String::Handle(callback_func.name());
+ exception_callback_name_ = strdup(callback_name.ToCString());
+ } else {
+ exception_callback_name_ = strdup("_unhandledExceptionCallback");
+ }
+}
+
+
+IsolateSpawnState::IsolateSpawnState(const char* script_url)
+ : isolate_(NULL),
+ library_url_(NULL),
+ function_name_(NULL),
+ exception_callback_name_(NULL) {
+ script_url_ = strdup(script_url);
+ library_url_ = NULL;
+ function_name_ = strdup("main");
+ exception_callback_name_ = strdup("_unhandledExceptionCallback");
+}
+
+
+IsolateSpawnState::~IsolateSpawnState() {
+ free(script_url_);
+ free(library_url_);
+ free(function_name_);
+ free(exception_callback_name_);
+}
+
+
+RawObject* IsolateSpawnState::ResolveFunction() {
+ // Resolve the library.
+ Library& lib = Library::Handle();
+ if (library_url()) {
+ const String& lib_url = String::Handle(String::New(library_url()));
+ lib = Library::LookupLibrary(lib_url);
+ if (lib.IsNull() || lib.IsError()) {
+ const String& msg = String::Handle(String::NewFormatted(
+ "Unable to find library '%s'.", library_url()));
+ return LanguageError::New(msg);
+ }
+ } else {
+ lib = isolate()->object_store()->root_library();
+ }
+ ASSERT(!lib.IsNull());
+
+ // Resolve the function.
+ const String& func_name =
+ String::Handle(String::New(function_name()));
+ const Function& func = Function::Handle(lib.LookupLocalFunction(func_name));
+ if (func.IsNull()) {
+ const String& msg = String::Handle(String::NewFormatted(
+ "Unable to resolve function '%s' in library '%s'.",
+ function_name(), (library_url() ? library_url() : script_url())));
+ return LanguageError::New(msg);
+ }
+ return func.raw();
+}
+
+
+void IsolateSpawnState::Cleanup() {
+ SwitchIsolateScope switch_scope(isolate());
+ Dart::ShutdownIsolate();
+}
+
} // namespace dart

Powered by Google App Engine
This is Rietveld 408576698