14514f5e3Sopenharmony_ci
24514f5e3Sopenharmony_ci/*
34514f5e3Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
44514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
54514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
64514f5e3Sopenharmony_ci * You may obtain a copy of the License at
74514f5e3Sopenharmony_ci *
84514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
94514f5e3Sopenharmony_ci *
104514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
114514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
124514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
144514f5e3Sopenharmony_ci * limitations under the License.
154514f5e3Sopenharmony_ci */
164514f5e3Sopenharmony_ci
174514f5e3Sopenharmony_ci#include "ecmascript/interpreter/frame_handler.h"
184514f5e3Sopenharmony_ci
194514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/program_object.h"
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_cinamespace panda::ecmascript {
224514f5e3Sopenharmony_ciFrameHandler::FrameHandler(const JSThread *thread)
234514f5e3Sopenharmony_ci    : sp_(const_cast<JSTaggedType *>(thread->GetCurrentFrame())), thread_(thread)
244514f5e3Sopenharmony_ci{
254514f5e3Sopenharmony_ci    AdvanceToJSFrame();
264514f5e3Sopenharmony_ci}
274514f5e3Sopenharmony_ci
284514f5e3Sopenharmony_ciARK_INLINE void FrameHandler::AdvanceToJSFrame()
294514f5e3Sopenharmony_ci{
304514f5e3Sopenharmony_ci    if (!thread_->IsAsmInterpreter()) {
314514f5e3Sopenharmony_ci        return;
324514f5e3Sopenharmony_ci    }
334514f5e3Sopenharmony_ci    FrameIterator it(sp_, thread_);
344514f5e3Sopenharmony_ci    for (; !it.Done(); it.Advance()) {
354514f5e3Sopenharmony_ci        FrameType t = it.GetFrameType();
364514f5e3Sopenharmony_ci        if (IsBaselineBuiltinFrame(t)) {
374514f5e3Sopenharmony_ci            FindAndSetBaselineNativePc(it);
384514f5e3Sopenharmony_ci        }
394514f5e3Sopenharmony_ci        if (IsJSFrame(t) || IsJSEntryFrame(t)) {
404514f5e3Sopenharmony_ci            break;
414514f5e3Sopenharmony_ci        }
424514f5e3Sopenharmony_ci    }
434514f5e3Sopenharmony_ci    sp_ = it.GetSp();
444514f5e3Sopenharmony_ci}
454514f5e3Sopenharmony_ci
464514f5e3Sopenharmony_ciARK_INLINE void FrameHandler::PrevJSFrame()
474514f5e3Sopenharmony_ci{
484514f5e3Sopenharmony_ci    if (!thread_->IsAsmInterpreter()) {
494514f5e3Sopenharmony_ci        FrameIterator it(sp_, thread_);
504514f5e3Sopenharmony_ci        if (IsBaselineBuiltinFrame(it.GetFrameType())) {
514514f5e3Sopenharmony_ci            FindAndSetBaselineNativePc(it);
524514f5e3Sopenharmony_ci        }
534514f5e3Sopenharmony_ci        it.Advance();
544514f5e3Sopenharmony_ci        sp_ = it.GetSp();
554514f5e3Sopenharmony_ci        return;
564514f5e3Sopenharmony_ci    }
574514f5e3Sopenharmony_ci    AdvanceToJSFrame();
584514f5e3Sopenharmony_ci    FrameIterator it(sp_, thread_);
594514f5e3Sopenharmony_ci    FrameType t = it.GetFrameType();
604514f5e3Sopenharmony_ci    if (t == FrameType::ASM_INTERPRETER_FRAME) {
614514f5e3Sopenharmony_ci        auto frame = it.GetFrame<AsmInterpretedFrame>();
624514f5e3Sopenharmony_ci        if (thread_->IsAsmInterpreter()) {
634514f5e3Sopenharmony_ci            fp_ = frame->GetCurrentFramePointer();
644514f5e3Sopenharmony_ci        }
654514f5e3Sopenharmony_ci    }
664514f5e3Sopenharmony_ci    it.Advance();
674514f5e3Sopenharmony_ci    sp_ = it.GetSp();
684514f5e3Sopenharmony_ci    AdvanceToJSFrame();
694514f5e3Sopenharmony_ci}
704514f5e3Sopenharmony_ci
714514f5e3Sopenharmony_ciJSTaggedType* FrameHandler::GetPrevJSFrame()
724514f5e3Sopenharmony_ci{
734514f5e3Sopenharmony_ci    PrevJSFrame();
744514f5e3Sopenharmony_ci    return GetSp();
754514f5e3Sopenharmony_ci}
764514f5e3Sopenharmony_ci
774514f5e3Sopenharmony_ciuint32_t FrameHandler::GetNumberArgs()
784514f5e3Sopenharmony_ci{
794514f5e3Sopenharmony_ci    if (thread_->IsAsmInterpreter()) {
804514f5e3Sopenharmony_ci        auto *frame = AsmInterpretedFrame::GetFrameFromSp(sp_);
814514f5e3Sopenharmony_ci        return static_cast<uint32_t>(frame->GetCurrentFramePointer() - sp_);
824514f5e3Sopenharmony_ci    }
834514f5e3Sopenharmony_ci    ASSERT(IsInterpretedFrame());
844514f5e3Sopenharmony_ci    JSTaggedType *prevSp = nullptr;
854514f5e3Sopenharmony_ci    FrameIterator it(sp_, thread_);
864514f5e3Sopenharmony_ci    if (IsAsmInterpretedFrame()) {
874514f5e3Sopenharmony_ci        auto *frame = it.GetFrame<AsmInterpretedFrame>();
884514f5e3Sopenharmony_ci        prevSp = frame->GetPrevFrameFp();
894514f5e3Sopenharmony_ci    } else {
904514f5e3Sopenharmony_ci        auto *frame = it.GetFrame<InterpretedFrame>();
914514f5e3Sopenharmony_ci        prevSp = frame->GetPrevFrameFp();
924514f5e3Sopenharmony_ci    }
934514f5e3Sopenharmony_ci    auto prevSpEnd = reinterpret_cast<JSTaggedType*>(GetInterpretedFrameEnd(prevSp));
944514f5e3Sopenharmony_ci    return static_cast<uint32_t>(prevSpEnd - sp_);
954514f5e3Sopenharmony_ci}
964514f5e3Sopenharmony_ci
974514f5e3Sopenharmony_ciJSTaggedValue FrameHandler::GetVRegValue(size_t index) const
984514f5e3Sopenharmony_ci{
994514f5e3Sopenharmony_ci    ASSERT(IsInterpretedFrame());
1004514f5e3Sopenharmony_ci    // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1014514f5e3Sopenharmony_ci    return JSTaggedValue(sp_[index]);
1024514f5e3Sopenharmony_ci}
1034514f5e3Sopenharmony_ci
1044514f5e3Sopenharmony_civoid FrameHandler::SetVRegValue(size_t index, JSTaggedValue value)
1054514f5e3Sopenharmony_ci{
1064514f5e3Sopenharmony_ci    ASSERT(IsInterpretedFrame());
1074514f5e3Sopenharmony_ci    // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
1084514f5e3Sopenharmony_ci    sp_[index] = value.GetRawData();
1094514f5e3Sopenharmony_ci}
1104514f5e3Sopenharmony_ci
1114514f5e3Sopenharmony_civoid FrameHandler::FindAndSetBaselineNativePc(FrameIterator it)
1124514f5e3Sopenharmony_ci{
1134514f5e3Sopenharmony_ci    ASSERT(IsBaselineBuiltinFrame(it.GetFrameType()));
1144514f5e3Sopenharmony_ci    auto *frame = it.GetFrame<BaselineBuiltinFrame>();
1154514f5e3Sopenharmony_ci    baselineNativePc_ = frame->GetReturnAddr();
1164514f5e3Sopenharmony_ci}
1174514f5e3Sopenharmony_ci
1184514f5e3Sopenharmony_ciJSTaggedValue FrameHandler::GetAcc() const
1194514f5e3Sopenharmony_ci{
1204514f5e3Sopenharmony_ci    ASSERT(IsInterpretedFrame());
1214514f5e3Sopenharmony_ci    FrameIterator it(sp_, thread_);
1224514f5e3Sopenharmony_ci    if (IsAsmInterpretedFrame()) {
1234514f5e3Sopenharmony_ci        auto *frame = it.GetFrame<AsmInterpretedFrame>();
1244514f5e3Sopenharmony_ci        return frame->acc;
1254514f5e3Sopenharmony_ci    } else {
1264514f5e3Sopenharmony_ci        auto *frame = it.GetFrame<InterpretedFrame>();
1274514f5e3Sopenharmony_ci        return frame->acc;
1284514f5e3Sopenharmony_ci    }
1294514f5e3Sopenharmony_ci}
1304514f5e3Sopenharmony_ci
1314514f5e3Sopenharmony_ciuint32_t FrameHandler::GetBytecodeOffset() const
1324514f5e3Sopenharmony_ci{
1334514f5e3Sopenharmony_ci    ASSERT(IsInterpretedFrame());
1344514f5e3Sopenharmony_ci    Method *method = GetMethod();
1354514f5e3Sopenharmony_ci    auto offset = GetPc() - method->GetBytecodeArray();
1364514f5e3Sopenharmony_ci    return static_cast<uint32_t>(offset);
1374514f5e3Sopenharmony_ci}
1384514f5e3Sopenharmony_ci
1394514f5e3Sopenharmony_ciMethod *FrameHandler::GetMethod() const
1404514f5e3Sopenharmony_ci{
1414514f5e3Sopenharmony_ci    ASSERT(IsJSFrame());
1424514f5e3Sopenharmony_ci    auto function = GetFunction();
1434514f5e3Sopenharmony_ci    return ECMAObject::Cast(function.GetTaggedObject())->GetCallTarget();
1444514f5e3Sopenharmony_ci}
1454514f5e3Sopenharmony_ci
1464514f5e3Sopenharmony_ciconst JSPandaFile* FrameHandler::GetJSPandaFile() const
1474514f5e3Sopenharmony_ci{
1484514f5e3Sopenharmony_ci    auto method = GetMethod();
1494514f5e3Sopenharmony_ci    return method->GetJSPandaFile();
1504514f5e3Sopenharmony_ci}
1514514f5e3Sopenharmony_ci
1524514f5e3Sopenharmony_cistd::string FrameHandler::GetFileName() const
1534514f5e3Sopenharmony_ci{
1544514f5e3Sopenharmony_ci    auto pandaFile = GetJSPandaFile();
1554514f5e3Sopenharmony_ci    ASSERT(pandaFile != nullptr);
1564514f5e3Sopenharmony_ci    return pandaFile->GetJSPandaFileDesc().c_str();
1574514f5e3Sopenharmony_ci}
1584514f5e3Sopenharmony_ci
1594514f5e3Sopenharmony_ciuint32_t FrameHandler::GetAbcId() const
1604514f5e3Sopenharmony_ci{
1614514f5e3Sopenharmony_ci    std::string abcName = GetFileName();
1624514f5e3Sopenharmony_ci    pgo::PGOProfilerManager* pm = pgo::PGOProfilerManager::GetInstance();
1634514f5e3Sopenharmony_ci    uint32_t abcId;
1644514f5e3Sopenharmony_ci    if (!pm->GetPandaFileId(CString(abcName), abcId) && !abcName.empty()) {
1654514f5e3Sopenharmony_ci        LOG_ECMA(ERROR) << "Get method abc id failed. abcName: " << abcName;
1664514f5e3Sopenharmony_ci    }
1674514f5e3Sopenharmony_ci    return abcId;
1684514f5e3Sopenharmony_ci}
1694514f5e3Sopenharmony_ci
1704514f5e3Sopenharmony_ciuint32_t FrameHandler::GetMethodId() const
1714514f5e3Sopenharmony_ci{
1724514f5e3Sopenharmony_ci    return GetMethod()->GetMethodId().GetOffset();
1734514f5e3Sopenharmony_ci}
1744514f5e3Sopenharmony_ci
1754514f5e3Sopenharmony_ciMethod *FrameHandler::CheckAndGetMethod() const
1764514f5e3Sopenharmony_ci{
1774514f5e3Sopenharmony_ci    ASSERT(IsJSFrame());
1784514f5e3Sopenharmony_ci    auto function = GetFunction();
1794514f5e3Sopenharmony_ci    if (function.IsJSFunctionBase() || function.IsJSProxy()) {
1804514f5e3Sopenharmony_ci        return ECMAObject::Cast(function.GetTaggedObject())->GetCallTarget();
1814514f5e3Sopenharmony_ci    }
1824514f5e3Sopenharmony_ci    return nullptr;
1834514f5e3Sopenharmony_ci}
1844514f5e3Sopenharmony_ci
1854514f5e3Sopenharmony_ciJSTaggedValue FrameHandler::GetThis() const
1864514f5e3Sopenharmony_ci{
1874514f5e3Sopenharmony_ci    ASSERT(IsInterpretedFrame());
1884514f5e3Sopenharmony_ci    FrameIterator it(sp_, thread_);
1894514f5e3Sopenharmony_ci    if (IsAsmInterpretedFrame()) {
1904514f5e3Sopenharmony_ci        auto *frame = it.GetFrame<AsmInterpretedFrame>();
1914514f5e3Sopenharmony_ci        return frame->thisObj;
1924514f5e3Sopenharmony_ci    } else {
1934514f5e3Sopenharmony_ci        auto *frame = it.GetFrame<InterpretedFrame>();
1944514f5e3Sopenharmony_ci        return frame->thisObj;
1954514f5e3Sopenharmony_ci    }
1964514f5e3Sopenharmony_ci}
1974514f5e3Sopenharmony_ci
1984514f5e3Sopenharmony_ciJSTaggedValue FrameHandler::GetFunction() const
1994514f5e3Sopenharmony_ci{
2004514f5e3Sopenharmony_ci    ASSERT(IsJSFrame());
2014514f5e3Sopenharmony_ci    if (thread_->IsAsmInterpreter()) {
2024514f5e3Sopenharmony_ci        FrameType type = GetFrameType();
2034514f5e3Sopenharmony_ci        switch (type) {
2044514f5e3Sopenharmony_ci            case FrameType::ASM_INTERPRETER_FRAME:
2054514f5e3Sopenharmony_ci            case FrameType::INTERPRETER_CONSTRUCTOR_FRAME: {
2064514f5e3Sopenharmony_ci                auto frame = AsmInterpretedFrame::GetFrameFromSp(sp_);
2074514f5e3Sopenharmony_ci                return frame->function;
2084514f5e3Sopenharmony_ci            }
2094514f5e3Sopenharmony_ci            case FrameType::BUILTIN_FRAME_WITH_ARGV: {
2104514f5e3Sopenharmony_ci                auto *frame = BuiltinWithArgvFrame::GetFrameFromSp(sp_);
2114514f5e3Sopenharmony_ci                return frame->GetFunction();
2124514f5e3Sopenharmony_ci            }
2134514f5e3Sopenharmony_ci            case FrameType::BUILTIN_ENTRY_FRAME:
2144514f5e3Sopenharmony_ci            case FrameType::BUILTIN_FRAME: {
2154514f5e3Sopenharmony_ci                auto *frame = BuiltinFrame::GetFrameFromSp(sp_);
2164514f5e3Sopenharmony_ci                return frame->GetFunction();
2174514f5e3Sopenharmony_ci            }
2184514f5e3Sopenharmony_ci            case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME:
2194514f5e3Sopenharmony_ci            case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
2204514f5e3Sopenharmony_ci                auto *frame = OptimizedJSFunctionFrame::GetFrameFromSp(sp_);
2214514f5e3Sopenharmony_ci                return frame->GetFunction();
2224514f5e3Sopenharmony_ci            }
2234514f5e3Sopenharmony_ci            case FrameType::FASTJIT_FUNCTION_FRAME:
2244514f5e3Sopenharmony_ci            case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: {
2254514f5e3Sopenharmony_ci                auto *frame = FASTJITFunctionFrame::GetFrameFromSp(sp_);
2264514f5e3Sopenharmony_ci                return frame->GetFunction();
2274514f5e3Sopenharmony_ci            }
2284514f5e3Sopenharmony_ci            case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME :
2294514f5e3Sopenharmony_ci            case FrameType::INTERPRETER_FRAME:
2304514f5e3Sopenharmony_ci            case FrameType::INTERPRETER_FAST_NEW_FRAME:
2314514f5e3Sopenharmony_ci            case FrameType::INTERPRETER_ENTRY_FRAME:
2324514f5e3Sopenharmony_ci            case FrameType::ASM_INTERPRETER_ENTRY_FRAME:
2334514f5e3Sopenharmony_ci            case FrameType::ASM_INTERPRETER_BRIDGE_FRAME:
2344514f5e3Sopenharmony_ci            case FrameType::INTERPRETER_BUILTIN_FRAME:
2354514f5e3Sopenharmony_ci            case FrameType::OPTIMIZED_FRAME:
2364514f5e3Sopenharmony_ci            case FrameType::BASELINE_BUILTIN_FRAME:
2374514f5e3Sopenharmony_ci            case FrameType::ASM_BRIDGE_FRAME:
2384514f5e3Sopenharmony_ci            case FrameType::LEAVE_FRAME:
2394514f5e3Sopenharmony_ci            case FrameType::LEAVE_FRAME_WITH_ARGV:
2404514f5e3Sopenharmony_ci            case FrameType::BUILTIN_CALL_LEAVE_FRAME:
2414514f5e3Sopenharmony_ci            case FrameType::OPTIMIZED_ENTRY_FRAME:
2424514f5e3Sopenharmony_ci            default: {
2434514f5e3Sopenharmony_ci                LOG_FULL(FATAL) << "frame type error!";
2444514f5e3Sopenharmony_ci                UNREACHABLE();
2454514f5e3Sopenharmony_ci            }
2464514f5e3Sopenharmony_ci        }
2474514f5e3Sopenharmony_ci    } else {
2484514f5e3Sopenharmony_ci        FrameType type = GetFrameType();
2494514f5e3Sopenharmony_ci        if (type == FrameType::INTERPRETER_FRAME || type == FrameType::INTERPRETER_FAST_NEW_FRAME) {
2504514f5e3Sopenharmony_ci            auto *frame = InterpretedFrame::GetFrameFromSp(sp_);
2514514f5e3Sopenharmony_ci            return frame->function;
2524514f5e3Sopenharmony_ci        } else {
2534514f5e3Sopenharmony_ci            auto *frame = InterpretedBuiltinFrame::GetFrameFromSp(sp_);
2544514f5e3Sopenharmony_ci            return frame->function;
2554514f5e3Sopenharmony_ci        }
2564514f5e3Sopenharmony_ci    }
2574514f5e3Sopenharmony_ci}
2584514f5e3Sopenharmony_ci
2594514f5e3Sopenharmony_ciconst uint8_t *FrameHandler::GetPc() const
2604514f5e3Sopenharmony_ci{
2614514f5e3Sopenharmony_ci    ASSERT(IsJSFrame());
2624514f5e3Sopenharmony_ci    FrameIterator it(sp_, thread_);
2634514f5e3Sopenharmony_ci    if (IsAsmInterpretedFrame()) {
2644514f5e3Sopenharmony_ci        auto *frame = it.GetFrame<AsmInterpretedFrame>();
2654514f5e3Sopenharmony_ci        return frame->GetPc();
2664514f5e3Sopenharmony_ci    } else {
2674514f5e3Sopenharmony_ci        auto *frame = it.GetFrame<InterpretedFrame>();
2684514f5e3Sopenharmony_ci        return frame->GetPc();
2694514f5e3Sopenharmony_ci    }
2704514f5e3Sopenharmony_ci}
2714514f5e3Sopenharmony_ci
2724514f5e3Sopenharmony_ciConstantPool *FrameHandler::GetConstpool() const
2734514f5e3Sopenharmony_ci{
2744514f5e3Sopenharmony_ci    ASSERT(IsInterpretedFrame());
2754514f5e3Sopenharmony_ci    auto method = GetMethod();
2764514f5e3Sopenharmony_ci    JSTaggedValue constpool = method->GetConstantPool();
2774514f5e3Sopenharmony_ci    return ConstantPool::Cast(constpool.GetTaggedObject());
2784514f5e3Sopenharmony_ci}
2794514f5e3Sopenharmony_ci
2804514f5e3Sopenharmony_ciJSTaggedValue FrameHandler::GetEnv() const
2814514f5e3Sopenharmony_ci{
2824514f5e3Sopenharmony_ci    ASSERT(IsInterpretedFrame());
2834514f5e3Sopenharmony_ci    FrameIterator it(sp_, thread_);
2844514f5e3Sopenharmony_ci    if (IsAsmInterpretedFrame()) {
2854514f5e3Sopenharmony_ci        auto *frame = it.GetFrame<AsmInterpretedFrame>();
2864514f5e3Sopenharmony_ci        return frame->GetEnv();
2874514f5e3Sopenharmony_ci    } else {
2884514f5e3Sopenharmony_ci        auto *frame = it.GetFrame<InterpretedFrame>();
2894514f5e3Sopenharmony_ci        return frame->env;
2904514f5e3Sopenharmony_ci    }
2914514f5e3Sopenharmony_ci}
2924514f5e3Sopenharmony_ci
2934514f5e3Sopenharmony_civoid FrameHandler::DumpStack(std::ostream &os) const
2944514f5e3Sopenharmony_ci{
2954514f5e3Sopenharmony_ci    size_t i = 0;
2964514f5e3Sopenharmony_ci    FrameHandler frameHandler(thread_);
2974514f5e3Sopenharmony_ci    for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) {
2984514f5e3Sopenharmony_ci        os << "[" << i++
2994514f5e3Sopenharmony_ci        << "]:" << frameHandler.GetMethod()->ParseFunctionName()
3004514f5e3Sopenharmony_ci        << "\n";
3014514f5e3Sopenharmony_ci    }
3024514f5e3Sopenharmony_ci}
3034514f5e3Sopenharmony_ci
3044514f5e3Sopenharmony_civoid FrameHandler::DumpPC(std::ostream &os, const uint8_t *pc) const
3054514f5e3Sopenharmony_ci{
3064514f5e3Sopenharmony_ci    FrameHandler frameHandler(thread_);
3074514f5e3Sopenharmony_ci    ASSERT(frameHandler.HasFrame());
3084514f5e3Sopenharmony_ci    // NOLINTNEXTLINE(cppcoreguidelines-narrowing-conversions, bugprone-narrowing-conversions)
3094514f5e3Sopenharmony_ci    int offset = pc - frameHandler.GetMethod()->GetBytecodeArray();
3104514f5e3Sopenharmony_ci    os << "offset: " << offset << "\n";
3114514f5e3Sopenharmony_ci}
3124514f5e3Sopenharmony_ci
3134514f5e3Sopenharmony_ciARK_INLINE uintptr_t FrameHandler::GetInterpretedFrameEnd(JSTaggedType *prevSp) const
3144514f5e3Sopenharmony_ci{
3154514f5e3Sopenharmony_ci    uintptr_t end = 0U;
3164514f5e3Sopenharmony_ci    FrameIterator it(prevSp, thread_);
3174514f5e3Sopenharmony_ci    FrameType type = it.GetFrameType();
3184514f5e3Sopenharmony_ci    switch (type) {
3194514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_FRAME:
3204514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_CONSTRUCTOR_FRAME: {
3214514f5e3Sopenharmony_ci            auto frame = it.GetFrame<AsmInterpretedFrame>();
3224514f5e3Sopenharmony_ci            end = ToUintPtr(frame);
3234514f5e3Sopenharmony_ci            break;
3244514f5e3Sopenharmony_ci        }
3254514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_FRAME:
3264514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_FAST_NEW_FRAME: {
3274514f5e3Sopenharmony_ci            auto frame = it.GetFrame<InterpretedFrame>();
3284514f5e3Sopenharmony_ci            end = ToUintPtr(frame);
3294514f5e3Sopenharmony_ci            break;
3304514f5e3Sopenharmony_ci        }
3314514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_ENTRY_FRAME: {
3324514f5e3Sopenharmony_ci            auto frame = it.GetFrame<InterpretedEntryFrame>();
3334514f5e3Sopenharmony_ci            end = ToUintPtr(frame);
3344514f5e3Sopenharmony_ci            break;
3354514f5e3Sopenharmony_ci        }
3364514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_BUILTIN_FRAME: {
3374514f5e3Sopenharmony_ci            auto frame = it.GetFrame<InterpretedBuiltinFrame>();
3384514f5e3Sopenharmony_ci            end = ToUintPtr(frame);
3394514f5e3Sopenharmony_ci            break;
3404514f5e3Sopenharmony_ci        }
3414514f5e3Sopenharmony_ci        case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME :
3424514f5e3Sopenharmony_ci        case FrameType::BUILTIN_FRAME_WITH_ARGV:
3434514f5e3Sopenharmony_ci        case FrameType::BUILTIN_ENTRY_FRAME:
3444514f5e3Sopenharmony_ci        case FrameType::BUILTIN_FRAME:
3454514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_FRAME:
3464514f5e3Sopenharmony_ci        case FrameType::ASM_BRIDGE_FRAME:
3474514f5e3Sopenharmony_ci        case FrameType::LEAVE_FRAME:
3484514f5e3Sopenharmony_ci        case FrameType::BASELINE_BUILTIN_FRAME:
3494514f5e3Sopenharmony_ci        case FrameType::LEAVE_FRAME_WITH_ARGV:
3504514f5e3Sopenharmony_ci        case FrameType::BUILTIN_CALL_LEAVE_FRAME:
3514514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_ENTRY_FRAME:
3524514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_ENTRY_FRAME:
3534514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_BRIDGE_FRAME:
3544514f5e3Sopenharmony_ci        default: {
3554514f5e3Sopenharmony_ci            LOG_FULL(FATAL) << "frame type error!";
3564514f5e3Sopenharmony_ci            UNREACHABLE();
3574514f5e3Sopenharmony_ci        }
3584514f5e3Sopenharmony_ci    }
3594514f5e3Sopenharmony_ci    return end;
3604514f5e3Sopenharmony_ci}
3614514f5e3Sopenharmony_ci
3624514f5e3Sopenharmony_civoid FrameHandler::IterateAssembleStack(const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor,
3634514f5e3Sopenharmony_ci    const RootBaseAndDerivedVisitor &derivedVisitor)
3644514f5e3Sopenharmony_ci{
3654514f5e3Sopenharmony_ci    JSTaggedType *current = const_cast<JSTaggedType *>(thread_->GetLastLeaveFrame());
3664514f5e3Sopenharmony_ci    IterateFrameChain(current, visitor, rangeVisitor, derivedVisitor);
3674514f5e3Sopenharmony_ci}
3684514f5e3Sopenharmony_ci
3694514f5e3Sopenharmony_ci// We seperate InterpretedEntryFrame from assemble stack when asm interpreter is enable.
3704514f5e3Sopenharmony_ci// To protect EcmaRuntimeCallInfo on InterpretedEntryFrame, we iterate InterpretedEntryFrame on thread sp individually.
3714514f5e3Sopenharmony_ci// And only InterpretedEntryFrame is on thread sp when asm interpreter is enable.
3724514f5e3Sopenharmony_civoid FrameHandler::IterateEcmaRuntimeCallInfo(const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor)
3734514f5e3Sopenharmony_ci{
3744514f5e3Sopenharmony_ci    ASSERT(thread_->IsAsmInterpreter());
3754514f5e3Sopenharmony_ci    JSTaggedType *current = const_cast<JSTaggedType *>(thread_->GetCurrentSPFrame());
3764514f5e3Sopenharmony_ci    for (FrameIterator it(current, thread_); !it.Done(); it.Advance()) {
3774514f5e3Sopenharmony_ci        ASSERT(it.GetFrameType() == FrameType::INTERPRETER_ENTRY_FRAME);
3784514f5e3Sopenharmony_ci        auto frame = it.GetFrame<InterpretedEntryFrame>();
3794514f5e3Sopenharmony_ci        frame->GCIterate(it, visitor, rangeVisitor);
3804514f5e3Sopenharmony_ci    }
3814514f5e3Sopenharmony_ci}
3824514f5e3Sopenharmony_ci
3834514f5e3Sopenharmony_civoid FrameHandler::Iterate(const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor,
3844514f5e3Sopenharmony_ci    const RootBaseAndDerivedVisitor &derivedVisitor)
3854514f5e3Sopenharmony_ci{
3864514f5e3Sopenharmony_ci    if (thread_->IsAsmInterpreter()) {
3874514f5e3Sopenharmony_ci        IterateEcmaRuntimeCallInfo(visitor, rangeVisitor);
3884514f5e3Sopenharmony_ci        IterateAssembleStack(visitor, rangeVisitor, derivedVisitor);
3894514f5e3Sopenharmony_ci        return;
3904514f5e3Sopenharmony_ci    }
3914514f5e3Sopenharmony_ci    JSTaggedType *current = const_cast<JSTaggedType *>(thread_->GetCurrentSPFrame());
3924514f5e3Sopenharmony_ci    FrameType frameType = FrameHandler::GetFrameType(current);
3934514f5e3Sopenharmony_ci    if (frameType != FrameType::INTERPRETER_ENTRY_FRAME) {
3944514f5e3Sopenharmony_ci        auto leaveFrame = const_cast<JSTaggedType *>(thread_->GetLastLeaveFrame());
3954514f5e3Sopenharmony_ci        if (leaveFrame != nullptr) {
3964514f5e3Sopenharmony_ci            current = leaveFrame;
3974514f5e3Sopenharmony_ci        }
3984514f5e3Sopenharmony_ci    }
3994514f5e3Sopenharmony_ci    // lazy assignment: only Iterate need arkStackMapParser_ in order to high improve performance
4004514f5e3Sopenharmony_ci    if (arkStackMapParser_ == nullptr) {
4014514f5e3Sopenharmony_ci        arkStackMapParser_ =
4024514f5e3Sopenharmony_ci            const_cast<JSThread *>(thread_)->GetEcmaVM()->GetAOTFileManager()->GetStackMapParser();
4034514f5e3Sopenharmony_ci    }
4044514f5e3Sopenharmony_ci    IterateFrameChain(current, visitor, rangeVisitor, derivedVisitor);
4054514f5e3Sopenharmony_ci}
4064514f5e3Sopenharmony_ci
4074514f5e3Sopenharmony_civoid FrameHandler::IterateFrameChain(JSTaggedType *start, const RootVisitor &visitor,
4084514f5e3Sopenharmony_ci    const RootRangeVisitor &rangeVisitor, const RootBaseAndDerivedVisitor &derivedVisitor) const
4094514f5e3Sopenharmony_ci{
4104514f5e3Sopenharmony_ci    JSTaggedType *current = start;
4114514f5e3Sopenharmony_ci    // if the current frame type is BASELINE_BUILTIN_FRAME, the upper frame must be BaselineFrame.
4124514f5e3Sopenharmony_ci    // isBaselineFrame is used to differentiate the AsmInterpterFrame and BaselineFrame
4134514f5e3Sopenharmony_ci    bool isBaselineFrame = false;
4144514f5e3Sopenharmony_ci    for (FrameIterator it(current, thread_); !it.Done(); it.Advance<GCVisitedFlag::VISITED>()) {
4154514f5e3Sopenharmony_ci        FrameType type = it.GetFrameType();
4164514f5e3Sopenharmony_ci        switch (type) {
4174514f5e3Sopenharmony_ci            case FrameType::OPTIMIZED_FRAME: {
4184514f5e3Sopenharmony_ci                auto frame = it.GetFrame<OptimizedFrame>();
4194514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor, derivedVisitor);
4204514f5e3Sopenharmony_ci                break;
4214514f5e3Sopenharmony_ci            }
4224514f5e3Sopenharmony_ci            case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME:
4234514f5e3Sopenharmony_ci            case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
4244514f5e3Sopenharmony_ci                auto frame = it.GetFrame<OptimizedJSFunctionFrame>();
4254514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor, derivedVisitor, type);
4264514f5e3Sopenharmony_ci                break;
4274514f5e3Sopenharmony_ci            }
4284514f5e3Sopenharmony_ci            case FrameType::BASELINE_BUILTIN_FRAME: {
4294514f5e3Sopenharmony_ci                isBaselineFrame = true;
4304514f5e3Sopenharmony_ci                auto frame = it.GetFrame<BaselineBuiltinFrame>();
4314514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor, derivedVisitor);
4324514f5e3Sopenharmony_ci                break;
4334514f5e3Sopenharmony_ci            }
4344514f5e3Sopenharmony_ci            case FrameType::FASTJIT_FUNCTION_FRAME:
4354514f5e3Sopenharmony_ci            case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: {
4364514f5e3Sopenharmony_ci                auto frame = it.GetFrame<FASTJITFunctionFrame>();
4374514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor, derivedVisitor, type);
4384514f5e3Sopenharmony_ci                break;
4394514f5e3Sopenharmony_ci            }
4404514f5e3Sopenharmony_ci            case FrameType::ASM_INTERPRETER_FRAME:
4414514f5e3Sopenharmony_ci            case FrameType::INTERPRETER_CONSTRUCTOR_FRAME: {
4424514f5e3Sopenharmony_ci                auto frame = it.GetFrame<AsmInterpretedFrame>();
4434514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor, derivedVisitor, isBaselineFrame);
4444514f5e3Sopenharmony_ci                isBaselineFrame = false;
4454514f5e3Sopenharmony_ci                break;
4464514f5e3Sopenharmony_ci            }
4474514f5e3Sopenharmony_ci            case FrameType::INTERPRETER_FRAME:
4484514f5e3Sopenharmony_ci            case FrameType::INTERPRETER_FAST_NEW_FRAME: {
4494514f5e3Sopenharmony_ci                auto frame = it.GetFrame<InterpretedFrame>();
4504514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor);
4514514f5e3Sopenharmony_ci                break;
4524514f5e3Sopenharmony_ci            }
4534514f5e3Sopenharmony_ci            case FrameType::INTERPRETER_BUILTIN_FRAME: {
4544514f5e3Sopenharmony_ci                auto frame = it.GetFrame<InterpretedBuiltinFrame>();
4554514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor);
4564514f5e3Sopenharmony_ci                break;
4574514f5e3Sopenharmony_ci            }
4584514f5e3Sopenharmony_ci            case FrameType::LEAVE_FRAME: {
4594514f5e3Sopenharmony_ci                auto frame = it.GetFrame<OptimizedLeaveFrame>();
4604514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor);
4614514f5e3Sopenharmony_ci                break;
4624514f5e3Sopenharmony_ci            }
4634514f5e3Sopenharmony_ci            case FrameType::LEAVE_FRAME_WITH_ARGV: {
4644514f5e3Sopenharmony_ci                auto frame = it.GetFrame<OptimizedWithArgvLeaveFrame>();
4654514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor);
4664514f5e3Sopenharmony_ci                break;
4674514f5e3Sopenharmony_ci            }
4684514f5e3Sopenharmony_ci            case FrameType::BUILTIN_CALL_LEAVE_FRAME: {
4694514f5e3Sopenharmony_ci                auto frame = it.GetFrame<OptimizedBuiltinLeaveFrame>();
4704514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor);
4714514f5e3Sopenharmony_ci                break;
4724514f5e3Sopenharmony_ci            }
4734514f5e3Sopenharmony_ci            case FrameType::BUILTIN_FRAME_WITH_ARGV: {
4744514f5e3Sopenharmony_ci                auto frame = it.GetFrame<BuiltinWithArgvFrame>();
4754514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor);
4764514f5e3Sopenharmony_ci                break;
4774514f5e3Sopenharmony_ci            }
4784514f5e3Sopenharmony_ci            case FrameType::BUILTIN_ENTRY_FRAME:
4794514f5e3Sopenharmony_ci            case FrameType::BUILTIN_FRAME: {
4804514f5e3Sopenharmony_ci                auto frame = it.GetFrame<BuiltinFrame>();
4814514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor);
4824514f5e3Sopenharmony_ci                break;
4834514f5e3Sopenharmony_ci            }
4844514f5e3Sopenharmony_ci            case FrameType::INTERPRETER_ENTRY_FRAME: {
4854514f5e3Sopenharmony_ci                auto frame = it.GetFrame<InterpretedEntryFrame>();
4864514f5e3Sopenharmony_ci                frame->GCIterate(it, visitor, rangeVisitor);
4874514f5e3Sopenharmony_ci                break;
4884514f5e3Sopenharmony_ci            }
4894514f5e3Sopenharmony_ci            case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME:
4904514f5e3Sopenharmony_ci            case FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME:
4914514f5e3Sopenharmony_ci            case FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME:
4924514f5e3Sopenharmony_ci            case FrameType::OPTIMIZED_ENTRY_FRAME:
4934514f5e3Sopenharmony_ci            case FrameType::ASM_BRIDGE_FRAME:
4944514f5e3Sopenharmony_ci            case FrameType::ASM_INTERPRETER_ENTRY_FRAME:
4954514f5e3Sopenharmony_ci            case FrameType::ASM_INTERPRETER_BRIDGE_FRAME: {
4964514f5e3Sopenharmony_ci                break;
4974514f5e3Sopenharmony_ci            }
4984514f5e3Sopenharmony_ci            default: {
4994514f5e3Sopenharmony_ci                LOG_FULL(FATAL) << "frame type error!";
5004514f5e3Sopenharmony_ci                UNREACHABLE();
5014514f5e3Sopenharmony_ci            }
5024514f5e3Sopenharmony_ci        }
5034514f5e3Sopenharmony_ci    }
5044514f5e3Sopenharmony_ci}
5054514f5e3Sopenharmony_ci}  // namespace panda::ecmascript
506