1/*
2 * Copyright (c) 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_COMPILER_HCR_GATE_META_DATA_H
17#define ECMASCRIPT_COMPILER_HCR_GATE_META_DATA_H
18
19#include <string>
20
21#include "ecmascript/compiler/bytecodes.h"
22#include "ecmascript/compiler/ecma_opcode_des.h"
23#include "ecmascript/compiler/type.h"
24#include "ecmascript/mem/chunk.h"
25#include "ecmascript/mem/chunk_containers.h"
26
27#include "ecmascript/elements.h"
28#include "ecmascript/pgo_profiler/types/pgo_profiler_type.h"
29#include "ecmascript/on_heap.h"
30#include "libpandabase/macros.h"
31
32#include "ecmascript/compiler/share_gate_meta_data.h"
33
34namespace panda::ecmascript::kungfu {
35
36class JSBytecodeMetaData : public GateMetaData {
37public:
38    explicit JSBytecodeMetaData(
39        size_t valuesIn, uint32_t methodId, EcmaOpcode opcode, uint32_t pcOffset, uint32_t bcIndex, GateFlags flags)
40        : GateMetaData(OpCode::JS_BYTECODE, flags, 1, 1, valuesIn), methodId_(methodId), opcode_(opcode),
41          pcOffset_(pcOffset), bcIndex_(bcIndex)
42    {
43        SetKind(GateMetaData::Kind::JSBYTECODE);
44    }
45
46    bool equal(const GateMetaData &other) const override
47    {
48        if (!GateMetaData::equal(other)) {
49            return false;
50        }
51        auto cast_other = static_cast<const JSBytecodeMetaData *>(&other);
52        if (opcode_ == cast_other->opcode_ &&
53            pcOffset_ == cast_other->pcOffset_ && type_ == cast_other->type_ &&
54            elementsKinds_ == cast_other->elementsKinds_) {
55            return true;
56        }
57        return false;
58    }
59
60    static const JSBytecodeMetaData* Cast(const GateMetaData* meta)
61    {
62        meta->AssertKind(GateMetaData::Kind::JSBYTECODE);
63        return static_cast<const JSBytecodeMetaData*>(meta);
64    }
65
66    uint32_t GetMethodId() const
67    {
68        return methodId_;
69    }
70
71    uint32_t GetPcOffset() const
72    {
73        return pcOffset_;
74    }
75
76    uint32_t GetBcIndex() const
77    {
78        return bcIndex_;
79    }
80
81    void SetType(PGOTypeRef type)
82    {
83        type_ = type;
84    }
85
86    PGOTypeRef GetType() const
87    {
88        return type_;
89    }
90
91    EcmaOpcode GetByteCodeOpcode() const
92    {
93        return opcode_;
94    }
95
96    void SetElementsKind(ElementsKind kind)
97    {
98        elementsKinds_.emplace_back(kind);
99    }
100
101    ElementsKind GetElementsKind() const
102    {
103        auto size = elementsKinds_.size();
104        if (size == 0) {
105            return ElementsKind::GENERIC;
106        }
107        return elementsKinds_[0];
108    }
109
110    std::vector<ElementsKind> GetElementsKinds() const
111    {
112        return elementsKinds_;
113    }
114
115    void SetTransitionElementsKind(ElementsKind kind)
116    {
117        transitionElementsKinds_.emplace_back(kind);
118    }
119
120    ElementsKind GetTransitionElementsKind() const
121    {
122        auto size = transitionElementsKinds_.size();
123        if (size == 0) {
124            return ElementsKind::GENERIC;
125        }
126        return transitionElementsKinds_[0];
127    }
128
129    std::vector<ElementsKind> GetTransitionElementsKinds() const
130    {
131        return transitionElementsKinds_;
132    }
133
134    void SetElementsLength(uint32_t length)
135    {
136        elementsLength_ = length;
137    }
138
139    uint32_t GetElementsLength() const
140    {
141        return elementsLength_;
142    }
143
144    void SetRegionSpaceFlag(RegionSpaceFlag flag)
145    {
146        regionSpaceFlag_ = flag;
147    }
148
149    RegionSpaceFlag GetRegionSpaceFlag() const
150    {
151        return regionSpaceFlag_;
152    }
153
154    std::string Str() const
155    {
156        return GetEcmaOpcodeStr(opcode_);
157    }
158
159    void SetOnHeapMode(OnHeapMode onHeapMode)
160    {
161        onHeapMode_ = onHeapMode;
162    }
163
164    OnHeapMode GetOnHeapMode() const
165    {
166        return onHeapMode_;
167    }
168
169private:
170    uint32_t methodId_;
171    EcmaOpcode opcode_;
172    uint32_t pcOffset_;
173    uint32_t bcIndex_;
174    uint32_t elementsLength_ { 0 };
175    PGOTypeRef type_;
176    std::vector<ElementsKind> elementsKinds_ {};
177    std::vector<ElementsKind> transitionElementsKinds_ {};
178    OnHeapMode onHeapMode_ {OnHeapMode::NONE};
179    RegionSpaceFlag regionSpaceFlag_ {RegionSpaceFlag::IN_YOUNG_SPACE};
180};
181
182
183class FrameStateOutput {
184public:
185    static constexpr uint32_t INVALID_INDEX = static_cast<uint32_t>(-1);
186    explicit FrameStateOutput(uint32_t value) : index_(value) {}
187
188    static FrameStateOutput Invalid()
189    {
190        return FrameStateOutput(INVALID_INDEX);
191    }
192
193    bool IsInvalid() const
194    {
195        return index_ == INVALID_INDEX;
196    }
197
198    uint32_t GetValue() const
199    {
200        return index_;
201    }
202private:
203    uint32_t index_;
204};
205
206}
207
208#endif  // ECMASCRIPT_COMPILER_HCR_GATE_META_DATA_H
209