Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Namespaces | Macros | Functions | Variables
stack_frame_test.cc File Reference
#include "vm/stack_frame.h"
#include "include/dart_api.h"
#include "platform/assert.h"
#include "vm/class_finalizer.h"
#include "vm/compiler/jit/compiler.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_entry.h"
#include "vm/heap/verifier.h"
#include "vm/resolver.h"
#include "vm/unit_test.h"
#include "vm/zone.h"

Go to the source code of this file.

Classes

struct  dart::NativeEntries
 

Namespaces

namespace  dart
 

Macros

#define FUNCTION_NAME(name)   StackFrame_##name
 
#define REGISTER_FUNCTION(name, count)   {"" #name, FUNCTION_NAME(name), count},
 
#define STACKFRAME_NATIVE_LIST(V)
 

Functions

 dart::ISOLATE_UNIT_TEST_CASE (EmptyStackFrameIteration)
 
 dart::ISOLATE_UNIT_TEST_CASE (EmptyDartStackFrameIteration)
 
void FUNCTION_NAME() dart::StackFrame_equals (Dart_NativeArguments args)
 
void FUNCTION_NAME() dart::StackFrame_frameCount (Dart_NativeArguments args)
 
void FUNCTION_NAME() dart::StackFrame_dartFrameCount (Dart_NativeArguments args)
 
void FUNCTION_NAME() dart::StackFrame_validateFrame (Dart_NativeArguments args)
 
static Dart_NativeFunction dart::native_lookup (Dart_Handle name, int argument_count, bool *auto_setup_scope)
 
 dart::TEST_CASE (ValidateStackFrameIteration)
 
 dart::TEST_CASE (ValidateNoSuchMethodStackFrameIteration)
 

Variables

static struct dart::NativeEntries dart::BuiltinEntries [] = {STACKFRAME_NATIVE_LIST(REGISTER_FUNCTION)}
 

Macro Definition Documentation

◆ FUNCTION_NAME

#define FUNCTION_NAME (   name)    StackFrame_##name

Definition at line 37 of file stack_frame_test.cc.

◆ REGISTER_FUNCTION

#define REGISTER_FUNCTION (   name,
  count 
)    {"" #name, FUNCTION_NAME(name), count},

Definition at line 38 of file stack_frame_test.cc.

◆ STACKFRAME_NATIVE_LIST

#define STACKFRAME_NATIVE_LIST (   V)
Value:
V(StackFrame_equals, 2) \
V(StackFrame_frameCount, 0) \
V(StackFrame_dartFrameCount, 0) \
V(StackFrame_validateFrame, 2)
#define V(name)
Definition raw_object.h:124

Definition at line 127 of file stack_frame_test.cc.

132 {
133 const char* name_;
134 Dart_NativeFunction function_;
135 int argument_count_;
137
139 int argument_count,
140 bool* auto_setup_scope) {
141 ASSERT(auto_setup_scope != nullptr);
142 *auto_setup_scope = false;
143 TransitionNativeToVM transition(Thread::Current());
144 const Object& obj = Object::Handle(Api::UnwrapHandle(name));
145 ASSERT(obj.IsString());
146 const char* function_name = obj.ToCString();
147 ASSERT(function_name != nullptr);
148 int num_entries = sizeof(BuiltinEntries) / sizeof(struct NativeEntries);
149 for (int i = 0; i < num_entries; i++) {
150 struct NativeEntries* entry = &(BuiltinEntries[i]);
151 if ((strcmp(function_name, entry->name_) == 0) &&
152 (entry->argument_count_ == argument_count)) {
153 return reinterpret_cast<Dart_NativeFunction>(entry->function_);
154 }
155 }
156 return nullptr;
157}
158
159// Unit test case to verify stack frame iteration.
160TEST_CASE(ValidateStackFrameIteration) {
161 const char* nullable_tag = TestCase::NullableTag();
162 // clang-format off
163 auto kScriptChars = Utils::CStringUniquePtr(
164 OS::SCreate(
165 nullptr,
166 "class StackFrame {"
167 " @pragma('vm:external-name', 'StackFrame_equals')\n"
168 " external static equals(var obj1, var obj2);\n"
169 " @pragma('vm:external-name', 'StackFrame_frameCount')\n"
170 " external static int frameCount();\n"
171 " @pragma('vm:external-name', 'StackFrame_dartFrameCount')\n"
172 " external static int dartFrameCount();\n"
173 " @pragma('vm:external-name', 'StackFrame_validateFrame')\n"
174 " external static validateFrame(int index, String name);"
175 "} "
176 "class First {"
177 " First() { }"
178 " int%s method1(int%s param) {"
179 " if (param == 1) {"
180 " param = method2(200);"
181 " } else {"
182 " param = method2(100);"
183 " }"
184 " }"
185 " int%s method2(int param) {"
186 " if (param == 200) {"
187 " First.staticmethod(this, param);"
188 " } else {"
189 " First.staticmethod(this, 10);"
190 " }"
191 " }"
192 " static int%s staticmethod(First obj, int param) {"
193 " if (param == 10) {"
194 " obj.method3(10);"
195 " } else {"
196 " obj.method3(200);"
197 " }"
198 " }"
199 " method3(int param) {"
200 " StackFrame.equals(9, StackFrame.frameCount());"
201 " StackFrame.equals(7, StackFrame.dartFrameCount());"
202 " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
203 " StackFrame.validateFrame(1, \"First_method3\");"
204 " StackFrame.validateFrame(2, \"First_staticmethod\");"
205 " StackFrame.validateFrame(3, \"First_method2\");"
206 " StackFrame.validateFrame(4, \"First_method1\");"
207 " StackFrame.validateFrame(5, \"Second_method1\");"
208 " StackFrame.validateFrame(6, \"StackFrameTest_testMain\");"
209 " }"
210 "}"
211 "class Second {"
212 " Second() { }"
213 " int%s method1(int%s param) {"
214 " if (param == 1) {"
215 " param = method2(200);"
216 " } else {"
217 " First obj = new First();"
218 " param = obj.method1(1);"
219 " param = obj.method1(2);"
220 " }"
221 " }"
222 " int%s method2(int param) {"
223 " Second.staticmethod(this, param);"
224 " }"
225 " static int%s staticmethod(Second obj, int param) {"
226 " obj.method3(10);"
227 " }"
228 " method3(int param) {"
229 " StackFrame.equals(8, StackFrame.frameCount());"
230 " StackFrame.equals(6, StackFrame.dartFrameCount());"
231 " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
232 " StackFrame.validateFrame(1, \"Second_method3\");"
233 " StackFrame.validateFrame(2, \"Second_staticmethod\");"
234 " StackFrame.validateFrame(3, \"Second_method2\");"
235 " StackFrame.validateFrame(4, \"Second_method1\");"
236 " StackFrame.validateFrame(5, \"StackFrameTest_testMain\");"
237 " }"
238 "}"
239 "class StackFrameTest {"
240 " static testMain() {"
241 " Second obj = new Second();"
242 " obj.method1(1);"
243 " obj.method1(2);"
244 " }"
245 "}",
246 nullable_tag, nullable_tag, nullable_tag, nullable_tag, nullable_tag,
247 nullable_tag, nullable_tag, nullable_tag),
248 std::free);
249 // clang-format on
250 Dart_Handle lib = TestCase::LoadTestScript(
251 kScriptChars.get(),
252 reinterpret_cast<Dart_NativeEntryResolver>(native_lookup));
253 Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrameTest"));
254 EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, nullptr));
255}
256
257// Unit test case to verify stack frame iteration.
258TEST_CASE(ValidateNoSuchMethodStackFrameIteration) {
259 const char* kScriptChars;
260 // The true stack depends on which strategy we are using for noSuchMethod. The
261 // stacktrace as seen by Dart is the same either way because dispatcher
262 // methods are marked invisible.
263 if (FLAG_lazy_dispatchers) {
264 kScriptChars =
265 "class StackFrame {"
266 " @pragma('vm:external-name', 'StackFrame_equals')\n"
267 " external static equals(var obj1, var obj2);\n"
268 " @pragma('vm:external-name', 'StackFrame_frameCount')\n"
269 " external static int frameCount();\n"
270 " @pragma('vm:external-name', 'StackFrame_dartFrameCount')\n"
271 " external static int dartFrameCount();\n"
272 " @pragma('vm:external-name', 'StackFrame_validateFrame')\n"
273 " external static validateFrame(int index, String name);"
274 "} "
275 "class StackFrame2Test {"
276 " StackFrame2Test() {}"
277 " noSuchMethod(Invocation im) {"
278 " /* We should have 6 general frames and 4 dart frames as follows:"
279 " * exit frame"
280 " * dart frame corresponding to StackFrame.frameCount"
281 " * dart frame corresponding to StackFrame2Test.noSuchMethod"
282 " * frame for instance function invocation stub calling "
283 "noSuchMethod"
284 " * dart frame corresponding to StackFrame2Test.testMain"
285 " * entry frame"
286 " */"
287 " StackFrame.equals(6, StackFrame.frameCount());"
288 " StackFrame.equals(4, StackFrame.dartFrameCount());"
289 " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
290 " StackFrame.validateFrame(1, \"StackFrame2Test_noSuchMethod\");"
291 " StackFrame.validateFrame(2, \"StackFrame2Test_foo\");"
292 " StackFrame.validateFrame(3, \"StackFrame2Test_testMain\");"
293 " return 5;"
294 " }"
295 " static testMain() {"
296 " /* Declare |obj| dynamic so that noSuchMethod can be"
297 " * called in strong mode. */"
298 " dynamic obj = new StackFrame2Test();"
299 " StackFrame.equals(5, obj.foo(101, 202));"
300 " }"
301 "}";
302 } else {
303 kScriptChars =
304 "class StackFrame {"
305 " @pragma('vm:external-name', 'StackFrame_equals')\n"
306 " external static equals(var obj1, var obj2);\n"
307 " @pragma('vm:external-name', 'StackFrame_frameCount')\n"
308 " external static int frameCount();\n"
309 " @pragma('vm:external-name', 'StackFrame_dartFrameCount')\n"
310 " external static int dartFrameCount();\n"
311 " @pragma('vm:external-name', 'StackFrame_validateFrame')\n"
312 " external static validateFrame(int index, String name);"
313 "} "
314 "class StackFrame2Test {"
315 " StackFrame2Test() {}"
316 " noSuchMethod(Invocation im) {"
317 " /* We should have 8 general frames and 3 dart frames as follows:"
318 " * exit frame"
319 " * dart frame corresponding to StackFrame.frameCount"
320 " * dart frame corresponding to StackFrame2Test.noSuchMethod"
321 " * entry frame"
322 " * exit frame (call to runtime NoSuchMethodFromCallStub)"
323 " * IC stub"
324 " * dart frame corresponding to StackFrame2Test.testMain"
325 " * entry frame"
326 " */"
327 " StackFrame.equals(8, StackFrame.frameCount());"
328 " StackFrame.equals(3, StackFrame.dartFrameCount());"
329 " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");"
330 " StackFrame.validateFrame(1, \"StackFrame2Test_noSuchMethod\");"
331 " StackFrame.validateFrame(2, \"StackFrame2Test_testMain\");"
332 " return 5;"
333 " }"
334 " static testMain() {"
335 " /* Declare |obj| dynamic so that noSuchMethod can be"
336 " * called in strong mode. */"
337 " dynamic obj = new StackFrame2Test();"
338 " StackFrame.equals(5, obj.foo(101, 202));"
339 " }"
340 "}";
341 }
342 Dart_Handle lib = TestCase::LoadTestScript(
343 kScriptChars, reinterpret_cast<Dart_NativeEntryResolver>(native_lookup));
344 Dart_Handle cls = Dart_GetClass(lib, NewString("StackFrame2Test"));
345 EXPECT_VALID(Dart_Invoke(cls, NewString("testMain"), 0, nullptr));
346}
347
348} // namespace dart
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_Invoke(Dart_Handle target, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
Dart_NativeFunction(* Dart_NativeEntryResolver)(Dart_Handle name, int num_of_arguments, bool *auto_setup_scope)
Definition dart_api.h:3225
DART_EXPORT Dart_Handle Dart_GetClass(Dart_Handle library, Dart_Handle class_name)
void(* Dart_NativeFunction)(Dart_NativeArguments arguments)
Definition dart_api.h:3198
#define ASSERT(E)
const char * name
Definition fuchsia.cc:50
int argument_count
Definition fuchsia.cc:52
static Dart_NativeFunction native_lookup(Dart_Handle name, int argument_count, bool *auto_setup_scope)
static struct dart::NativeEntries BuiltinEntries[]
const char *const function_name
#define STACKFRAME_NATIVE_LIST(V)
#define REGISTER_FUNCTION(name, count)
Dart_Handle NewString(const char *str)
Definition unit_test.h:229
#define TEST_CASE(name)
Definition unit_test.h:85
#define EXPECT_VALID(handle)
Definition unit_test.h:650