| 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_api.h" | 5 #include "include/dart_api.h" |
| 6 #include "platform/assert.h" | 6 #include "platform/assert.h" |
| 7 #include "vm/class_finalizer.h" | 7 #include "vm/class_finalizer.h" |
| 8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 | 27 |
| 28 // Unit test for empty dart stack frame iteration. | 28 // Unit test for empty dart stack frame iteration. |
| 29 VM_TEST_CASE(EmptyDartStackFrameIteration) { | 29 VM_TEST_CASE(EmptyDartStackFrameIteration) { |
| 30 DartFrameIterator iterator; | 30 DartFrameIterator iterator; |
| 31 EXPECT(iterator.NextFrame() == NULL); | 31 EXPECT(iterator.NextFrame() == NULL); |
| 32 VerifyPointersVisitor::VerifyPointers(); | 32 VerifyPointersVisitor::VerifyPointers(); |
| 33 } | 33 } |
| 34 | 34 |
| 35 | 35 |
| 36 #define FUNCTION_NAME(name) StackFrame_##name | 36 #define FUNCTION_NAME(name) StackFrame_##name |
| 37 #define REGISTER_FUNCTION(name, count) \ | 37 #define REGISTER_FUNCTION(name, count) {"" #name, FUNCTION_NAME(name), count}, |
| 38 { ""#name, FUNCTION_NAME(name), count }, | |
| 39 | 38 |
| 40 | 39 |
| 41 void FUNCTION_NAME(StackFrame_equals)(Dart_NativeArguments args) { | 40 void FUNCTION_NAME(StackFrame_equals)(Dart_NativeArguments args) { |
| 42 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 41 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
| 43 const Instance& expected = Instance::CheckedHandle(arguments->NativeArgAt(0)); | 42 const Instance& expected = Instance::CheckedHandle(arguments->NativeArgAt(0)); |
| 44 const Instance& actual = Instance::CheckedHandle(arguments->NativeArgAt(1)); | 43 const Instance& actual = Instance::CheckedHandle(arguments->NativeArgAt(1)); |
| 45 if (!expected.OperatorEquals(actual)) { | 44 if (!expected.OperatorEquals(actual)) { |
| 46 OS::Print("expected: '%s' actual: '%s'\n", | 45 OS::Print("expected: '%s' actual: '%s'\n", expected.ToCString(), |
| 47 expected.ToCString(), actual.ToCString()); | 46 actual.ToCString()); |
| 48 FATAL("Expect_equals fails.\n"); | 47 FATAL("Expect_equals fails.\n"); |
| 49 } | 48 } |
| 50 } | 49 } |
| 51 | 50 |
| 52 | 51 |
| 53 void FUNCTION_NAME(StackFrame_frameCount)(Dart_NativeArguments args) { | 52 void FUNCTION_NAME(StackFrame_frameCount)(Dart_NativeArguments args) { |
| 54 int count = 0; | 53 int count = 0; |
| 55 StackFrameIterator frames(StackFrameIterator::kValidateFrames); | 54 StackFrameIterator frames(StackFrameIterator::kValidateFrames); |
| 56 while (frames.NextFrame() != NULL) { | 55 while (frames.NextFrame() != NULL) { |
| 57 count += 1; // Count the frame. | 56 count += 1; // Count the frame. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 // Find the function corresponding to this frame and check if it | 91 // Find the function corresponding to this frame and check if it |
| 93 // matches the function name passed in. | 92 // matches the function name passed in. |
| 94 const Function& function = | 93 const Function& function = |
| 95 Function::Handle(zone, frame->LookupDartFunction()); | 94 Function::Handle(zone, frame->LookupDartFunction()); |
| 96 if (function.IsNull()) { | 95 if (function.IsNull()) { |
| 97 FATAL("StackFrame_validateFrame fails, invalid dart frame.\n"); | 96 FATAL("StackFrame_validateFrame fails, invalid dart frame.\n"); |
| 98 } | 97 } |
| 99 const char* name = function.ToFullyQualifiedCString(); | 98 const char* name = function.ToFullyQualifiedCString(); |
| 100 // Currently all unit tests are loaded as being part of dart:core-lib. | 99 // Currently all unit tests are loaded as being part of dart:core-lib. |
| 101 String& url = String::Handle(zone, String::New(TestCase::url())); | 100 String& url = String::Handle(zone, String::New(TestCase::url())); |
| 102 const Library& lib = Library::Handle(zone, | 101 const Library& lib = |
| 103 Library::LookupLibrary(thread, url)); | 102 Library::Handle(zone, Library::LookupLibrary(thread, url)); |
| 104 ASSERT(!lib.IsNull()); | 103 ASSERT(!lib.IsNull()); |
| 105 const char* lib_name = String::Handle(zone, lib.url()).ToCString(); | 104 const char* lib_name = String::Handle(zone, lib.url()).ToCString(); |
| 106 char* full_name = OS::SCreate(zone, "%s_%s", lib_name, expected_name); | 105 char* full_name = OS::SCreate(zone, "%s_%s", lib_name, expected_name); |
| 107 if (strcmp(full_name, name) != 0) { | 106 if (strcmp(full_name, name) != 0) { |
| 108 FATAL("StackFrame_validateFrame fails, incorrect frame.\n"); | 107 FATAL("StackFrame_validateFrame fails, incorrect frame.\n"); |
| 109 } | 108 } |
| 110 return; | 109 return; |
| 111 } | 110 } |
| 112 count += 1; // Count the dart frames. | 111 count += 1; // Count the dart frames. |
| 113 frame = frames.NextFrame(); | 112 frame = frames.NextFrame(); |
| 114 } | 113 } |
| 115 FATAL("StackFrame_validateFrame fails, frame count < index passed in.\n"); | 114 FATAL("StackFrame_validateFrame fails, frame count < index passed in.\n"); |
| 116 } | 115 } |
| 117 | 116 |
| 118 | 117 |
| 119 // List all native functions implemented in the vm or core boot strap dart | 118 // List all native functions implemented in the vm or core boot strap dart |
| 120 // libraries so that we can resolve the native function to it's entry | 119 // libraries so that we can resolve the native function to it's entry |
| 121 // point. | 120 // point. |
| 122 #define STACKFRAME_NATIVE_LIST(V) \ | 121 #define STACKFRAME_NATIVE_LIST(V) \ |
| 123 V(StackFrame_equals, 2) \ | 122 V(StackFrame_equals, 2) \ |
| 124 V(StackFrame_frameCount, 0) \ | 123 V(StackFrame_frameCount, 0) \ |
| 125 V(StackFrame_dartFrameCount, 0) \ | 124 V(StackFrame_dartFrameCount, 0) \ |
| 126 V(StackFrame_validateFrame, 2) \ | 125 V(StackFrame_validateFrame, 2) |
| 127 | 126 |
| 128 | 127 |
| 129 static struct NativeEntries { | 128 static struct NativeEntries { |
| 130 const char* name_; | 129 const char* name_; |
| 131 Dart_NativeFunction function_; | 130 Dart_NativeFunction function_; |
| 132 int argument_count_; | 131 int argument_count_; |
| 133 } BuiltinEntries[] = { | 132 } BuiltinEntries[] = {STACKFRAME_NATIVE_LIST(REGISTER_FUNCTION)}; |
| 134 STACKFRAME_NATIVE_LIST(REGISTER_FUNCTION) | |
| 135 }; | |
| 136 | 133 |
| 137 | 134 |
| 138 static Dart_NativeFunction native_lookup(Dart_Handle name, | 135 static Dart_NativeFunction native_lookup(Dart_Handle name, |
| 139 int argument_count, | 136 int argument_count, |
| 140 bool* auto_setup_scope) { | 137 bool* auto_setup_scope) { |
| 141 ASSERT(auto_setup_scope != NULL); | 138 ASSERT(auto_setup_scope != NULL); |
| 142 *auto_setup_scope = false; | 139 *auto_setup_scope = false; |
| 143 const Object& obj = Object::Handle(Api::UnwrapHandle(name)); | 140 const Object& obj = Object::Handle(Api::UnwrapHandle(name)); |
| 144 ASSERT(obj.IsString()); | 141 ASSERT(obj.IsString()); |
| 145 const char* function_name = obj.ToCString(); | 142 const char* function_name = obj.ToCString(); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 " }" | 227 " }" |
| 231 "}" | 228 "}" |
| 232 "class StackFrameTest {" | 229 "class StackFrameTest {" |
| 233 " static testMain() {" | 230 " static testMain() {" |
| 234 " Second obj = new Second();" | 231 " Second obj = new Second();" |
| 235 " obj.method1(1);" | 232 " obj.method1(1);" |
| 236 " obj.method1(2);" | 233 " obj.method1(2);" |
| 237 " }" | 234 " }" |
| 238 "}"; | 235 "}"; |
| 239 Dart_Handle lib = TestCase::LoadTestScript( | 236 Dart_Handle lib = TestCase::LoadTestScript( |
| 240 kScriptChars, | 237 kScriptChars, reinterpret_cast<Dart_NativeEntryResolver>(native_lookup)); |
| 241 reinterpret_cast<Dart_NativeEntryResolver>(native_lookup)); | |
| 242 Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrameTest")); | 238 Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrameTest")); |
| 243 EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, NULL)); | 239 EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, NULL)); |
| 244 } | 240 } |
| 245 | 241 |
| 246 | 242 |
| 247 // Unit test case to verify stack frame iteration. | 243 // Unit test case to verify stack frame iteration. |
| 248 TEST_CASE(ValidateNoSuchMethodStackFrameIteration) { | 244 TEST_CASE(ValidateNoSuchMethodStackFrameIteration) { |
| 249 const char* kScriptChars; | 245 const char* kScriptChars; |
| 250 // The true stack depends on which strategy we are using for noSuchMethod. The | 246 // The true stack depends on which strategy we are using for noSuchMethod. The |
| 251 // stacktrace as seen by Dart is the same either way because dispatcher | 247 // stacktrace as seen by Dart is the same either way because dispatcher |
| 252 // methods are marked invisible. | 248 // methods are marked invisible. |
| 253 if (FLAG_lazy_dispatchers) { | 249 if (FLAG_lazy_dispatchers) { |
| 254 kScriptChars = | 250 kScriptChars = |
| 255 "class StackFrame {" | 251 "class StackFrame {" |
| 256 " static equals(var obj1, var obj2) native \"StackFrame_equals\";" | 252 " static equals(var obj1, var obj2) native \"StackFrame_equals\";" |
| 257 " static int frameCount() native \"StackFrame_frameCount\";" | 253 " static int frameCount() native \"StackFrame_frameCount\";" |
| 258 " static int dartFrameCount() native \"StackFrame_dartFrameCount\";" | 254 " static int dartFrameCount() native \"StackFrame_dartFrameCount\";" |
| 259 " static validateFrame(int index," | 255 " static validateFrame(int index," |
| 260 " String name) native \"StackFrame_validateFrame\";" | 256 " String name) native " |
| 261 "} " | 257 "\"StackFrame_validateFrame\";" |
| 262 "class StackFrame2Test {" | 258 "} " |
| 263 " StackFrame2Test() {}" | 259 "class StackFrame2Test {" |
| 264 " noSuchMethod(Invocation im) {" | 260 " StackFrame2Test() {}" |
| 265 " /* We should have 6 general frames and 4 dart frames as follows:" | 261 " noSuchMethod(Invocation im) {" |
| 266 " * exit frame" | 262 " /* We should have 6 general frames and 4 dart frames as follows:" |
| 267 " * dart frame corresponding to StackFrame.frameCount" | 263 " * exit frame" |
| 268 " * dart frame corresponding to StackFrame2Test.noSuchMethod" | 264 " * dart frame corresponding to StackFrame.frameCount" |
| 269 " * frame for instance function invocation stub calling noSuchMethod" | 265 " * dart frame corresponding to StackFrame2Test.noSuchMethod" |
| 270 " * dart frame corresponding to StackFrame2Test.testMain" | 266 " * frame for instance function invocation stub calling " |
| 271 " * entry frame" | 267 "noSuchMethod" |
| 272 " */" | 268 " * dart frame corresponding to StackFrame2Test.testMain" |
| 273 " StackFrame.equals(6, StackFrame.frameCount());" | 269 " * entry frame" |
| 274 " StackFrame.equals(4, StackFrame.dartFrameCount());" | 270 " */" |
| 275 " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");" | 271 " StackFrame.equals(6, StackFrame.frameCount());" |
| 276 " StackFrame.validateFrame(1, \"StackFrame2Test_noSuchMethod\");" | 272 " StackFrame.equals(4, StackFrame.dartFrameCount());" |
| 277 " StackFrame.validateFrame(2, \"StackFrame2Test_foo\");" | 273 " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");" |
| 278 " StackFrame.validateFrame(3, \"StackFrame2Test_testMain\");" | 274 " StackFrame.validateFrame(1, \"StackFrame2Test_noSuchMethod\");" |
| 279 " return 5;" | 275 " StackFrame.validateFrame(2, \"StackFrame2Test_foo\");" |
| 280 " }" | 276 " StackFrame.validateFrame(3, \"StackFrame2Test_testMain\");" |
| 281 " static testMain() {" | 277 " return 5;" |
| 282 " var obj = new StackFrame2Test();" | 278 " }" |
| 283 " StackFrame.equals(5, obj.foo(101, 202));" | 279 " static testMain() {" |
| 284 " }" | 280 " var obj = new StackFrame2Test();" |
| 285 "}"; | 281 " StackFrame.equals(5, obj.foo(101, 202));" |
| 282 " }" |
| 283 "}"; |
| 286 } else { | 284 } else { |
| 287 kScriptChars = | 285 kScriptChars = |
| 288 "class StackFrame {" | 286 "class StackFrame {" |
| 289 " static equals(var obj1, var obj2) native \"StackFrame_equals\";" | 287 " static equals(var obj1, var obj2) native \"StackFrame_equals\";" |
| 290 " static int frameCount() native \"StackFrame_frameCount\";" | 288 " static int frameCount() native \"StackFrame_frameCount\";" |
| 291 " static int dartFrameCount() native \"StackFrame_dartFrameCount\";" | 289 " static int dartFrameCount() native \"StackFrame_dartFrameCount\";" |
| 292 " static validateFrame(int index," | 290 " static validateFrame(int index," |
| 293 " String name) native \"StackFrame_validateFrame\";" | 291 " String name) native " |
| 294 "} " | 292 "\"StackFrame_validateFrame\";" |
| 295 "class StackFrame2Test {" | 293 "} " |
| 296 " StackFrame2Test() {}" | 294 "class StackFrame2Test {" |
| 297 " noSuchMethod(Invocation im) {" | 295 " StackFrame2Test() {}" |
| 298 " /* We should have 8 general frames and 3 dart frames as follows:" | 296 " noSuchMethod(Invocation im) {" |
| 299 " * exit frame" | 297 " /* We should have 8 general frames and 3 dart frames as follows:" |
| 300 " * dart frame corresponding to StackFrame.frameCount" | 298 " * exit frame" |
| 301 " * dart frame corresponding to StackFrame2Test.noSuchMethod" | 299 " * dart frame corresponding to StackFrame.frameCount" |
| 302 " * entry frame" | 300 " * dart frame corresponding to StackFrame2Test.noSuchMethod" |
| 303 " * exit frame (call to runtime InvokeNoSuchMethodDispatcher)" | 301 " * entry frame" |
| 304 " * IC stub" | 302 " * exit frame (call to runtime InvokeNoSuchMethodDispatcher)" |
| 305 " * dart frame corresponding to StackFrame2Test.testMain" | 303 " * IC stub" |
| 306 " * entry frame" | 304 " * dart frame corresponding to StackFrame2Test.testMain" |
| 307 " */" | 305 " * entry frame" |
| 308 " StackFrame.equals(8, StackFrame.frameCount());" | 306 " */" |
| 309 " StackFrame.equals(3, StackFrame.dartFrameCount());" | 307 " StackFrame.equals(8, StackFrame.frameCount());" |
| 310 " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");" | 308 " StackFrame.equals(3, StackFrame.dartFrameCount());" |
| 311 " StackFrame.validateFrame(1, \"StackFrame2Test_noSuchMethod\");" | 309 " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");" |
| 312 " StackFrame.validateFrame(2, \"StackFrame2Test_testMain\");" | 310 " StackFrame.validateFrame(1, \"StackFrame2Test_noSuchMethod\");" |
| 313 " return 5;" | 311 " StackFrame.validateFrame(2, \"StackFrame2Test_testMain\");" |
| 314 " }" | 312 " return 5;" |
| 315 " static testMain() {" | 313 " }" |
| 316 " var obj = new StackFrame2Test();" | 314 " static testMain() {" |
| 317 " StackFrame.equals(5, obj.foo(101, 202));" | 315 " var obj = new StackFrame2Test();" |
| 318 " }" | 316 " StackFrame.equals(5, obj.foo(101, 202));" |
| 319 "}"; | 317 " }" |
| 318 "}"; |
| 320 } | 319 } |
| 321 Dart_Handle lib = TestCase::LoadTestScript( | 320 Dart_Handle lib = TestCase::LoadTestScript( |
| 322 kScriptChars, | 321 kScriptChars, reinterpret_cast<Dart_NativeEntryResolver>(native_lookup)); |
| 323 reinterpret_cast<Dart_NativeEntryResolver>(native_lookup)); | |
| 324 Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrame2Test")); | 322 Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrame2Test")); |
| 325 EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, NULL)); | 323 EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, NULL)); |
| 326 } | 324 } |
| 327 | 325 |
| 328 } // namespace dart | 326 } // namespace dart |
| OLD | NEW |