1/*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef ECMASCRIPT_TOOLING_BACKEND_JS_SINGLE_STEPPER_H
17#define ECMASCRIPT_TOOLING_BACKEND_JS_SINGLE_STEPPER_H
18
19#include "ecmascript/debugger/js_debugger_interface.h"
20#include "ecmascript/debugger/js_pt_method.h"
21#include "ecmascript/js_thread.h"
22#include "ecmascript/jspandafile/debug_info_extractor.h"
23
24#include "libpandabase/macros.h"
25
26namespace panda::ecmascript::tooling {
27class SingleStepper {
28public:
29    enum class Type { STEP_INTO, STEP_OVER, STEP_OUT };
30    SingleStepper(const EcmaVM *ecmaVm, std::unique_ptr<PtMethod> ptMethod,
31        std::list<JSPtStepRange> stepRanges, Type type)
32        : ecmaVm_(ecmaVm),
33          method_(std::move(ptMethod)),
34          stepRanges_(std::move(stepRanges)),
35          stackDepth_(GetStackDepth()),
36          type_(type) {}
37
38    virtual ~SingleStepper() = default;
39    NO_COPY_SEMANTIC(SingleStepper);
40    NO_MOVE_SEMANTIC(SingleStepper);
41
42    bool StepComplete(uint32_t bcOffset) const;
43    Type GetStepperType() const
44    {
45        return type_;
46    }
47
48    static std::unique_ptr<SingleStepper> GetStepIntoStepper(const EcmaVM *ecmaVm);
49    static std::unique_ptr<SingleStepper> GetStepOverStepper(const EcmaVM *ecmaVm);
50    static std::unique_ptr<SingleStepper> GetStepOutStepper(const EcmaVM *ecmaVm);
51
52private:
53    uint32_t GetStackDepth() const;
54    bool InStepRange(uint32_t pc) const;
55    static std::list<JSPtStepRange> GetStepRanges(DebugInfoExtractor *extractor,
56        panda_file::File::EntityId methodId, uint32_t offset);
57    static std::unique_ptr<SingleStepper> GetStepper(const EcmaVM *ecmaVm, SingleStepper::Type type);
58
59    const EcmaVM *ecmaVm_;
60    std::unique_ptr<PtMethod> method_;
61    std::list<JSPtStepRange> stepRanges_;
62    uint32_t stackDepth_;
63    Type type_;
64};
65}  // namespace panda::ecmascript::tooling
66#endif  // ECMASCRIPT_TOOLING_BACKEND_JS_SINGLE_STEPPER_H
67