Flutter Engine
The Flutter Engine
stack_frame_test.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/stack_frame.h"
6#include "include/dart_api.h"
7#include "platform/assert.h"
10#include "vm/dart_api_impl.h"
11#include "vm/dart_entry.h"
12#include "vm/heap/verifier.h"
13#include "vm/resolver.h"
14#include "vm/unit_test.h"
15#include "vm/zone.h"
16
17namespace dart {
18
19// Unit test for empty stack frame iteration.
20ISOLATE_UNIT_TEST_CASE(EmptyStackFrameIteration) {
24 EXPECT(!iterator.HasNextFrame());
25 EXPECT(iterator.NextFrame() == nullptr);
26 VerifyPointersVisitor::VerifyPointers("EmptyStackFrameIterationTest");
27}
28
29// Unit test for empty dart stack frame iteration.
30ISOLATE_UNIT_TEST_CASE(EmptyDartStackFrameIteration) {
33 EXPECT(iterator.NextFrame() == nullptr);
34 VerifyPointersVisitor::VerifyPointers("EmptyDartStackFrameIterationTest");
35}
36
37#define FUNCTION_NAME(name) StackFrame_##name
38#define REGISTER_FUNCTION(name, count) {"" #name, FUNCTION_NAME(name), count},
39
41 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
42 TransitionNativeToVM transition(arguments->thread());
43 Zone* zone = arguments->thread()->zone();
44 const Instance& expected =
45 Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
46 const Instance& actual =
47 Instance::CheckedHandle(zone, arguments->NativeArgAt(1));
48 if (!expected.OperatorEquals(actual)) {
49 OS::PrintErr("expected: '%s' actual: '%s'\n", expected.ToCString(),
50 actual.ToCString());
51 EXPECT(false);
52 }
53}
54
56 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
57 TransitionNativeToVM transition(arguments->thread());
58 int count = 0;
60 arguments->thread(),
62 while (frames.NextFrame() != nullptr) {
63 count += 1; // Count the frame.
64 }
65 VerifyPointersVisitor::VerifyPointers("StackFrame_frameCount_Test");
67}
68
71 int count = 0;
74 while (frames.NextFrame() != nullptr) {
75 count += 1; // Count the dart frame.
76 }
77 VerifyPointersVisitor::VerifyPointers("StackFrame_dartFrameCount_Test");
78 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
80}
81
83 Thread* thread = Thread::Current();
84 Zone* zone = thread->zone();
85
88
89 TransitionNativeToVM transition(thread);
90 const Smi& frame_index_smi =
91 Smi::CheckedHandle(zone, Api::UnwrapHandle(index));
92 const char* expected_name =
93 String::CheckedHandle(zone, Api::UnwrapHandle(name)).ToCString();
94 int frame_index = frame_index_smi.Value();
95 int count = 0;
97 StackFrame* frame = frames.NextFrame();
98 while (frame != nullptr) {
99 if (count == frame_index) {
100 // Find the function corresponding to this frame and check if it
101 // matches the function name passed in.
102 const Function& function =
103 Function::Handle(zone, frame->LookupDartFunction());
104 if (function.IsNull()) {
105 FATAL("StackFrame_validateFrame fails, invalid dart frame.\n");
106 }
107 const char* name = function.ToFullyQualifiedCString();
108 // Currently all unit tests are loaded as being part of dart:core-lib.
110 const Library& lib =
111 Library::Handle(zone, Library::LookupLibrary(thread, url));
112 ASSERT(!lib.IsNull());
113 const char* lib_name = String::Handle(zone, lib.url()).ToCString();
114 char* full_name = OS::SCreate(zone, "%s_%s", lib_name, expected_name);
115 EXPECT_STREQ(full_name, name);
116 return;
117 }
118 count += 1; // Count the dart frames.
119 frame = frames.NextFrame();
120 }
121 FATAL("StackFrame_validateFrame fails, frame count < index passed in.\n");
122}
123
124// List all native functions implemented in the vm or core boot strap dart
125// libraries so that we can resolve the native function to it's entry
126// point.
127#define STACKFRAME_NATIVE_LIST(V) \
128 V(StackFrame_equals, 2) \
129 V(StackFrame_frameCount, 0) \
130 V(StackFrame_dartFrameCount, 0) \
131 V(StackFrame_validateFrame, 2)
132
133static struct NativeEntries {
134 const char* name_;
136 int argument_count_;
138
140 int argument_count,
141 bool* auto_setup_scope) {
142 ASSERT(auto_setup_scope != nullptr);
143 *auto_setup_scope = false;
146 ASSERT(obj.IsString());
147 const char* function_name = obj.ToCString();
148 ASSERT(function_name != nullptr);
149 int num_entries = sizeof(BuiltinEntries) / sizeof(struct NativeEntries);
150 for (int i = 0; i < num_entries; i++) {
151 struct NativeEntries* entry = &(BuiltinEntries[i]);
152 if ((strcmp(function_name, entry->name_) == 0) &&
153 (entry->argument_count_ == argument_count)) {
154 return reinterpret_cast<Dart_NativeFunction>(entry->function_);
155 }
156 }
157 return nullptr;
158}
159
160// Unit test case to verify stack frame iteration.
161TEST_CASE(ValidateStackFrameIteration) {
162 // clang-format off
163 const char* kScriptChars =
164 "class StackFrame {"
165 " @pragma('vm:external-name', 'StackFrame_equals')\n"
166 " external static equals(var obj1, var obj2);\n"
167 " @pragma('vm:external-name', 'StackFrame_frameCount')\n"
168 " external static int frameCount();\n"
169 " @pragma('vm:external-name', 'StackFrame_dartFrameCount')\n"
170 " external static int dartFrameCount();\n"
171 " @pragma('vm:external-name', 'StackFrame_validateFrame')\n"
172 " external static validateFrame(int index, String name);"
173 "} "
174 "class First {"
175 " First() { }"
176 " int? method1(int? param) {"
177 " if (param == 1) {"
178 " param = method2(200);"
179 " } else {"
180 " param = method2(100);"
181 " }"
182 " }"
183 " int? method2(int param) {"
184 " if (param == 200) {"
185 " First.staticmethod(this, param);"
186 " } else {"
187 " First.staticmethod(this, 10);"
188 " }"
189 " }"
190 " static int? staticmethod(First obj, int param) {"
191 " if (param == 10) {"
192 " obj.method3(10);"
193 " } else {"
194 " obj.method3(200);"
195 " }"
196 " }"
197 " method3(int param) {"
198 " StackFrame.equals(9, StackFrame.frameCount());"
199 " StackFrame.equals(7, StackFrame.dartFrameCount());"
200 " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
201 " StackFrame.validateFrame(1, \"First_method3\");"
202 " StackFrame.validateFrame(2, \"First_staticmethod\");"
203 " StackFrame.validateFrame(3, \"First_method2\");"
204 " StackFrame.validateFrame(4, \"First_method1\");"
205 " StackFrame.validateFrame(5, \"Second_method1\");"
206 " StackFrame.validateFrame(6, \"StackFrameTest_testMain\");"
207 " }"
208 "}"
209 "class Second {"
210 " Second() { }"
211 " int? method1(int? param) {"
212 " if (param == 1) {"
213 " param = method2(200);"
214 " } else {"
215 " First obj = new First();"
216 " param = obj.method1(1);"
217 " param = obj.method1(2);"
218 " }"
219 " }"
220 " int? method2(int param) {"
221 " Second.staticmethod(this, param);"
222 " }"
223 " static int? staticmethod(Second obj, int param) {"
224 " obj.method3(10);"
225 " }"
226 " method3(int param) {"
227 " StackFrame.equals(8, StackFrame.frameCount());"
228 " StackFrame.equals(6, StackFrame.dartFrameCount());"
229 " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
230 " StackFrame.validateFrame(1, \"Second_method3\");"
231 " StackFrame.validateFrame(2, \"Second_staticmethod\");"
232 " StackFrame.validateFrame(3, \"Second_method2\");"
233 " StackFrame.validateFrame(4, \"Second_method1\");"
234 " StackFrame.validateFrame(5, \"StackFrameTest_testMain\");"
235 " }"
236 "}"
237 "class StackFrameTest {"
238 " static testMain() {"
239 " Second obj = new Second();"
240 " obj.method1(1);"
241 " obj.method1(2);"
242 " }"
243 "}";
244 // clang-format on
246 kScriptChars, reinterpret_cast<Dart_NativeEntryResolver>(native_lookup));
247 Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrameTest"));
248 EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, nullptr));
249}
250
251// Unit test case to verify stack frame iteration.
252TEST_CASE(ValidateNoSuchMethodStackFrameIteration) {
253 const char* const kScriptChars =
254 "class StackFrame {"
255 " @pragma('vm:external-name', 'StackFrame_equals')\n"
256 " external static equals(var obj1, var obj2);\n"
257 " @pragma('vm:external-name', 'StackFrame_frameCount')\n"
258 " external static int frameCount();\n"
259 " @pragma('vm:external-name', 'StackFrame_dartFrameCount')\n"
260 " external static int dartFrameCount();\n"
261 " @pragma('vm:external-name', 'StackFrame_validateFrame')\n"
262 " external static validateFrame(int index, String name);"
263 "} "
264 "class StackFrame2Test {"
265 " StackFrame2Test() {}"
266 " noSuchMethod(Invocation im) {"
267 " /* We should have 6 general frames and 4 dart frames as follows:"
268 " * exit frame"
269 " * dart frame corresponding to StackFrame.frameCount"
270 " * dart frame corresponding to StackFrame2Test.noSuchMethod"
271 " * frame for instance function invocation stub calling "
272 "noSuchMethod"
273 " * dart frame corresponding to StackFrame2Test.testMain"
274 " * entry frame"
275 " */"
276 " StackFrame.equals(6, StackFrame.frameCount());"
277 " StackFrame.equals(4, StackFrame.dartFrameCount());"
278 " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
279 " StackFrame.validateFrame(1, \"StackFrame2Test_noSuchMethod\");"
280 " StackFrame.validateFrame(2, \"StackFrame2Test_foo\");"
281 " StackFrame.validateFrame(3, \"StackFrame2Test_testMain\");"
282 " return 5;"
283 " }"
284 " static testMain() {"
285 " /* Declare |obj| dynamic so that noSuchMethod can be"
286 " * called in strong mode. */"
287 " dynamic obj = new StackFrame2Test();"
288 " StackFrame.equals(5, obj.foo(101, 202));"
289 " }"
290 "}";
292 kScriptChars, reinterpret_cast<Dart_NativeEntryResolver>(native_lookup));
293 Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrame2Test"));
294 EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, nullptr));
295}
296
297} // namespace dart
int count
Definition: FontMgrTest.cpp:50
#define EXPECT(type, expectedAlignment, expectedSize)
static ObjectPtr UnwrapHandle(Dart_Handle object)
StackFrame * NextFrame()
Definition: stack_frame.h:352
virtual bool OperatorEquals(const Instance &other) const
Definition: object.cc:20855
static LibraryPtr LookupLibrary(Thread *thread, const String &url)
Definition: object.cc:14599
StringPtr url() const
Definition: object.h:5097
Thread * thread() const
void SetReturn(const Object &value) const
ObjectPtr NativeArgAt(int index) const
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static char * SCreate(Zone *zone, const char *format,...) PRINTF_ATTRIBUTE(2
virtual const char * ToCString() const
Definition: object.h:366
bool IsNull() const
Definition: object.h:363
static Object & Handle()
Definition: object.h:407
static SmiPtr New(intptr_t value)
Definition: object.h:10006
intptr_t Value() const
Definition: object.h:9990
bool HasNextFrame() const
Definition: stack_frame.h:247
StackFrame * NextFrame()
Definition: stack_frame.cc:549
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition: object.cc:23698
static Dart_Handle LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri=RESOLVED_USER_TEST_URI, bool finalize=true, bool allow_compile_errors=false)
Definition: unit_test.cc:436
static const char * url()
Definition: unit_test.cc:185
Zone * zone() const
Definition: thread_state.h:37
static Thread * Current()
Definition: thread.h:362
static void VerifyPointers(const char *msg, MarkExpectation mark_expectation=kForbidMarked)
Definition: verifier.cc:81
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
Dart_NativeFunction(* Dart_NativeEntryResolver)(Dart_Handle name, int num_of_arguments, bool *auto_setup_scope)
Definition: dart_api.h:3234
struct _Dart_NativeArguments * Dart_NativeArguments
Definition: dart_api.h:3019
void(* Dart_NativeFunction)(Dart_NativeArguments arguments)
Definition: dart_api.h:3207
#define ASSERT(E)
double frame
Definition: examples.cpp:31
#define FATAL(error)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
Dart_NativeFunction function
Definition: fuchsia.cc:51
int argument_count
Definition: fuchsia.cc:52
Definition: dart_vm.cc:33
const char *const name
void FUNCTION_NAME() StackFrame_dartFrameCount(Dart_NativeArguments args)
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library, Dart_Handle class_name)
void FUNCTION_NAME() StackFrame_validateFrame(Dart_NativeArguments args)
static Dart_NativeFunction native_lookup(Dart_Handle name, int argument_count, bool *auto_setup_scope)
static struct dart::NativeEntries BuiltinEntries[]
ISOLATE_UNIT_TEST_CASE(StackAllocatedDestruction)
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
TEST_CASE(DirectoryCurrent)
Dart_Handle NewString(const char *str)
void FUNCTION_NAME() StackFrame_equals(Dart_NativeArguments args)
void FUNCTION_NAME() StackFrame_frameCount(Dart_NativeArguments args)
const char *const function_name
#define STACKFRAME_NATIVE_LIST(V)
#define REGISTER_FUNCTION(name, count)
#define FUNCTION_NAME(name)
const char *const name_
#define EXPECT_VALID(handle)
Definition: unit_test.h:643