OLD | NEW |
---|---|
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 "include/dart_api.h" | 5 #include "include/dart_api.h" |
6 | 6 |
7 #include "vm/assert.h" | 7 #include "vm/assert.h" |
8 #include "vm/dart_api_impl.h" | 8 #include "vm/dart_api_impl.h" |
9 #include "vm/dart_api_state.h" | 9 #include "vm/dart_api_state.h" |
10 #include "vm/thread.h" | |
10 #include "vm/unit_test.h" | 11 #include "vm/unit_test.h" |
11 #include "vm/utils.h" | 12 #include "vm/utils.h" |
12 #include "vm/verifier.h" | 13 #include "vm/verifier.h" |
13 | 14 |
14 namespace dart { | 15 namespace dart { |
15 | 16 |
16 #if defined(TARGET_ARCH_IA32) // only ia32 can run execution tests. | 17 #if defined(TARGET_ARCH_IA32) // only ia32 can run execution tests. |
17 | 18 |
18 UNIT_TEST_CASE(ErrorHandles) { | 19 UNIT_TEST_CASE(ErrorHandles) { |
19 const char* kScriptChars = | 20 const char* kScriptChars = |
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
424 EXPECT_VALID(ext8); | 425 EXPECT_VALID(ext8); |
425 | 426 |
426 result = Dart_ExternalStringGetPeer(ext8, &peer); | 427 result = Dart_ExternalStringGetPeer(ext8, &peer); |
427 EXPECT_VALID(result); | 428 EXPECT_VALID(result); |
428 EXPECT_EQ(&peer_data, peer); | 429 EXPECT_EQ(&peer_data, peer); |
429 | 430 |
430 // NULL peer. | 431 // NULL peer. |
431 result = Dart_ExternalStringGetPeer(ext8, NULL); | 432 result = Dart_ExternalStringGetPeer(ext8, NULL); |
432 EXPECT(Dart_IsError(result)); | 433 EXPECT(Dart_IsError(result)); |
433 EXPECT_STREQ("Dart_ExternalStringGetPeer expects argument 'peer' to be " | 434 EXPECT_STREQ("Dart_ExternalStringGetPeer expects argument 'peer' to be " |
434 "non-NULL.", Dart_GetError(result)); | 435 "non-null.", Dart_GetError(result)); |
435 | 436 |
436 // String is not external. | 437 // String is not external. |
437 peer = NULL; | 438 peer = NULL; |
438 Dart_Handle str8 = Dart_NewString8(data8, ARRAY_SIZE(data8)); | 439 Dart_Handle str8 = Dart_NewString8(data8, ARRAY_SIZE(data8)); |
439 EXPECT_VALID(str8); | 440 EXPECT_VALID(str8); |
440 result = Dart_ExternalStringGetPeer(str8, &peer); | 441 result = Dart_ExternalStringGetPeer(str8, &peer); |
441 EXPECT(Dart_IsError(result)); | 442 EXPECT(Dart_IsError(result)); |
442 EXPECT_STREQ("Dart_ExternalStringGetPeer expects argument 'object' to be " | 443 EXPECT_STREQ("Dart_ExternalStringGetPeer expects argument 'object' to be " |
443 "an external String.", Dart_GetError(result)); | 444 "an external String.", Dart_GetError(result)); |
444 EXPECT(peer == NULL); | 445 EXPECT(peer == NULL); |
(...skipping 2318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2763 | 2764 |
2764 UNIT_TEST_CASE(RunLoop_Success) { | 2765 UNIT_TEST_CASE(RunLoop_Success) { |
2765 RunLoopTest(false); | 2766 RunLoopTest(false); |
2766 } | 2767 } |
2767 | 2768 |
2768 | 2769 |
2769 UNIT_TEST_CASE(RunLoop_Exception) { | 2770 UNIT_TEST_CASE(RunLoop_Exception) { |
2770 RunLoopTest(true); | 2771 RunLoopTest(true); |
2771 } | 2772 } |
2772 | 2773 |
2774 | |
2775 static Monitor* sync = NULL; | |
2776 static Dart_Isolate shared_isolate = NULL; | |
2777 void BusyLoop_start(uword unused) { | |
2778 // TODO(turnidge): Get rid of call to 'function' after interrupts | |
2779 // are checked on backward branches. | |
2780 const char* kScriptChars = | |
2781 "void throwException() {\n" | |
Ivan Posva
2011/12/14 23:59:50
This does not really throw the exception, how abou
turnidge
2011/12/15 21:30:07
Removed.
| |
2782 " return new Exception('foo');\n" | |
2783 "}\n" | |
2784 "\n" | |
2785 "void function([foo='hi']) {\n" | |
2786 "}\n" | |
2787 "\n" | |
2788 "void main() {\n" | |
2789 " while (true) {\n" // Infinite loop. | |
2790 " function();\n" | |
2791 " }\n" | |
2792 "}\n"; | |
2793 | |
2794 char* error = NULL; | |
2795 shared_isolate = Dart_CreateIsolate(NULL, NULL, &error); | |
2796 EXPECT(shared_isolate != NULL); | |
2797 Dart_EnterScope(); | |
2798 Dart_Handle url = Dart_NewString(TestCase::url()); | |
2799 Dart_Handle source = Dart_NewString(kScriptChars); | |
2800 Dart_Handle lib = Dart_LoadScript(url, source, TestCase::library_handler); | |
2801 EXPECT_VALID(lib); | |
2802 | |
2803 // Tell the other thread that shared_isolate is created. | |
2804 { | |
2805 MonitorLocker ml(sync); | |
2806 ml.Notify(); | |
2807 } | |
2808 | |
2809 Dart_Handle result = Dart_InvokeStatic(lib, | |
2810 Dart_NewString(""), | |
2811 Dart_NewString("main"), | |
2812 0, | |
2813 NULL); | |
2814 EXPECT(Dart_IsError(result)); | |
2815 EXPECT(Dart_ErrorHasException(result)); | |
2816 EXPECT_SUBSTRING("Unhandled exception:\nException: foo\n", | |
2817 Dart_GetError(result)); | |
2818 | |
2819 // Tell the other thread that we are done. | |
2820 { | |
2821 MonitorLocker ml(sync); | |
2822 shared_isolate = NULL; | |
2823 ml.Notify(); | |
2824 } | |
2825 | |
2826 Dart_ExitScope(); | |
2827 Dart_ShutdownIsolate(); | |
2828 } | |
2829 | |
2830 | |
2831 // This callback handles isolate interrupts for the IsolateInterrupt | |
2832 // test. It ignores the first two interrupts and throws an exception | |
2833 // on the third interrupt. | |
2834 static int interrupt_count = 0; | |
2835 static bool IsolateInterruptTestCallback() { | |
2836 interrupt_count++; | |
2837 OS::Print(" =========== Interrupt callback called #%d\n", interrupt_count); | |
2838 if (interrupt_count >= 3) { | |
2839 Dart_EnterScope(); | |
2840 Dart_Handle lib = Dart_LookupLibrary(Dart_NewString(TestCase::url())); | |
2841 EXPECT_VALID(lib); | |
2842 Dart_Handle exc = Dart_InvokeStatic(lib, | |
2843 Dart_NewString(""), | |
2844 Dart_NewString("throwException"), | |
2845 0, | |
2846 NULL); | |
2847 EXPECT_VALID(exc); | |
2848 Dart_Handle result = Dart_ThrowException(exc); | |
Ivan Posva
2011/12/14 23:59:50
You could also throw a string here. That way you d
turnidge
2011/12/15 21:30:07
Done.
| |
2849 EXPECT_VALID(result); | |
2850 UNREACHABLE(); // Dart_ThrowException only returns if it gets an error. | |
2851 return false; | |
2852 } | |
2853 return true; | |
2854 } | |
2855 | |
2856 | |
2857 TEST_CASE(IsolateInterrupt) { | |
2858 Dart_IsolateInterruptCallback saved = Isolate::InterruptCallback(); | |
2859 Isolate::SetInterruptCallback(IsolateInterruptTestCallback); | |
2860 | |
2861 sync = new Monitor(); | |
2862 Thread* thread = new Thread(BusyLoop_start, 0); | |
2863 EXPECT(thread != NULL); | |
2864 | |
2865 // Wait for the other isolate to start. | |
2866 while (shared_isolate == NULL) { | |
2867 MonitorLocker ml(sync); | |
Ivan Posva
2011/12/14 23:59:50
This locking here is strange.
turnidge
2011/12/15 21:30:07
Fixed.
| |
2868 ml.Wait(5); | |
2869 } | |
2870 | |
2871 // Send three interrupts to the other isolate. The first two allow | |
2872 // execution to continue. The third causes an exception in the | |
2873 // isolate. | |
2874 Dart_InterruptIsolate(shared_isolate); | |
2875 OS::Sleep(5); | |
2876 Dart_InterruptIsolate(shared_isolate); | |
2877 OS::Sleep(5); | |
2878 Dart_InterruptIsolate(shared_isolate); | |
2879 | |
2880 // Wait for our isolate to finish. | |
2881 while (shared_isolate != NULL) { | |
2882 MonitorLocker ml(sync); | |
2883 ml.Wait(5); | |
2884 } | |
2885 | |
2886 // We should have received 3 interrupts. | |
2887 EXPECT_EQ(3, interrupt_count); | |
2888 | |
2889 // Give the spawned thread enough time to properly exit. | |
2890 OS::Sleep(20); | |
2891 Isolate::SetInterruptCallback(saved); | |
2892 } | |
2893 | |
2773 #endif // TARGET_ARCH_IA32. | 2894 #endif // TARGET_ARCH_IA32. |
2774 | 2895 |
2775 } // namespace dart | 2896 } // namespace dart |
OLD | NEW |