| 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/unit_test.h" | 8 #include "vm/unit_test.h" |
| 9 | 9 |
| 10 namespace dart { | 10 namespace dart { |
| 11 | 11 |
| 12 // Only ia32 and x64 can run execution tests. | 12 // Only ia32 and x64 can run execution tests. |
| 13 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) | 13 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) |
| 14 | 14 |
| 15 static bool breakpoint_hit = false; | 15 static bool breakpoint_hit = false; |
| 16 static int breakpoint_hit_counter = 0; | 16 static int breakpoint_hit_counter = 0; |
| 17 | 17 |
| 18 static const bool verbose = false; | 18 static const bool verbose = false; |
| 19 | 19 |
| 20 #define EXPECT_NOT_ERROR(handle) \ | 20 #define EXPECT_NOT_ERROR(handle) \ |
| 21 if (Dart_IsError(handle)) { \ | 21 if (Dart_IsError(handle)) { \ |
| 22 OS::Print("Error: %s\n", Dart_GetError(handle)); \ | 22 OS::Print("Error: %s\n", Dart_GetError(handle)); \ |
| 23 } \ | 23 } \ |
| 24 EXPECT(!Dart_IsError(handle)); | 24 EXPECT(!Dart_IsError(handle)); |
| 25 | 25 |
| 26 | 26 |
| 27 static Dart_Handle Invoke(Dart_Handle lib, const char* func_name) { |
| 28 return Dart_InvokeStatic(lib, |
| 29 Dart_NewString(""), |
| 30 Dart_NewString(func_name), |
| 31 0, |
| 32 NULL); |
| 33 } |
| 34 |
| 35 |
| 27 void TestBreakpointHandler(Dart_Breakpoint bpt, Dart_StackTrace trace) { | 36 void TestBreakpointHandler(Dart_Breakpoint bpt, Dart_StackTrace trace) { |
| 28 const char* expected_trace[] = {"A.foo", "main"}; | 37 const char* expected_trace[] = {"A.foo", "main"}; |
| 29 const intptr_t expected_trace_length = 2; | 38 const intptr_t expected_trace_length = 2; |
| 30 breakpoint_hit = true; | 39 breakpoint_hit = true; |
| 31 breakpoint_hit_counter++; | 40 breakpoint_hit_counter++; |
| 32 intptr_t trace_len; | 41 intptr_t trace_len; |
| 33 Dart_Handle res = Dart_StackTraceLength(trace, &trace_len); | 42 Dart_Handle res = Dart_StackTraceLength(trace, &trace_len); |
| 34 EXPECT_NOT_ERROR(res); | 43 EXPECT_NOT_ERROR(res); |
| 35 EXPECT_EQ(expected_trace_length, trace_len); | 44 EXPECT_EQ(expected_trace_length, trace_len); |
| 36 for (int i = 0; i < trace_len; i++) { | 45 for (int i = 0; i < trace_len; i++) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 66 | 75 |
| 67 Dart_SetBreakpointHandler(&TestBreakpointHandler); | 76 Dart_SetBreakpointHandler(&TestBreakpointHandler); |
| 68 | 77 |
| 69 Dart_Handle c_name = Dart_NewString("A"); | 78 Dart_Handle c_name = Dart_NewString("A"); |
| 70 Dart_Handle f_name = Dart_NewString("foo"); | 79 Dart_Handle f_name = Dart_NewString("foo"); |
| 71 Dart_Breakpoint bpt; | 80 Dart_Breakpoint bpt; |
| 72 Dart_Handle res = Dart_SetBreakpointAtEntry(lib, c_name, f_name, &bpt); | 81 Dart_Handle res = Dart_SetBreakpointAtEntry(lib, c_name, f_name, &bpt); |
| 73 EXPECT_NOT_ERROR(res); | 82 EXPECT_NOT_ERROR(res); |
| 74 | 83 |
| 75 breakpoint_hit = false; | 84 breakpoint_hit = false; |
| 76 Dart_Handle retval = Dart_InvokeStatic(lib, | 85 Dart_Handle retval = Invoke(lib, "main"); |
| 77 Dart_NewString(""), | |
| 78 Dart_NewString("main"), | |
| 79 0, | |
| 80 NULL); | |
| 81 EXPECT(!Dart_IsError(retval)); | 86 EXPECT(!Dart_IsError(retval)); |
| 82 EXPECT(breakpoint_hit == true); | 87 EXPECT(breakpoint_hit == true); |
| 83 } | 88 } |
| 84 | 89 |
| 85 | 90 |
| 86 static void DeleteBreakpointHandler(Dart_Breakpoint bpt, | 91 static void DeleteBreakpointHandler(Dart_Breakpoint bpt, |
| 87 Dart_StackTrace trace) { | 92 Dart_StackTrace trace) { |
| 88 const char* expected_trace[] = {"foo", "main"}; | 93 const char* expected_trace[] = {"foo", "main"}; |
| 89 const intptr_t expected_trace_length = 2; | 94 const intptr_t expected_trace_length = 2; |
| 90 breakpoint_hit_counter++; | 95 breakpoint_hit_counter++; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 Dart_SetBreakpointHandler(&DeleteBreakpointHandler); | 142 Dart_SetBreakpointHandler(&DeleteBreakpointHandler); |
| 138 | 143 |
| 139 Dart_Breakpoint bpt; | 144 Dart_Breakpoint bpt; |
| 140 Dart_Handle res = Dart_SetBreakpointAtLine(script_url, line_no, &bpt); | 145 Dart_Handle res = Dart_SetBreakpointAtLine(script_url, line_no, &bpt); |
| 141 EXPECT_NOT_ERROR(res); | 146 EXPECT_NOT_ERROR(res); |
| 142 | 147 |
| 143 // Function main() calls foo() 3 times. On the second iteration, the | 148 // Function main() calls foo() 3 times. On the second iteration, the |
| 144 // breakpoint is removed by the handler, so we expect the breakpoint | 149 // breakpoint is removed by the handler, so we expect the breakpoint |
| 145 // to fire twice only. | 150 // to fire twice only. |
| 146 breakpoint_hit_counter = 0; | 151 breakpoint_hit_counter = 0; |
| 147 Dart_Handle retval = Dart_InvokeStatic(lib, | 152 Dart_Handle retval = Invoke(lib, "main"); |
| 148 Dart_NewString(""), | |
| 149 Dart_NewString("main"), | |
| 150 0, | |
| 151 NULL); | |
| 152 EXPECT(!Dart_IsError(retval)); | 153 EXPECT(!Dart_IsError(retval)); |
| 153 EXPECT(breakpoint_hit_counter == 2); | 154 EXPECT(breakpoint_hit_counter == 2); |
| 154 } | 155 } |
| 155 | 156 |
| 156 | 157 |
| 158 TEST_CASE(Debug_InspectObject) { |
| 159 const char* kScriptChars = |
| 160 " class A { \n" |
| 161 " int a_field = 'a'; \n" |
| 162 " static var bla = 'yada yada yada';\n" |
| 163 " var d = 42.1; \n" |
| 164 " } \n" |
| 165 " class B extends A { \n" |
| 166 " var oneDay = const Duration(hours: 24); \n" |
| 167 " static var bla = 'blah blah'; \n" |
| 168 " } \n" |
| 169 " get_b() { return new B(); } \n" |
| 170 " get_int() { return 666; } \n"; |
| 171 |
| 172 // Number of instance fields in an object of class B. |
| 173 const intptr_t kNumObjectFields = 3; |
| 174 |
| 175 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
| 176 EXPECT_NOT_ERROR(lib); |
| 177 |
| 178 Dart_Handle script_url = Dart_NewString(TestCase::url()); |
| 179 Dart_Handle line_no = Dart_NewInteger(4); // In function 'foo'. |
| 180 |
| 181 Dart_Handle object_b = Invoke(lib, "get_b"); |
| 182 |
| 183 EXPECT_NOT_ERROR(object_b); |
| 184 |
| 185 Dart_Handle fields = Dart_GetInstanceFields(object_b); |
| 186 EXPECT_NOT_ERROR(fields); |
| 187 EXPECT(Dart_IsList(fields)); |
| 188 intptr_t list_length = 0; |
| 189 Dart_Handle retval = Dart_ListLength(fields, &list_length); |
| 190 EXPECT_NOT_ERROR(retval); |
| 191 EXPECT_EQ(2 * kNumObjectFields, list_length); |
| 192 printf("Object has %d fields:\n", list_length / 2); |
| 193 for (int i = 0; i + 1 < list_length; i += 2) { |
| 194 Dart_Handle name_handle = Dart_ListGetAt(fields, i); |
| 195 EXPECT_NOT_ERROR(name_handle); |
| 196 EXPECT(Dart_IsString(name_handle)); |
| 197 char const* name; |
| 198 Dart_StringToCString(name_handle, &name); |
| 199 Dart_Handle value_handle = Dart_ListGetAt(fields, i + 1); |
| 200 EXPECT_NOT_ERROR(value_handle); |
| 201 value_handle = Dart_ToString(value_handle); |
| 202 EXPECT_NOT_ERROR(value_handle); |
| 203 EXPECT(Dart_IsString(value_handle)); |
| 204 char const* value; |
| 205 Dart_StringToCString(value_handle, &value); |
| 206 printf(" %s: %s\n", name, value); |
| 207 } |
| 208 |
| 209 // Check that an integer value returns an empty list of fields. |
| 210 Dart_Handle triple_six = Invoke(lib, "get_int"); |
| 211 EXPECT_NOT_ERROR(triple_six); |
| 212 EXPECT(Dart_IsInteger(triple_six)); |
| 213 int64_t int_value = 0; |
| 214 Dart_IntegerToInt64(triple_six, &int_value); |
| 215 EXPECT_EQ(666, int_value); |
| 216 fields = Dart_GetInstanceFields(triple_six); |
| 217 EXPECT_NOT_ERROR(fields); |
| 218 EXPECT(Dart_IsList(fields)); |
| 219 retval = Dart_ListLength(fields, &list_length); |
| 220 EXPECT_EQ(0, list_length); |
| 221 |
| 222 // Check static field of class B (one field named 'bla') |
| 223 Dart_Handle class_B = Dart_GetObjClass(object_b); |
| 224 EXPECT_NOT_ERROR(class_B); |
| 225 EXPECT(!Dart_IsNull(class_B)); |
| 226 fields = Dart_GetStaticFields(class_B); |
| 227 EXPECT_NOT_ERROR(fields); |
| 228 EXPECT(Dart_IsList(fields)); |
| 229 list_length = 0; |
| 230 retval = Dart_ListLength(fields, &list_length); |
| 231 EXPECT_NOT_ERROR(retval); |
| 232 EXPECT_EQ(2, list_length); |
| 233 Dart_Handle name_handle = Dart_ListGetAt(fields, 0); |
| 234 EXPECT_NOT_ERROR(name_handle); |
| 235 EXPECT(Dart_IsString(name_handle)); |
| 236 char const* name; |
| 237 Dart_StringToCString(name_handle, &name); |
| 238 EXPECT_STREQ("bla", name); |
| 239 Dart_Handle value_handle = Dart_ListGetAt(fields, 1); |
| 240 EXPECT_NOT_ERROR(value_handle); |
| 241 value_handle = Dart_ToString(value_handle); |
| 242 EXPECT_NOT_ERROR(value_handle); |
| 243 EXPECT(Dart_IsString(value_handle)); |
| 244 char const* value; |
| 245 Dart_StringToCString(value_handle, &value); |
| 246 EXPECT_STREQ("blah blah", value); |
| 247 |
| 248 // Check static field of B's superclass (one field named 'bla') |
| 249 Dart_Handle class_A = Dart_GetSuperclass(class_B); |
| 250 EXPECT_NOT_ERROR(class_A); |
| 251 EXPECT(!Dart_IsNull(class_A)); |
| 252 fields = Dart_GetStaticFields(class_A); |
| 253 EXPECT_NOT_ERROR(fields); |
| 254 EXPECT(Dart_IsList(fields)); |
| 255 list_length = 0; |
| 256 retval = Dart_ListLength(fields, &list_length); |
| 257 EXPECT_NOT_ERROR(retval); |
| 258 EXPECT_EQ(2, list_length); |
| 259 name_handle = Dart_ListGetAt(fields, 0); |
| 260 EXPECT_NOT_ERROR(name_handle); |
| 261 EXPECT(Dart_IsString(name_handle)); |
| 262 Dart_StringToCString(name_handle, &name); |
| 263 EXPECT_STREQ("bla", name); |
| 264 value_handle = Dart_ListGetAt(fields, 1); |
| 265 EXPECT_NOT_ERROR(value_handle); |
| 266 value_handle = Dart_ToString(value_handle); |
| 267 EXPECT_NOT_ERROR(value_handle); |
| 268 EXPECT(Dart_IsString(value_handle)); |
| 269 Dart_StringToCString(value_handle, &value); |
| 270 EXPECT_STREQ("yada yada yada", value); |
| 271 } |
| 272 |
| 273 |
| 157 TEST_CASE(Debug_LookupSourceLine) { | 274 TEST_CASE(Debug_LookupSourceLine) { |
| 158 const char* kScriptChars = | 275 const char* kScriptChars = |
| 159 /*1*/ "class A {\n" | 276 /*1*/ "class A {\n" |
| 160 /*2*/ " static void foo() {\n" | 277 /*2*/ " static void foo() {\n" |
| 161 /*3*/ " moo('good news');\n" | 278 /*3*/ " moo('good news');\n" |
| 162 /*4*/ " }\n" | 279 /*4*/ " }\n" |
| 163 /*5*/ "}\n" | 280 /*5*/ "}\n" |
| 164 /*6*/ "\n" | 281 /*6*/ "\n" |
| 165 /*7*/ "void main() {\n" | 282 /*7*/ "void main() {\n" |
| 166 /*8*/ " A.foo();\n" | 283 /*8*/ " A.foo();\n" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 EXPECT(Dart_IsString(source)); | 340 EXPECT(Dart_IsString(source)); |
| 224 char const* source_chars; | 341 char const* source_chars; |
| 225 Dart_StringToCString(source, &source_chars); | 342 Dart_StringToCString(source, &source_chars); |
| 226 printf("\n=== source: ===\n%s", source_chars); | 343 printf("\n=== source: ===\n%s", source_chars); |
| 227 EXPECT_STREQ(kScriptChars, source_chars); | 344 EXPECT_STREQ(kScriptChars, source_chars); |
| 228 } | 345 } |
| 229 | 346 |
| 230 #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64). | 347 #endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64). |
| 231 | 348 |
| 232 } // namespace dart | 349 } // namespace dart |
| OLD | NEW |