14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include <cstdio> 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ci#include "assembler/assembly-emitter.h" 194514f5e3Sopenharmony_ci#include "assembler/assembly-parser.h" 204514f5e3Sopenharmony_ci#include "libpandafile/class_data_accessor-inl.h" 214514f5e3Sopenharmony_ci#include "libziparchive/zip_archive.h" 224514f5e3Sopenharmony_ci#include "ecmascript/dfx/stackinfo/js_stackinfo.h" 234514f5e3Sopenharmony_ci#include "ecmascript/tests/test_helper.h" 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_ciusing namespace panda::ecmascript; 264514f5e3Sopenharmony_ci 274514f5e3Sopenharmony_cinamespace panda::test { 284514f5e3Sopenharmony_ciclass JsStackInfoTest : public testing::Test { 294514f5e3Sopenharmony_cipublic: 304514f5e3Sopenharmony_ci static void SetUpTestCase() 314514f5e3Sopenharmony_ci { 324514f5e3Sopenharmony_ci GTEST_LOG_(INFO) << "SetUpTestCase"; 334514f5e3Sopenharmony_ci } 344514f5e3Sopenharmony_ci 354514f5e3Sopenharmony_ci static void TearDownTestCase() 364514f5e3Sopenharmony_ci { 374514f5e3Sopenharmony_ci GTEST_LOG_(INFO) << "TearDownCase"; 384514f5e3Sopenharmony_ci } 394514f5e3Sopenharmony_ci 404514f5e3Sopenharmony_ci void SetUp() override 414514f5e3Sopenharmony_ci { 424514f5e3Sopenharmony_ci TestHelper::CreateEcmaVMWithScope(instance, thread, scope); 434514f5e3Sopenharmony_ci instance->SetEnableForceGC(false); 444514f5e3Sopenharmony_ci } 454514f5e3Sopenharmony_ci 464514f5e3Sopenharmony_ci void TearDown() override 474514f5e3Sopenharmony_ci { 484514f5e3Sopenharmony_ci TestHelper::DestroyEcmaVMWithScope(instance, scope); 494514f5e3Sopenharmony_ci } 504514f5e3Sopenharmony_ci 514514f5e3Sopenharmony_ci EcmaVM *instance {nullptr}; 524514f5e3Sopenharmony_ci EcmaHandleScope *scope {nullptr}; 534514f5e3Sopenharmony_ci JSThread *thread {nullptr}; 544514f5e3Sopenharmony_ci}; 554514f5e3Sopenharmony_ci 564514f5e3Sopenharmony_ciuintptr_t ToUintPtr(FrameType frame) 574514f5e3Sopenharmony_ci{ 584514f5e3Sopenharmony_ci return static_cast<uintptr_t>(frame); 594514f5e3Sopenharmony_ci} 604514f5e3Sopenharmony_ci 614514f5e3Sopenharmony_cibool ReadMemFunc([[maybe_unused]] void *ctx, uintptr_t addr, uintptr_t *value) 624514f5e3Sopenharmony_ci{ 634514f5e3Sopenharmony_ci *value = *(reinterpret_cast<uintptr_t *>(addr)); 644514f5e3Sopenharmony_ci return true; 654514f5e3Sopenharmony_ci} 664514f5e3Sopenharmony_ci 674514f5e3Sopenharmony_ci/** 684514f5e3Sopenharmony_ci * @tc.name: ArkFrameCheck 694514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "ArkFrameCheck" function is within expectations. 704514f5e3Sopenharmony_ci * @tc.type: FUNC 714514f5e3Sopenharmony_ci * @tc.require: 724514f5e3Sopenharmony_ci */ 734514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestArkFrameCheck) 744514f5e3Sopenharmony_ci{ 754514f5e3Sopenharmony_ci for (uintptr_t i = 0; i < 25; i++) { 764514f5e3Sopenharmony_ci bool ret = ArkFrameCheck(i); 774514f5e3Sopenharmony_ci if (i == ToUintPtr(FrameType::OPTIMIZED_ENTRY_FRAME) || 784514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::ASM_INTERPRETER_ENTRY_FRAME)) { 794514f5e3Sopenharmony_ci EXPECT_TRUE(ret == true); 804514f5e3Sopenharmony_ci } else { 814514f5e3Sopenharmony_ci EXPECT_TRUE(ret == false); 824514f5e3Sopenharmony_ci } 834514f5e3Sopenharmony_ci } 844514f5e3Sopenharmony_ci} 854514f5e3Sopenharmony_ci 864514f5e3Sopenharmony_ci/** 874514f5e3Sopenharmony_ci * @tc.name: IsJsFunctionFrame 884514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "IsJsFunctionFrame" function is within expectations. 894514f5e3Sopenharmony_ci * @tc.type: FUNC 904514f5e3Sopenharmony_ci * @tc.require: 914514f5e3Sopenharmony_ci */ 924514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestIsJsFunctionFrame) 934514f5e3Sopenharmony_ci{ 944514f5e3Sopenharmony_ci for (uintptr_t i = 0; i < 25; i++) { 954514f5e3Sopenharmony_ci bool ret = IsJsFunctionFrame(i); 964514f5e3Sopenharmony_ci if (i == ToUintPtr(FrameType::ASM_INTERPRETER_FRAME) || 974514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::INTERPRETER_CONSTRUCTOR_FRAME) || 984514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::INTERPRETER_FRAME) || 994514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::INTERPRETER_FAST_NEW_FRAME)) { 1004514f5e3Sopenharmony_ci EXPECT_TRUE(ret == true); 1014514f5e3Sopenharmony_ci } else { 1024514f5e3Sopenharmony_ci EXPECT_TRUE(ret == false); 1034514f5e3Sopenharmony_ci } 1044514f5e3Sopenharmony_ci } 1054514f5e3Sopenharmony_ci} 1064514f5e3Sopenharmony_ci 1074514f5e3Sopenharmony_ci/** 1084514f5e3Sopenharmony_ci * @tc.name: IsFastJitFunctionFrame 1094514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "IsFastJitFunctionFrame" function is within expectations. 1104514f5e3Sopenharmony_ci * @tc.type: FUNC 1114514f5e3Sopenharmony_ci * @tc.require: 1124514f5e3Sopenharmony_ci */ 1134514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestIsFastJitFunctionFrame) 1144514f5e3Sopenharmony_ci{ 1154514f5e3Sopenharmony_ci for (uintptr_t i = 0; i < 25; i++) { 1164514f5e3Sopenharmony_ci bool ret = IsFastJitFunctionFrame(i); 1174514f5e3Sopenharmony_ci if (i == ToUintPtr(FrameType::FASTJIT_FUNCTION_FRAME) || 1184514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME)) { 1194514f5e3Sopenharmony_ci EXPECT_TRUE(ret == true); 1204514f5e3Sopenharmony_ci } else { 1214514f5e3Sopenharmony_ci EXPECT_TRUE(ret == false); 1224514f5e3Sopenharmony_ci } 1234514f5e3Sopenharmony_ci } 1244514f5e3Sopenharmony_ci} 1254514f5e3Sopenharmony_ci 1264514f5e3Sopenharmony_ci/** 1274514f5e3Sopenharmony_ci * @tc.name: IsNativeFunctionFrame 1284514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "IsNativeFunctionFrame" function is within expectations. 1294514f5e3Sopenharmony_ci * @tc.type: FUNC 1304514f5e3Sopenharmony_ci * @tc.require: 1314514f5e3Sopenharmony_ci */ 1324514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestIsNativeFunctionFrame) 1334514f5e3Sopenharmony_ci{ 1344514f5e3Sopenharmony_ci for (uintptr_t i = 0; i < 25; i++) { 1354514f5e3Sopenharmony_ci bool ret = IsNativeFunctionFrame(i); 1364514f5e3Sopenharmony_ci if (i == ToUintPtr(FrameType::OPTIMIZED_FRAME) || 1374514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::BASELINE_BUILTIN_FRAME) || 1384514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::ASM_BRIDGE_FRAME) || 1394514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME) || 1404514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME) || 1414514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME) || 1424514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_FRAME) || 1434514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::LEAVE_FRAME) || 1444514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::LEAVE_FRAME_WITH_ARGV) || 1454514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::BUILTIN_CALL_LEAVE_FRAME) || 1464514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::BUILTIN_FRAME) || 1474514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::BUILTIN_ENTRY_FRAME) || 1484514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::BUILTIN_FRAME_WITH_ARGV) || 1494514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME) || 1504514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::ASM_INTERPRETER_BRIDGE_FRAME)) { 1514514f5e3Sopenharmony_ci EXPECT_TRUE(ret == true); 1524514f5e3Sopenharmony_ci } else { 1534514f5e3Sopenharmony_ci EXPECT_TRUE(ret == false); 1544514f5e3Sopenharmony_ci } 1554514f5e3Sopenharmony_ci } 1564514f5e3Sopenharmony_ci} 1574514f5e3Sopenharmony_ci 1584514f5e3Sopenharmony_ci/** 1594514f5e3Sopenharmony_ci * @tc.name: IsAotFunctionFrame 1604514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "IsAotFunctionFrame" function is within expectations. 1614514f5e3Sopenharmony_ci * @tc.type: FUNC 1624514f5e3Sopenharmony_ci * @tc.require: 1634514f5e3Sopenharmony_ci */ 1644514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestIsAotFunctionFrame) 1654514f5e3Sopenharmony_ci{ 1664514f5e3Sopenharmony_ci for (uintptr_t i = 0; i < 25; i++) { 1674514f5e3Sopenharmony_ci bool ret = IsAotFunctionFrame(i); 1684514f5e3Sopenharmony_ci if (i == ToUintPtr(FrameType::OPTIMIZED_JS_FUNCTION_FRAME) || 1694514f5e3Sopenharmony_ci i == ToUintPtr(FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME)) { 1704514f5e3Sopenharmony_ci EXPECT_TRUE(ret == true); 1714514f5e3Sopenharmony_ci } else { 1724514f5e3Sopenharmony_ci EXPECT_TRUE(ret == false); 1734514f5e3Sopenharmony_ci } 1744514f5e3Sopenharmony_ci } 1754514f5e3Sopenharmony_ci} 1764514f5e3Sopenharmony_ci 1774514f5e3Sopenharmony_ci/** 1784514f5e3Sopenharmony_ci * @tc.name: ReadMethodInfo 1794514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "ReadMethodInfo" function is within expectations. 1804514f5e3Sopenharmony_ci * @tc.type: FUNC 1814514f5e3Sopenharmony_ci * @tc.require: 1824514f5e3Sopenharmony_ci */ 1834514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestReadMethodInfo) 1844514f5e3Sopenharmony_ci{ 1854514f5e3Sopenharmony_ci const char *filename = "__JSPandaFileManagerTest1.pa"; 1864514f5e3Sopenharmony_ci const char *data = R"( 1874514f5e3Sopenharmony_ci .function void foo() { 1884514f5e3Sopenharmony_ci return 1894514f5e3Sopenharmony_ci } 1904514f5e3Sopenharmony_ci )"; 1914514f5e3Sopenharmony_ci pandasm::Parser parser; 1924514f5e3Sopenharmony_ci auto res = parser.Parse(data); 1934514f5e3Sopenharmony_ci auto file = pandasm::AsmEmitter::Emit(res.Value()); 1944514f5e3Sopenharmony_ci auto jsPandaFile = std::make_shared<JSPandaFile>(file.release(), CString(filename)); 1954514f5e3Sopenharmony_ci EXPECT_TRUE(jsPandaFile != nullptr); 1964514f5e3Sopenharmony_ci CVector<MethodInfo> result; 1974514f5e3Sopenharmony_ci const panda_file::File *pf = jsPandaFile->GetPandaFile(); 1984514f5e3Sopenharmony_ci Span<const uint32_t> classIndexes = jsPandaFile->GetClasses(); 1994514f5e3Sopenharmony_ci for (const uint32_t index : classIndexes) { 2004514f5e3Sopenharmony_ci panda_file::File::EntityId classId(index); 2014514f5e3Sopenharmony_ci if (jsPandaFile->IsExternal(classId)) { 2024514f5e3Sopenharmony_ci continue; 2034514f5e3Sopenharmony_ci } 2044514f5e3Sopenharmony_ci panda_file::ClassDataAccessor cda(*pf, classId); 2054514f5e3Sopenharmony_ci cda.EnumerateMethods([&result, jsPandaFile](panda_file::MethodDataAccessor &mda) { 2064514f5e3Sopenharmony_ci auto info = JSStackTrace::ReadMethodInfo(mda); 2074514f5e3Sopenharmony_ci if (!info) { 2084514f5e3Sopenharmony_ci return; 2094514f5e3Sopenharmony_ci } 2104514f5e3Sopenharmony_ci result.push_back(info.value()); 2114514f5e3Sopenharmony_ci }); 2124514f5e3Sopenharmony_ci } 2134514f5e3Sopenharmony_ci EXPECT_TRUE(result.size() > 0); 2144514f5e3Sopenharmony_ci} 2154514f5e3Sopenharmony_ci 2164514f5e3Sopenharmony_ci/** 2174514f5e3Sopenharmony_ci * @tc.name: ReadAllMethodInfos 2184514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "ReadAllMethodInfos" function is within expectations. 2194514f5e3Sopenharmony_ci * @tc.type: FUNC 2204514f5e3Sopenharmony_ci * @tc.require: 2214514f5e3Sopenharmony_ci */ 2224514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestReadAllMethodInfos) 2234514f5e3Sopenharmony_ci{ 2244514f5e3Sopenharmony_ci const char *filename = "__JsStackInfoTest.pa"; 2254514f5e3Sopenharmony_ci const char *data = R"( 2264514f5e3Sopenharmony_ci .function void foo() { 2274514f5e3Sopenharmony_ci return 2284514f5e3Sopenharmony_ci } 2294514f5e3Sopenharmony_ci )"; 2304514f5e3Sopenharmony_ci pandasm::Parser parser; 2314514f5e3Sopenharmony_ci auto res = parser.Parse(data); 2324514f5e3Sopenharmony_ci auto file = pandasm::AsmEmitter::Emit(res.Value()); 2334514f5e3Sopenharmony_ci auto pf = std::make_shared<JSPandaFile>(file.release(), CString(filename)); 2344514f5e3Sopenharmony_ci EXPECT_TRUE(pf != nullptr); 2354514f5e3Sopenharmony_ci auto methods = JSStackTrace::ReadAllMethodInfos(pf); 2364514f5e3Sopenharmony_ci EXPECT_TRUE(methods.size() > 0); 2374514f5e3Sopenharmony_ci pf = nullptr; 2384514f5e3Sopenharmony_ci methods = JSStackTrace::ReadAllMethodInfos(pf); 2394514f5e3Sopenharmony_ci EXPECT_TRUE(methods.size() == 0); 2404514f5e3Sopenharmony_ci} 2414514f5e3Sopenharmony_ci 2424514f5e3Sopenharmony_ci/** 2434514f5e3Sopenharmony_ci * @tc.name: TranslateByteCodePc 2444514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "TranslateByteCodePc" function is within expectations. 2454514f5e3Sopenharmony_ci * @tc.type: FUNC 2464514f5e3Sopenharmony_ci * @tc.require: 2474514f5e3Sopenharmony_ci */ 2484514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestTranslateByteCodePc) 2494514f5e3Sopenharmony_ci{ 2504514f5e3Sopenharmony_ci CVector<MethodInfo> vec = { 2514514f5e3Sopenharmony_ci {0, 0, 24}, 2524514f5e3Sopenharmony_ci {1, 24, 30}, 2534514f5e3Sopenharmony_ci {2, 54, 56}, 2544514f5e3Sopenharmony_ci {3, 110, 60} 2554514f5e3Sopenharmony_ci }; 2564514f5e3Sopenharmony_ci uintptr_t realPc = 115; 2574514f5e3Sopenharmony_ci 2584514f5e3Sopenharmony_ci auto ret = JSStackTrace::TranslateByteCodePc(realPc, vec); 2594514f5e3Sopenharmony_ci EXPECT_TRUE(ret != std::nullopt); 2604514f5e3Sopenharmony_ci 2614514f5e3Sopenharmony_ci vec.clear(); 2624514f5e3Sopenharmony_ci ret = JSStackTrace::TranslateByteCodePc(realPc, vec); 2634514f5e3Sopenharmony_ci EXPECT_TRUE(ret == std::nullopt); 2644514f5e3Sopenharmony_ci 2654514f5e3Sopenharmony_ci vec.push_back({2, 54, 56}); 2664514f5e3Sopenharmony_ci ret = JSStackTrace::TranslateByteCodePc(realPc, vec); 2674514f5e3Sopenharmony_ci EXPECT_TRUE(ret == std::nullopt); 2684514f5e3Sopenharmony_ci} 2694514f5e3Sopenharmony_ci 2704514f5e3Sopenharmony_ci/** 2714514f5e3Sopenharmony_ci * @tc.name: ParseJsFrameInfo 2724514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "ParseJsFrameInfo" function is within expectations. 2734514f5e3Sopenharmony_ci * @tc.type: FUNC 2744514f5e3Sopenharmony_ci * @tc.require: 2754514f5e3Sopenharmony_ci */ 2764514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestParseJsFrameInfo) 2774514f5e3Sopenharmony_ci{ 2784514f5e3Sopenharmony_ci const char *filename = "__JsStackInfoTest.pa"; 2794514f5e3Sopenharmony_ci const char *data = R"( 2804514f5e3Sopenharmony_ci .function void foo() { 2814514f5e3Sopenharmony_ci return 2824514f5e3Sopenharmony_ci } 2834514f5e3Sopenharmony_ci )"; 2844514f5e3Sopenharmony_ci pandasm::Parser parser; 2854514f5e3Sopenharmony_ci auto res = parser.Parse(data); 2864514f5e3Sopenharmony_ci auto file = pandasm::AsmEmitter::Emit(res.Value()); 2874514f5e3Sopenharmony_ci auto jsPandaFile = std::make_shared<JSPandaFile>(file.release(), CString(filename)); 2884514f5e3Sopenharmony_ci EXPECT_TRUE(jsPandaFile != nullptr); 2894514f5e3Sopenharmony_ci auto debugExtractor = std::make_unique<DebugInfoExtractor>(jsPandaFile.get()); 2904514f5e3Sopenharmony_ci auto methods = JSStackTrace::ReadAllMethodInfos(jsPandaFile); 2914514f5e3Sopenharmony_ci uintptr_t offset = 0; 2924514f5e3Sopenharmony_ci JsFunction jsFunction; 2934514f5e3Sopenharmony_ci ParseJsFrameInfo(jsPandaFile.get(), debugExtractor.get(), EntityId(methods[0].methodId), offset, jsFunction); 2944514f5e3Sopenharmony_ci EXPECT_TRUE(std::string(jsFunction.functionName) == "foo"); 2954514f5e3Sopenharmony_ci} 2964514f5e3Sopenharmony_ci 2974514f5e3Sopenharmony_ci/** 2984514f5e3Sopenharmony_ci * @tc.name: ArkParseJsFrameInfo 2994514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "ArkCreateJSSymbolExtractor" function is within expectations; 3004514f5e3Sopenharmony_ci * Check whether the result returned through "ArkParseJsFrameInfo" function is within expectations; 3014514f5e3Sopenharmony_ci * Check whether the result returned through "ArkDestoryJSSymbolExtractor" function is within expectations. 3024514f5e3Sopenharmony_ci * @tc.type: FUNC 3034514f5e3Sopenharmony_ci * @tc.require: 3044514f5e3Sopenharmony_ci */ 3054514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestArkParseJsFrameInfo) 3064514f5e3Sopenharmony_ci{ 3074514f5e3Sopenharmony_ci const char *filename1 = "__JsStackInfoTest1.pa"; 3084514f5e3Sopenharmony_ci const char *filename2 = "__JsStackInfoTest2.pa"; 3094514f5e3Sopenharmony_ci const char *pfdata1 = R"( 3104514f5e3Sopenharmony_ci .function void foo() { 3114514f5e3Sopenharmony_ci return 3124514f5e3Sopenharmony_ci } 3134514f5e3Sopenharmony_ci )"; 3144514f5e3Sopenharmony_ci const char *pfdata2 = R"( 3154514f5e3Sopenharmony_ci .language ECMAScript 3164514f5e3Sopenharmony_ci .function any func_main_0(any a0, any a1, any a2) { 3174514f5e3Sopenharmony_ci ldai 1 3184514f5e3Sopenharmony_ci return 3194514f5e3Sopenharmony_ci } 3204514f5e3Sopenharmony_ci )"; 3214514f5e3Sopenharmony_ci pandasm::Parser parser1; 3224514f5e3Sopenharmony_ci pandasm::Parser parser2; 3234514f5e3Sopenharmony_ci auto res1 = parser1.Parse(pfdata1); 3244514f5e3Sopenharmony_ci auto res2 = parser2.Parse(pfdata2); 3254514f5e3Sopenharmony_ci auto file1 = pandasm::AsmEmitter::Emit(res1.Value()); 3264514f5e3Sopenharmony_ci auto file2 = pandasm::AsmEmitter::Emit(res2.Value()); 3274514f5e3Sopenharmony_ci auto jsPandaFile1 = std::make_shared<JSPandaFile>(file1.release(), CString(filename1)); 3284514f5e3Sopenharmony_ci auto jsPandaFile2 = std::make_shared<JSPandaFile>(file2.release(), CString(filename2)); 3294514f5e3Sopenharmony_ci EXPECT_TRUE(jsPandaFile1 != nullptr); 3304514f5e3Sopenharmony_ci EXPECT_TRUE(jsPandaFile2 != nullptr); 3314514f5e3Sopenharmony_ci auto debugExtractor1 = std::make_unique<DebugInfoExtractor>(jsPandaFile1.get()); 3324514f5e3Sopenharmony_ci auto debugExtractor2 = std::make_unique<DebugInfoExtractor>(jsPandaFile2.get()); 3334514f5e3Sopenharmony_ci auto methods1 = JSStackTrace::ReadAllMethodInfos(jsPandaFile1); 3344514f5e3Sopenharmony_ci auto methods2 = JSStackTrace::ReadAllMethodInfos(jsPandaFile2); 3354514f5e3Sopenharmony_ci 3364514f5e3Sopenharmony_ci uintptr_t byteCodePc1 = methods1[0].codeBegin; 3374514f5e3Sopenharmony_ci uintptr_t byteCodePc2 = methods2[0].codeBegin; 3384514f5e3Sopenharmony_ci uintptr_t methodId1 = methods1[0].methodId; 3394514f5e3Sopenharmony_ci uintptr_t methodId2 = methods2[0].methodId; 3404514f5e3Sopenharmony_ci uintptr_t mapBase1 = reinterpret_cast<uintptr_t>(jsPandaFile1->GetHeader()); 3414514f5e3Sopenharmony_ci uintptr_t mapBase2 = reinterpret_cast<uintptr_t>(jsPandaFile2->GetHeader()); 3424514f5e3Sopenharmony_ci uintptr_t loadOffset1 = 0; 3434514f5e3Sopenharmony_ci uintptr_t loadOffset2 = 0; 3444514f5e3Sopenharmony_ci const uint8_t* data1 = jsPandaFile1->GetPandaFile()->GetBase(); 3454514f5e3Sopenharmony_ci const uint8_t* data2 = jsPandaFile2->GetPandaFile()->GetBase(); 3464514f5e3Sopenharmony_ci uint64_t dataSize1 = jsPandaFile1->GetFileSize(); 3474514f5e3Sopenharmony_ci uint64_t dataSize2 = jsPandaFile2->GetFileSize(); 3484514f5e3Sopenharmony_ci uintptr_t extractorptr1 = 0; 3494514f5e3Sopenharmony_ci uintptr_t extractorptr2 = 0; 3504514f5e3Sopenharmony_ci JsFunction jsFunction1; 3514514f5e3Sopenharmony_ci JsFunction jsFunction2; 3524514f5e3Sopenharmony_ci 3534514f5e3Sopenharmony_ci auto ret = ark_create_js_symbol_extractor(&extractorptr1); 3544514f5e3Sopenharmony_ci EXPECT_TRUE(ret == 1); 3554514f5e3Sopenharmony_ci EXPECT_TRUE(extractorptr1 != 0); 3564514f5e3Sopenharmony_ci ret = ark_create_js_symbol_extractor(&extractorptr2); 3574514f5e3Sopenharmony_ci EXPECT_TRUE(ret == 1); 3584514f5e3Sopenharmony_ci EXPECT_TRUE(extractorptr2 != 0); 3594514f5e3Sopenharmony_ci 3604514f5e3Sopenharmony_ci ret = ark_parse_js_frame_info(byteCodePc1, methodId1, mapBase1, loadOffset1, 3614514f5e3Sopenharmony_ci reinterpret_cast<uint8_t *>(const_cast<char*>(pfdata1)), 3624514f5e3Sopenharmony_ci strlen(pfdata1) + 1, extractorptr1, &jsFunction1); 3634514f5e3Sopenharmony_ci EXPECT_TRUE(ret == -1); 3644514f5e3Sopenharmony_ci 3654514f5e3Sopenharmony_ci ret = ark_parse_js_frame_info(byteCodePc1, methodId1, mapBase1, loadOffset1, 3664514f5e3Sopenharmony_ci const_cast<uint8_t*>(data1), dataSize1, extractorptr1, &jsFunction1); 3674514f5e3Sopenharmony_ci EXPECT_TRUE(ret == 1); 3684514f5e3Sopenharmony_ci EXPECT_TRUE(std::string(jsFunction1.functionName) == "foo"); 3694514f5e3Sopenharmony_ci 3704514f5e3Sopenharmony_ci ret = ark_parse_js_frame_info(byteCodePc1, methodId1, mapBase1, loadOffset1, 3714514f5e3Sopenharmony_ci const_cast<uint8_t*>(data1), dataSize1 + 1, 0, &jsFunction1); 3724514f5e3Sopenharmony_ci EXPECT_TRUE(ret == -1); 3734514f5e3Sopenharmony_ci 3744514f5e3Sopenharmony_ci ret = ark_parse_js_frame_info(byteCodePc1, methodId1, mapBase1, loadOffset1, 3754514f5e3Sopenharmony_ci nullptr, 0, extractorptr1, &jsFunction1); 3764514f5e3Sopenharmony_ci EXPECT_TRUE(ret == -1); 3774514f5e3Sopenharmony_ci 3784514f5e3Sopenharmony_ci ret = ark_parse_js_frame_info(byteCodePc1, methodId1, mapBase1, loadOffset1, 3794514f5e3Sopenharmony_ci const_cast<uint8_t*>(data2), dataSize2, extractorptr2, &jsFunction1); 3804514f5e3Sopenharmony_ci EXPECT_TRUE(ret == -1); 3814514f5e3Sopenharmony_ci 3824514f5e3Sopenharmony_ci ret = ark_parse_js_frame_info(byteCodePc2, methodId1, mapBase1, loadOffset1, 3834514f5e3Sopenharmony_ci const_cast<uint8_t*>(data2), dataSize2, extractorptr2, &jsFunction1); 3844514f5e3Sopenharmony_ci EXPECT_TRUE(ret == -1); 3854514f5e3Sopenharmony_ci 3864514f5e3Sopenharmony_ci ret = ark_parse_js_frame_info(byteCodePc2, methodId2, mapBase1, loadOffset1, 3874514f5e3Sopenharmony_ci const_cast<uint8_t*>(data2), dataSize2, extractorptr2, &jsFunction1); 3884514f5e3Sopenharmony_ci EXPECT_TRUE(ret == -1); 3894514f5e3Sopenharmony_ci 3904514f5e3Sopenharmony_ci ret = ark_parse_js_frame_info(byteCodePc2, methodId2, mapBase2, loadOffset2, 3914514f5e3Sopenharmony_ci const_cast<uint8_t*>(data2), dataSize2, extractorptr2, &jsFunction2); 3924514f5e3Sopenharmony_ci EXPECT_TRUE(ret == 1); 3934514f5e3Sopenharmony_ci EXPECT_TRUE(std::string(jsFunction2.functionName) == "func_main_0"); 3944514f5e3Sopenharmony_ci 3954514f5e3Sopenharmony_ci ret = ark_destory_js_symbol_extractor(extractorptr1); 3964514f5e3Sopenharmony_ci EXPECT_TRUE(ret == 1); 3974514f5e3Sopenharmony_ci 3984514f5e3Sopenharmony_ci ret = ark_destory_js_symbol_extractor(extractorptr2); 3994514f5e3Sopenharmony_ci EXPECT_TRUE(ret == 1); 4004514f5e3Sopenharmony_ci} 4014514f5e3Sopenharmony_ci 4024514f5e3Sopenharmony_ci/** 4034514f5e3Sopenharmony_ci * @tc.name: BuildJsStackInfo 4044514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "BuildJsStackInfo" function is within expectations; 4054514f5e3Sopenharmony_ci * @tc.type: FUNC 4064514f5e3Sopenharmony_ci * @tc.require: 4074514f5e3Sopenharmony_ci */ 4084514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestBuildJsStackInfo) 4094514f5e3Sopenharmony_ci{ 4104514f5e3Sopenharmony_ci auto jsFrame = JsStackInfo::BuildJsStackInfo(thread); 4114514f5e3Sopenharmony_ci EXPECT_TRUE(jsFrame.empty()); 4124514f5e3Sopenharmony_ci} 4134514f5e3Sopenharmony_ci 4144514f5e3Sopenharmony_ci/** 4154514f5e3Sopenharmony_ci * @tc.name: ark_destory_local 4164514f5e3Sopenharmony_ci * @tc.desc: Check whether the result returned through "ark_destory_local" function is within expectations; 4174514f5e3Sopenharmony_ci * @tc.type: FUNC 4184514f5e3Sopenharmony_ci * @tc.require: 4194514f5e3Sopenharmony_ci */ 4204514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestArkDestoryLocal) 4214514f5e3Sopenharmony_ci{ 4224514f5e3Sopenharmony_ci auto ret = ark_destory_local(); // Direct destruct without creating Pointers 4234514f5e3Sopenharmony_ci EXPECT_TRUE(ret); 4244514f5e3Sopenharmony_ci auto trace = JSStackTrace::GetInstance(); 4254514f5e3Sopenharmony_ci EXPECT_TRUE(trace != nullptr); 4264514f5e3Sopenharmony_ci ret = ark_destory_local(); // destory 4274514f5e3Sopenharmony_ci EXPECT_TRUE(ret); 4284514f5e3Sopenharmony_ci ret = ark_destory_local(); // multiple destory 4294514f5e3Sopenharmony_ci EXPECT_TRUE(ret); 4304514f5e3Sopenharmony_ci 4314514f5e3Sopenharmony_ci // Create and destruct multiple times within the process 4324514f5e3Sopenharmony_ci trace = JSStackTrace::GetInstance(); 4334514f5e3Sopenharmony_ci EXPECT_TRUE(trace != nullptr); 4344514f5e3Sopenharmony_ci ret = ark_destory_local(); 4354514f5e3Sopenharmony_ci EXPECT_TRUE(ret); 4364514f5e3Sopenharmony_ci} 4374514f5e3Sopenharmony_ci 4384514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestStepArk__001) 4394514f5e3Sopenharmony_ci{ 4404514f5e3Sopenharmony_ci void *ctx = nullptr; 4414514f5e3Sopenharmony_ci uintptr_t sp = 0; 4424514f5e3Sopenharmony_ci uintptr_t pc = 0; 4434514f5e3Sopenharmony_ci bool isJsFrame = true; 4444514f5e3Sopenharmony_ci uintptr_t frame[10][3]; 4454514f5e3Sopenharmony_ci uintptr_t fp[10]; 4464514f5e3Sopenharmony_ci for (int i = 0; i < 10; i++) { 4474514f5e3Sopenharmony_ci frame[i][0] = 0; 4484514f5e3Sopenharmony_ci frame[i][1] = 0; 4494514f5e3Sopenharmony_ci } 4504514f5e3Sopenharmony_ci fp[0] = reinterpret_cast<uintptr_t>(&frame[0][2]) + 8; 4514514f5e3Sopenharmony_ci for (int i = 1; i < 10; i++) { 4524514f5e3Sopenharmony_ci fp[i] = fp[i-1] + 24; 4534514f5e3Sopenharmony_ci } 4544514f5e3Sopenharmony_ci frame[0][2] = static_cast<uintptr_t>(FrameType::INTERPRETER_CONSTRUCTOR_FRAME); 4554514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[0], &sp, &pc, nullptr, &isJsFrame)); 4564514f5e3Sopenharmony_ci frame[1][2] = static_cast<uintptr_t>(FrameType::INTERPRETER_FAST_NEW_FRAME); 4574514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[1], &sp, &pc, nullptr, &isJsFrame)); 4584514f5e3Sopenharmony_ci frame[2][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME); 4594514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[2], &sp, &pc, nullptr, &isJsFrame)); 4604514f5e3Sopenharmony_ci frame[3][2] = static_cast<uintptr_t>(FrameType::ASM_INTERPRETER_ENTRY_FRAME); 4614514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[3], &sp, &pc, nullptr, &isJsFrame)); 4624514f5e3Sopenharmony_ci frame[4][2] = static_cast<uintptr_t>(FrameType::BUILTIN_ENTRY_FRAME); 4634514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[4], &sp, &pc, nullptr, &isJsFrame)); 4644514f5e3Sopenharmony_ci frame[5][2] = static_cast<uintptr_t>(FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME); 4654514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[5], &sp, &pc, nullptr, &isJsFrame)); 4664514f5e3Sopenharmony_ci frame[6][2] = static_cast<uintptr_t>(FrameType::BASELINE_BUILTIN_FRAME); 4674514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[6], &sp, &pc, nullptr, &isJsFrame)); 4684514f5e3Sopenharmony_ci frame[7][2] = static_cast<uintptr_t>(FrameType::ASM_BRIDGE_FRAME); 4694514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[7], &sp, &pc, nullptr, &isJsFrame)); 4704514f5e3Sopenharmony_ci frame[8][2] = static_cast<uintptr_t>(FrameType::LEAVE_FRAME); 4714514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[8], &sp, &pc, nullptr, &isJsFrame)); 4724514f5e3Sopenharmony_ci frame[9][2] = static_cast<uintptr_t>(FrameType::LEAVE_FRAME_WITH_ARGV); 4734514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[9], &sp, &pc, nullptr, &isJsFrame)); 4744514f5e3Sopenharmony_ci} 4754514f5e3Sopenharmony_ci 4764514f5e3Sopenharmony_ciHWTEST_F_L0(JsStackInfoTest, TestStepArk__002) 4774514f5e3Sopenharmony_ci{ 4784514f5e3Sopenharmony_ci void *ctx = nullptr; 4794514f5e3Sopenharmony_ci uintptr_t sp = 0; 4804514f5e3Sopenharmony_ci uintptr_t pc = 0; 4814514f5e3Sopenharmony_ci bool isJsFrame = true; 4824514f5e3Sopenharmony_ci uintptr_t frame[30][3]; 4834514f5e3Sopenharmony_ci uintptr_t fp[30]; 4844514f5e3Sopenharmony_ci for (int i = 0; i < 30; i++) { 4854514f5e3Sopenharmony_ci frame[i][0] = 0; 4864514f5e3Sopenharmony_ci frame[i][1] = 0; 4874514f5e3Sopenharmony_ci } 4884514f5e3Sopenharmony_ci fp[0] = reinterpret_cast<uintptr_t>(&frame[0][2]) + 8; 4894514f5e3Sopenharmony_ci for (int i = 1; i < 30; i++) { 4904514f5e3Sopenharmony_ci fp[i] = fp[i-1] + 24; 4914514f5e3Sopenharmony_ci } 4924514f5e3Sopenharmony_ci frame[0][2] = static_cast<uintptr_t>(FrameType::BUILTIN_CALL_LEAVE_FRAME); 4934514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[0], &sp, &pc, nullptr, &isJsFrame)); 4944514f5e3Sopenharmony_ci frame[1][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_FRAME); 4954514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[1], &sp, &pc, nullptr, &isJsFrame)); 4964514f5e3Sopenharmony_ci frame[2][2] = static_cast<uintptr_t>(FrameType::ASM_INTERPRETER_BRIDGE_FRAME); 4974514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[2], &sp, &pc, nullptr, &isJsFrame)); 4984514f5e3Sopenharmony_ci frame[3][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME); 4994514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[3], &sp, &pc, nullptr, &isJsFrame)); 5004514f5e3Sopenharmony_ci frame[4][2] = static_cast<uintptr_t>(FrameType::INTERPRETER_CONSTRUCTOR_FRAME); 5014514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[4], &sp, &pc, nullptr, &isJsFrame)); 5024514f5e3Sopenharmony_ci frame[5][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_ENTRY_FRAME); 5034514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[5], &sp, &pc, nullptr, &isJsFrame)); 5044514f5e3Sopenharmony_ci frame[6][2] = static_cast<uintptr_t>(FrameType::ASM_BRIDGE_FRAME); 5054514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[6], &sp, &pc, nullptr, &isJsFrame)); 5064514f5e3Sopenharmony_ci frame[7][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME); 5074514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[7], &sp, &pc, nullptr, &isJsFrame)); 5084514f5e3Sopenharmony_ci frame[8][2] = static_cast<uintptr_t>(FrameType::OPTIMIZED_JS_FUNCTION_FRAME); 5094514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[8], &sp, &pc, nullptr, &isJsFrame)); 5104514f5e3Sopenharmony_ci frame[9][2] = 100; 5114514f5e3Sopenharmony_ci ASSERT_TRUE(step_ark(ctx, ReadMemFunc, &fp[9], &sp, &pc, nullptr, &isJsFrame)); 5124514f5e3Sopenharmony_ci} 5134514f5e3Sopenharmony_ci} // namespace panda::test