OLD | NEW |
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 "include/dart_debugger_api.h" | 5 #include "include/dart_debugger_api.h" |
6 #include "platform/assert.h" | 6 #include "platform/assert.h" |
7 #include "vm/dart_api_impl.h" | 7 #include "vm/dart_api_impl.h" |
| 8 #include "vm/thread.h" |
8 #include "vm/unit_test.h" | 9 #include "vm/unit_test.h" |
9 | 10 |
10 namespace dart { | 11 namespace dart { |
11 | 12 |
12 // Only ia32 and x64 can run execution tests. | 13 // Only ia32 and x64 can run execution tests. |
13 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) | 14 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) |
14 | 15 |
15 static bool breakpoint_hit = false; | 16 static bool breakpoint_hit = false; |
16 static int breakpoint_hit_counter = 0; | 17 static int breakpoint_hit_counter = 0; |
17 static Dart_Handle script_lib = NULL; | 18 static Dart_Handle script_lib = NULL; |
(...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 lib_list = Dart_GetLibraryURLs(); | 1033 lib_list = Dart_GetLibraryURLs(); |
1033 EXPECT_VALID(lib_list); | 1034 EXPECT_VALID(lib_list); |
1034 EXPECT(Dart_IsList(lib_list)); | 1035 EXPECT(Dart_IsList(lib_list)); |
1035 list_as_string = Dart_ToString(lib_list); | 1036 list_as_string = Dart_ToString(lib_list); |
1036 list_cstr = ""; | 1037 list_cstr = ""; |
1037 EXPECT_VALID(Dart_StringToCString(list_as_string, &list_cstr)); | 1038 EXPECT_VALID(Dart_StringToCString(list_as_string, &list_cstr)); |
1038 EXPECT_SUBSTRING(TestCase::url(), list_cstr); | 1039 EXPECT_SUBSTRING(TestCase::url(), list_cstr); |
1039 } | 1040 } |
1040 | 1041 |
1041 | 1042 |
| 1043 static Dart_IsolateId test_isolate_id = ILLEGAL_ISOLATE_ID; |
| 1044 static int verify_callback = 0; |
| 1045 static void TestIsolateID(Dart_IsolateId isolate_id, Dart_IsolateEvent kind) { |
| 1046 if (kind == kCreated) { |
| 1047 EXPECT(test_isolate_id == ILLEGAL_ISOLATE_ID); |
| 1048 test_isolate_id = isolate_id; |
| 1049 Dart_Isolate isolate = Dart_GetIsolate(isolate_id); |
| 1050 EXPECT(isolate == Dart_CurrentIsolate()); |
| 1051 verify_callback |= 0x1; // Register create callback. |
| 1052 } else if (kind == kInterrupted) { |
| 1053 EXPECT(test_isolate_id == isolate_id); |
| 1054 Dart_Isolate isolate = Dart_GetIsolate(isolate_id); |
| 1055 EXPECT(isolate == Dart_CurrentIsolate()); |
| 1056 verify_callback |= 0x2; // Register interrupt callback. |
| 1057 } else if (kind == kShutdown) { |
| 1058 EXPECT(test_isolate_id == isolate_id); |
| 1059 Dart_Isolate isolate = Dart_GetIsolate(isolate_id); |
| 1060 EXPECT(isolate == Dart_CurrentIsolate()); |
| 1061 verify_callback |= 0x4; // Register shutdown callback. |
| 1062 } |
| 1063 } |
| 1064 |
| 1065 |
| 1066 UNIT_TEST_CASE(Debug_IsolateID) { |
| 1067 const char* kScriptChars = |
| 1068 "void moo(s) { } \n" |
| 1069 "class A { \n" |
| 1070 " static void foo() { \n" |
| 1071 " moo('good news'); \n" |
| 1072 " } \n" |
| 1073 "} \n" |
| 1074 "void main() { \n" |
| 1075 " A.foo(); \n" |
| 1076 "} \n"; |
| 1077 |
| 1078 Dart_SetIsolateEventHandler(&TestIsolateID); |
| 1079 Dart_Isolate isolate = TestCase::CreateTestIsolate(); |
| 1080 ASSERT(isolate != NULL); |
| 1081 Dart_EnterScope(); |
| 1082 LoadScript(kScriptChars); |
| 1083 Dart_Handle retval = Invoke("main"); |
| 1084 EXPECT_VALID(retval); |
| 1085 EXPECT(test_isolate_id != ILLEGAL_ISOLATE_ID); |
| 1086 EXPECT(Dart_GetIsolate(test_isolate_id) == isolate); |
| 1087 Dart_ExitScope(); |
| 1088 Dart_ShutdownIsolate(); |
| 1089 EXPECT(verify_callback == 0x5); // Only created and shutdown events. |
| 1090 } |
| 1091 |
| 1092 |
| 1093 static Monitor* sync = NULL; |
| 1094 static bool isolate_interrupted = false; |
| 1095 static Dart_IsolateId interrupt_isolate_id = ILLEGAL_ISOLATE_ID; |
| 1096 static volatile bool continue_isolate_loop = true; |
| 1097 |
| 1098 |
| 1099 static void TestInterruptIsolate(Dart_IsolateId isolate_id, |
| 1100 Dart_IsolateEvent kind) { |
| 1101 if (kind == kCreated) { |
| 1102 EXPECT(interrupt_isolate_id == ILLEGAL_ISOLATE_ID); |
| 1103 // Indicate that the isolate has been created. |
| 1104 { |
| 1105 MonitorLocker ml(sync); |
| 1106 interrupt_isolate_id = isolate_id; |
| 1107 ml.Notify(); |
| 1108 } |
| 1109 } else if (kind == kInterrupted) { |
| 1110 // Indicate that isolate has been interrupted. |
| 1111 { |
| 1112 MonitorLocker ml(sync); |
| 1113 isolate_interrupted = true; |
| 1114 continue_isolate_loop = false; |
| 1115 ml.Notify(); |
| 1116 } |
| 1117 } else if (kind == kShutdown) { |
| 1118 if (interrupt_isolate_id == isolate_id) { |
| 1119 MonitorLocker ml(sync); |
| 1120 interrupt_isolate_id = ILLEGAL_ISOLATE_ID; |
| 1121 ml.Notify(); |
| 1122 } |
| 1123 } |
| 1124 } |
| 1125 |
| 1126 |
| 1127 static void InterruptNativeFunction(Dart_NativeArguments args) { |
| 1128 Dart_EnterScope(); |
| 1129 Dart_Handle val = Dart_NewBoolean(continue_isolate_loop); |
| 1130 Dart_SetReturnValue(args, val); |
| 1131 Dart_ExitScope(); |
| 1132 } |
| 1133 |
| 1134 |
| 1135 static Dart_NativeFunction InterruptNativeResolver(Dart_Handle name, |
| 1136 int arg_count) { |
| 1137 return &InterruptNativeFunction; |
| 1138 } |
| 1139 |
| 1140 |
| 1141 static void InterruptIsolateRun(uword unused) { |
| 1142 const char* kScriptChars = |
| 1143 "void moo(s) { } \n" |
| 1144 "class A { \n" |
| 1145 " static check() native 'a'; \n" |
| 1146 " static void foo() { \n" |
| 1147 " var loop = true; \n" |
| 1148 " while (loop) { \n" |
| 1149 " moo('good news'); \n" |
| 1150 " loop = check(); \n" |
| 1151 " } \n" |
| 1152 " } \n" |
| 1153 "} \n" |
| 1154 "void main() { \n" |
| 1155 " A.foo(); \n" |
| 1156 "} \n"; |
| 1157 |
| 1158 Dart_Isolate isolate = TestCase::CreateTestIsolate(); |
| 1159 ASSERT(isolate != NULL); |
| 1160 Dart_EnterScope(); |
| 1161 LoadScript(kScriptChars); |
| 1162 |
| 1163 Dart_Handle result = Dart_SetNativeResolver(script_lib, |
| 1164 &InterruptNativeResolver); |
| 1165 EXPECT_VALID(result); |
| 1166 |
| 1167 Dart_Handle retval = Invoke("main"); |
| 1168 EXPECT_VALID(retval); |
| 1169 Dart_ExitScope(); |
| 1170 Dart_ShutdownIsolate(); |
| 1171 } |
| 1172 |
| 1173 |
| 1174 TEST_CASE(Debug_InterruptIsolate) { |
| 1175 Dart_SetIsolateEventHandler(&TestInterruptIsolate); |
| 1176 sync = new Monitor(); |
| 1177 EXPECT(interrupt_isolate_id == ILLEGAL_ISOLATE_ID); |
| 1178 int result = Thread::Start(InterruptIsolateRun, 0); |
| 1179 EXPECT_EQ(0, result); |
| 1180 |
| 1181 // Wait for the test isolate to be created. |
| 1182 { |
| 1183 MonitorLocker ml(sync); |
| 1184 while (interrupt_isolate_id == ILLEGAL_ISOLATE_ID) { |
| 1185 ml.Wait(); |
| 1186 } |
| 1187 } |
| 1188 EXPECT(interrupt_isolate_id != ILLEGAL_ISOLATE_ID); |
| 1189 |
| 1190 Dart_Isolate isolate = Dart_GetIsolate(interrupt_isolate_id); |
| 1191 EXPECT(isolate != NULL); |
| 1192 Dart_InterruptIsolate(isolate); |
| 1193 |
| 1194 // Wait for the test isolate to be interrupted. |
| 1195 { |
| 1196 MonitorLocker ml(sync); |
| 1197 while (!isolate_interrupted) { |
| 1198 ml.Wait(); |
| 1199 } |
| 1200 } |
| 1201 EXPECT(isolate_interrupted); |
| 1202 |
| 1203 // Wait for the test isolate to shutdown. |
| 1204 { |
| 1205 MonitorLocker ml(sync); |
| 1206 while (interrupt_isolate_id != ILLEGAL_ISOLATE_ID) { |
| 1207 ml.Wait(); |
| 1208 } |
| 1209 } |
| 1210 EXPECT(interrupt_isolate_id == ILLEGAL_ISOLATE_ID); |
| 1211 } |
| 1212 |
1042 #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64). | 1213 #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64). |
1043 | 1214 |
1044 } // namespace dart | 1215 } // namespace dart |
OLD | NEW |