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 "vm/stack_frame.h" |
5 #include "include/dart_api.h" | 6 #include "include/dart_api.h" |
6 #include "platform/assert.h" | 7 #include "platform/assert.h" |
7 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
8 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
9 #include "vm/dart_api_impl.h" | 10 #include "vm/dart_api_impl.h" |
10 #include "vm/dart_entry.h" | 11 #include "vm/dart_entry.h" |
11 #include "vm/resolver.h" | 12 #include "vm/resolver.h" |
12 #include "vm/stack_frame.h" | |
13 #include "vm/unit_test.h" | 13 #include "vm/unit_test.h" |
14 #include "vm/verifier.h" | 14 #include "vm/verifier.h" |
15 #include "vm/zone.h" | 15 #include "vm/zone.h" |
16 | 16 |
17 namespace dart { | 17 namespace dart { |
18 | 18 |
19 // Unit test for empty stack frame iteration. | 19 // Unit test for empty stack frame iteration. |
20 ISOLATE_UNIT_TEST_CASE(EmptyStackFrameIteration) { | 20 ISOLATE_UNIT_TEST_CASE(EmptyStackFrameIteration) { |
21 StackFrameIterator iterator(StackFrameIterator::kValidateFrames, | 21 StackFrameIterator iterator(StackFrameIterator::kValidateFrames, |
22 Thread::Current(), | 22 Thread::Current(), |
23 StackFrameIterator::kNoCrossThreadIteration); | 23 StackFrameIterator::kNoCrossThreadIteration); |
24 EXPECT(!iterator.HasNextFrame()); | 24 EXPECT(!iterator.HasNextFrame()); |
25 EXPECT(iterator.NextFrame() == NULL); | 25 EXPECT(iterator.NextFrame() == NULL); |
26 VerifyPointersVisitor::VerifyPointers(); | 26 VerifyPointersVisitor::VerifyPointers(); |
27 } | 27 } |
28 | 28 |
29 | |
30 // Unit test for empty dart stack frame iteration. | 29 // Unit test for empty dart stack frame iteration. |
31 ISOLATE_UNIT_TEST_CASE(EmptyDartStackFrameIteration) { | 30 ISOLATE_UNIT_TEST_CASE(EmptyDartStackFrameIteration) { |
32 DartFrameIterator iterator(Thread::Current(), | 31 DartFrameIterator iterator(Thread::Current(), |
33 StackFrameIterator::kNoCrossThreadIteration); | 32 StackFrameIterator::kNoCrossThreadIteration); |
34 EXPECT(iterator.NextFrame() == NULL); | 33 EXPECT(iterator.NextFrame() == NULL); |
35 VerifyPointersVisitor::VerifyPointers(); | 34 VerifyPointersVisitor::VerifyPointers(); |
36 } | 35 } |
37 | 36 |
38 | |
39 #define FUNCTION_NAME(name) StackFrame_##name | 37 #define FUNCTION_NAME(name) StackFrame_##name |
40 #define REGISTER_FUNCTION(name, count) {"" #name, FUNCTION_NAME(name), count}, | 38 #define REGISTER_FUNCTION(name, count) {"" #name, FUNCTION_NAME(name), count}, |
41 | 39 |
42 | |
43 void FUNCTION_NAME(StackFrame_equals)(Dart_NativeArguments args) { | 40 void FUNCTION_NAME(StackFrame_equals)(Dart_NativeArguments args) { |
44 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 41 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
45 const Instance& expected = Instance::CheckedHandle(arguments->NativeArgAt(0)); | 42 const Instance& expected = Instance::CheckedHandle(arguments->NativeArgAt(0)); |
46 const Instance& actual = Instance::CheckedHandle(arguments->NativeArgAt(1)); | 43 const Instance& actual = Instance::CheckedHandle(arguments->NativeArgAt(1)); |
47 if (!expected.OperatorEquals(actual)) { | 44 if (!expected.OperatorEquals(actual)) { |
48 OS::Print("expected: '%s' actual: '%s'\n", expected.ToCString(), | 45 OS::Print("expected: '%s' actual: '%s'\n", expected.ToCString(), |
49 actual.ToCString()); | 46 actual.ToCString()); |
50 FATAL("Expect_equals fails.\n"); | 47 FATAL("Expect_equals fails.\n"); |
51 } | 48 } |
52 } | 49 } |
53 | 50 |
54 | |
55 void FUNCTION_NAME(StackFrame_frameCount)(Dart_NativeArguments args) { | 51 void FUNCTION_NAME(StackFrame_frameCount)(Dart_NativeArguments args) { |
56 int count = 0; | 52 int count = 0; |
57 StackFrameIterator frames(StackFrameIterator::kValidateFrames, | 53 StackFrameIterator frames(StackFrameIterator::kValidateFrames, |
58 Thread::Current(), | 54 Thread::Current(), |
59 StackFrameIterator::kNoCrossThreadIteration); | 55 StackFrameIterator::kNoCrossThreadIteration); |
60 while (frames.NextFrame() != NULL) { | 56 while (frames.NextFrame() != NULL) { |
61 count += 1; // Count the frame. | 57 count += 1; // Count the frame. |
62 } | 58 } |
63 VerifyPointersVisitor::VerifyPointers(); | 59 VerifyPointersVisitor::VerifyPointers(); |
64 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 60 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
65 arguments->SetReturn(Object::Handle(Smi::New(count))); | 61 arguments->SetReturn(Object::Handle(Smi::New(count))); |
66 } | 62 } |
67 | 63 |
68 | |
69 void FUNCTION_NAME(StackFrame_dartFrameCount)(Dart_NativeArguments args) { | 64 void FUNCTION_NAME(StackFrame_dartFrameCount)(Dart_NativeArguments args) { |
70 int count = 0; | 65 int count = 0; |
71 DartFrameIterator frames(Thread::Current(), | 66 DartFrameIterator frames(Thread::Current(), |
72 StackFrameIterator::kNoCrossThreadIteration); | 67 StackFrameIterator::kNoCrossThreadIteration); |
73 while (frames.NextFrame() != NULL) { | 68 while (frames.NextFrame() != NULL) { |
74 count += 1; // Count the dart frame. | 69 count += 1; // Count the dart frame. |
75 } | 70 } |
76 VerifyPointersVisitor::VerifyPointers(); | 71 VerifyPointersVisitor::VerifyPointers(); |
77 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 72 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
78 arguments->SetReturn(Object::Handle(Smi::New(count))); | 73 arguments->SetReturn(Object::Handle(Smi::New(count))); |
79 } | 74 } |
80 | 75 |
81 | |
82 void FUNCTION_NAME(StackFrame_validateFrame)(Dart_NativeArguments args) { | 76 void FUNCTION_NAME(StackFrame_validateFrame)(Dart_NativeArguments args) { |
83 Thread* thread = Thread::Current(); | 77 Thread* thread = Thread::Current(); |
84 Zone* zone = thread->zone(); | 78 Zone* zone = thread->zone(); |
85 | 79 |
86 Dart_Handle index = Dart_GetNativeArgument(args, 0); | 80 Dart_Handle index = Dart_GetNativeArgument(args, 0); |
87 Dart_Handle name = Dart_GetNativeArgument(args, 1); | 81 Dart_Handle name = Dart_GetNativeArgument(args, 1); |
88 const Smi& frame_index_smi = Smi::CheckedHandle(Api::UnwrapHandle(index)); | 82 const Smi& frame_index_smi = Smi::CheckedHandle(Api::UnwrapHandle(index)); |
89 const char* expected_name = | 83 const char* expected_name = |
90 String::CheckedHandle(Api::UnwrapHandle(name)).ToCString(); | 84 String::CheckedHandle(Api::UnwrapHandle(name)).ToCString(); |
91 int frame_index = frame_index_smi.Value(); | 85 int frame_index = frame_index_smi.Value(); |
(...skipping 22 matching lines...) Expand all Loading... |
114 FATAL("StackFrame_validateFrame fails, incorrect frame.\n"); | 108 FATAL("StackFrame_validateFrame fails, incorrect frame.\n"); |
115 } | 109 } |
116 return; | 110 return; |
117 } | 111 } |
118 count += 1; // Count the dart frames. | 112 count += 1; // Count the dart frames. |
119 frame = frames.NextFrame(); | 113 frame = frames.NextFrame(); |
120 } | 114 } |
121 FATAL("StackFrame_validateFrame fails, frame count < index passed in.\n"); | 115 FATAL("StackFrame_validateFrame fails, frame count < index passed in.\n"); |
122 } | 116 } |
123 | 117 |
124 | |
125 // 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 |
126 // 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 |
127 // point. | 120 // point. |
128 #define STACKFRAME_NATIVE_LIST(V) \ | 121 #define STACKFRAME_NATIVE_LIST(V) \ |
129 V(StackFrame_equals, 2) \ | 122 V(StackFrame_equals, 2) \ |
130 V(StackFrame_frameCount, 0) \ | 123 V(StackFrame_frameCount, 0) \ |
131 V(StackFrame_dartFrameCount, 0) \ | 124 V(StackFrame_dartFrameCount, 0) \ |
132 V(StackFrame_validateFrame, 2) | 125 V(StackFrame_validateFrame, 2) |
133 | 126 |
134 | |
135 static struct NativeEntries { | 127 static struct NativeEntries { |
136 const char* name_; | 128 const char* name_; |
137 Dart_NativeFunction function_; | 129 Dart_NativeFunction function_; |
138 int argument_count_; | 130 int argument_count_; |
139 } BuiltinEntries[] = {STACKFRAME_NATIVE_LIST(REGISTER_FUNCTION)}; | 131 } BuiltinEntries[] = {STACKFRAME_NATIVE_LIST(REGISTER_FUNCTION)}; |
140 | 132 |
141 | |
142 static Dart_NativeFunction native_lookup(Dart_Handle name, | 133 static Dart_NativeFunction native_lookup(Dart_Handle name, |
143 int argument_count, | 134 int argument_count, |
144 bool* auto_setup_scope) { | 135 bool* auto_setup_scope) { |
145 ASSERT(auto_setup_scope != NULL); | 136 ASSERT(auto_setup_scope != NULL); |
146 *auto_setup_scope = false; | 137 *auto_setup_scope = false; |
147 const Object& obj = Object::Handle(Api::UnwrapHandle(name)); | 138 const Object& obj = Object::Handle(Api::UnwrapHandle(name)); |
148 ASSERT(obj.IsString()); | 139 ASSERT(obj.IsString()); |
149 const char* function_name = obj.ToCString(); | 140 const char* function_name = obj.ToCString(); |
150 ASSERT(function_name != NULL); | 141 ASSERT(function_name != NULL); |
151 int num_entries = sizeof(BuiltinEntries) / sizeof(struct NativeEntries); | 142 int num_entries = sizeof(BuiltinEntries) / sizeof(struct NativeEntries); |
152 for (int i = 0; i < num_entries; i++) { | 143 for (int i = 0; i < num_entries; i++) { |
153 struct NativeEntries* entry = &(BuiltinEntries[i]); | 144 struct NativeEntries* entry = &(BuiltinEntries[i]); |
154 if (!strcmp(function_name, entry->name_) && | 145 if (!strcmp(function_name, entry->name_) && |
155 (entry->argument_count_ == argument_count)) { | 146 (entry->argument_count_ == argument_count)) { |
156 return reinterpret_cast<Dart_NativeFunction>(entry->function_); | 147 return reinterpret_cast<Dart_NativeFunction>(entry->function_); |
157 } | 148 } |
158 } | 149 } |
159 return NULL; | 150 return NULL; |
160 } | 151 } |
161 | 152 |
162 | |
163 // Unit test case to verify stack frame iteration. | 153 // Unit test case to verify stack frame iteration. |
164 TEST_CASE(ValidateStackFrameIteration) { | 154 TEST_CASE(ValidateStackFrameIteration) { |
165 const char* kScriptChars = | 155 const char* kScriptChars = |
166 "class StackFrame {" | 156 "class StackFrame {" |
167 " static equals(var obj1, var obj2) native \"StackFrame_equals\";" | 157 " static equals(var obj1, var obj2) native \"StackFrame_equals\";" |
168 " static int frameCount() native \"StackFrame_frameCount\";" | 158 " static int frameCount() native \"StackFrame_frameCount\";" |
169 " static int dartFrameCount() native \"StackFrame_dartFrameCount\";" | 159 " static int dartFrameCount() native \"StackFrame_dartFrameCount\";" |
170 " static validateFrame(int index," | 160 " static validateFrame(int index," |
171 " String name) native \"StackFrame_validateFrame\";" | 161 " String name) native \"StackFrame_validateFrame\";" |
172 "} " | 162 "} " |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 " obj.method1(1);" | 229 " obj.method1(1);" |
240 " obj.method1(2);" | 230 " obj.method1(2);" |
241 " }" | 231 " }" |
242 "}"; | 232 "}"; |
243 Dart_Handle lib = TestCase::LoadTestScript( | 233 Dart_Handle lib = TestCase::LoadTestScript( |
244 kScriptChars, reinterpret_cast<Dart_NativeEntryResolver>(native_lookup)); | 234 kScriptChars, reinterpret_cast<Dart_NativeEntryResolver>(native_lookup)); |
245 Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrameTest")); | 235 Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrameTest")); |
246 EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, NULL)); | 236 EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, NULL)); |
247 } | 237 } |
248 | 238 |
249 | |
250 // Unit test case to verify stack frame iteration. | 239 // Unit test case to verify stack frame iteration. |
251 TEST_CASE(ValidateNoSuchMethodStackFrameIteration) { | 240 TEST_CASE(ValidateNoSuchMethodStackFrameIteration) { |
252 const char* kScriptChars; | 241 const char* kScriptChars; |
253 // The true stack depends on which strategy we are using for noSuchMethod. The | 242 // The true stack depends on which strategy we are using for noSuchMethod. The |
254 // stacktrace as seen by Dart is the same either way because dispatcher | 243 // stacktrace as seen by Dart is the same either way because dispatcher |
255 // methods are marked invisible. | 244 // methods are marked invisible. |
256 if (FLAG_lazy_dispatchers) { | 245 if (FLAG_lazy_dispatchers) { |
257 kScriptChars = | 246 kScriptChars = |
258 "class StackFrame {" | 247 "class StackFrame {" |
259 " static equals(var obj1, var obj2) native \"StackFrame_equals\";" | 248 " static equals(var obj1, var obj2) native \"StackFrame_equals\";" |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 " }" | 313 " }" |
325 "}"; | 314 "}"; |
326 } | 315 } |
327 Dart_Handle lib = TestCase::LoadTestScript( | 316 Dart_Handle lib = TestCase::LoadTestScript( |
328 kScriptChars, reinterpret_cast<Dart_NativeEntryResolver>(native_lookup)); | 317 kScriptChars, reinterpret_cast<Dart_NativeEntryResolver>(native_lookup)); |
329 Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrame2Test")); | 318 Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrame2Test")); |
330 EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, NULL)); | 319 EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, NULL)); |
331 } | 320 } |
332 | 321 |
333 } // namespace dart | 322 } // namespace dart |
OLD | NEW |