• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_GATE_H
17 #define ECMASCRIPT_COMPILER_GATE_H
18 
19 #include <array>
20 #include <iostream>
21 #include <map>
22 #include <optional>
23 #include <set>
24 #include <sstream>
25 #include <string>
26 #include <type_traits>
27 #include <vector>
28 
29 #include "ecmascript/compiler/gate_meta_data.h"
30 #include "ecmascript/compiler/type.h"
31 
32 #include "libpandabase/macros.h"
33 
34 namespace panda::ecmascript::kungfu {
35 using BitField = uint64_t;
36 using GateRef = int32_t; // for external users
37 using GateId = uint32_t;
38 using GateOp = uint8_t;
39 using GateMark = uint8_t;
40 using TimeStamp = uint8_t;
41 using SecondaryOp = uint8_t;
42 using OutIdx = uint32_t;
43 class Gate;
44 class BytecodeCircuitBuilder;
45 
46 enum MarkCode : GateMark {
47     NO_MARK,
48     VISITED,
49     FINISHED,
50 };
51 
52 class Out {
53 public:
54     Out() = default;
55     void SetNextOut(const Out *ptr);
56     [[nodiscard]] Out *GetNextOut();
57     [[nodiscard]] const Out *GetNextOutConst() const;
58     void SetPrevOut(const Out *ptr);
59     [[nodiscard]] Out *GetPrevOut();
60     [[nodiscard]] const Out *GetPrevOutConst() const;
61     void SetIndex(OutIdx idx);
62     [[nodiscard]] OutIdx GetIndex() const;
63     [[nodiscard]] Gate *GetGate();
64     [[nodiscard]] const Gate *GetGateConst() const;
65     void SetPrevOutNull();
66     [[nodiscard]] bool IsPrevOutNull() const;
67     void SetNextOutNull();
68     [[nodiscard]] bool IsNextOutNull() const;
69     [[nodiscard]] bool IsStateEdge() const;
70     ~Out() = default;
71 
72 private:
73     GateRef nextOut_;
74     GateRef prevOut_;
75     OutIdx idx_;
76 };
77 
78 class In {
79 public:
80     In() = default;
81     void SetGate(const Gate *ptr);
82     [[nodiscard]] Gate *GetGate();
83     [[nodiscard]] const Gate *GetGateConst() const;
84     void SetGateNull();
85     [[nodiscard]] bool IsGateNull() const;
86     ~In() = default;
87 
88 private:
89     GateRef gatePtr_;
90 };
91 
92 // Gate structure
93 // for example:
94 // ```
95 // g0 = op0(...)
96 // g1 = op1(...)
97 // g2 = op2(g0, g1)
98 // g3 = op3(g2)
99 // g4 = op4(g2, g0, g1)
100 // g5 = op5(g3, g4)
101 
102 // +---- out[1] ----+---- out[0] ----+-------- g2 --------+-- in[0] --+-- in[1] --+
103 // |                |                |                    |           |           |
104 // | next=null      | next=null      | ...                |           |           |
105 // | idx=1          | idx=0          |                    |    g0     |    g1     |
106 // | prev=g4.out[2] | prev=g4.out[1] | firstOut=g4.out[0] |           |           |
107 // |                |                |                    |           |           |
108 // +----------------+----------------+--------------------+-----------+-----------+
109 //       ^               ^
110 //       |               |
111 //       |               |
112 //       |               |          +---- out[0] ----+-------- g3 --------+-- in[0] --+
113 //       |               |          |                |                    |           |
114 //       |               |          | next=null      | ...                |           |
115 //       |               |          | idx=0          |                    |    g2     |
116 //       |               |          | prev=g4.out[0] | firstOut=g5.out[0] |           |
117 //       |               |          |                |                    |           |
118 //       |               |          +----------------+--------------------+-----------+
119 //       |               |               ^
120 //       |               |               |
121 //       |               |               |
122 //       V               V               V
123 // +---- out[2] ----+---- out[1] ----+---- out[0] ----+-------- g4 --------+-- in[0] --+-- in[1] --+-- in[2] --+
124 // |                |                |                |                    |           |           |           |
125 // | next=g2.out[1] | next=g2.out[0] | next=g3.out[0] | ...                |           |           |           |
126 // | idx=2          | idx=1          | idx=0          |                    |    g2     |    g0     |    g1     |
127 // | prev=null      | prev=null      | prev=null      | firstOut=g5.out[1] |           |           |           |
128 // |                |                |                |                    |           |           |           |
129 // +----------------+----------------+----------------+--------------------+-----------+-----------+-----------+
130 // ```
131 
132 class Gate {
133 public:
134     // NOLINTNEXTLINE(modernize-avoid-c-arrays)
135     Gate(const GateMetaData* meta, GateId id, Gate *inList[], MachineType machineType, GateType type);
GetGateSize(size_t numIns)136     static size_t GetGateSize(size_t numIns)
137     {
138         numIns = (numIns == 0) ? 1 : numIns;
139         return numIns * (sizeof(In) + sizeof(Out)) + sizeof(Gate);
140     }
GetOutListSize(size_t numIns)141     static size_t GetOutListSize(size_t numIns)
142     {
143         numIns = (numIns == 0) ? 1 : numIns;
144         return numIns * sizeof(Out);
145     }
146     void NewIn(size_t idx, Gate *in);
147     void ModifyIn(size_t idx, Gate *in);
148     void DeleteIn(size_t idx);
149     void DeleteGate();
150     static constexpr GateRef InvalidGateRef = -1;
151     [[nodiscard]] Out *GetOut(size_t idx);
152     [[nodiscard]] Out *GetFirstOut();
153     [[nodiscard]] const Out *GetOutConst(size_t idx) const;
154     [[nodiscard]] const Out *GetFirstOutConst() const;
155     // note: GetFirstOut() is not equal to GetOut(0)
156     // note: behavior of GetFirstOut() is undefined when there are no Outs
157     // note: use IsFirstOutNull() to check first if there may be no Outs
158     void SetFirstOut(const Out *firstOut);
159     void SetFirstOutNull();
160     [[nodiscard]] bool IsFirstOutNull() const;
161     [[nodiscard]] In *GetIn(size_t idx);
162     [[nodiscard]] const In *GetInConst(size_t idx) const;
163     [[nodiscard]] Gate *GetInGate(size_t idx);
164     [[nodiscard]] const Gate *GetInGateConst(size_t idx) const;
165     // note: behavior of GetInGate(idx) is undefined when Ins[idx] is deleted or not assigned
166     // note: use IsInGateNull(idx) to check first if Ins[idx] may be deleted or not assigned
167     [[nodiscard]] bool IsInGateNull(size_t idx) const;
168     [[nodiscard]] OpCode GetOpCode() const;
169     [[nodiscard]] GateId GetId() const;
170     [[nodiscard]] size_t GetNumIns() const;
171     [[nodiscard]] size_t GetStateCount() const;
172     [[nodiscard]] size_t GetDependCount() const;
173     [[nodiscard]] size_t GetInValueCount() const;
174     [[nodiscard]] size_t GetInFrameStateCount() const;
175     [[nodiscard]] size_t GetInValueStarts() const;
176     [[nodiscard]] size_t GetRootCount() const;
177     [[nodiscard]] size_t GetInFrameStateStarts() const;
178     void AppendIn(const Gate *in);  // considered very slow
179     void Print(std::string bytecode = "", bool inListPreview = false, size_t highlightIdx = -1) const;
180     void ShortPrint(std::string bytecode = "", bool inListPreview = false, size_t highlightIdx = -1) const;
181     size_t PrintInGate(size_t numIns, size_t idx, size_t size, bool inListPreview, size_t highlightIdx,
182                        std::string &log, bool isEnd = false) const;
183     void PrintByteCode(std::string bytecode) const;
184     void CheckNullInput() const;
185     void CheckStateInput() const;
186     void CheckValueInput(bool isArch64) const;
187     void CheckDependInput() const;
188     void CheckRootInput() const;
189     void CheckFrameStateInput() const;
190     void CheckStateOutput() const;
191     void CheckBranchOutput() const;
192     void CheckNOP() const;
193     void CheckSelector() const;
194     void CheckRelay() const;
195     void Verify(bool isArch64) const;
196     [[nodiscard]] MarkCode GetMark(TimeStamp stamp) const;
197     void SetMark(MarkCode mark, TimeStamp stamp);
GetMachineType()198     MachineType GetMachineType() const
199     {
200         return machineType_;
201     }
SetMachineType(MachineType machineType)202     void SetMachineType(MachineType machineType)
203     {
204         machineType_ = machineType;
205     }
GetGateType()206     GateType GetGateType() const
207     {
208         return type_;
209     }
SetGateType(GateType type)210     void SetGateType(GateType type)
211     {
212         type_ = type;
213     }
GetMetaData()214     const GateMetaData* GetMetaData() const
215     {
216         return meta_;
217     }
218 
GetOneParameterMetaData()219     const OneParameterMetaData* GetOneParameterMetaData() const
220     {
221         return OneParameterMetaData::Cast(meta_);
222     }
223 
GetTypedBinaryMegaData()224     const TypedBinaryMegaData* GetTypedBinaryMegaData() const
225     {
226         return TypedBinaryMegaData::Cast(meta_);
227     }
228 
GetJSBytecodeMetaData()229     const JSBytecodeMetaData* GetJSBytecodeMetaData() const
230     {
231         return JSBytecodeMetaData::Cast(meta_);
232     }
233 
234     std::string MachineTypeStr(MachineType machineType) const;
235     std::string GateTypeStr(GateType gateType) const;
236     ~Gate() = default;
237 
238 private:
239     friend class Circuit;
240     friend class GateAccessor;
241     void CheckInputOpcode(size_t i, OpCode expected) const;
242     void CheckInputMachineType(size_t i, MachineType expected, bool isArch64) const;
243     void CheckGeneralState(size_t idx) const;
244     void CheckFailed(std::string errorString, size_t highlightIdx) const;
SetMetaData(const GateMetaData * meta)245     void SetMetaData(const GateMetaData* meta)
246     {
247         meta_ = meta;
248     }
TryGetValue()249     uint64_t TryGetValue() const
250     {
251         if (meta_->IsOneParameterKind()) {
252             return GetOneParameterMetaData()->GetValue();
253         }
254         return 0;
255     }
256     // ...
257     // out(2)
258     // out(1)
259     // out(0)
260     const GateMetaData *meta_ { nullptr }; // uintptr_t
261     GateId id_ { 0 }; // uint32_t
262     GateType type_ { GateType::Empty() }; // uint32_t
263     MachineType machineType_ { MachineType::NOVALUE }; // uint8_t
264     TimeStamp stamp_ { 0 }; // uint8_t
265     MarkCode mark_ { MarkCode::NO_MARK }; // uint8_t
266     uint8_t bitField_ { 0 };
267     GateRef firstOut_ { 0 }; // int32_t
268     // in(0)
269     // in(1)
270     // in(2)
271     // ...
272 };
273 } // namespace panda::ecmascript::kungfu
274 
275 #endif  // ECMASCRIPT_COMPILER_GATE_H