1 /*
2 * Copyright (c) 2024-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <cstdio>
17
18 #include "ecmascript/dfx/stackinfo/tests/js_stackinfo_test.h"
19
20 #include "assembler/assembly-emitter.h"
21 #include "assembler/assembly-parser.h"
22 #include "libpandafile/class_data_accessor-inl.h"
23 #include "libziparchive/zip_archive.h"
24 #include "ecmascript/dfx/stackinfo/js_stackinfo.h"
25 #include "ecmascript/tests/test_helper.h"
26
27 using namespace panda::ecmascript;
28
29 namespace panda::test {
30 class JsStackInfoTest : public testing::Test {
31 public:
SetUpTestCase()32 static void SetUpTestCase()
33 {
34 GTEST_LOG_(INFO) << "SetUpTestCase";
35 }
36
TearDownTestCase()37 static void TearDownTestCase()
38 {
39 GTEST_LOG_(INFO) << "TearDownCase";
40 }
41
SetUp()42 void SetUp() override
43 {
44 TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
45 instance->SetEnableForceGC(false);
46 }
47
TearDown()48 void TearDown() override
49 {
50 TestHelper::DestroyEcmaVMWithScope(instance, scope);
51 JsStackInfo::nameMap.clear();
52 }
53
54 EcmaVM *instance {nullptr};
55 EcmaHandleScope *scope {nullptr};
56 JSThread *thread {nullptr};
57 };
58
59 template<typename T>
ToUintPtr(T frame)60 uintptr_t ToUintPtr(T frame)
61 {
62 return static_cast<uintptr_t>(frame);
63 }
64
ReadMemFunc(void * ctx,uintptr_t addr,uintptr_t * value)65 bool ReadMemFunc([[maybe_unused]] void *ctx, uintptr_t addr, uintptr_t *value)
66 {
67 *value = *(reinterpret_cast<uintptr_t *>(addr));
68 return true;
69 }
70
71 /**
72 * @tc.name: ArkFrameCheck
73 * @tc.desc: Check whether the result returned through "ArkFrameCheck" function is within expectations.
74 * @tc.type: FUNC
75 * @tc.require:
76 */
HWTEST_F_L0(JsStackInfoTest,TestArkFrameCheck)77 HWTEST_F_L0(JsStackInfoTest, TestArkFrameCheck)
78 {
79 for (uintptr_t i = 0; i < 25; i++) {
80 bool ret = ArkFrameCheck(i);
81 if (i == ToUintPtr(FrameType::OPTIMIZED_ENTRY_FRAME) ||
82 i == ToUintPtr(FrameType::ASM_INTERPRETER_ENTRY_FRAME)) {
83 EXPECT_TRUE(ret == true);
84 } else {
85 EXPECT_TRUE(ret == false);
86 }
87 }
88 }
89
90 /**
91 * @tc.name: IsJsFunctionFrame
92 * @tc.desc: Check whether the result returned through "IsJsFunctionFrame" function is within expectations.
93 * @tc.type: FUNC
94 * @tc.require:
95 */
HWTEST_F_L0(JsStackInfoTest,TestIsJsFunctionFrame)96 HWTEST_F_L0(JsStackInfoTest, TestIsJsFunctionFrame)
97 {
98 for (uintptr_t i = 0; i < 25; i++) {
99 bool ret = IsJsFunctionFrame(i);
100 if (i == ToUintPtr(FrameType::ASM_INTERPRETER_FRAME) ||
101 i == ToUintPtr(FrameType::INTERPRETER_CONSTRUCTOR_FRAME) ||
102 i == ToUintPtr(FrameType::INTERPRETER_FRAME) ||
103 i == ToUintPtr(FrameType::INTERPRETER_FAST_NEW_FRAME)) {
104 EXPECT_TRUE(ret == true);
105 } else {
106 EXPECT_TRUE(ret == false);
107 }
108 }
109 }
110
111 /**
112 * @tc.name: IsFastJitFunctionFrame
113 * @tc.desc: Check whether the result returned through "IsFastJitFunctionFrame" function is within expectations.
114 * @tc.type: FUNC
115 * @tc.require:
116 */
HWTEST_F_L0(JsStackInfoTest,TestIsFastJitFunctionFrame)117 HWTEST_F_L0(JsStackInfoTest, TestIsFastJitFunctionFrame)
118 {
119 for (uintptr_t i = 0; i < 25; i++) {
120 bool ret = IsFastJitFunctionFrame(i);
121 if (i == ToUintPtr(FrameType::FASTJIT_FUNCTION_FRAME) ||
122 i == ToUintPtr(FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME)) {
123 EXPECT_TRUE(ret == true);
124 } else {
125 EXPECT_TRUE(ret == false);
126 }
127 }
128 }
129
130 /**
131 * @tc.name: IsNativeFunctionFrame
132 * @tc.desc: Check whether the result returned through "IsNativeFunctionFrame" function is within expectations.
133 * @tc.type: FUNC
134 * @tc.require:
135 */
HWTEST_F_L0(JsStackInfoTest,TestIsNativeFunctionFrame)136 HWTEST_F_L0(JsStackInfoTest, TestIsNativeFunctionFrame)
137 {
138 for (uintptr_t i = 0; i < 25; i++) {
139 bool ret = IsNativeFunctionFrame(i);
140 if (i == ToUintPtr(FrameType::OPTIMIZED_FRAME) ||
141 i == ToUintPtr(FrameType::BASELINE_BUILTIN_FRAME) ||
142 i == ToUintPtr(FrameType::ASM_BRIDGE_FRAME) ||
143 i == ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME) ||
144 i == ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME) ||
145 i == ToUintPtr(FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME) ||
146 i == ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_FRAME) ||
147 i == ToUintPtr(FrameType::LEAVE_FRAME) ||
148 i == ToUintPtr(FrameType::LEAVE_FRAME_WITH_ARGV) ||
149 i == ToUintPtr(FrameType::BUILTIN_CALL_LEAVE_FRAME) ||
150 i == ToUintPtr(FrameType::BUILTIN_FRAME) ||
151 i == ToUintPtr(FrameType::BUILTIN_ENTRY_FRAME) ||
152 i == ToUintPtr(FrameType::BUILTIN_FRAME_WITH_ARGV) ||
153 i == ToUintPtr(FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME) ||
154 i == ToUintPtr(FrameType::ASM_INTERPRETER_BRIDGE_FRAME)) {
155 EXPECT_TRUE(ret == true);
156 } else {
157 EXPECT_TRUE(ret == false);
158 }
159 }
160 }
161
162 /**
163 * @tc.name: IsAotFunctionFrame
164 * @tc.desc: Check whether the result returned through "IsAotFunctionFrame" function is within expectations.
165 * @tc.type: FUNC
166 * @tc.require:
167 */
HWTEST_F_L0(JsStackInfoTest,TestIsAotFunctionFrame)168 HWTEST_F_L0(JsStackInfoTest, TestIsAotFunctionFrame)
169 {
170 for (uintptr_t i = 0; i < 25; i++) {
171 bool ret = IsAotFunctionFrame(i);
172 if (i == ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_FRAME) ||
173 i == ToUintPtr(FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME)) {
174 EXPECT_TRUE(ret == true);
175 } else {
176 EXPECT_TRUE(ret == false);
177 }
178 }
179 }
180
181 /**
182 * @tc.name: ReadMethodInfo
183 * @tc.desc: Check whether the result returned through "ReadMethodInfo" function is within expectations.
184 * @tc.type: FUNC
185 * @tc.require:
186 */
HWTEST_F_L0(JsStackInfoTest,TestReadMethodInfo)187 HWTEST_F_L0(JsStackInfoTest, TestReadMethodInfo)
188 {
189 const char *filename = "__JSPandaFileManagerTest1.pa";
190 const char *data = R"(
191 .function void foo() {
192 return
193 }
194 )";
195 pandasm::Parser parser;
196 auto res = parser.Parse(data);
197 auto file = pandasm::AsmEmitter::Emit(res.Value());
198 auto jsPandaFile = std::make_shared<JSPandaFile>(file.release(), CString(filename), CreateMode::DFX);
199 EXPECT_TRUE(jsPandaFile != nullptr);
200 CVector<MethodInfo> result;
201 const panda_file::File *pf = jsPandaFile->GetPandaFile();
202 Span<const uint32_t> classIndexes = jsPandaFile->GetClasses();
203 for (const uint32_t index : classIndexes) {
204 panda_file::File::EntityId classId(index);
205 if (jsPandaFile->IsExternal(classId)) {
206 continue;
207 }
208 panda_file::ClassDataAccessor cda(*pf, classId);
209 cda.EnumerateMethods([&result, jsPandaFile](panda_file::MethodDataAccessor &mda) {
210 auto info = JSStackTrace::ReadMethodInfo(mda);
211 if (!info) {
212 return;
213 }
214 result.push_back(info.value());
215 });
216 }
217 EXPECT_TRUE(result.size() > 0);
218 }
219
220 /**
221 * @tc.name: ReadAllMethodInfos
222 * @tc.desc: Check whether the result returned through "ReadAllMethodInfos" function is within expectations.
223 * @tc.type: FUNC
224 * @tc.require:
225 */
HWTEST_F_L0(JsStackInfoTest,TestReadAllMethodInfos)226 HWTEST_F_L0(JsStackInfoTest, TestReadAllMethodInfos)
227 {
228 const char *filename = "__JsStackInfoTest.pa";
229 const char *data = R"(
230 .function void foo() {
231 return
232 }
233 )";
234 pandasm::Parser parser;
235 auto res = parser.Parse(data);
236 auto file = pandasm::AsmEmitter::Emit(res.Value());
237 auto pf = std::make_shared<JSPandaFile>(file.release(), CString(filename), CreateMode::DFX);
238 EXPECT_TRUE(pf != nullptr);
239 auto methods = JSStackTrace::ReadAllMethodInfos(pf);
240 EXPECT_TRUE(methods.size() > 0);
241 pf = nullptr;
242 methods = JSStackTrace::ReadAllMethodInfos(pf);
243 EXPECT_TRUE(methods.size() == 0);
244 }
245
246 /**
247 * @tc.name: TranslateByteCodePc
248 * @tc.desc: Check whether the result returned through "TranslateByteCodePc" function is within expectations.
249 * @tc.type: FUNC
250 * @tc.require:
251 */
HWTEST_F_L0(JsStackInfoTest,TestTranslateByteCodePc)252 HWTEST_F_L0(JsStackInfoTest, TestTranslateByteCodePc)
253 {
254 CVector<MethodInfo> vec = {
255 {0, 0, 24},
256 {1, 24, 30},
257 {2, 54, 56},
258 {3, 110, 60}
259 };
260 uintptr_t realPc = 115;
261
262 auto ret = JSStackTrace::TranslateByteCodePc(realPc, vec);
263 EXPECT_TRUE(ret != std::nullopt);
264
265 vec.clear();
266 ret = JSStackTrace::TranslateByteCodePc(realPc, vec);
267 EXPECT_TRUE(ret == std::nullopt);
268
269 vec.push_back({2, 54, 56});
270 ret = JSStackTrace::TranslateByteCodePc(realPc, vec);
271 EXPECT_TRUE(ret == std::nullopt);
272 }
273
274 /**
275 * @tc.name: ParseJsFrameInfo
276 * @tc.desc: Check whether the result returned through "ParseJsFrameInfo" function is within expectations.
277 * @tc.type: FUNC
278 * @tc.require:
279 */
HWTEST_F_L0(JsStackInfoTest,TestParseJsFrameInfo)280 HWTEST_F_L0(JsStackInfoTest, TestParseJsFrameInfo)
281 {
282 const char *filename = "__JsStackInfoTest.pa";
283 const char *data = R"(
284 .function void foo() {
285 return
286 }
287 )";
288 pandasm::Parser parser;
289 auto res = parser.Parse(data);
290 auto file = pandasm::AsmEmitter::Emit(res.Value());
291 auto jsPandaFile = std::make_shared<JSPandaFile>(file.release(), CString(filename), CreateMode::DFX);
292 EXPECT_TRUE(jsPandaFile != nullptr);
293 auto debugExtractor = std::make_unique<DebugInfoExtractor>(jsPandaFile.get());
294 auto methods = JSStackTrace::ReadAllMethodInfos(jsPandaFile);
295 uintptr_t offset = 0;
296 JsFunction jsFunction;
297 ParseJsFrameInfo(jsPandaFile.get(), debugExtractor.get(), EntityId(methods[0].methodId), offset, jsFunction);
298 EXPECT_TRUE(std::string(jsFunction.functionName) == "foo");
299 EXPECT_TRUE(JsStackInfo::nameMap.empty());
300 }
301
302 /**
303 * @tc.name: ArkParseJsFrameInfo
304 * @tc.desc: Check whether the result returned through "ArkCreateJSSymbolExtractor" function is within expectations;
305 * Check whether the result returned through "ArkParseJsFrameInfo" function is within expectations;
306 * Check whether the result returned through "ArkDestoryJSSymbolExtractor" function is within expectations.
307 * @tc.type: FUNC
308 * @tc.require:
309 */
HWTEST_F_L0(JsStackInfoTest,TestArkParseJsFrameInfo)310 HWTEST_F_L0(JsStackInfoTest, TestArkParseJsFrameInfo)
311 {
312 const char *filename1 = "__JsStackInfoTest1.pa";
313 const char *filename2 = "__JsStackInfoTest2.pa";
314 const char *pfdata1 = R"(
315 .function void foo() {
316 return
317 }
318 )";
319 const char *pfdata2 = R"(
320 .language ECMAScript
321 .function any func_main_0(any a0, any a1, any a2) {
322 ldai 1
323 return
324 }
325 )";
326 pandasm::Parser parser1;
327 pandasm::Parser parser2;
328 auto res1 = parser1.Parse(pfdata1);
329 auto res2 = parser2.Parse(pfdata2);
330 auto file1 = pandasm::AsmEmitter::Emit(res1.Value());
331 auto file2 = pandasm::AsmEmitter::Emit(res2.Value());
332 auto jsPandaFile1 = std::make_shared<JSPandaFile>(file1.release(), CString(filename1), CreateMode::DFX);
333 auto jsPandaFile2 = std::make_shared<JSPandaFile>(file2.release(), CString(filename2), CreateMode::DFX);
334 EXPECT_TRUE(jsPandaFile1 != nullptr);
335 EXPECT_TRUE(jsPandaFile2 != nullptr);
336 auto debugExtractor1 = std::make_unique<DebugInfoExtractor>(jsPandaFile1.get());
337 auto debugExtractor2 = std::make_unique<DebugInfoExtractor>(jsPandaFile2.get());
338 auto methods1 = JSStackTrace::ReadAllMethodInfos(jsPandaFile1);
339 auto methods2 = JSStackTrace::ReadAllMethodInfos(jsPandaFile2);
340
341 uintptr_t byteCodePc1 = methods1[0].codeBegin;
342 uintptr_t byteCodePc2 = methods2[0].codeBegin;
343 uintptr_t mapBase1 = reinterpret_cast<uintptr_t>(jsPandaFile1->GetHeader());
344 uintptr_t mapBase2 = reinterpret_cast<uintptr_t>(jsPandaFile2->GetHeader());
345 uintptr_t loadOffset1 = 0;
346 uintptr_t loadOffset2 = 0;
347 const uint8_t* data1 = jsPandaFile1->GetPandaFile()->GetBase();
348 const uint8_t* data2 = jsPandaFile2->GetPandaFile()->GetBase();
349 uint64_t dataSize1 = jsPandaFile1->GetFileSize();
350 uint64_t dataSize2 = jsPandaFile2->GetFileSize();
351 uintptr_t extractorptr1 = 0;
352 uintptr_t extractorptr2 = 0;
353 JsFunction jsFunction1;
354 JsFunction jsFunction2;
355
356 auto ret = ark_create_js_symbol_extractor(&extractorptr1);
357 EXPECT_TRUE(ret == 1);
358 EXPECT_TRUE(extractorptr1 != 0);
359 ret = ark_create_js_symbol_extractor(&extractorptr2);
360 EXPECT_TRUE(ret == 1);
361 EXPECT_TRUE(extractorptr2 != 0);
362
363 ret = ark_parse_js_frame_info(byteCodePc1, mapBase1, loadOffset1,
364 reinterpret_cast<uint8_t *>(const_cast<char*>(pfdata1)),
365 strlen(pfdata1) + 1, extractorptr1, &jsFunction1);
366 EXPECT_TRUE(ret == -1);
367
368 ret = ark_parse_js_frame_info(byteCodePc1, mapBase1, loadOffset1,
369 const_cast<uint8_t*>(data1), dataSize1, extractorptr1, &jsFunction1);
370 EXPECT_TRUE(ret == 1);
371 EXPECT_TRUE(std::string(jsFunction1.functionName) == "foo");
372
373 ret = ark_parse_js_frame_info(byteCodePc1, mapBase1, loadOffset1,
374 const_cast<uint8_t*>(data1), dataSize1 + 1, 0, &jsFunction1);
375 EXPECT_TRUE(ret == -1);
376
377 ret = ark_parse_js_frame_info(byteCodePc1, mapBase1, loadOffset1,
378 nullptr, 0, extractorptr1, &jsFunction1);
379 EXPECT_TRUE(ret == -1);
380
381 ret = ark_parse_js_frame_info(byteCodePc1, mapBase1, loadOffset1,
382 const_cast<uint8_t*>(data2), dataSize2, extractorptr2, &jsFunction1);
383 EXPECT_TRUE(ret == -1);
384
385 ret = ark_parse_js_frame_info(byteCodePc2, mapBase1, loadOffset1,
386 const_cast<uint8_t*>(data2), dataSize2, extractorptr2, &jsFunction1);
387 EXPECT_TRUE(ret == -1);
388
389 ret = ark_parse_js_frame_info(byteCodePc2, mapBase1, loadOffset1,
390 const_cast<uint8_t*>(data2), dataSize2, extractorptr2, &jsFunction1);
391 EXPECT_TRUE(ret == -1);
392
393 ret = ark_parse_js_frame_info(byteCodePc2, mapBase2, loadOffset2,
394 const_cast<uint8_t*>(data2), dataSize2, extractorptr2, &jsFunction2);
395 EXPECT_TRUE(ret == 1);
396 EXPECT_TRUE(std::string(jsFunction2.functionName) == "func_main_0");
397
398 ret = ark_destory_js_symbol_extractor(extractorptr1);
399 EXPECT_TRUE(ret == 1);
400
401 ret = ark_destory_js_symbol_extractor(extractorptr2);
402 EXPECT_TRUE(!JsStackInfo::nameMap.empty());
403 EXPECT_TRUE(ret == 1);
404 }
405
406 /**
407 * @tc.name: BuildJsStackInfo
408 * @tc.desc: Check whether the result returned through "BuildJsStackInfo" function is within expectations;
409 * @tc.type: FUNC
410 * @tc.require:
411 */
HWTEST_F_L0(JsStackInfoTest,TestBuildJsStackInfo)412 HWTEST_F_L0(JsStackInfoTest, TestBuildJsStackInfo)
413 {
414 auto jsFrame = JsStackInfo::BuildJsStackInfo(thread);
415 EXPECT_TRUE(jsFrame.empty());
416 }
417
418 /**
419 * @tc.name: ark_destory_local
420 * @tc.desc: Check whether the result returned through "ark_destory_local" function is within expectations;
421 * @tc.type: FUNC
422 * @tc.require:
423 */
HWTEST_F_L0(JsStackInfoTest,TestArkDestoryLocal)424 HWTEST_F_L0(JsStackInfoTest, TestArkDestoryLocal)
425 {
426 auto ret = ark_destroy_local(); // Direct destruct without creating Pointers
427 EXPECT_TRUE(ret);
428 ret = ark_create_local(); // ref count = 1
429 ret = ark_create_local(); // ref count = 2
430 EXPECT_TRUE(ret);
431 auto trace = JSStackTrace::GetInstance();
432 EXPECT_TRUE(trace != nullptr);
433 ret = ark_destroy_local(); // ref count = 1
434 trace = JSStackTrace::GetInstance();
435 EXPECT_TRUE(trace != nullptr);
436 ret = ark_destroy_local(); // ref count = 0
437 trace = JSStackTrace::GetInstance();
438 EXPECT_TRUE(trace == nullptr);
439 EXPECT_TRUE(ret);
440 ret = ark_destroy_local(); // multiple destory
441 EXPECT_TRUE(ret);
442
443 // Create and destruct multiple times within the process
444 ret = ark_create_local(); // ref count = 1
445 trace = JSStackTrace::GetInstance();
446 EXPECT_TRUE(trace != nullptr);
447 ret = ark_destroy_local();
448 EXPECT_TRUE(ret);
449 }
450
HWTEST_F_L0(JsStackInfoTest,TestStepArk__001)451 HWTEST_F_L0(JsStackInfoTest, TestStepArk__001)
452 {
453 void *ctx = nullptr;
454 uintptr_t sp = 0;
455 uintptr_t pc = 0;
456 bool isJsFrame = true;
457 uintptr_t frame[10][3];
458 uintptr_t fp[10];
459 for (int i = 0; i < 10; i++) {
460 frame[i][0] = 0;
461 frame[i][1] = 0;
462 }
463 fp[0] = reinterpret_cast<uintptr_t>(&frame[0][2]) + 8;
464 for (int i = 1; i < 10; i++) {
465 fp[i] = fp[i-1] + 24;
466 }
467 ArkStepParam arkStepParam{ &fp[0], &sp, &pc, &isJsFrame };
468 frame[0][2] = static_cast<uintptr_t>(FrameType::INTERPRETER_CONSTRUCTOR_FRAME);
469 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
470 frame[1][2] = static_cast<uintptr_t>(FrameType::INTERPRETER_FAST_NEW_FRAME);
471 arkStepParam.fp = &fp[1];
472 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
473 frame[2][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME);
474 arkStepParam.fp = &fp[2];
475 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
476 frame[3][2] = static_cast<uintptr_t>(FrameType::ASM_INTERPRETER_ENTRY_FRAME);
477 arkStepParam.fp = &fp[3];
478 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
479 frame[4][2] = static_cast<uintptr_t>(FrameType::BUILTIN_ENTRY_FRAME);
480 arkStepParam.fp = &fp[4];
481 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
482 frame[5][2] = static_cast<uintptr_t>(FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME);
483 arkStepParam.fp = &fp[5];
484 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
485 frame[6][2] = static_cast<uintptr_t>(FrameType::BASELINE_BUILTIN_FRAME);
486 arkStepParam.fp = &fp[6];
487 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
488 frame[7][2] = static_cast<uintptr_t>(FrameType::ASM_BRIDGE_FRAME);
489 arkStepParam.fp = &fp[7];
490 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
491 frame[8][2] = static_cast<uintptr_t>(FrameType::LEAVE_FRAME);
492 arkStepParam.fp = &fp[8];
493 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
494 frame[9][2] = static_cast<uintptr_t>(FrameType::LEAVE_FRAME_WITH_ARGV);
495 arkStepParam.fp = &fp[9];
496 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
497 }
498
HWTEST_F_L0(JsStackInfoTest,TestStepArk__002)499 HWTEST_F_L0(JsStackInfoTest, TestStepArk__002)
500 {
501 void *ctx = nullptr;
502 uintptr_t sp = 0;
503 uintptr_t pc = 0;
504 bool isJsFrame = true;
505 uintptr_t frame[30][3];
506 uintptr_t fp[30];
507 for (int i = 0; i < 30; i++) {
508 frame[i][0] = 0;
509 frame[i][1] = 0;
510 }
511 fp[0] = reinterpret_cast<uintptr_t>(&frame[0][2]) + 8;
512 for (int i = 1; i < 30; i++) {
513 fp[i] = fp[i-1] + 24;
514 }
515 ArkStepParam arkStepParam{ &fp[0], &sp, &pc, &isJsFrame };
516 frame[0][2] = static_cast<uintptr_t>(FrameType::BUILTIN_CALL_LEAVE_FRAME);
517 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
518 frame[1][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_FRAME);
519 arkStepParam.fp = &fp[1];
520 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
521 frame[2][2] = static_cast<uintptr_t>(FrameType::ASM_INTERPRETER_BRIDGE_FRAME);
522 arkStepParam.fp = &fp[2];
523 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
524 frame[3][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME);
525 arkStepParam.fp = &fp[3];
526 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
527 frame[4][2] = static_cast<uintptr_t>(FrameType::INTERPRETER_CONSTRUCTOR_FRAME);
528 arkStepParam.fp = &fp[4];
529 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
530 frame[5][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_ENTRY_FRAME);
531 arkStepParam.fp = &fp[5];
532 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
533 frame[6][2] = static_cast<uintptr_t>(FrameType::ASM_BRIDGE_FRAME);
534 arkStepParam.fp = &fp[6];
535 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
536 frame[7][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME);
537 arkStepParam.fp = &fp[7];
538 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
539 frame[8][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_JS_FUNCTION_FRAME);
540 arkStepParam.fp = &fp[8];
541 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
542 frame[9][2] = 100;
543 arkStepParam.fp = &fp[9];
544 ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &arkStepParam));
545 }
546
HWTEST_F_L0(JsStackInfoTest,TestLocalParseJsFrameInfo__001)547 HWTEST_F_L0(JsStackInfoTest, TestLocalParseJsFrameInfo__001)
548 {
549 const char *filename = "__JsStackInfoTest1.pa";
550 const char *pfdata = R"(
551 .function void foo() {
552 return
553 }
554 )";
555
556 auto pfManager = JSPandaFileManager::GetInstance();
557
558 pandasm::Parser parser1;
559 auto res = parser1.Parse(pfdata);
560 auto file = pandasm::AsmEmitter::Emit(res.Value());
561 auto jsPandaFile = pfManager->NewJSPandaFile(file.release(), CString(filename));
562 pfManager->AddJSPandaFile(jsPandaFile);
563 EXPECT_TRUE(jsPandaFile != nullptr);
564 auto methods = JSStackTrace::ReadAllMethodInfos(jsPandaFile);
565
566 uintptr_t byteCodePc = methods[0].codeBegin;
567 uintptr_t mapBase = reinterpret_cast<uintptr_t>(jsPandaFile->GetHeader());
568 uintptr_t loadOffset = 0;
569 JsFunction jsFunction;
570
571 // Incorrect invocation demonstration
572 auto ret = ark_parse_js_frame_info_local(byteCodePc, mapBase, loadOffset, &jsFunction);
573 EXPECT_TRUE(ret == -1);
574
575 // Correct invocation demonstration
576 ark_create_local();
577 ret = ark_parse_js_frame_info_local(byteCodePc, mapBase, loadOffset, &jsFunction);
578 EXPECT_TRUE(ret == 1);
579
580 ret = ark_parse_js_frame_info_local(byteCodePc, mapBase, loadOffset, &jsFunction);
581 EXPECT_TRUE(ret == 1);
582 EXPECT_TRUE(JsStackInfo::nameMap.empty());
583
584 ark_destroy_local();
585
586 pfManager->RemoveJSPandaFile(jsPandaFile.get());
587 }
588
HWTEST_F_L0(JsStackInfoTest,TestLocalParseJsFrameInfo__002)589 HWTEST_F_L0(JsStackInfoTest, TestLocalParseJsFrameInfo__002)
590 {
591 const char *filename = "__JsStackInfoTest1.pa";
592 const char *pfdata = R"(
593 .function void foo() {
594 return
595 }
596 )";
597
598 auto pfManager = JSPandaFileManager::GetInstance();
599
600 pandasm::Parser parser1;
601 auto res = parser1.Parse(pfdata);
602 auto file = pandasm::AsmEmitter::Emit(res.Value());
603 auto jsPandaFile = pfManager->NewJSPandaFile(file.release(), CString(filename));
604 EXPECT_TRUE(jsPandaFile != nullptr);
605 auto methods = JSStackTrace::ReadAllMethodInfos(jsPandaFile);
606
607 uintptr_t byteCodePc = methods[0].codeBegin;
608 uintptr_t mapBase = reinterpret_cast<uintptr_t>(jsPandaFile->GetHeader());
609 uintptr_t loadOffset = 0;
610 JsFunction jsFunction;
611
612 ark_create_local();
613 auto ret = ark_parse_js_frame_info_local(byteCodePc, mapBase, loadOffset, &jsFunction);
614 ark_destroy_local();
615 // pandafile manager can't find jsPandaFile
616 EXPECT_TRUE(ret == -1);
617 }
618
619 #if defined(PANDA_TARGET_ARM64)
HWTEST_F_L0(JsStackInfoTest,TestFrameType_001)620 HWTEST_F_L0(JsStackInfoTest, TestFrameType_001)
621 {
622 EXPECT_TRUE(ToUintPtr(arkts_frame_type::OPTIMIZED_FRAME) ==
623 ToUintPtr(FrameType::OPTIMIZED_FRAME));
624 EXPECT_TRUE(ToUintPtr(arkts_frame_type::OPTIMIZED_ENTRY_FRAME) ==
625 ToUintPtr(FrameType::OPTIMIZED_ENTRY_FRAME));
626 EXPECT_TRUE(ToUintPtr(arkts_frame_type::OPTIMIZED_JS_FUNCTION_FRAME) ==
627 ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_FRAME));
628 EXPECT_TRUE(ToUintPtr(arkts_frame_type::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME) ==
629 ToUintPtr(FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME));
630 EXPECT_TRUE(ToUintPtr(arkts_frame_type::FASTJIT_FUNCTION_FRAME) ==
631 ToUintPtr(FrameType::FASTJIT_FUNCTION_FRAME));
632 EXPECT_TRUE(ToUintPtr(arkts_frame_type::FASTJIT_FAST_CALL_FUNCTION_FRAME) ==
633 ToUintPtr(FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME));
634 EXPECT_TRUE(ToUintPtr(arkts_frame_type::ASM_BRIDGE_FRAME) ==
635 ToUintPtr(FrameType::ASM_BRIDGE_FRAME));
636 EXPECT_TRUE(ToUintPtr(arkts_frame_type::LEAVE_FRAME) ==
637 ToUintPtr(FrameType::LEAVE_FRAME));
638 EXPECT_TRUE(ToUintPtr(arkts_frame_type::LEAVE_FRAME_WITH_ARGV) ==
639 ToUintPtr(FrameType::LEAVE_FRAME_WITH_ARGV));
640 EXPECT_TRUE(ToUintPtr(arkts_frame_type::BUILTIN_CALL_LEAVE_FRAME) ==
641 ToUintPtr(FrameType::BUILTIN_CALL_LEAVE_FRAME));
642 EXPECT_TRUE(ToUintPtr(arkts_frame_type::INTERPRETER_FRAME) ==
643 ToUintPtr(FrameType::INTERPRETER_FRAME));
644 EXPECT_TRUE(ToUintPtr(arkts_frame_type::ASM_INTERPRETER_FRAME) ==
645 ToUintPtr(FrameType::ASM_INTERPRETER_FRAME));
646 EXPECT_TRUE(ToUintPtr(arkts_frame_type::INTERPRETER_CONSTRUCTOR_FRAME) ==
647 ToUintPtr(FrameType::INTERPRETER_CONSTRUCTOR_FRAME));
648 EXPECT_TRUE(ToUintPtr(arkts_frame_type::BUILTIN_FRAME) ==
649 ToUintPtr(FrameType::BUILTIN_FRAME));
650 }
651
HWTEST_F_L0(JsStackInfoTest,TestFrameType_002)652 HWTEST_F_L0(JsStackInfoTest, TestFrameType_002)
653 {
654 EXPECT_TRUE(ToUintPtr(arkts_frame_type::BUILTIN_FRAME_WITH_ARGV) ==
655 ToUintPtr(FrameType::BUILTIN_FRAME_WITH_ARGV));
656 EXPECT_TRUE(ToUintPtr(arkts_frame_type::BUILTIN_ENTRY_FRAME) ==
657 ToUintPtr(FrameType::BUILTIN_ENTRY_FRAME));
658 EXPECT_TRUE(ToUintPtr(arkts_frame_type::INTERPRETER_BUILTIN_FRAME) ==
659 ToUintPtr(FrameType::INTERPRETER_BUILTIN_FRAME));
660 EXPECT_TRUE(ToUintPtr(arkts_frame_type::INTERPRETER_FAST_NEW_FRAME) ==
661 ToUintPtr(FrameType::INTERPRETER_FAST_NEW_FRAME));
662 EXPECT_TRUE(ToUintPtr(arkts_frame_type::INTERPRETER_ENTRY_FRAME) ==
663 ToUintPtr(FrameType::INTERPRETER_ENTRY_FRAME));
664 EXPECT_TRUE(ToUintPtr(arkts_frame_type::ASM_INTERPRETER_ENTRY_FRAME) ==
665 ToUintPtr(FrameType::ASM_INTERPRETER_ENTRY_FRAME));
666 EXPECT_TRUE(ToUintPtr(arkts_frame_type::ASM_INTERPRETER_BRIDGE_FRAME) ==
667 ToUintPtr(FrameType::ASM_INTERPRETER_BRIDGE_FRAME));
668 EXPECT_TRUE(ToUintPtr(arkts_frame_type::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME) ==
669 ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME));
670 EXPECT_TRUE(ToUintPtr(arkts_frame_type::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME) ==
671 ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME));
672 EXPECT_TRUE(ToUintPtr(arkts_frame_type::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME) ==
673 ToUintPtr(FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME));
674 EXPECT_TRUE(ToUintPtr(arkts_frame_type::BASELINE_BUILTIN_FRAME) ==
675 ToUintPtr(FrameType::BASELINE_BUILTIN_FRAME));
676 }
677
HWTEST_F_L0(JsStackInfoTest,TestStepArk_001)678 HWTEST_F_L0(JsStackInfoTest, TestStepArk_001)
679 {
680 size_t size = 3; // 3: size of OPTIMIZED_FRAME
681 JSTaggedType frame[size];
682 frame[0] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_FRAME); // 0: type
683 frame[1] = static_cast<JSTaggedType>(62480); // 1: prevFp
684 frame[2] = static_cast<JSTaggedType>(123456); // 2: returnAddr
685
686 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
687 uintptr_t sp = 0;
688 uintptr_t pc = 0;
689 bool isJsFrame = true;
690
691 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
692 ctx->count = -1;
693 unwind_stack_frame_s cur_frame = { fp, 0 };
694 auto pre_frame = unwind_arkts(ctx, &cur_frame);
695 EXPECT_TRUE(pre_frame.fp == frame[1]);
696 EXPECT_TRUE(pre_frame.pc == frame[2]);
697
698 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
699 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
700 EXPECT_TRUE(*arkStepParam.fp == frame[1]);
701 EXPECT_TRUE(*arkStepParam.pc == frame[2]);
702 EXPECT_TRUE(ret == 1);
703
704 free(ctx);
705 }
706
HWTEST_F_L0(JsStackInfoTest,TestStepArk_002)707 HWTEST_F_L0(JsStackInfoTest, TestStepArk_002)
708 {
709 size_t size = 4; // 4: size of OPTIMIZED_ENTRY_FRAME + returnaddr
710 JSTaggedType frame[size];
711 frame[0] = static_cast<JSTaggedType>(0); // 0: preLeaveFrameFp
712 frame[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_ENTRY_FRAME); // 1: type
713 frame[2] = static_cast<JSTaggedType>(62480); // 2: prevFP
714 frame[3] = static_cast<JSTaggedType>(123456); // 3: returnAddr
715
716 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[1]) + 8; // 1: type addr
717 uintptr_t sp = 0;
718 uintptr_t pc = 0;
719 bool isJsFrame = true;
720 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
721 ctx->count = -1;
722 unwind_stack_frame_s cur_frame = { fp, pc };
723 auto pre_frame = unwind_arkts(ctx, &cur_frame);
724 EXPECT_TRUE(pre_frame.fp == frame[2]);
725 EXPECT_TRUE(pre_frame.pc == frame[3]);
726
727 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
728 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
729 EXPECT_TRUE(*arkStepParam.fp == frame[2]);
730 EXPECT_TRUE(*arkStepParam.pc == frame[3]);
731 EXPECT_TRUE(ret == 1);
732
733 free(ctx);
734 }
735
HWTEST_F_L0(JsStackInfoTest,TestStepArk_003)736 HWTEST_F_L0(JsStackInfoTest, TestStepArk_003)
737 {
738 size_t size = 4; // 4: size of OPTIMIZED_JS_FUNCTION_FRAME
739 JSTaggedType frame[size];
740 frame[0] = JSTaggedValue::Hole().GetRawData(); // 0: JSFunction
741 frame[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_JS_FUNCTION_FRAME); // 1: type
742 frame[2] = static_cast<JSTaggedType>(62480); // 2: prevFp
743 frame[3] = static_cast<JSTaggedType>(123456); // 3: returnAddr
744
745 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[1]) + 8; // 1: type addr
746 uintptr_t sp = 0;
747 uintptr_t pc = 0;
748 bool isJsFrame = true;
749 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
750 ctx->count = -1;
751 unwind_stack_frame_s cur_frame = { fp, pc };
752 auto pre_frame = unwind_arkts(ctx, &cur_frame);
753 EXPECT_TRUE(pre_frame.fp == frame[2]);
754 EXPECT_TRUE(pre_frame.pc == frame[3]);
755
756 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
757 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
758 EXPECT_TRUE(*arkStepParam.fp == frame[2]);
759 EXPECT_TRUE(*arkStepParam.pc == frame[3]);
760 EXPECT_TRUE(ret == 1);
761
762 free(ctx);
763 }
764
HWTEST_F_L0(JsStackInfoTest,TestStepArk_004)765 HWTEST_F_L0(JsStackInfoTest, TestStepArk_004)
766 {
767 size_t size = 4; // 4: size of OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME
768 JSTaggedType frame[size];
769 frame[0] = JSTaggedValue::Hole().GetRawData(); // 0: JSFunction
770 frame[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME); // 1: type
771 frame[2] = static_cast<JSTaggedType>(62480); // 2: prevFp
772 frame[3] = static_cast<JSTaggedType>(123456); // 3: returnAddr
773
774 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[1]) + 8; // 1: type addr
775 uintptr_t sp = 0;
776 uintptr_t pc = 0;
777 bool isJsFrame = true;
778 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
779 ctx->count = -1;
780 unwind_stack_frame_s cur_frame = { fp, pc };
781 auto pre_frame = unwind_arkts(ctx, &cur_frame);
782 EXPECT_TRUE(pre_frame.fp == frame[2]);
783 EXPECT_TRUE(pre_frame.pc == frame[3]);
784
785 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
786 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
787 EXPECT_TRUE(*arkStepParam.fp == frame[2]);
788 EXPECT_TRUE(*arkStepParam.pc == frame[3]);
789 EXPECT_TRUE(ret == 1);
790
791 free(ctx);
792 }
793
HWTEST_F_L0(JsStackInfoTest,TestStepArk_005)794 HWTEST_F_L0(JsStackInfoTest, TestStepArk_005)
795 {
796 size_t size1 = 4; // 4: size of OPTIMIZED_ENTRY_FRAME + returnaddr
797 JSTaggedType frame1[size1];
798 frame1[0] = static_cast<JSTaggedType>(0); // 0: preLeaveFrameFp
799 frame1[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_ENTRY_FRAME); // 1: type
800 frame1[2] = static_cast<JSTaggedType>(62480); // 2: prevFP
801 frame1[3] = static_cast<JSTaggedType>(123456); // 3: returnAddr
802
803 size_t size2 = 5; // 4: size of FASTJIT_FUNCTION_FRAME
804 JSTaggedType frame2[size2];
805 frame2[0] = static_cast<JSTaggedType>(1234); // 0: pc
806 frame2[1] = JSTaggedValue::Hole().GetRawData(); // 1: JSFunction
807 frame2[2] = static_cast<JSTaggedType>(FrameType::FASTJIT_FUNCTION_FRAME); // 2: type
808 frame2[3] = static_cast<JSTaggedType>(reinterpret_cast<uintptr_t>(&frame1[1]) + 8); // 3: prevFp
809 frame2[4] = static_cast<JSTaggedType>(0); // 4: returnAddr
810
811 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame2[2]) + 8; // 0: type addr
812 uintptr_t sp = 0;
813 uintptr_t pc = 0;
814 bool isJsFrame = true;
815 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
816 ctx->count = -1;
817 unwind_stack_frame_s cur_frame = { fp, pc };
818 auto pre_frame = unwind_arkts(ctx, &cur_frame);
819
820 EXPECT_TRUE(pre_frame.fp == frame1[2]);
821 EXPECT_TRUE(pre_frame.pc == frame1[3]);
822
823 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
824 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
825 EXPECT_TRUE(*arkStepParam.fp == frame1[2]);
826 EXPECT_TRUE(*arkStepParam.pc == frame1[3]);
827 EXPECT_TRUE(ret == 1);
828
829 free(ctx);
830 }
831
HWTEST_F_L0(JsStackInfoTest,TestStepArk_006)832 HWTEST_F_L0(JsStackInfoTest, TestStepArk_006)
833 {
834 size_t size1 = 4; // 4: size of OPTIMIZED_ENTRY_FRAME + returnaddr
835 JSTaggedType frame1[size1];
836 frame1[0] = static_cast<JSTaggedType>(0); // 0: preLeaveFrameFp
837 frame1[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_ENTRY_FRAME); // 1: type
838 frame1[2] = static_cast<JSTaggedType>(62480); // 2: prevFP
839 frame1[3] = static_cast<JSTaggedType>(123456); // 3: returnAddr
840
841 size_t size2 = 5; // 4: size of FASTJIT_FAST_CALL_FUNCTION_FRAME
842 JSTaggedType frame2[size2];
843 frame2[0] = static_cast<JSTaggedType>(1234); // 0: pc
844 frame2[1] = JSTaggedValue::Hole().GetRawData(); // 1: JSFunction
845 frame2[2] = static_cast<JSTaggedType>(FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME); // 2: type
846 frame2[3] = static_cast<JSTaggedType>(reinterpret_cast<uintptr_t>(&frame1[1]) + 8); // 3: prevFp
847 frame2[4] = static_cast<JSTaggedType>(0); // 4: returnAddr
848
849 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame2[2]) + 8; // 0: type addr
850 uintptr_t sp = 0;
851 uintptr_t pc = 0;
852 bool isJsFrame = true;
853 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
854 ctx->count = -1;
855 unwind_stack_frame_s cur_frame = { fp, pc };
856 auto pre_frame = unwind_arkts(ctx, &cur_frame);
857
858 EXPECT_TRUE(pre_frame.fp == frame1[2]);
859 EXPECT_TRUE(pre_frame.pc == frame1[3]);
860
861 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
862 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
863 EXPECT_TRUE(*arkStepParam.fp == frame1[2]);
864 EXPECT_TRUE(*arkStepParam.pc == frame1[3]);
865 EXPECT_TRUE(ret == 1);
866
867 free(ctx);
868 }
869
HWTEST_F_L0(JsStackInfoTest,TestStepArk_007)870 HWTEST_F_L0(JsStackInfoTest, TestStepArk_007)
871 {
872 size_t size = 3; // 3: size of ASM_BRIDGE_FRAME
873 JSTaggedType frame[size];
874 frame[0] = static_cast<JSTaggedType>(FrameType::ASM_BRIDGE_FRAME); // 0: type
875 frame[1] = static_cast<JSTaggedType>(62480); // 1: prevFp
876 frame[2] = static_cast<JSTaggedType>(123456); // 2: returnAddr
877
878 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
879 uintptr_t sp = 0;
880 uintptr_t pc = 0;
881 bool isJsFrame = true;
882 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
883 ctx->count = -1;
884 unwind_stack_frame_s cur_frame = { fp, pc };
885 auto pre_frame = unwind_arkts(ctx, &cur_frame);
886
887 EXPECT_TRUE(pre_frame.fp == frame[1]);
888 EXPECT_TRUE(pre_frame.pc == frame[2]);
889
890 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
891 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
892 EXPECT_TRUE(*arkStepParam.fp == frame[1]);
893 EXPECT_TRUE(*arkStepParam.pc == frame[2]);
894 EXPECT_TRUE(ret == 1);
895
896 free(ctx);
897 }
898
HWTEST_F_L0(JsStackInfoTest,TestStepArk_008)899 HWTEST_F_L0(JsStackInfoTest, TestStepArk_008)
900 {
901 size_t size = 5; // 5: size of LEAVE_FRAME
902 JSTaggedType frame[size];
903 frame[0] = static_cast<JSTaggedType>(FrameType::LEAVE_FRAME); // 0: type
904 frame[1] = static_cast<JSTaggedType>(62480); // 1: callsiteFp
905 frame[2] = static_cast<JSTaggedType>(123456); // 2: returnAddr
906 frame[3] = static_cast<JSTaggedType>(0); // 3: argRuntimeId
907 frame[4] = static_cast<JSTaggedType>(0); // 4: argc
908
909 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
910 uintptr_t sp = 0;
911 uintptr_t pc = 0;
912 bool isJsFrame = true;
913 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
914 ctx->count = -1;
915 unwind_stack_frame_s cur_frame = { fp, pc };
916 auto pre_frame = unwind_arkts(ctx, &cur_frame);
917
918 EXPECT_TRUE(pre_frame.fp == frame[1]);
919 EXPECT_TRUE(pre_frame.pc == frame[2]);
920
921 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
922 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
923 EXPECT_TRUE(*arkStepParam.fp == frame[1]);
924 EXPECT_TRUE(*arkStepParam.pc == frame[2]);
925 EXPECT_TRUE(ret == 1);
926
927 free(ctx);
928 }
929
HWTEST_F_L0(JsStackInfoTest,TestStepArk_009)930 HWTEST_F_L0(JsStackInfoTest, TestStepArk_009)
931 {
932 size_t size = 5; // 5: size of LEAVE_FRAME_WITH_ARGV
933 JSTaggedType frame[size];
934 frame[0] = static_cast<JSTaggedType>(FrameType::LEAVE_FRAME); // 0: type
935 frame[1] = static_cast<JSTaggedType>(62480); // 1: callsiteFp
936 frame[2] = static_cast<JSTaggedType>(123456); // 2: returnAddr
937 frame[3] = static_cast<JSTaggedType>(0); // 3: argRuntimeId
938 frame[4] = static_cast<JSTaggedType>(0); // 4: argc
939
940 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
941 uintptr_t sp = 0;
942 uintptr_t pc = 0;
943 bool isJsFrame = true;
944 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
945 ctx->count = -1;
946 unwind_stack_frame_s cur_frame = { fp, pc };
947 auto pre_frame = unwind_arkts(ctx, &cur_frame);
948
949 EXPECT_TRUE(pre_frame.fp == frame[1]);
950 EXPECT_TRUE(pre_frame.pc == frame[2]);
951
952 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
953 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
954 EXPECT_TRUE(*arkStepParam.fp == frame[1]);
955 EXPECT_TRUE(*arkStepParam.pc == frame[2]);
956 EXPECT_TRUE(ret == 1);
957
958 free(ctx);
959 }
960
HWTEST_F_L0(JsStackInfoTest,TestStepArk_010)961 HWTEST_F_L0(JsStackInfoTest, TestStepArk_010)
962 {
963 size_t size = 5; // 5: size of BUILTIN_CALL_LEAVE_FRAME
964 JSTaggedType frame[size];
965 frame[0] = static_cast<JSTaggedType>(0); // 0: type
966 frame[1] = static_cast<JSTaggedType>(62480); // 1: prev fp
967 frame[2] = static_cast<JSTaggedType>(123456); // 2: returnAddr
968 frame[3] = JSTaggedValue::Hole().GetRawData(); // 3: thread
969 frame[4] = static_cast<JSTaggedType>(0); // 4: argc
970
971
972 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
973 uintptr_t sp = 0;
974 uintptr_t pc = 0;
975 bool isJsFrame = true;
976 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
977 ctx->count = -1;
978 unwind_stack_frame_s cur_frame = { fp, pc };
979 auto pre_frame = unwind_arkts(ctx, &cur_frame);
980
981 EXPECT_TRUE(pre_frame.fp == frame[1]);
982 EXPECT_TRUE(pre_frame.pc == frame[2]);
983
984 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
985 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
986 EXPECT_TRUE(*arkStepParam.fp == frame[1]);
987 EXPECT_TRUE(*arkStepParam.pc == frame[2]);
988 EXPECT_TRUE(ret == 1);
989
990 free(ctx);
991 }
992
HWTEST_F_L0(JsStackInfoTest,TestStepArk_011)993 HWTEST_F_L0(JsStackInfoTest, TestStepArk_011)
994 {
995 size_t size = 9; // 9: size of INTERPRETER_FRAME
996 JSTaggedType frame[size];
997 frame[0] = JSTaggedValue::Hole().GetRawData(); // 0: constpool
998 frame[1] = JSTaggedValue::Hole().GetRawData(); // 1: function
999 frame[2] = JSTaggedValue::Hole().GetRawData(); // 2: thisObj
1000 frame[3] = JSTaggedValue::Hole().GetRawData(); // 3: profileTypeInfo
1001 frame[4] = JSTaggedValue::Hole().GetRawData(); // 4: acc
1002 frame[5] = JSTaggedValue::Hole().GetRawData(); // 5: env
1003 frame[6] = static_cast<JSTaggedType>(123456); // 6: pc
1004 frame[7] = static_cast<JSTaggedType>(62480); // 7: base.prevfp
1005 frame[8] = static_cast<JSTaggedType>(FrameType::INTERPRETER_FRAME); // 8: base.type
1006
1007 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[8]) + 8; // 8: type addr
1008 uintptr_t sp = 0;
1009 uintptr_t pc = 0;
1010 bool isJsFrame = true;
1011 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1012 ctx->count = -1;
1013 unwind_stack_frame_s cur_frame = { fp, pc };
1014 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1015
1016 EXPECT_TRUE(pre_frame.fp == frame[7]);
1017 EXPECT_TRUE(pre_frame.pc == frame[6]);
1018
1019 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1020 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1021 EXPECT_TRUE(*arkStepParam.fp == frame[7]);
1022 EXPECT_TRUE(*arkStepParam.pc == frame[6]);
1023 EXPECT_TRUE(ret == 1);
1024
1025 free(ctx);
1026 }
1027
HWTEST_F_L0(JsStackInfoTest,TestStepArk_012)1028 HWTEST_F_L0(JsStackInfoTest, TestStepArk_012)
1029 {
1030 size_t size = 9; // 9: size of ASM_INTERPRETER_FRAME
1031 JSTaggedType frame[size];
1032 frame[0] = JSTaggedValue::Hole().GetRawData(); // 0: function
1033 frame[1] = JSTaggedValue::Hole().GetRawData(); // 1: thisObj
1034 frame[2] = JSTaggedValue::Hole().GetRawData(); // 2: acc
1035 frame[3] = JSTaggedValue::Hole().GetRawData(); // 3: env
1036 frame[4] = JSTaggedValue::Hole().GetRawData(); // 4: callSize
1037 frame[5] = JSTaggedValue::Hole().GetRawData(); // 5: fp
1038 frame[6] = static_cast<JSTaggedType>(123456); // 6: pc
1039 frame[7] = static_cast<JSTaggedType>(62480); // 7: base.prevfp
1040 frame[8] = static_cast<JSTaggedType>(FrameType::ASM_INTERPRETER_FRAME); // 8: base.type
1041
1042 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[8]) + 8; // 8: type addr
1043 uintptr_t sp = 0;
1044 uintptr_t pc = 0;
1045 bool isJsFrame = true;
1046 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1047 ctx->count = -1;
1048 unwind_stack_frame_s cur_frame = { fp, pc };
1049 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1050
1051 EXPECT_TRUE(pre_frame.fp == frame[7]);
1052 EXPECT_TRUE(pre_frame.pc == frame[6]);
1053
1054 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1055 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1056 EXPECT_TRUE(*arkStepParam.fp == frame[7]);
1057 EXPECT_TRUE(*arkStepParam.pc == frame[6]);
1058 EXPECT_TRUE(ret == 1);
1059
1060 free(ctx);
1061 }
1062
HWTEST_F_L0(JsStackInfoTest,TestStepArk_013)1063 HWTEST_F_L0(JsStackInfoTest, TestStepArk_013)
1064 {
1065 size_t size = 9; // 9: size of INTERPRETER_CONSTRUCTOR_FRAME
1066 JSTaggedType frame[size];
1067 frame[0] = JSTaggedValue::Hole().GetRawData(); // 0: function
1068 frame[1] = JSTaggedValue::Hole().GetRawData(); // 1: thisObj
1069 frame[2] = JSTaggedValue::Hole().GetRawData(); // 2: acc
1070 frame[3] = JSTaggedValue::Hole().GetRawData(); // 3: env
1071 frame[4] = JSTaggedValue::Hole().GetRawData(); // 4: callSize
1072 frame[5] = JSTaggedValue::Hole().GetRawData(); // 5: fp
1073 frame[6] = static_cast<JSTaggedType>(123456); // 6: pc
1074 frame[7] = static_cast<JSTaggedType>(62480); // 7: base.prevfp
1075 frame[8] = static_cast<JSTaggedType>(FrameType::INTERPRETER_CONSTRUCTOR_FRAME); // 8: base.type
1076
1077 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[8]) + 8; // 8: type addr
1078 uintptr_t sp = 0;
1079 uintptr_t pc = 0;
1080 bool isJsFrame = true;
1081 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1082 ctx->count = -1;
1083 unwind_stack_frame_s cur_frame = { fp, pc };
1084 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1085
1086 EXPECT_TRUE(pre_frame.fp == frame[7]);
1087 EXPECT_TRUE(pre_frame.pc == frame[6]);
1088
1089 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1090 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1091 EXPECT_TRUE(*arkStepParam.fp == frame[7]);
1092 EXPECT_TRUE(*arkStepParam.pc == frame[6]);
1093 EXPECT_TRUE(ret == 1);
1094
1095 free(ctx);
1096 }
1097
1098
HWTEST_F_L0(JsStackInfoTest,TestStepArk_014)1099 HWTEST_F_L0(JsStackInfoTest, TestStepArk_014)
1100 {
1101 size_t size = 6; // 6: size of BUILTIN_FRAME
1102 JSTaggedType frame[size];
1103 frame[0] = static_cast<JSTaggedType>(FrameType::BUILTIN_FRAME); // 0: type
1104 frame[1] = static_cast<JSTaggedType>(62480); // 1: prevFp
1105 frame[2] = static_cast<JSTaggedType>(123456); // 2: returnAddr
1106 frame[3] = JSTaggedValue::Hole().GetRawData(); // 3: thread
1107 frame[4] = JSTaggedValue::Hole().GetRawData(); // 4: numArgs
1108 frame[5] = JSTaggedValue::Hole().GetRawData(); // 5: stackArgs
1109
1110 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
1111 uintptr_t sp = 0;
1112 uintptr_t pc = 0;
1113 bool isJsFrame = true;
1114 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1115 ctx->count = -1;
1116 unwind_stack_frame_s cur_frame = { fp, pc };
1117 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1118
1119 EXPECT_TRUE(pre_frame.fp == frame[1]);
1120 EXPECT_TRUE(pre_frame.pc == frame[2]);
1121
1122 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1123 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1124 EXPECT_TRUE(*arkStepParam.fp == frame[1]);
1125 EXPECT_TRUE(*arkStepParam.pc == frame[2]);
1126 EXPECT_TRUE(ret == 1);
1127
1128 free(ctx);
1129 }
1130
HWTEST_F_L0(JsStackInfoTest,TestStepArk_015)1131 HWTEST_F_L0(JsStackInfoTest, TestStepArk_015)
1132 {
1133 size_t size = 3; // 3: size of BUILTIN_FRAME_WITH_ARGV
1134 JSTaggedType frame[size];
1135 frame[0] = static_cast<JSTaggedType>(FrameType::BUILTIN_FRAME_WITH_ARGV); // 0: type
1136 frame[1] = static_cast<JSTaggedType>(62480); // 1: prevFp
1137 frame[2] = static_cast<JSTaggedType>(123456); // 2: returnAddr
1138
1139 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
1140 uintptr_t sp = 0;
1141 uintptr_t pc = 0;
1142 bool isJsFrame = true;
1143 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1144 ctx->count = -1;
1145 unwind_stack_frame_s cur_frame = { fp, pc };
1146 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1147
1148 EXPECT_TRUE(pre_frame.fp == frame[1]);
1149 EXPECT_TRUE(pre_frame.pc == frame[2]);
1150
1151 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1152 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1153 EXPECT_TRUE(*arkStepParam.fp == frame[1]);
1154 EXPECT_TRUE(*arkStepParam.pc == frame[2]);
1155 EXPECT_TRUE(ret == 1);
1156
1157 free(ctx);
1158 }
1159
HWTEST_F_L0(JsStackInfoTest,TestStepArk_016)1160 HWTEST_F_L0(JsStackInfoTest, TestStepArk_016)
1161 {
1162 size_t size = 3; // 3: size of BUILTIN_ENTRY_FRAME
1163 JSTaggedType frame[size];
1164 frame[0] = static_cast<JSTaggedType>(FrameType::BUILTIN_ENTRY_FRAME); // 0: type
1165 frame[1] = static_cast<JSTaggedType>(62480); // 1: prevFp
1166 frame[2] = static_cast<JSTaggedType>(123456); // 2: returnAddr
1167
1168 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
1169 uintptr_t sp = 0;
1170 uintptr_t pc = 0;
1171 bool isJsFrame = true;
1172 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1173 ctx->count = -1;
1174 unwind_stack_frame_s cur_frame = { fp, pc };
1175 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1176
1177 EXPECT_TRUE(pre_frame.fp == frame[1]);
1178 EXPECT_TRUE(pre_frame.pc == frame[2]);
1179
1180 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1181 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1182 EXPECT_TRUE(*arkStepParam.fp == frame[1]);
1183 EXPECT_TRUE(*arkStepParam.pc == frame[2]);
1184 EXPECT_TRUE(ret == 1);
1185
1186 free(ctx);
1187 }
1188
HWTEST_F_L0(JsStackInfoTest,TestStepArk_017)1189 HWTEST_F_L0(JsStackInfoTest, TestStepArk_017)
1190 {
1191 size_t size1 = 9; // 9: size of INTERPRETER_FRAME
1192 JSTaggedType frame1[size1];
1193 frame1[0] = JSTaggedValue::Hole().GetRawData(); // 0: constpool
1194 frame1[1] = JSTaggedValue::Hole().GetRawData(); // 1: function
1195 frame1[2] = JSTaggedValue::Hole().GetRawData(); // 2: thisObj
1196 frame1[3] = JSTaggedValue::Hole().GetRawData(); // 3: profileTypeInfo
1197 frame1[4] = JSTaggedValue::Hole().GetRawData(); // 4: acc
1198 frame1[5] = JSTaggedValue::Hole().GetRawData(); // 5: env
1199 frame1[6] = static_cast<JSTaggedType>(123456); // 6: pc
1200 frame1[7] = static_cast<JSTaggedType>(62480); // 7: base.prevfp
1201 frame1[8] = static_cast<JSTaggedType>(FrameType::INTERPRETER_FRAME); // 8: base.type
1202
1203 size_t size2 = 4; // 3: size of INTERPRETER_BUILTIN_FRAME
1204 JSTaggedType frame2[size2];
1205 frame2[0] = JSTaggedValue::Hole().GetRawData(); // 0: function
1206 frame2[1] = static_cast<JSTaggedType>(0); // 1: pc
1207 frame2[2] = static_cast<JSTaggedType>(reinterpret_cast<uintptr_t>(&frame1[8]) + 8); // 2: base.prevfp
1208 frame2[3] = static_cast<JSTaggedType>(FrameType::INTERPRETER_BUILTIN_FRAME); // 3: base.type
1209
1210 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame2[3]) + 8; // 3: type addr
1211 uintptr_t sp = 0;
1212 uintptr_t pc = 0;
1213 bool isJsFrame = true;
1214 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1215 ctx->count = -1;
1216 unwind_stack_frame_s cur_frame = { fp, pc };
1217 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1218
1219 EXPECT_TRUE(pre_frame.fp == frame1[7]);
1220 EXPECT_TRUE(pre_frame.pc == frame1[6]);
1221
1222 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1223 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1224 EXPECT_TRUE(*arkStepParam.fp == frame1[7]);
1225 EXPECT_TRUE(*arkStepParam.pc == frame1[6]);
1226 EXPECT_TRUE(ret == 1);
1227
1228 free(ctx);
1229 }
1230
HWTEST_F_L0(JsStackInfoTest,TestStepArk_018)1231 HWTEST_F_L0(JsStackInfoTest, TestStepArk_018)
1232 {
1233 size_t size1 = 9; // 9: size of INTERPRETER_FAST_NEW_FRAME
1234 JSTaggedType frame[size1];
1235 frame[0] = JSTaggedValue::Hole().GetRawData(); // 0: constpool
1236 frame[1] = JSTaggedValue::Hole().GetRawData(); // 1: function
1237 frame[2] = JSTaggedValue::Hole().GetRawData(); // 2: thisObj
1238 frame[3] = JSTaggedValue::Hole().GetRawData(); // 3: profileTypeInfo
1239 frame[4] = JSTaggedValue::Hole().GetRawData(); // 4: acc
1240 frame[5] = JSTaggedValue::Hole().GetRawData(); // 5: env
1241 frame[6] = static_cast<JSTaggedType>(123456); // 6: pc
1242 frame[7] = static_cast<JSTaggedType>(62480); // 7: base.prevfp
1243 frame[8] = static_cast<JSTaggedType>(FrameType::INTERPRETER_FAST_NEW_FRAME); // 8: base.type
1244
1245 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[8]) + 8; // 8: type addr
1246 uintptr_t sp = 0;
1247 uintptr_t pc = 0;
1248 bool isJsFrame = true;
1249 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1250 ctx->count = -1;
1251 unwind_stack_frame_s cur_frame = { fp, pc };
1252 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1253
1254 EXPECT_TRUE(pre_frame.fp == frame[7]);
1255 EXPECT_TRUE(pre_frame.pc == frame[6]);
1256
1257 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1258 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1259 EXPECT_TRUE(*arkStepParam.fp == frame[7]);
1260 EXPECT_TRUE(*arkStepParam.pc == frame[6]);
1261 EXPECT_TRUE(ret == 1);
1262
1263 free(ctx);
1264 }
1265
HWTEST_F_L0(JsStackInfoTest,TestStepArk_019)1266 HWTEST_F_L0(JsStackInfoTest, TestStepArk_019)
1267 {
1268 size_t size1 = 9; // 9: size of INTERPRETER_FRAME
1269 JSTaggedType frame1[size1];
1270 frame1[0] = JSTaggedValue::Hole().GetRawData(); // 0: constpool
1271 frame1[1] = JSTaggedValue::Hole().GetRawData(); // 1: function
1272 frame1[2] = JSTaggedValue::Hole().GetRawData(); // 2: thisObj
1273 frame1[3] = JSTaggedValue::Hole().GetRawData(); // 3: profileTypeInfo
1274 frame1[4] = JSTaggedValue::Hole().GetRawData(); // 4: acc
1275 frame1[5] = JSTaggedValue::Hole().GetRawData(); // 5: env
1276 frame1[6] = static_cast<JSTaggedType>(123456); // 6: pc
1277 frame1[7] = static_cast<JSTaggedType>(62480); // 7: base.prevfp
1278 frame1[8] = static_cast<JSTaggedType>(FrameType::INTERPRETER_FRAME); // 8: base.type
1279
1280 size_t size2 = 3; // 3: size of INTERPRETER_ENTRY_FRAME
1281 JSTaggedType frame2[size2];
1282 frame2[0] = static_cast<JSTaggedType>(0); // 0: pc
1283 frame2[1] = static_cast<JSTaggedType>(reinterpret_cast<uintptr_t>(&frame1[8]) + 8); // 1: base.prevfp
1284 frame2[2] = static_cast<JSTaggedType>(FrameType::INTERPRETER_BUILTIN_FRAME); // 2: base.type
1285
1286 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame2[2]) + 8; // 3: type addr
1287 uintptr_t sp = 0;
1288 uintptr_t pc = 0;
1289 bool isJsFrame = true;
1290 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1291 ctx->count = -1;
1292 unwind_stack_frame_s cur_frame = { fp, pc };
1293 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1294
1295 EXPECT_TRUE(pre_frame.fp == frame1[7]);
1296 EXPECT_TRUE(pre_frame.pc == frame1[6]);
1297
1298 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1299 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1300 EXPECT_TRUE(*arkStepParam.fp == frame1[7]);
1301 EXPECT_TRUE(*arkStepParam.pc == frame1[6]);
1302 EXPECT_TRUE(ret == 1);
1303
1304 free(ctx);
1305 }
1306
HWTEST_F_L0(JsStackInfoTest,TestStepArk_020)1307 HWTEST_F_L0(JsStackInfoTest, TestStepArk_020)
1308 {
1309 size_t size = 5; // 5: size of ASM_INTERPRETER_ENTRY_FRAME + prevfp + returnaddr
1310 JSTaggedType frame[size];
1311 frame[0] = static_cast<JSTaggedType>(0); // 0: pc
1312 frame[1] = static_cast<JSTaggedType>(reinterpret_cast<uintptr_t>(&frame[8]) + 8); // 1: base.prevfp
1313 frame[2] = static_cast<JSTaggedType>(FrameType::ASM_INTERPRETER_ENTRY_FRAME); // 2: base.type
1314 frame[3] = static_cast<JSTaggedType>(62480); // 3: prev fp
1315 frame[4] = static_cast<JSTaggedType>(123456); // 4: returnaddr
1316
1317 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[2]) + 8; // 8: type addr
1318 uintptr_t sp = 0;
1319 uintptr_t pc = 0;
1320 bool isJsFrame = true;
1321 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1322 ctx->count = -1;
1323 unwind_stack_frame_s cur_frame = { fp, pc };
1324 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1325
1326 EXPECT_TRUE(pre_frame.fp == frame[3]);
1327 EXPECT_TRUE(pre_frame.pc == frame[4]);
1328
1329 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1330 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1331 EXPECT_TRUE(*arkStepParam.fp == frame[3]);
1332 EXPECT_TRUE(*arkStepParam.pc == frame[4]);
1333 EXPECT_TRUE(ret == 1);
1334
1335 free(ctx);
1336 }
1337
HWTEST_F_L0(JsStackInfoTest,TestStepArk_021)1338 HWTEST_F_L0(JsStackInfoTest, TestStepArk_021)
1339 {
1340 size_t size = 5; // 5: size of ASM_INTERPRETER_BRIDGE_FRAME
1341 JSTaggedType frame[size];
1342 frame[0] = static_cast<JSTaggedType>(0); // 0: pc
1343 frame[1] = static_cast<JSTaggedType>(62480); // 1: base.prevfp
1344 frame[2] = static_cast<JSTaggedType>(FrameType::ASM_INTERPRETER_BRIDGE_FRAME); // 2: base.type
1345 frame[3] = static_cast<JSTaggedType>(123456); // 3: returnaddr
1346
1347 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[2]) + 8; // 8: type addr
1348 uintptr_t sp = 0;
1349 uintptr_t pc = 0;
1350 bool isJsFrame = true;
1351 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1352 ctx->count = -1;
1353 unwind_stack_frame_s cur_frame = { fp, pc };
1354 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1355
1356 EXPECT_TRUE(pre_frame.fp == frame[1]);
1357 EXPECT_TRUE(pre_frame.pc == frame[3]);
1358
1359 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1360 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1361 EXPECT_TRUE(*arkStepParam.fp == frame[1]);
1362 EXPECT_TRUE(*arkStepParam.pc == frame[3]);
1363 EXPECT_TRUE(ret == 1);
1364
1365 free(ctx);
1366 }
1367
HWTEST_F_L0(JsStackInfoTest,TestStepArk_022)1368 HWTEST_F_L0(JsStackInfoTest, TestStepArk_022)
1369 {
1370 size_t size = 4; // 4: size of OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME
1371 JSTaggedType frame[size];
1372 frame[0] = JSTaggedValue::Undefined().GetRawData(); // 0: function
1373 frame[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME); // 1: type
1374 frame[2] = static_cast<JSTaggedType>(62480); // 2: prevfp
1375 frame[3] = static_cast<JSTaggedType>(123456); // 3: returnaddr
1376
1377 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[1]) + 8; // 8: type addr
1378 uintptr_t sp = 0;
1379 uintptr_t pc = 0;
1380 bool isJsFrame = true;
1381 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1382 ctx->count = -1;
1383 unwind_stack_frame_s cur_frame = { fp, pc };
1384 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1385
1386 EXPECT_TRUE(pre_frame.fp == frame[2]);
1387 EXPECT_TRUE(pre_frame.pc == frame[3]);
1388
1389 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1390 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1391 EXPECT_TRUE(*arkStepParam.fp == frame[2]);
1392 EXPECT_TRUE(*arkStepParam.pc == frame[3]);
1393 EXPECT_TRUE(ret == 1);
1394
1395 free(ctx);
1396 }
1397
HWTEST_F_L0(JsStackInfoTest,TestStepArk_023)1398 HWTEST_F_L0(JsStackInfoTest, TestStepArk_023)
1399 {
1400 size_t size = 4; // 4: size of OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME
1401 JSTaggedType frame[size];
1402 frame[0] = JSTaggedValue::Undefined().GetRawData(); // 0: CallSiteSp
1403 frame[1] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME); // 1: type
1404 frame[2] = static_cast<JSTaggedType>(62480); // 2: prevfp
1405 frame[3] = static_cast<JSTaggedType>(123456); // 3: returnaddr
1406
1407 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[1]) + 8; // 8: type addr
1408 uintptr_t sp = 0;
1409 uintptr_t pc = 0;
1410 bool isJsFrame = true;
1411 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1412 ctx->count = -1;
1413 unwind_stack_frame_s cur_frame = { fp, pc };
1414 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1415
1416 EXPECT_TRUE(pre_frame.fp == frame[2]);
1417 EXPECT_TRUE(pre_frame.pc == frame[3]);
1418
1419 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1420 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1421 EXPECT_TRUE(*arkStepParam.fp == frame[2]);
1422 EXPECT_TRUE(*arkStepParam.pc == frame[3]);
1423 EXPECT_TRUE(ret == 1);
1424
1425 free(ctx);
1426 }
1427
HWTEST_F_L0(JsStackInfoTest,TestStepArk_024)1428 HWTEST_F_L0(JsStackInfoTest, TestStepArk_024)
1429 {
1430 size_t size = 3; // 3: size of BUILTIN_FRAME_WITH_ARGV
1431 JSTaggedType frame[size];
1432 frame[0] = static_cast<JSTaggedType>(FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME); // 0: type
1433 frame[1] = static_cast<JSTaggedType>(62480); // 1: prevFp
1434 frame[2] = static_cast<JSTaggedType>(123456); // 2: returnAddr
1435
1436 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
1437 uintptr_t sp = 0;
1438 uintptr_t pc = 0;
1439 bool isJsFrame = true;
1440 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1441 ctx->count = -1;
1442 unwind_stack_frame_s cur_frame = { fp, pc };
1443 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1444
1445 EXPECT_TRUE(pre_frame.fp == frame[1]);
1446 EXPECT_TRUE(pre_frame.pc == frame[2]);
1447
1448 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1449 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1450 EXPECT_TRUE(*arkStepParam.fp == frame[1]);
1451 EXPECT_TRUE(*arkStepParam.pc == frame[2]);
1452 EXPECT_TRUE(ret == 1);
1453
1454 free(ctx);
1455 }
1456
HWTEST_F_L0(JsStackInfoTest,TestStepArk_025)1457 HWTEST_F_L0(JsStackInfoTest, TestStepArk_025)
1458 {
1459 size_t size = 3; // 3: size of BASELINE_BUILTIN_FRAME
1460 JSTaggedType frame[size];
1461 frame[0] = static_cast<JSTaggedType>(FrameType::BASELINE_BUILTIN_FRAME); // 0: type
1462 frame[1] = static_cast<JSTaggedType>(62480); // 1: prevFp
1463 frame[2] = static_cast<JSTaggedType>(123456); // 2: returnAddr
1464
1465 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
1466 uintptr_t sp = 0;
1467 uintptr_t pc = 0;
1468 bool isJsFrame = true;
1469 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1470 ctx->count = -1;
1471 unwind_stack_frame_s cur_frame = { fp, pc };
1472 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1473
1474 EXPECT_TRUE(pre_frame.fp == frame[1]);
1475 EXPECT_TRUE(pre_frame.pc == frame[2]);
1476
1477 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1478 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1479 EXPECT_TRUE(*arkStepParam.fp == frame[1]);
1480 EXPECT_TRUE(*arkStepParam.pc == frame[2]);
1481 EXPECT_TRUE(ret == 1);
1482 }
1483
HWTEST_F_L0(JsStackInfoTest,TestStepArk_026)1484 HWTEST_F_L0(JsStackInfoTest, TestStepArk_026)
1485 {
1486 size_t size = 1; // 1: unknown tpye
1487 JSTaggedType frame[size];
1488 frame[0] = static_cast<JSTaggedType>(FrameType::BASELINE_BUILTIN_FRAME) + 1; // 0: type
1489
1490 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
1491 uintptr_t sp = 0;
1492 uintptr_t pc = 0;
1493 bool isJsFrame = true;
1494 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1495 ctx->count = -1;
1496 unwind_stack_frame_s cur_frame = { fp, pc };
1497 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1498
1499 EXPECT_TRUE(pre_frame.fp == 0);
1500 EXPECT_TRUE(pre_frame.pc == 0);
1501
1502 ArkStepParam arkStepParam{ &fp, &sp, &pc, &isJsFrame };
1503 int ret = step_ark(ctx, ReadMemFunc, &arkStepParam);
1504 EXPECT_TRUE(ret == -1);
1505
1506 free(ctx);
1507 }
1508
HWTEST_F_L0(JsStackInfoTest,TestStepArk_027)1509 HWTEST_F_L0(JsStackInfoTest, TestStepArk_027)
1510 {
1511 unsigned int type = static_cast<unsigned int>(arkts_frame_type::FRAME_TYPE_MAX) + 1;
1512 bool ret = is_entry_frame(type);
1513 EXPECT_TRUE(ret == false);
1514 ret = is_js_function_frame(type);
1515 EXPECT_TRUE(ret == false);
1516 ret = is_native_function_frame(type);
1517 EXPECT_TRUE(ret == false);
1518 }
1519
HWTEST_F_L0(JsStackInfoTest,TestUnwindArkts_001)1520 HWTEST_F_L0(JsStackInfoTest, TestUnwindArkts_001)
1521 {
1522 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1523 unwind_stack_frame_s cur_frame = UNWIND_FRAME_EMPTY;
1524
1525 auto pre_frame = unwind_arkts(nullptr, &cur_frame);
1526 EXPECT_TRUE(pre_frame.fp == 0);
1527 EXPECT_TRUE(pre_frame.pc == 0);
1528 pre_frame = unwind_arkts(ctx, nullptr);
1529 EXPECT_TRUE(pre_frame.fp == 0);
1530 EXPECT_TRUE(pre_frame.pc == 0);
1531
1532 free(ctx);
1533 }
1534
HWTEST_F_L0(JsStackInfoTest,TestUnwindArkts_002)1535 HWTEST_F_L0(JsStackInfoTest, TestUnwindArkts_002)
1536 {
1537 size_t size = 3; // 3: size of OPTIMIZED_FRAME
1538 JSTaggedType frame[size];
1539 frame[0] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_FRAME); // 0: type
1540 frame[1] = static_cast<JSTaggedType>(62480); // 1: prevFp
1541 frame[2] = static_cast<JSTaggedType>(123456); // 2: returnAddr
1542
1543 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
1544
1545 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1546 ctx->count = 0;
1547 unwind_stack_frame_s cur_frame = { fp, 0 };
1548 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1549 EXPECT_TRUE(pre_frame.fp == 0);
1550 EXPECT_TRUE(pre_frame.pc == 0);
1551
1552 free(ctx);
1553 }
1554
HWTEST_F_L0(JsStackInfoTest,TestUnwindArkts_003)1555 HWTEST_F_L0(JsStackInfoTest, TestUnwindArkts_003)
1556 {
1557 size_t size = 3; // 3: size of OPTIMIZED_FRAME
1558 JSTaggedType frame[size];
1559 frame[0] = static_cast<JSTaggedType>(FrameType::OPTIMIZED_FRAME); // 0: type
1560 frame[1] = static_cast<JSTaggedType>(62480); // 1: prevFp
1561 frame[2] = static_cast<JSTaggedType>(123456); // 2: returnAddr
1562
1563 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[0]) + 8; // 0: type addr
1564
1565 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1566 ctx->count = 1;
1567 unwind_stack_frame_s cur_frame = { fp, 0 };
1568 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1569 EXPECT_TRUE(pre_frame.fp == 0);
1570 EXPECT_TRUE(pre_frame.pc == 0);
1571
1572 free(ctx);
1573 }
1574
HWTEST_F_L0(JsStackInfoTest,TestUnwindArkts_004)1575 HWTEST_F_L0(JsStackInfoTest, TestUnwindArkts_004)
1576 {
1577 size_t size = 5; // 4: size of FASTJIT_FUNCTION_FRAME
1578 JSTaggedType frame[size];
1579 frame[0] = static_cast<JSTaggedType>(1234); // 0: pc
1580 frame[1] = JSTaggedValue::Hole().GetRawData(); // 1: JSFunction
1581 frame[2] = static_cast<JSTaggedType>(FrameType::FASTJIT_FUNCTION_FRAME); // 2: type
1582 frame[3] = static_cast<JSTaggedType>(62480); // 3: prevFp
1583 frame[4] = static_cast<JSTaggedType>(0); // 4: returnAddr
1584
1585 uintptr_t fp = reinterpret_cast<uintptr_t>(&frame[2]) + 8; // 0: type addr
1586 uintptr_t pc = 0;
1587 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1588 ctx->count = 2;
1589 unwind_stack_frame_s cur_frame = { fp, pc };
1590 auto pre_frame = unwind_arkts(ctx, &cur_frame);
1591
1592 EXPECT_TRUE(pre_frame.fp == 0);
1593 EXPECT_TRUE(pre_frame.pc == 0);
1594 }
1595
HWTEST_F_L0(JsStackInfoTest,TestNextArkFrame)1596 HWTEST_F_L0(JsStackInfoTest, TestNextArkFrame)
1597 {
1598 unwind_user_context_s *ctx = (unwind_user_context_s*)malloc(sizeof(unwind_user_context_s));
1599 ctx->count = 0;
1600 uintptr_t fp = 0;
1601 unsigned int type = 0;
1602 unwind_stack_frame_s frame = UNWIND_FRAME_EMPTY;
1603 bool retFrameAvail = false;
1604 int ret = next_ark_frame(ctx, fp, type, &frame, &retFrameAvail);
1605 EXPECT_TRUE(ret == -1);
1606
1607 free(ctx);
1608 }
1609 #endif
1610 } // namespace panda::test