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