| Index: vm/debugger_api_impl_test.cc
|
| ===================================================================
|
| --- vm/debugger_api_impl_test.cc (revision 13206)
|
| +++ vm/debugger_api_impl_test.cc (working copy)
|
| @@ -5,6 +5,7 @@
|
| #include "include/dart_debugger_api.h"
|
| #include "platform/assert.h"
|
| #include "vm/dart_api_impl.h"
|
| +#include "vm/thread.h"
|
| #include "vm/unit_test.h"
|
|
|
| namespace dart {
|
| @@ -1039,6 +1040,176 @@
|
| }
|
|
|
|
|
| +static Dart_IsolateId test_isolate_id = ILLEGAL_ISOLATE_ID;
|
| +static int verify_callback = 0;
|
| +static void TestIsolateID(Dart_IsolateId isolate_id, Dart_IsolateEvent kind) {
|
| + if (kind == kCreated) {
|
| + EXPECT(test_isolate_id == ILLEGAL_ISOLATE_ID);
|
| + test_isolate_id = isolate_id;
|
| + Dart_Isolate isolate = Dart_GetIsolate(isolate_id);
|
| + EXPECT(isolate == Dart_CurrentIsolate());
|
| + verify_callback |= 0x1; // Register create callback.
|
| + } else if (kind == kInterrupted) {
|
| + EXPECT(test_isolate_id == isolate_id);
|
| + Dart_Isolate isolate = Dart_GetIsolate(isolate_id);
|
| + EXPECT(isolate == Dart_CurrentIsolate());
|
| + verify_callback |= 0x2; // Register interrupt callback.
|
| + } else if (kind == kShutdown) {
|
| + EXPECT(test_isolate_id == isolate_id);
|
| + Dart_Isolate isolate = Dart_GetIsolate(isolate_id);
|
| + EXPECT(isolate == Dart_CurrentIsolate());
|
| + verify_callback |= 0x4; // Register shutdown callback.
|
| + }
|
| +}
|
| +
|
| +
|
| +UNIT_TEST_CASE(Debug_IsolateID) {
|
| + const char* kScriptChars =
|
| + "void moo(s) { } \n"
|
| + "class A { \n"
|
| + " static void foo() { \n"
|
| + " moo('good news'); \n"
|
| + " } \n"
|
| + "} \n"
|
| + "void main() { \n"
|
| + " A.foo(); \n"
|
| + "} \n";
|
| +
|
| + Dart_SetIsolateEventHandler(&TestIsolateID);
|
| + Dart_Isolate isolate = TestCase::CreateTestIsolate();
|
| + ASSERT(isolate != NULL);
|
| + Dart_EnterScope();
|
| + LoadScript(kScriptChars);
|
| + Dart_Handle retval = Invoke("main");
|
| + EXPECT_VALID(retval);
|
| + EXPECT(test_isolate_id != ILLEGAL_ISOLATE_ID);
|
| + EXPECT(Dart_GetIsolate(test_isolate_id) == isolate);
|
| + Dart_ExitScope();
|
| + Dart_ShutdownIsolate();
|
| + EXPECT(verify_callback == 0x5); // Only created and shutdown events.
|
| +}
|
| +
|
| +
|
| +static Monitor* sync = NULL;
|
| +static bool isolate_interrupted = false;
|
| +static Dart_IsolateId interrupt_isolate_id = ILLEGAL_ISOLATE_ID;
|
| +static volatile bool continue_isolate_loop = true;
|
| +
|
| +
|
| +static void TestInterruptIsolate(Dart_IsolateId isolate_id,
|
| + Dart_IsolateEvent kind) {
|
| + if (kind == kCreated) {
|
| + EXPECT(interrupt_isolate_id == ILLEGAL_ISOLATE_ID);
|
| + // Indicate that the isolate has been created.
|
| + {
|
| + MonitorLocker ml(sync);
|
| + interrupt_isolate_id = isolate_id;
|
| + ml.Notify();
|
| + }
|
| + } else if (kind == kInterrupted) {
|
| + // Indicate that isolate has been interrupted.
|
| + {
|
| + MonitorLocker ml(sync);
|
| + isolate_interrupted = true;
|
| + continue_isolate_loop = false;
|
| + ml.Notify();
|
| + }
|
| + } else if (kind == kShutdown) {
|
| + if (interrupt_isolate_id == isolate_id) {
|
| + MonitorLocker ml(sync);
|
| + interrupt_isolate_id = ILLEGAL_ISOLATE_ID;
|
| + ml.Notify();
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +static void InterruptNativeFunction(Dart_NativeArguments args) {
|
| + Dart_EnterScope();
|
| + Dart_Handle val = Dart_NewBoolean(continue_isolate_loop);
|
| + Dart_SetReturnValue(args, val);
|
| + Dart_ExitScope();
|
| +}
|
| +
|
| +
|
| +static Dart_NativeFunction InterruptNativeResolver(Dart_Handle name,
|
| + int arg_count) {
|
| + return &InterruptNativeFunction;
|
| +}
|
| +
|
| +
|
| +static void InterruptIsolateRun(uword unused) {
|
| + const char* kScriptChars =
|
| + "void moo(s) { } \n"
|
| + "class A { \n"
|
| + " static check() native 'a'; \n"
|
| + " static void foo() { \n"
|
| + " var loop = true; \n"
|
| + " while (loop) { \n"
|
| + " moo('good news'); \n"
|
| + " loop = check(); \n"
|
| + " } \n"
|
| + " } \n"
|
| + "} \n"
|
| + "void main() { \n"
|
| + " A.foo(); \n"
|
| + "} \n";
|
| +
|
| + Dart_Isolate isolate = TestCase::CreateTestIsolate();
|
| + ASSERT(isolate != NULL);
|
| + Dart_EnterScope();
|
| + LoadScript(kScriptChars);
|
| +
|
| + Dart_Handle result = Dart_SetNativeResolver(script_lib,
|
| + &InterruptNativeResolver);
|
| + EXPECT_VALID(result);
|
| +
|
| + Dart_Handle retval = Invoke("main");
|
| + EXPECT_VALID(retval);
|
| + Dart_ExitScope();
|
| + Dart_ShutdownIsolate();
|
| +}
|
| +
|
| +
|
| +TEST_CASE(Debug_InterruptIsolate) {
|
| + Dart_SetIsolateEventHandler(&TestInterruptIsolate);
|
| + sync = new Monitor();
|
| + EXPECT(interrupt_isolate_id == ILLEGAL_ISOLATE_ID);
|
| + int result = Thread::Start(InterruptIsolateRun, 0);
|
| + EXPECT_EQ(0, result);
|
| +
|
| + // Wait for the test isolate to be created.
|
| + {
|
| + MonitorLocker ml(sync);
|
| + while (interrupt_isolate_id == ILLEGAL_ISOLATE_ID) {
|
| + ml.Wait();
|
| + }
|
| + }
|
| + EXPECT(interrupt_isolate_id != ILLEGAL_ISOLATE_ID);
|
| +
|
| + Dart_Isolate isolate = Dart_GetIsolate(interrupt_isolate_id);
|
| + EXPECT(isolate != NULL);
|
| + Dart_InterruptIsolate(isolate);
|
| +
|
| + // Wait for the test isolate to be interrupted.
|
| + {
|
| + MonitorLocker ml(sync);
|
| + while (!isolate_interrupted) {
|
| + ml.Wait();
|
| + }
|
| + }
|
| + EXPECT(isolate_interrupted);
|
| +
|
| + // Wait for the test isolate to shutdown.
|
| + {
|
| + MonitorLocker ml(sync);
|
| + while (interrupt_isolate_id != ILLEGAL_ISOLATE_ID) {
|
| + ml.Wait();
|
| + }
|
| + }
|
| + EXPECT(interrupt_isolate_id == ILLEGAL_ISOLATE_ID);
|
| +}
|
| +
|
| #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64).
|
|
|
| } // namespace dart
|
|
|