Index: runtime/vm/dart_api_impl.cc |
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc |
index d316138f93480972c01f8e758d06017b63ab859e..c3941441852a16261b4223713bcbd72aa8cc6534 100644 |
--- a/runtime/vm/dart_api_impl.cc |
+++ b/runtime/vm/dart_api_impl.cc |
@@ -354,6 +354,26 @@ static RawObject* Send1Arg(const Instance& receiver, |
} |
+static const char* GetErrorString(Thread* thread, const Object& obj) { |
+ // This function requires an API scope to be present. |
+ if (obj.IsError()) { |
+ ASSERT(thread->api_top_scope() != NULL); |
+ const Error& error = Error::Cast(obj); |
+ const char* str = error.ToErrorCString(); |
+ intptr_t len = strlen(str) + 1; |
+ char* str_copy = Api::TopScope(thread)->zone()->Alloc<char>(len); |
+ strncpy(str_copy, str, len); |
+ // Strip a possible trailing '\n'. |
+ if ((len > 1) && (str_copy[len - 2] == '\n')) { |
+ str_copy[len - 2] = '\0'; |
+ } |
+ return str_copy; |
+ } else { |
+ return ""; |
+ } |
+} |
+ |
+ |
Dart_Handle Api::InitNewHandle(Thread* thread, RawObject* raw) { |
LocalHandles* local_handles = Api::TopScope(thread)->local_handles(); |
ASSERT(local_handles != NULL); |
@@ -448,7 +468,9 @@ Dart_Isolate Api::CastIsolate(Isolate* isolate) { |
Dart_Handle Api::NewError(const char* format, ...) { |
- DARTSCOPE(Thread::Current()); |
+ Thread* T = Thread::Current(); |
+ CHECK_API_SCOPE(T); |
+ HANDLESCOPE(T); |
CHECK_CALLBACK_STATE(T); |
va_list args; |
@@ -745,20 +767,7 @@ DART_EXPORT const char* Dart_GetError(Dart_Handle handle) { |
API_TIMELINE_DURATION; |
DARTSCOPE(Thread::Current()); |
const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle)); |
- if (obj.IsError()) { |
- const Error& error = Error::Cast(obj); |
- const char* str = error.ToErrorCString(); |
- intptr_t len = strlen(str) + 1; |
- char* str_copy = Api::TopScope(T)->zone()->Alloc<char>(len); |
- strncpy(str_copy, str, len); |
- // Strip a possible trailing '\n'. |
- if ((len > 1) && (str_copy[len - 2] == '\n')) { |
- str_copy[len - 2] = '\0'; |
- } |
- return str_copy; |
- } else { |
- return ""; |
- } |
+ return GetErrorString(T, obj); |
} |
@@ -815,7 +824,8 @@ DART_EXPORT Dart_Handle Dart_NewUnhandledExceptionError(Dart_Handle exception) { |
Instance& obj = Instance::Handle(Z); |
intptr_t class_id = Api::ClassId(exception); |
if ((class_id == kApiErrorCid) || (class_id == kLanguageErrorCid)) { |
- obj = String::New(::Dart_GetError(exception)); |
+ const Object& excp = Object::Handle(Z, Api::UnwrapHandle(exception)); |
+ obj = String::New(GetErrorString(T, excp)); |
} else { |
obj = Api::UnwrapInstanceHandle(Z, exception).raw(); |
if (obj.IsNull()) { |
@@ -1030,6 +1040,7 @@ DART_EXPORT Dart_WeakPersistentHandle Dart_NewWeakPersistentHandle( |
if (callback == NULL) { |
return NULL; |
} |
+ TransitionNativeToVM transition(thread); |
return AllocateFinalizableHandle(thread, |
object, |
peer, |
@@ -1248,6 +1259,12 @@ DART_EXPORT Dart_Isolate Dart_CreateIsolate(const char* script_uri, |
#endif // defined(DART_NO_SNAPSHOT). |
// We exit the API scope entered above. |
Dart_ExitScope(); |
+ // A Thread structure has been associated to the thread, we do the |
+ // safepoint transition explicity here instead of using the |
+ // TransitionXXX scope objects as the reverse transition happens |
+ // outside this scope in Dart_ShutdownIsolate/Dart_ExitIsolate. |
+ T->set_execution_state(Thread::kThreadInNative); |
+ T->EnterSafepoint(); |
return Api::CastIsolate(I); |
} |
*error = strdup(error_obj.ToErrorCString()); |
@@ -1269,6 +1286,12 @@ DART_EXPORT void Dart_ShutdownIsolate() { |
HandleScope handle_scope(T); |
Dart::RunShutdownCallback(); |
} |
+ // The Thread structure is disassociated from the isolate, we do the |
+ // safepoint transition explicity here instead of using the TransitionXXX |
+ // scope objects as the original transition happened outside this scope in |
+ // Dart_EnterIsolate/Dart_CreateIsolate. |
+ T->ExitSafepoint(); |
+ T->set_execution_state(Thread::kThreadInVM); |
Dart::ShutdownIsolate(); |
} |
@@ -1312,6 +1335,13 @@ DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate) { |
if (!Thread::EnterIsolate(iso)) { |
FATAL("Unable to Enter Isolate as Dart VM is shutting down"); |
} |
+ // A Thread structure has been associated to the thread, we do the |
+ // safepoint transition explicity here instead of using the |
+ // TransitionXXX scope objects as the reverse transition happens |
+ // outside this scope in Dart_ExitIsolate/Dart_ShutdownIsolate. |
+ Thread* T = Thread::Current(); |
+ T->set_execution_state(Thread::kThreadInNative); |
+ T->EnterSafepoint(); |
} |
@@ -1334,7 +1364,15 @@ DART_EXPORT void Dart_ThreadEnableProfiling() { |
DART_EXPORT void Dart_ExitIsolate() { |
- CHECK_ISOLATE(Isolate::Current()); |
+ Thread* T = Thread::Current(); |
+ CHECK_ISOLATE(T->isolate()); |
+ // The Thread structure is disassociated from the isolate, we do the |
+ // safepoint transition explicity here instead of using the TransitionXXX |
+ // scope objects as the original transition happened outside this scope in |
+ // Dart_EnterIsolate/Dart_CreateIsolate. |
+ ASSERT(T->execution_state() == Thread::kThreadInNative); |
+ T->ExitSafepoint(); |
+ T->set_execution_state(Thread::kThreadInVM); |
Thread::ExitIsolate(); |
} |
@@ -1500,7 +1538,7 @@ DART_EXPORT Dart_Handle Dart_RunLoop() { |
{ |
// The message handler run loop does not expect to have a current isolate |
// so we exit the isolate here and enter it again after the runloop is done. |
- Thread::ExitIsolate(); |
+ Dart_ExitIsolate(); |
RunLoopData data; |
data.monitor = &monitor; |
data.done = false; |
@@ -1510,9 +1548,7 @@ DART_EXPORT Dart_Handle Dart_RunLoop() { |
while (!data.done) { |
ml.Wait(); |
} |
- if (!Thread::EnterIsolate(I)) { |
- FATAL("Inconsistent state, VM shutting down while in run loop."); |
- } |
+ Dart_EnterIsolate(Api::CastIsolate(I)); |
} |
if (I->object_store()->sticky_error() != Object::null()) { |
Dart_Handle error = Api::NewHandle(T, I->object_store()->sticky_error()); |
@@ -1533,6 +1569,7 @@ DART_EXPORT Dart_Handle Dart_HandleMessage() { |
CHECK_API_SCOPE(T); |
CHECK_CALLBACK_STATE(T); |
API_TIMELINE_BEGIN_END; |
+ TransitionNativeToVM trainsition(T); |
if (I->message_handler()->HandleNextMessage() != MessageHandler::kOK) { |
Dart_Handle error = Api::NewHandle(T, I->object_store()->sticky_error()); |
I->object_store()->clear_sticky_error(); |
@@ -1548,6 +1585,7 @@ DART_EXPORT bool Dart_HandleServiceMessages() { |
CHECK_API_SCOPE(T); |
CHECK_CALLBACK_STATE(T); |
API_TIMELINE_DURATION; |
+ TransitionNativeToVM trainsition(T); |
ASSERT(I->GetAndClearResumeRequest() == false); |
MessageHandler::MessageStatus status = |
I->message_handler()->HandleOOBMessages(); |
@@ -4819,10 +4857,11 @@ DART_EXPORT void Dart_SetWeakHandleReturnValue(Dart_NativeArguments args, |
// --- Environment --- |
RawString* Api::CallEnvironmentCallback(Thread* thread, const String& name) { |
Isolate* isolate = thread->isolate(); |
- Scope api_scope(thread); |
Dart_EnvironmentCallback callback = isolate->environment_callback(); |
String& result = String::Handle(thread->zone()); |
if (callback != NULL) { |
+ TransitionVMToNative transition(thread); |
+ Scope api_scope(thread); |
Dart_Handle response = callback(Api::NewHandle(thread, name.raw())); |
if (::Dart_IsString(response)) { |
result ^= Api::UnwrapHandle(response); |