• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2024 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_CIRCUIT_BUILDER_H
17 #define ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H
18 
19 #include "ecmascript/base/number_helper.h"
20 #include "ecmascript/compiler/assembler/assembler.h"
21 #include "ecmascript/compiler/builtins/builtins_call_signature.h"
22 #include "ecmascript/compiler/call_signature.h"
23 #include "ecmascript/compiler/circuit.h"
24 #include "ecmascript/compiler/compilation_env.h"
25 #include "ecmascript/compiler/gate.h"
26 #include "ecmascript/compiler/gate_accessor.h"
27 #include "ecmascript/compiler/lcr_gate_meta_data.h"
28 #include "ecmascript/compiler/share_gate_meta_data.h"
29 #include "ecmascript/compiler/variable_type.h"
30 #include "ecmascript/global_env_constants.h"
31 #include "ecmascript/js_tagged_value.h"
32 #include "ecmascript/jspandafile/constpool_value.h"
33 
34 namespace panda::ecmascript::kungfu {
35 using namespace panda::ecmascript;
36 #define DEFVALUE(varname, cirBuilder, type, val) \
37         Variable varname(cirBuilder, type, cirBuilder->NextVariableId(), val)
38 
39 class BuiltinsTypedArrayStubBuilder;
40 class BuiltinsStringStubBuilder;
41 class CompilationConfig;
42 class Environment;
43 class Label;
44 class NTypeBytecodeLowering;
45 class SlowPathLowering;
46 class StubBuilder;
47 class TypedBytecodeLowering;
48 class PGOHCRLowering;
49 class NTypeHCRLowering;
50 class TSHCRLowering;
51 class Variable;
52 class NativeInlineLowering;
53 class TypedHCRLowering;
54 class TypedNativeInlineLowering;
55 class StringBuilderOptimizer;
56 class PostSchedule;
57 class TSHCROptPass;
58 class BuiltinLowering;
59 
60 #define BINARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(V)                    \
61     V(Int16Add, Add, MachineType::I16)                                    \
62     V(Int32Add, Add, MachineType::I32)                                    \
63     V(Int64Add, Add, MachineType::I64)                                    \
64     V(DoubleAdd, Add, MachineType::F64)                                   \
65     V(PtrAdd, Add, MachineType::ARCH)                                     \
66     V(DoubleExp, Exp, MachineType::F64)                                   \
67     V(Int16Sub, Sub, MachineType::I16)                                    \
68     V(Int32Sub, Sub, MachineType::I32)                                    \
69     V(Int64Sub, Sub, MachineType::I64)                                    \
70     V(DoubleSub, Sub, MachineType::F64)                                   \
71     V(PtrSub, Sub, MachineType::ARCH)                                     \
72     V(Int32Mul, Mul, MachineType::I32)                                    \
73     V(Int64Mul, Mul, MachineType::I64)                                    \
74     V(DoubleMul, Mul, MachineType::F64)                                   \
75     V(PtrMul, Mul, MachineType::ARCH)                                     \
76     V(Int32Div, Sdiv, MachineType::I32)                                   \
77     V(Int64Div, Sdiv, MachineType::I64)                                   \
78     V(DoubleDiv, Fdiv, MachineType::F64)                                  \
79     V(Int32Mod, Smod, MachineType::I32)                                   \
80     V(IntPtrMod, Smod, MachineType::I64)                                  \
81     V(DoubleMod, Smod, MachineType::F64)                                  \
82     V(BitAnd, And, MachineType::I1)                                       \
83     V(Int8And, And, MachineType::I8)                                      \
84     V(Int8Xor, Xor, MachineType::I8)                                      \
85     V(Int16And, And, MachineType::I16)                                    \
86     V(Int32And, And, MachineType::I32)                                    \
87     V(Int64And, And, MachineType::I64)                                    \
88     V(BitOr, Or, MachineType::I1)                                         \
89     V(Int16Or, Or, MachineType::I16)                                      \
90     V(Int32Or, Or, MachineType::I32)                                      \
91     V(Int64Or, Or, MachineType::I64)                                      \
92     V(Int32Xor, Xor, MachineType::I32)                                    \
93     V(Int64Xor, Xor, MachineType::I64)                                    \
94     V(Int16LSL, Lsl, MachineType::I16)                                    \
95     V(Int32LSL, Lsl, MachineType::I32)                                    \
96     V(Int64LSL, Lsl, MachineType::I64)                                    \
97     V(Int8LSR, Lsr, MachineType::I8)                                      \
98     V(Int16LSR, Lsr, MachineType::I16)                                      \
99     V(Int32LSR, Lsr, MachineType::I32)                                    \
100     V(Int64LSR, Lsr, MachineType::I64)                                    \
101     V(Int32ASR, Asr, MachineType::I32)                                    \
102     V(Int64ASR, Asr, MachineType::I64)                                    \
103     V(Int32Min, Min, MachineType::I32)                                    \
104     V(DoubleMin, Min, MachineType::F64)                                   \
105     V(Int32Max, Max, MachineType::I32)                                    \
106     V(DoubleMax, Max, MachineType::F64)
107 
108 #define UNARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(V)                  \
109     V(BoolNot, Rev, MachineType::I1)                                   \
110     V(Int32Not, Rev, MachineType::I32)                                 \
111     V(Int64Not, Rev, MachineType::I64)                                 \
112     V(CastDoubleToInt64, Bitcast, MachineType::I64)                    \
113     V(CastInt64ToFloat64, Bitcast, MachineType::F64)                   \
114     V(CastInt32ToFloat32, Bitcast, MachineType::F32)                   \
115     V(CastFloat32ToInt32, Bitcast, MachineType::I32)                   \
116     V(SExtInt32ToInt64, Sext, MachineType::I64)                        \
117     V(SExtInt1ToInt64, Sext, MachineType::I64)                         \
118     V(SExtInt1ToInt32, Sext, MachineType::I32)                         \
119     V(ZExtInt8ToInt16, Zext, MachineType::I16)                         \
120     V(ZExtInt32ToInt64, Zext, MachineType::I64)                        \
121     V(ZExtInt1ToInt64, Zext, MachineType::I64)                         \
122     V(ZExtInt1ToInt32, Zext, MachineType::I32)                         \
123     V(ZExtInt8ToInt32, Zext, MachineType::I32)                         \
124     V(ZExtInt8ToInt64, Zext, MachineType::I64)                         \
125     V(ZExtInt8ToPtr, Zext, MachineType::ARCH)                          \
126     V(ZExtInt16ToPtr, Zext, MachineType::ARCH)                         \
127     V(ZExtInt32ToPtr, Zext, MachineType::ARCH)                         \
128     V(SExtInt32ToPtr, Sext, MachineType::ARCH)                         \
129     V(ZExtInt16ToInt32, Zext, MachineType::I32)                        \
130     V(ZExtInt16ToInt64, Zext, MachineType::I64)                        \
131     V(DoubleTrunc, DoubleTrunc, MachineType::F64)                      \
132     V(TruncInt16ToInt8, Trunc, MachineType::I8)                        \
133     V(TruncInt64ToInt32, Trunc, MachineType::I32)                      \
134     V(TruncPtrToInt32, Trunc, MachineType::I32)                        \
135     V(TruncInt64ToInt1, Trunc, MachineType::I1)                        \
136     V(TruncInt64ToInt16, Trunc, MachineType::I16)                      \
137     V(TruncInt32ToInt1, Trunc, MachineType::I1)                        \
138     V(TruncInt32ToInt8, Trunc, MachineType::I8)                        \
139     V(TruncInt32ToInt16, Trunc, MachineType::I16)                      \
140     V(TruncFloatToInt64, TruncFloatToInt64, MachineType::I64)          \
141     V(TruncFloatToInt32, TruncFloatToInt32, MachineType::I32)          \
142     V(ExtFloat32ToDouble, Fext, MachineType::F64)                      \
143     V(TruncDoubleToFloat32, Ftrunc, MachineType::F32)                  \
144     V(ChangeInt32ToFloat64, SignedIntToFloat, MachineType::F64)        \
145     V(ChangeInt32ToFloat32, SignedIntToFloat, MachineType::F32)        \
146     V(ChangeUInt32ToFloat64, UnsignedIntToFloat, MachineType::F64)     \
147     V(ChangeFloat64ToInt32, FloatToSignedInt, MachineType::I32)        \
148     V(ChangeTaggedPointerToInt64, TaggedToInt64, MachineType::I64)     \
149     V(SExtInt16ToInt64, Sext, MachineType::I64)                        \
150     V(SExtInt16ToInt32, Sext, MachineType::I32)                        \
151     V(SExtInt8ToInt32, Sext, MachineType::I32)                         \
152     V(SExtInt8ToInt64, Sext, MachineType::I64)                         \
153     V(Abs, Abs, MachineType::I32)                                      \
154     V(FAbs, Abs, MachineType::F64)                                     \
155     V(CountLeadingZeroes32, Clz32, MachineType::I32)                   \
156     V(DoubleCeil, Ceil, MachineType::F64)                              \
157     V(DoubleFloor, Floor, MachineType::F64)                            \
158     V(Int64Rev, BitRev, MachineType::I64)                              \
159     V(Int32Rev, BitRev, MachineType::I32)                              \
160     V(Int16Rev, BitRev, MachineType::I16)                              \
161     V(Int8Rev, BitRev, MachineType::I8)
162 
163 #define BINARY_CMP_METHOD_LIST_WITHOUT_BITWIDTH(V)                                      \
164     V(DoubleLessThan, Fcmp, static_cast<BitField>(FCmpCondition::OLT))                  \
165     V(DoubleLessThanOrEqual, Fcmp, static_cast<BitField>(FCmpCondition::OLE))           \
166     V(DoubleGreaterThan, Fcmp, static_cast<BitField>(FCmpCondition::OGT))               \
167     V(DoubleGreaterThanOrEqual, Fcmp, static_cast<BitField>(FCmpCondition::OGE))        \
168     V(DoubleEqual, Fcmp, static_cast<BitField>(FCmpCondition::OEQ))                     \
169     V(DoubleNotEqual, Fcmp, static_cast<BitField>(FCmpCondition::ONE))                  \
170     V(Int8GreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SGE))          \
171     V(Int32LessThan, Icmp, static_cast<BitField>(ICmpCondition::SLT))                   \
172     V(Int32LessThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SLE))            \
173     V(Int32GreaterThan, Icmp, static_cast<BitField>(ICmpCondition::SGT))                \
174     V(Int32GreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SGE))         \
175     V(Int32UnsignedLessThan, Icmp, static_cast<BitField>(ICmpCondition::ULT))           \
176     V(Int32UnsignedLessThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::ULE))    \
177     V(Int32UnsignedGreaterThan, Icmp, static_cast<BitField>(ICmpCondition::UGT))        \
178     V(Int32UnsignedGreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::UGE)) \
179     V(Int64LessThan, Icmp, static_cast<BitField>(ICmpCondition::SLT))                   \
180     V(Int64LessThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SLE))            \
181     V(Int64GreaterThan, Icmp, static_cast<BitField>(ICmpCondition::SGT))                \
182     V(Int64GreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SGE))         \
183     V(Int64UnsignedLessThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::ULE))    \
184     V(Int64UnsignedGreaterThan, Icmp, static_cast<BitField>(ICmpCondition::UGT))        \
185     V(Int64UnsignedGreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::UGE))
186 
187 class CircuitBuilder {
188 public:
CircuitBuilder(Circuit * circuit)189     explicit CircuitBuilder(Circuit *circuit) : circuit_(circuit), acc_(circuit) {}
CircuitBuilder(Circuit * circuit,CompilationConfig * cmpCfg)190     CircuitBuilder(Circuit *circuit, CompilationConfig *cmpCfg)
191         : circuit_(circuit), acc_(circuit), cmpCfg_(cmpCfg)
192     {
193     }
194     ~CircuitBuilder() = default;
195     NO_MOVE_SEMANTIC(CircuitBuilder);
196     NO_COPY_SEMANTIC(CircuitBuilder);
197 
198     enum JudgeMethodType {
199         HAS_AOT,
200         HAS_AOT_FASTCALL,
201         HAS_AOT_NOTFASTCALL,
202     };
203 
204     // **************************** Share IR *****************************
205     GateRef Arguments(size_t index);
206     GateRef DefaultCase(GateRef switchBranch);
207     GateRef DependRelay(GateRef state, GateRef depend);
208     void DeoptCheck(GateRef condition, GateRef frameState, DeoptType type);
209     GateRef GetElementsArray(GateRef glue, GateRef object);
210     GateRef GetLengthOfTaggedArray(GateRef array);
211     GateRef GetLengthOfJSTypedArray(GateRef array);
212     GateRef GetDataOfTaggedArray(GateRef array);
213     GateRef GetLengthOfJSArray(GateRef array);
214     GateRef IsTypedArray(GateRef glue, GateRef array);
215     GateRef IsSharedTypedArray(GateRef glue, GateRef array);
216     GateRef GetSuperConstructor(GateRef ctor);
217     GateRef Merge(const std::vector<GateRef> &inList);
218     GateRef Selector(OpCode opcode, MachineType machineType, GateRef control, const std::vector<GateRef> &values,
219         int valueCounts, VariableType type = VariableType::VOID());
220     GateRef Selector(OpCode opcode, GateRef control, const std::vector<GateRef> &values,
221         int valueCounts, VariableType type = VariableType::VOID());
222     GateRef Nop();
223     GateRef Return(GateRef state, GateRef depend, GateRef value);
224     GateRef ReturnVoid(GateRef state, GateRef depend);
225     GateRef Goto(GateRef state);
226     GateRef LoopBegin(GateRef state);
227     GateRef LoopEnd(GateRef state);
228     GateRef LoopExit(GateRef state);
229     GateRef LoopExitDepend(GateRef state, GateRef depend);
230     GateRef LoopExitValue(GateRef state, GateRef value);
231     GateRef IfTrue(GateRef ifBranch);
232     GateRef IfFalse(GateRef ifBranch);
233     GateRef IsJsCOWArray(GateRef glue, GateRef obj);
234     GateRef IsJsCOWArray(GateRef glue, GateRef obj, const CompilationEnv *compilationEnv);
235     GateRef IsCOWArray(GateRef objectType);
236     GateRef IsTaggedArray(GateRef glue, GateRef object);
237     GateRef CheckJSType(GateRef glue, GateRef object, JSType jsType);
238     GateRef IsMutantTaggedArray(GateRef objectType);
239     GateRef SwitchCase(GateRef switchBranch, int64_t value);
240     GateRef Int8(int8_t val);
241     GateRef Int16(int16_t val);
242     GateRef Int32(int32_t value);
243     GateRef Int64(int64_t value);
244     GateRef IntPtr(int64_t val);
245     GateRef HeapConstant(uint32_t val);
246     GateRef StringPtr(std::string_view str);
247     GateRef StringPtr(const std::string &str);
248     GateRef Boolean(bool value);
249     GateRef Double(double value);
250     GateRef UndefineConstant();
251     GateRef HoleConstant();
252     GateRef SpecialHoleConstant();
253     GateRef NullPtrConstant();
254     GateRef NullConstant();
255     GateRef TaggedValueConstant(JSTaggedValue taggedValue);
256     GateRef ExceptionConstant();
257     void ClearConstantCache(GateRef gate);
258     GateRef NanValue();
259     GateRef RelocatableData(uint64_t val);
260 
261 #define BRANCH(condition, trueLabel, falseLabel)                                         \
262     {                                                                                    \
263         std::ostringstream os;                                                           \
264         os << __func__ << ": " << #trueLabel << "- " << #falseLabel;                     \
265         Branch(condition, trueLabel, falseLabel, 1, 1, os.str().c_str());                \
266     }
267 
268 #define BRANCH_CIR(condition, trueLabel, falseLabel)                                     \
269     {                                                                                    \
270         std::ostringstream os;                                                           \
271         os << __func__ << ": " << #trueLabel << "- " << #falseLabel;                     \
272         builder_.Branch(condition, trueLabel, falseLabel, 1, 1, os.str().c_str());       \
273     }
274 
275 #define BRANCH_LIKELY(condition, trueLabel, falseLabel)                                  \
276     {                                                                                    \
277         std::ostringstream os;                                                           \
278         os << __func__ << ": " << #trueLabel << "(likely)- " << #falseLabel;             \
279         Branch(condition, trueLabel, falseLabel,                                         \
280             BranchWeight::DEOPT_WEIGHT, BranchWeight::ONE_WEIGHT, os.str().c_str());     \
281     }
282 
283 #define BRANCH_CIR_LIKELY(condition, trueLabel, falseLabel)                              \
284     {                                                                                    \
285         std::ostringstream os;                                                           \
286         os << __func__ << ": " << #trueLabel << "(likely)- " << #falseLabel;             \
287         builder_.Branch(condition, trueLabel, falseLabel,                                \
288             BranchWeight::DEOPT_WEIGHT, BranchWeight::ONE_WEIGHT, os.str().c_str());     \
289     }
290 
291 #define BRANCH_UNLIKELY(condition, trueLabel, falseLabel)                                \
292     {                                                                                    \
293         std::ostringstream os;                                                           \
294         os << __func__ << ": " << #trueLabel << "(unlikely)- " << #falseLabel;           \
295         Branch(condition, trueLabel, falseLabel,                                         \
296             BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, os.str().c_str());     \
297     }
298 
299 #define BRANCH_CIR_UNLIKELY(condition, trueLabel, falseLabel)                            \
300     {                                                                                    \
301         std::ostringstream os;                                                           \
302         os << __func__ << ": " << #trueLabel << "(unlikely)- " << #falseLabel;           \
303         builder_.Branch(condition, trueLabel, falseLabel,                                \
304             BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, os.str().c_str());     \
305     }
306 
307 #define BRANCH_NO_WEIGHT(condition, trueLabel, falseLabel)                               \
308     {                                                                                    \
309         std::ostringstream os;                                                           \
310         os << __func__ << ": " << #trueLabel << "(no weight)- " << #falseLabel;          \
311         Branch(condition, trueLabel, falseLabel,                                         \
312             BranchWeight::ZERO_WEIGHT, BranchWeight::ZERO_WEIGHT, os.str().c_str());     \
313     }
314 
315     GateRef Branch(GateRef state, GateRef condition, uint32_t leftWeight = 1, uint32_t rightWeight = 1,
316                    const char* comment = nullptr);  // 1: default branch weight
317     GateRef SwitchBranch(GateRef state, GateRef index, int caseCounts);
318     void AppendFrameState(std::vector<GateRef> &args, GateRef hirGate);
319     inline GateRef True();
320     inline GateRef False();
321     inline GateRef Undefined();
322     inline GateRef Hole();
323 
324     GateRef ElementsKindIsInt(GateRef kind);
325     GateRef ElementsKindIsIntOrHoleInt(GateRef kind);
326     GateRef ElementsKindIsNumber(GateRef kind);
327     GateRef ElementsKindIsNumOrHoleNum(GateRef kind);
328     GateRef ElementsKindIsString(GateRef kind);
329     GateRef ElementsKindIsStringOrHoleString(GateRef kind);
330     GateRef ElementsKindIsHeapKind(GateRef kind);
331     GateRef ElementsKindHasHole(GateRef kind);
332 
333     GateRef LoadBuiltinObject(size_t offset);
334 
335     // Get
336     GateRef GetConstPoolFromFunction(GateRef glue, GateRef jsFunc);
337     GateRef GetUnsharedConstpoolFromGlue(GateRef glue, GateRef constpool);
338     GateRef GetUnsharedConstpoolIndex(GateRef glue, GateRef constpool);
339     GateRef GetUnsharedConstpool(GateRef glue, GateRef arrayAddr, GateRef index);
340     GateRef GetUnsharedConstpoolArrayLen(GateRef glue);
341     GateRef GetCodeAddr(GateRef jsFunc);
342     GateRef GetBaselineCodeAddr(GateRef baselineCode);
343     GateRef GetObjectByIndexFromConstPool(GateRef glue, GateRef hirGate, GateRef frameState, GateRef index,
344                                    ConstPoolType type);
345     GateRef GetObjectFromConstPool(GateRef glue, GateRef hirGate, GateRef shardConstPool, GateRef unsharedConstPool,
346                                    GateRef module, GateRef index, ConstPoolType type);
347     GateRef GetFunctionLexicalEnv(GateRef glue, GateRef function);
348     GateRef GetGlobalEnv();
349     GateRef GetGlobalEnvObj(GateRef env, size_t index);
350     GateRef GetGlobalEnvObjHClass(GateRef env, size_t index);
351     GateRef GetGlobalConstantValue(ConstantIndex index);
352     GateRef GetGlobalEnvValue(VariableType type, GateRef glue, GateRef env, size_t index);
353     GateRef GetGlobalEnv(GateRef glue);
354     GateRef GetGlobalObject(GateRef glue, GateRef globalEnv);
355     GateRef GetMethodFromFunction(GateRef glue, GateRef function);
356     GateRef GetModuleFromFunction(GateRef glue, GateRef function);
357     GateRef GetSendableEnvFromModule(GateRef glue, GateRef module);
358     GateRef GetHomeObjectFromFunction(GateRef glue, GateRef function);
359     GateRef GetHClassGateFromIndex(GateRef gate, int32_t index);
360     GateRef GetProfileTypeInfo(GateRef glue, GateRef function);
361     inline GateRef GetExpectedNumOfArgs(GateRef method);
362     inline GateRef GetGlobalConstantOffset(ConstantIndex index); // shareir
363     GateRef GetEmptyArray(GateRef glue);
364     GateRef IsCompositeHClass(GateRef hClass);
365     void CheckHClassFieldInvalidAccess(GateRef glue, GateRef hClass);
366     void CheckHClassAddrInvalid(GateRef glue, GateRef hClass);
367     GateRef GetPrototypeFromHClass(GateRef glue, GateRef hClass);
368     GateRef GetEnumCacheFromHClass(GateRef glue, GateRef hClass);
369     GateRef GetProtoChangeMarkerFromHClass(GateRef glue, GateRef hClass);
370     GateRef GetCacheKindFromForInIterator(GateRef iter);
371     GateRef GetLengthFromForInIterator(GateRef iter);
372     GateRef GetIndexFromForInIterator(GateRef iter);
373     GateRef GetKeysFromForInIterator(GateRef glue, GateRef iter);
374     GateRef GetObjectFromForInIterator(GateRef glue, GateRef iter);
375     GateRef GetCachedHClassFromForInIterator(GateRef glue, GateRef iter);
376     void SetLengthOfForInIterator(GateRef glue, GateRef iter, GateRef length);
377     void SetCacheKindForInIterator(GateRef glue, GateRef iter, GateRef cacheKind);
378     void SetIndexOfForInIterator(GateRef glue, GateRef iter, GateRef index);
379     void SetKeysOfForInIterator(GateRef glue, GateRef iter, GateRef keys);
380     void SetObjectOfForInIterator(GateRef glue, GateRef iter, GateRef object);
381     void SetCachedHClassOfForInIterator(GateRef glue, GateRef iter, GateRef hclass);
382     void IncreaseIteratorIndex(GateRef glue, GateRef iter, GateRef index);
383     void IncreaseArrayIteratorIndex(GateRef glue, GateRef iter, GateRef index);
384     void SetNextIndexOfArrayIterator(GateRef glue, GateRef iter, GateRef nextIndex);
385     void SetIteratedArrayOfArrayIterator(GateRef glue, GateRef iter, GateRef iteratedArray);
386     void SetBitFieldOfArrayIterator(GateRef glue, GateRef iter, GateRef kind);
387     GateRef GetArrayIterationKind(GateRef iter);
388     GateRef GetHasChanged(GateRef object);
389     GateRef GetAccessorHasChanged(GateRef object);
390     GateRef GetNotFoundHasChanged(GateRef object);
391     GateRef HasDeleteProperty(GateRef hClass);
392     GateRef IsOnHeap(GateRef hClass);
393     GateRef IsEcmaObject(GateRef glue, GateRef obj);
394     GateRef GetStageOfHotReload(GateRef glue);
395     GateRef IsNotLdEndExecPatchMain(GateRef glue);
396     GateRef FloatArrayElementConvert(GateRef value, bool isFloat32);
397 
398     // Set
399     void SetLengthToFunction(GateRef glue, GateRef function, GateRef value);
400     void SetLexicalEnvToFunction(GateRef glue, GateRef function, GateRef value);
401     void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value);
402     void SetModuleToFunction(GateRef glue, GateRef function, GateRef value);
403     void SetSendableEnvToModule(GateRef glue, GateRef module, GateRef value);
404     void SetRawProfileTypeInfoToFunction(GateRef glue, GateRef function, GateRef value);
405     void UpdateProfileTypeInfoCellToFunction(GateRef glue, GateRef function,
406                                              GateRef profileTypeInfo, GateRef slotId);
407     void UpdateProfileTypeInfoCellType(GateRef glue, GateRef profileTypeInfoCell);
408 
409     GateRef FunctionIsResolved(GateRef function);
410     GateRef HasPendingException(GateRef glue); // shareir
411     GateRef HasPendingException(GateRef glue, const CompilationEnv *compilationEnv);
412     GateRef IsUtf8String(GateRef string);
413     GateRef IsUtf16String(GateRef string);
414     GateRef IsInternString(GateRef string);
415     GateRef LoadObjectFromConstPool(GateRef glue, GateRef constPool, GateRef index);
416     GateRef IsAccessorInternal(GateRef glue, GateRef accessor);
417 
418     // label related
419     void NewEnvironment(GateRef hir);
420     void DeleteCurrentEnvironment();
421     inline int NextVariableId();
422     inline void HandleException(GateRef result, Label *success, Label *exception, Label *exit);
423     inline void HandleException(GateRef result, Label *success, Label *fail, Label *exit, GateRef exceptionVal);
424     inline void SubCfgEntry(Label *entry);
425     inline void SubCfgExit();
426     inline GateRef Return(GateRef value);
427     inline GateRef Return();
428     inline void Bind(Label *label);
429     inline void Bind(Label *label, bool justSlowPath);
430     void Jump(Label *label);
431     void Branch(GateRef condition, Label *trueLabel, Label *falseLabel,
432                 uint32_t trueWeight = 1, uint32_t falseWeight = 1, const char* comment = nullptr);
433     void Switch(GateRef index, Label *defaultLabel,
434                 const int64_t *keysValue, Label *keysLabel, int numberOfKeys);
435     void Switch(GateRef index, Label *defaultLabel,
436                 const int64_t *keysValue, Label * const *keysLabel, int numberOfKeys);
437     void LoopBegin(Label *loopHead);
438     void LoopEnd(Label *loopHead);
439     void LoopExit(const std::vector<Variable*> &vars, size_t diff = 1);
440     inline Label *GetCurrentLabel() const;
441     inline GateRef GetState() const;
442     inline GateRef GetDepend() const;
443     inline StateDepend GetStateDepend() const;
444 
GetCircuit()445     Circuit *GetCircuit() const
446     {
447         return circuit_;
448     }
449 
SetEnvironment(Environment * env)450     void SetEnvironment(Environment *env)
451     {
452         env_ = env;
453     }
GetCurrentEnvironment()454     Environment *GetCurrentEnvironment() const
455     {
456         return env_;
457     }
SetCompilationConfig(CompilationConfig * cmpCfg)458     void SetCompilationConfig(CompilationConfig *cmpCfg)
459     {
460         cmpCfg_ = cmpCfg;
461     }
GetCompilationConfig()462     CompilationConfig *GetCompilationConfig() const
463     {
464         return cmpCfg_;
465     }
466 
467     // **************************** High IR ******************************
468     GateRef CreateArray(ElementsKind kind, uint32_t arraySize, GateRef elementsLength, RegionSpaceFlag flag);
469     GateRef CreateArrayWithBuffer(ElementsKind kind, ArrayMetaDataAccessor::Mode mode, GateRef cpId,
470                                   GateRef constPoolIndex, RegionSpaceFlag flag);
471     GateRef CreateArguments(ElementsKind kind, CreateArgumentsAccessor::Mode mode, GateRef restIdx);
472     GateRef Construct(GateRef hirGate, std::vector<GateRef> args);
473     GateRef CallNew(GateRef hirGate, std::vector<GateRef> args, bool needPushArgv = false, bool isFastCall = false);
474     GateRef CallInternal(GateRef hirGate, std::vector<GateRef> args, uint64_t pcOffset);
475     GateRef TypedCallNative(GateRef hirGate, GateRef thisObj, GateRef funcId);
476     GateRef IsBase(GateRef glue, GateRef ctor);
477     GateRef IsDerived(GateRef glue, GateRef ctor);
478     GateRef ToLength(GateRef receiver);
479     GateRef StoreModuleVar(GateRef jsFunc, GateRef index, GateRef value);
480     GateRef LdLocalModuleVar(GateRef jsFunc, GateRef index);
481     GateRef LdExternalModuleVar(GateRef jsFunc, GateRef index);
482     GateRef BuiltinConstructor(BuiltinsStubCSigns::ID id, GateRef gate);
483 
484     inline GateRef GetMethodId(GateRef glue, GateRef func);
485     inline GateRef GetBuiltinsId(GateRef glue, GateRef func);
486     inline GateRef IsAOTLiteralInfo(GateRef glue, GateRef x);
487     GateRef GetKeyFromLexivalEnv(GateRef glue, GateRef lexicalEnv, GateRef levelIndex, GateRef slotIndex);
488     GateRef GetParentEnv(GateRef glue, GateRef object);
489     GateRef GetSendableParentEnv(GateRef glue, GateRef object);
490     GateRef GetPropertiesFromLexicalEnv(GateRef glue, GateRef object, GateRef index);
491     GateRef GetPropertiesFromSendableEnv(GateRef glue, GateRef object, GateRef index);
492     GateRef Float32ArrayConstructor(GateRef hirGate, std::vector<GateRef> args);
493 
494     // call operation
495     GateRef CallPrivateGetter(GateRef hirGate, GateRef receiver, GateRef accessor, const char* comment = nullptr);
496     GateRef CallPrivateSetter(
497         GateRef hirGate, GateRef receiver, GateRef accessor, GateRef value, const char* comment = nullptr);
498     GateRef CallGetter(GateRef hirGate, GateRef receiver, GateRef holder,
499         GateRef propertyLookupResult, const char* comment = nullptr);
500     GateRef CallSetter(GateRef hirGate, GateRef receiver, GateRef holder, GateRef propertyLookupResult,
501                        GateRef value, const char* comment = nullptr);
502     GateRef CallBCHandler(GateRef glue, GateRef target, const std::vector<GateRef> &args,
503                           const char* comment = nullptr);
504     GateRef CallBCDebugger(GateRef glue, GateRef target, const std::vector<GateRef> &args,
505                            const char* comment = nullptr);
506     GateRef CallBuiltin(GateRef glue, GateRef target, const std::vector<GateRef> &args,
507                         GateRef hir = Circuit::NullGate(),
508                         const char* comment = nullptr);
509     GateRef CallBuiltinWithArgv(GateRef glue, GateRef target, const std::vector<GateRef> &args,
510                                 const char* comment = nullptr);
511     GateRef CallRuntimeVarargs(GateRef glue, int index, GateRef argc, GateRef argv, const char* comment = nullptr);
512     GateRef CallRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args, GateRef hirGate,
513                         const char* comment = nullptr);
514     GateRef CallNGCRuntime(GateRef glue, GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel);
515 
516     GateRef CallNGCRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args,
517                            GateRef hirGate, const char* comment = nullptr);
518     GateRef FastCallOptimized(GateRef glue, GateRef code, GateRef depend, const std::vector<GateRef> &args,
519                               GateRef hirGate);
520     GateRef CallOptimized(GateRef glue, GateRef code, GateRef depend, const std::vector<GateRef> &args,
521                           GateRef hirGate);
522     GateRef CallStub(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args,
523                      const char* comment = nullptr);
524     GateRef CallCommonStub(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args,
525                            const char *comment = nullptr);
526     GateRef CallBuiltinRuntime(GateRef glue, GateRef depend, const std::vector<GateRef> &args, bool isNew = false);
527     GateRef CallBuiltinRuntimeWithNewTarget(GateRef glue, GateRef depend, const std::vector<GateRef> &args);
528     GateRef Call(const CallSignature* cs, GateRef glue, GateRef target, GateRef depend,
529                  const std::vector<GateRef> &args, GateRef hirGate, const char* comment = nullptr);
530     GateRef NoLabelCallRuntime(GateRef glue, GateRef depend, size_t index, std::vector<GateRef> &args, GateRef hirGate);
531 
532     void StartCallTimer(GateRef glue, GateRef gate, const std::vector<GateRef> &args, bool useLabel);
533     void EndCallTimer(GateRef glue, GateRef gate, const std::vector<GateRef> &args, bool useLabel);
534     GateRef GetCallBuiltinId(GateRef method);
535 
536     // FastCall
537     inline GateRef CanFastCall(GateRef jsFunc);
538 
539     // Js world
540     inline GateRef GetObjectType(GateRef hClass);
541     inline GateRef HasConstructor(GateRef glue, GateRef object);
542     inline GateRef IsSpecial(GateRef x, JSTaggedType type);
543     inline GateRef IsJSFunction(GateRef glue, GateRef obj);
544     inline GateRef IsDictionaryMode(GateRef glue, GateRef object);
545     inline GateRef IsJsType(GateRef glue, GateRef object, JSType type);
546     inline GateRef IsStableElements(GateRef hClass);
547     inline GateRef IsStableElements(GateRef hClass, CompilationEnv *compilationEnv);
548     inline GateRef IsStableArguments(GateRef hClass);
549     inline GateRef IsStableArray(GateRef hClass);
550     inline GateRef IsDictionaryElement(GateRef hClass);
551     inline GateRef IsJSArrayPrototypeModified(GateRef hClass);
552     inline GateRef IsClassConstructor(GateRef glue, GateRef object);
553     inline GateRef IsClassConstructorWithBitField(GateRef bitfield);
554     inline GateRef IsConstructor(GateRef glue, GateRef object);
555     inline GateRef IsClassPrototype(GateRef glue, GateRef object);
556     inline GateRef IsClassPrototypeWithBitField(GateRef object);
557     inline GateRef IsExtensible(GateRef glue, GateRef object);
558     inline GateRef IsJSObject(GateRef glue, GateRef obj);
559     inline GateRef IsCallable(GateRef glue, GateRef obj);
560     inline GateRef IsCallableFromBitField(GateRef bitfield);
561     inline GateRef AlreadyDeopt(GateRef method);
562     inline GateRef AlreadyDeoptFromExtraLiteralInfo(GateRef callfield);
563     inline GateRef IsPrototypeHClass(GateRef hclass);
564     inline GateRef IsJsProxy(GateRef glue, GateRef obj);
565     GateRef IsJSHClass(GateRef glue, GateRef obj);
566     // It must sets zero for high 32 bits field when store hclass to object header.
567     inline void StoreHClass(GateRef glue, GateRef object, GateRef hClass,
568                             MemoryAttribute mAttr = MemoryAttribute::NeedBarrier());
569     // It must keeps high 32 bits field when store hclass to object header.
570     inline void TransitionHClass(GateRef glue, GateRef object, GateRef hClass,
571                              MemoryAttribute mAttr = MemoryAttribute::NeedBarrier());
572     inline void TransitionHClassByConstOffset(GateRef glue, GateRef object, GateRef hClass,
573                                               MemoryAttribute mAttr = MemoryAttribute::NeedBarrier());
574     inline void StorePrototype(GateRef glue, GateRef hclass, GateRef prototype);
575     void SetExtensibleToBitfield(GateRef glue, GateRef obj, bool isExtensible);
576 
577     // WeakRef
578     inline GateRef CreateWeakRef(GateRef x);
579     inline GateRef LoadObjectFromWeakRef(GateRef x);
580 
581     // hClass
582     inline GateRef GetElementsKindByHClass(GateRef hClass);
583     inline GateRef GetObjectSizeFromHClass(GateRef hClass);
584     inline GateRef HasConstructorByHClass(GateRef hClass);
585     inline GateRef IsDictionaryModeByHClass(GateRef hClass);
586     inline GateRef LoadHclassImpl(GateRef glue, GateRef object, int line);
587     // notice: if jump here by stub_builder please see stub_builder-inl.h/stub_builder.h LoadHclassImpl
588 #define LoadHClass(glue, object) LoadHclassImpl(glue, object, __LINE__)
589     inline GateRef LoadHClassByConstOffset(GateRef glue, GateRef object);
590     inline GateRef LoadPrototype(GateRef glue, GateRef hclass);
591     inline GateRef LoadProtoChangeMarker(GateRef glue, GateRef hclass);
592     inline GateRef LoadPrototypeHClass(GateRef glue, GateRef object);
593     inline GateRef LoadPrototypeOfPrototypeHClass(GateRef glue, GateRef object);
594     void SetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass,
595                                  GateRef value, GateRef attrOffset, VariableType type);
596 
597     // Others
598     GateRef OrdinaryHasInstance(GateRef obj, GateRef target);
599     GateRef MigrateArrayWithKind(GateRef receiver, GateRef oldElementsKind, GateRef newElementsKind);
600 
601     // **************************** Middle IR ****************************
602     GateRef EcmaObjectCheck(GateRef gate);
603     GateRef HeapObjectCheck(GateRef gate, GateRef frameState);
604     GateRef MathHClassConsistencyCheck(GateRef receiver);
605     GateRef HeapObjectIsEcmaObjectCheck(GateRef gate, GateRef frameState);
606     GateRef ProtoChangeMarkerCheck(GateRef gate, GateRef frameState = Gate::InvalidGateRef);
607     GateRef PrimitiveTypeProtoChangeMarkerCheck(GateRef gate, GateRef frameState);
608     GateRef StableArrayCheck(GateRef gate, ElementsKind kind, ArrayMetaDataAccessor::Mode mode);
609     GateRef ElementsKindCheck(GateRef receiver, ElementsKind kind, ArrayMetaDataAccessor::Mode mode);
610     GateRef COWArrayCheck(GateRef gate);
611     GateRef EcmaStringCheck(GateRef gate);
612     GateRef StringKeyCheck(GateRef key, GateRef value);
613     GateRef InternStringKeyCheck(GateRef key, GateRef value);
614     GateRef InternStringCheck(GateRef gate);
615     GateRef EcmaMapCheck(GateRef gate);
616     GateRef FlattenTreeStringCheck(GateRef gate);
617     GateRef HClassStableArrayCheck(GateRef gate, GateRef frameState, ArrayMetaDataAccessor accessor);
618     GateRef ArrayGuardianCheck(GateRef frameState);
619     GateRef TypedArrayCheck(GateRef gate, ParamType paramType, TypedArrayMetaDataAccessor::Mode mode,
620                             OnHeapMode onHeap = OnHeapMode::NONE);
621     GateRef LoadTypedArrayLength(GateRef gate, ParamType paramType, OnHeapMode onHeap = OnHeapMode::NONE);
622     GateRef RangeGuard(GateRef gate, uint32_t left, uint32_t right);
623     GateRef BuiltinInstanceHClassCheck(GateRef gate, BuiltinTypeId type, ElementsKind kind,
624                                        bool isPrototypeOfPrototype);
625     GateRef BuiltinPrototypeHClassCheck(GateRef gate, BuiltinTypeId type, ElementsKind kind,
626                                         bool isPrototypeOfPrototype);
627     GateRef OrdinaryHasInstanceCheck(GateRef target, GateRef jsFunc, std::vector<GateRef> &expectedHCIndexes);
628     GateRef IndexCheck(GateRef gate, GateRef index);
629     GateRef ObjectTypeCheck(bool isHeapObject, GateRef gate, GateRef hclassIndex,
630                             GateRef frameState = Gate::InvalidGateRef);
631     GateRef ObjectTypeCheck(bool isHeapObject, GateRef gate, const std::vector<int>& hclassIndexList,
632                             GateRef frameState = Gate::InvalidGateRef);
633     GateRef TryPrimitiveTypeCheck(GateType type, GateRef gate);
634     GateRef CallTargetCheck(GateRef gate, GateRef function, GateRef id, const char* comment = nullptr);
635     GateRef CallTargetCheck(GateRef gate, GateRef function, GateRef id, std::vector<GateRef> params,
636                             const char* comment = nullptr);
637     GateRef InlineSuperCtorCheck(GateRef gate, GateRef function, GateRef newTarget, GateRef methodOffset,
638                                  const char* comment = nullptr);
639     template<TypedCallTargetCheckOp Op>
640     GateRef JSCallTargetTypeCheck(GateRef func, GateRef methodIndex, GateRef gate);
641     template<TypedCallTargetCheckOp Op>
642     inline GateRef JSNoGCCallThisTargetTypeCheck(GateRef func, GateRef methodId, GateRef gate);
643     GateRef CallTargetIsCompiledCheck(GateRef func, GateRef gate);
644     GateRef TypeOfCheck(GateRef gate, ParamType paramType);
645     GateRef TypedTypeOf(ParamType paramType);
646     GateRef TypedCallOperator(GateRef hirGate, MachineType type, const std::vector<GateRef>& inList, bool isSideEffect);
647     inline GateRef CallNewBuiltin(GateRef hirGate, std::vector<GateRef> &args);
648     inline GateRef TypedCallBuiltin(GateRef hirGate, const std::vector<GateRef> &args,
649                                     BuiltinsStubCSigns::ID id, bool isSideEffect);
650     GateRef TypeConvert(MachineType type, ParamType typeFrom, GateType typeTo, const std::vector<GateRef>& inList);
651     GateRef ProductIsNegativeZero(GateRef result, GateRef left, GateRef right);
652     GateRef Int32CheckRightIsZero(GateRef right);
653     GateRef RemainderIsNegativeZero(GateRef left, GateRef right);
654     GateRef Float64CheckRightIsZero(GateRef right);
655     GateRef ValueCheckNegOverflow(GateRef value);
656     GateRef OverflowCheck(GateRef value);
657     GateRef LexVarIsHoleCheck(GateRef value);
658     GateRef IsUndefinedOrHoleCheck(GateRef value);
659     GateRef IsNotUndefinedOrHoleCheck(GateRef value);
660     GateRef IsDataViewCheck(GateRef obj);
661     GateRef IsCallableCheck(GateRef func, GateRef frameState = Circuit::NullGate());
662     GateRef Int32UnsignedUpperBoundCheck(GateRef value, GateRef upperBound);
663     GateRef Int32DivWithCheck(GateRef left, GateRef right);
664     GateType GetGateTypeOfValueType(ValueType type);
665     GateRef InsertStableArrayCheck(GateRef array, ArrayMetaDataAccessor accessor);
666     GateRef InsertLoadArrayLength(GateRef array, GateRef length, bool isTypedArray);
667     GateRef InsertTypedArrayCheck(GateRef array, TypedArrayMetaDataAccessor accessor);
668     GateRef TypedConstructorCheck(GateRef gate, size_t type);
669     GateRef ArrayConstructorCheck(GateRef gate);
670     GateRef Float32ArrayConstructorCheck(GateRef gate);
671     GateRef ObjectConstructorCheck(GateRef gate);
672     GateRef BooleanConstructorCheck(GateRef gate);
673     GateRef InsertTypedBinaryop(GateRef left, GateRef right, TypedBinOp op);
674     GateRef InsertRangeCheckPredicate(GateRef left, TypedBinOp cond, GateRef right);
675     GateRef TypedConditionJump(MachineType type, TypedJumpOp jumpOp, uint32_t weight, ParamType paramType,
676                                const std::vector<GateRef>& inList);
677     GateRef TypedNewAllocateThis(GateRef ctor, GateRef hclass, GateRef size, GateRef frameState);
678     GateRef TypedSuperAllocateThis(GateRef superCtor, GateRef newTarget);
679     template<TypedBinOp Op>
680     inline GateRef TypedBinaryOp(GateRef x, GateRef y, ParamType paramType);
681     template<TypedUnOp Op>
682     inline GateRef TypedUnaryOp(GateRef x, ParamType paramType);
683     template<TypedJumpOp Op>
684     inline GateRef TypedConditionJump(GateRef x, ParamType paramType, uint32_t weight);
685     GateRef Convert(GateRef gate, ValueType src, ValueType dst);
686     GateRef ConvertBoolToTaggedBoolean(GateRef gate);
687     GateRef ConvertTaggedBooleanToBool(GateRef gate);
688     GateRef ConvertInt32ToBool(GateRef gate);
689     GateRef ConvertFloat64ToBool(GateRef gate);
690     GateRef ConvertInt32ToTaggedInt(GateRef gate);
691     GateRef ConvertFloat64ToTaggedDouble(GateRef gate);
692     GateRef ConvertFloat64ToInt32(GateRef gate);
693     GateRef ConvertInt32ToFloat64(GateRef gate);
694     GateRef ConvertBoolToInt32(GateRef gate, ConvertSupport support);
695     GateRef ConvertBoolToFloat64(GateRef gate, ConvertSupport support);
696     GateRef ConvertUInt32ToBool(GateRef gate);
697     GateRef ConvertUInt32ToTaggedNumber(GateRef gate);
698     GateRef ConvertUInt32ToFloat64(GateRef gate);
699     GateRef ConvertCharToEcmaString(GateRef gate);
700     GateRef ConvertCharToInt32(GateRef gate);
701     GateRef ConvertCharToDouble(GateRef gate);
702     GateRef CheckAndConvert(
703         GateRef gate, ValueType src, ValueType dst, ConvertSupport support = ConvertSupport::ENABLE);
704     GateRef ConvertHoleAsUndefined(GateRef receiver);
705     GateRef ConvertSpecialHoleIntToTagged(GateRef gate);
706     GateRef ConvertSpecialHoleDoubleToTagged(GateRef gate);
707     GateRef CheckSpecialHoleAndConvertToTaggedInt(GateRef receiver);
708     GateRef CheckSpecialHoleAndConvertToTaggedDouble(GateRef receiver);
709     GateRef CheckUInt32AndConvertToInt32(GateRef gate);
710     GateRef CheckTaggedIntAndConvertToInt32(GateRef gate);
711     GateRef CheckTaggedDoubleAndConvertToInt32(GateRef gate);
712     GateRef CheckTaggedNumberAndConvertToInt32(GateRef gate);
713     GateRef CheckTaggedIntAndConvertToFloat64(GateRef gate);
714     GateRef CheckTaggedDoubleAndConvertToFloat64(GateRef gate);
715     GateRef CheckTaggedNumberAndConvertToFloat64(GateRef gate);
716     GateRef CheckTaggedNumberAndConvertToBool(GateRef gate);
717     GateRef CheckTaggedBooleanAndConvertToBool(GateRef gate);
718     GateRef CheckNullAndConvertToInt32(GateRef gate);
719     GateRef CheckTaggedBooleanAndConvertToInt32(GateRef gate);
720     GateRef CheckHoleIntAndConvertToTaggedInt(GateRef gate);
721     GateRef CheckHoleDoubleAndConvertToTaggedDouble(GateRef gate);
722     GateRef CheckNullAndConvertToFloat64(GateRef gate);
723     GateRef CheckTaggedBooleanAndConvertToFloat64(GateRef gate);
724     GateRef CheckUndefinedAndConvertToFloat64(GateRef gate);
725     GateRef CheckUndefinedAndConvertToBool(GateRef gate);
726     GateRef CheckNullAndConvertToBool(GateRef gate);
727     GateRef CheckUndefinedAndConvertToInt32(GateRef gate);
728     GateRef CheckHoleIntAndConvertToInt32(GateRef gate);
729     GateRef CheckHoleDoubleAndConvertToInt32(GateRef gate);
730     GateRef CheckHoleIntAndConvertToFloat64(GateRef gate);
731     GateRef CheckHoleDoubleAndConvertToFloat64(GateRef gate);
732     GateRef CheckFloat64ConvertToInt32Legally(GateRef gate);
733     GateRef StartAllocate();
734     GateRef FinishAllocate(GateRef value);
735 
736     inline GateRef PrimitiveToNumber(GateRef x, ParamType paramType);
737     inline GateRef GetValueFromTaggedArray(GateRef glue, GateRef array, GateRef index);
738     inline GateRef GetValueFromTaggedArray(GateRef glue, GateRef array, GateRef index, GateRef depend);
739     inline GateRef GetValueFromTaggedArray(VariableType valType, GateRef array, GateRef index);
740     inline GateRef GetValueFromJSArrayWithElementsKind(VariableType type, GateRef array, GateRef index);
741     inline GateRef GetArrayElementsGuardians(GateRef env);
742     inline GateRef GetMapIteratorDetector(GateRef env);
743     inline GateRef GetSetIteratorDetector(GateRef env);
744     inline GateRef GetStringIteratorDetector(GateRef env);
745     inline GateRef GetArrayIteratorDetector(GateRef env);
746     inline GateRef GetTypedArrayIteratorDetector(GateRef env);
747     inline GateRef GetTypedArraySpeciesProtectDetector(GateRef env);
748     template<TypedLoadOp Op>
749     GateRef LoadElement(GateRef receiver, GateRef index, OnHeapMode onHeap = OnHeapMode::NONE);
750     GateRef LoadProperty(GateRef receiver, GateRef propertyLookupResult, bool isFunction);
751     GateRef LoadArrayLength(GateRef gate, ElementsKind kind, ArrayMetaDataAccessor::Mode mode);
752     inline GateRef LoadFromTaggedArray(GateRef array, size_t index);
753     GateRef LoadStringLength(GateRef string);
754     GateRef LoadMapSize(GateRef string);
755     GateRef LoadConstOffset(VariableType type, GateRef receiver, size_t offset,
756                             MemoryAttribute mAttr = MemoryAttribute::Default());
757     GateRef LoadHClassByConstOffset(VariableType type, GateRef receiver);
758     GateRef LoadHClassFromConstpool(GateRef constpool, size_t index);
759     GateRef TypedCall(GateRef hirGate, std::vector<GateRef> args, bool isNoGC);
760     GateRef TypedFastCall(GateRef hirGate, std::vector<GateRef> args, bool isNoGC);
761     inline void SetValueToTaggedArray(VariableType valType, GateRef glue, GateRef array, GateRef index, GateRef val);
762     GateRef StoreConstOffset(VariableType type, GateRef receiver, size_t offset, GateRef value,
763                              MemoryAttribute mAttr = MemoryAttribute::Default());
764     GateRef StoreHClassConstOffset(VariableType type, GateRef receiver, GateRef value, GateRef compValue,
765                                    MemoryAttribute mAttr = MemoryAttribute::Default());
766     inline GateRef StoreToTaggedArray(GateRef array, size_t index, GateRef value);
767     GateRef StringEqual(GateRef x, GateRef y);
768     GateRef StringAdd(GateRef x, GateRef y, uint32_t stringStatus = 0);
769     template<TypedStoreOp Op>
770     GateRef StoreElement(GateRef receiver, GateRef index, GateRef value, OnHeapMode onHeap = OnHeapMode::NONE);
771     GateRef StoreMemory(MemoryType Op, VariableType type, GateRef receiver, GateRef index, GateRef value);
772     GateRef StoreProperty(GateRef receiver, GateRef propertyLookupResult, GateRef value, uint32_t receiverHClassIndex);
773     inline GateRef JudgeAotAndFastCall(GateRef jsFunc, JudgeMethodType type);
774     GateRef ComputeTaggedArraySize(GateRef length);
775     GateRef HeapAlloc(GateRef glue, GateRef size, GateType type, RegionSpaceFlag flag);
776     GateRef TaggedIsHeapObjectOp(GateRef value);
777     GateRef IsSpecificObjectType(GateRef obj, JSType type);
778     GateRef IsMarkerCellValid(GateRef cell);
779     GateRef IsMarkerCellValidOp(GateRef cell);
780     GateRef MonoLoadPropertyOnProto(GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex);
781     GateRef MonoCallGetterOnProto(GateRef gate, GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex);
782     GateRef MonoStorePropertyLookUpProto(GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex,
783                                          GateRef value);
784     GateRef MonoStoreProperty(GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex,
785                               GateRef value, GateRef keyIndex, GateRef isProto, GateRef frameState);
786     GateRef TypedCreateObjWithBuffer(std::vector<GateRef> &valueIn);
787     template<TypedLoadOp Op>
788     GateRef ConvertJSArrayHoleAsUndefined(GateRef receiver);
789     GateRef BuildBigIntAsIntN(const GateMetaData* op, std::vector<GateRef> &&args);
790     GateRef NewJSPrimitiveRef(GateRef glue, GateRef globalEnv, size_t index, GateRef obj);
791     GateRef ToObject(GateRef glue, GateRef globalEnv, GateRef obj);
792     GateRef GetPrototype(GateRef glue, GateRef object);
793 
794     GateRef GetGlobalConstantValue(VariableType type, GateRef glue, ConstantIndex index);
795     GateRef TransProtoWithoutLayout(GateRef glue, GateRef hClass, GateRef proto);
796     GateRef OrdinaryNewJSObjectCreate(GateRef glue, GateRef proto);
797 
798     // bit operation
799     inline GateRef TaggedIsInt(GateRef x);
800     inline GateRef TaggedIsDouble(GateRef x);
801     inline GateRef TaggedIsObject(GateRef x);
802     inline GateRef TaggedIsNumber(GateRef x);
803     inline GateRef TaggedIsNumeric(GateRef glue, GateRef x);
804     inline GateRef TaggedIsNotHole(GateRef x);
805     inline GateRef TaggedIsHole(GateRef x);
806     inline GateRef TaggedIsNullPtr(GateRef x);
807     inline GateRef TaggedIsUndefined(GateRef x);
808     inline GateRef TaggedIsException(GateRef x);
809     inline GateRef TaggedIsSpecial(GateRef x);
810     inline GateRef TaggedIsHeapObject(GateRef x);
811     inline GateRef TaggedIsHeapObject(GateRef x, const CompilationEnv *compilationEnv);
812     inline GateRef TaggedIsJSFunction(GateRef glue, GateRef x);
813     inline GateRef TaggedIsArrayIterator(GateRef glue, GateRef obj);
814     inline GateRef TaggedIsAsyncGeneratorObject(GateRef glue, GateRef x);
815     inline GateRef TaggedIsJSGlobalObject(GateRef glue, GateRef x);
816     inline GateRef TaggedIsGeneratorObject(GateRef glue, GateRef x);
817     inline GateRef TaggedIsJSArray(GateRef glue, GateRef x);
818     inline GateRef TaggedIsJSProxy(GateRef glue, GateRef x);
819     inline GateRef TaggedIsPropertyBox(GateRef glue, GateRef x);
820     inline GateRef TaggedIsWeak(GateRef x);
821     inline GateRef TaggedIsPrototypeHandler(GateRef glue, GateRef x);
822     inline GateRef TaggedIsTransitionHandler(GateRef glue, GateRef x);
823     inline GateRef TaggedIsStoreAOTHandler(GateRef glue, GateRef x);
824     inline GateRef TaggedIsTransWithProtoHandler(GateRef glue, GateRef x);
825     inline GateRef TaggedIsUndefinedOrNull(GateRef x);
826     inline GateRef TaggedIsUndefinedOrNullOrHole(GateRef x);
827     inline GateRef TaggedIsNotUndefinedAndNullAndHole(GateRef x);
828     inline GateRef TaggedIsNotUndefinedAndNull(GateRef x);
829     inline GateRef TaggedIsUndefinedOrHole(GateRef x);
830     inline GateRef TaggedIsTrue(GateRef x);
831     inline GateRef TaggedIsFalse(GateRef x);
832     inline GateRef TaggedIsNull(GateRef x);
833     inline GateRef TaggedIsNotNull(GateRef x);
834     inline GateRef TaggedIsBoolean(GateRef x);
835     inline GateRef TaggedIsNativePointer(GateRef glue, GateRef x);
836     inline GateRef TaggedIsBigInt(GateRef glue, GateRef obj);
837     inline GateRef TaggedIsString(GateRef glue, GateRef obj);
838     inline GateRef TaggedIsLineUtf8String(GateRef glue, GateRef obj);
839     inline GateRef TaggedIsStringIterator(GateRef glue, GateRef obj);
840     inline GateRef TaggedIsSharedObj(GateRef glue, GateRef obj);
841     inline GateRef TaggedIsStableArray(GateRef glue, GateRef obj);
842     inline GateRef TaggedIsStringOrSymbol(GateRef glue, GateRef obj);
843     inline GateRef TaggedIsSymbol(GateRef glue, GateRef obj);
844     inline GateRef TaggedIsEnumCache(GateRef glue, GateRef obj);
845     inline GateRef TaggedIsProtoChangeMarker(GateRef glue, GateRef obj);
846     inline GateRef TaggedObjectIsJSMap(GateRef glue, GateRef obj);
847     inline GateRef TaggedObjectIsJSSet(GateRef glue, GateRef obj);
848     inline GateRef TaggedObjectIsJSDate(GateRef glue, GateRef obj);
849     inline GateRef TaggedObjectIsTypedArray(GateRef glue, GateRef obj);
850     inline GateRef TaggedObjectIsJSArray(GateRef glue, GateRef obj);
851     inline GateRef TaggedIsBoundFunction(GateRef glue, GateRef obj);
852     inline GateRef TaggedGetInt(GateRef x);
853     inline GateRef TaggedObjectIsString(GateRef glue, GateRef obj);
854     inline GateRef TaggedObjectIsString(GateRef glue, GateRef obj, const CompilationEnv *compilationEnv);
855     inline GateRef TaggedObjectIsShared(GateRef glue, GateRef obj);
856     inline GateRef TaggedObjectIsEcmaObject(GateRef glue, GateRef obj);
857     inline GateRef TaggedObjectIsByteArray(GateRef glue, GateRef obj);
858     inline GateRef TaggedObjectIsMap(GateRef glue, GateRef obj);
859     inline GateRef TaggedObjectIsDataView(GateRef glue, GateRef obj);
860     inline GateRef IsSpecialHole(GateRef x);
861     inline GateRef IsNotSpecialHole(GateRef x);
862     inline GateRef TaggedTrue();
863     inline GateRef TaggedFalse();
864 
865     // String
866     inline GateRef BothAreString(GateRef glue, GateRef x, GateRef y);
867     inline GateRef IsTreeString(GateRef glue, GateRef obj);
868     inline GateRef IsSlicedString(GateRef glue, GateRef obj);
869     inline GateRef IsSpecialSlicedString(GateRef glue, GateRef obj);
870     inline GateRef IsLineString(GateRef glue, GateRef obj);
871     inline GateRef TreeStringIsFlat(GateRef glue, GateRef string);
872     inline GateRef GetFirstFromTreeString(GateRef glue, GateRef string);
873     inline GateRef GetSecondFromTreeString(GateRef glue, GateRef string);
874     inline GateRef ComputeSizeUtf8(GateRef length);
875     inline GateRef ComputeSizeUtf16(GateRef length);
876     inline GateRef AlignUp(GateRef x, GateRef alignment);
877     GateRef NumberToString(GateRef number);
878     GateRef TaggedPointerToInt64(GateRef x);
879     GateRef GetLengthFromString(GateRef value);
880     GateRef Rotl(GateRef word, uint32_t shift);
881     GateRef CalcHashcodeForInt(GateRef value);
882     GateRef GetHashcodeFromString(GateRef glue, GateRef value, GateRef hir = Circuit::NullGate());
883     GateRef TryGetHashcodeFromString(GateRef string);
884     GateRef CanBeConcat(GateRef glue, GateRef leftString, GateRef rightString, GateRef isValidOpt);
885     GateRef CanBackStore(GateRef glue, GateRef rightString, GateRef isValidOpt);
886     void CopyUtf8AsUtf16(GateRef glue, GateRef dst, GateRef src, GateRef sourceLength);
887     void CopyChars(GateRef glue, GateRef dst, GateRef source, GateRef sourceLength,
888         GateRef charSize, VariableType type);
889     void SetMixHashcode(GateRef glue, GateRef str, GateRef rawHashcode);
890     GateRef StringFromSingleCharCode(GateRef gate);
891     GateRef StringCharCodeAt(GateRef thisValue, GateRef posTag);
892     GateRef StringSubstring(GateRef thisValue, GateRef startTag, GateRef endTag);
893     GateRef StringSubStr(GateRef thisValue, GateRef intStart, GateRef lengthTag);
894     GateRef StringSlice(GateRef thisValue, GateRef startTag, GateRef endTag);
895     GateRef NumberIsNaN(GateRef gate);
896     GateRef NumberParseFloat(GateRef gate, GateRef frameState);
897     GateRef NumberParseInt(GateRef gate, GateRef radix);
898     GateRef NumberIsFinite(GateRef gate);
899     GateRef NumberIsInteger(GateRef gate);
900     GateRef NumberIsSafeInteger(GateRef gate);
901     GateRef ArrayBufferIsView(GateRef gate);
902     GateRef DataViewGet(
903         GateRef thisobj, GateRef index, GateRef dataViewCallID, GateRef isLittleEndian, GateRef frameState);
904     GateRef DataViewSet(GateRef thisobj,
905                         GateRef index,
906                         GateRef value,
907                         GateRef dataViewCallID,
908                         GateRef isLittleEndian,
909                         GateRef frameState);
910     GateRef ArrayIncludesIndexOf(
911         GateRef elements, GateRef target, GateRef fromIndex, GateRef len, GateRef CallID, GateRef ArrayKind);
912     GateRef ArrayIteratorBuiltin(GateRef thisArray, GateRef callID);
913     GateRef ArrayForEach(GateRef thisValue, GateRef callBackFn, GateRef usingThis,
914         GateRef frameState, uint32_t pcOffset);
915     GateRef ArraySort(GateRef thisValue, GateRef callBackFn);
916     GateRef ArrayFilter(
917         GateRef thisValue, GateRef callBackFn, GateRef usingThis, GateRef frameState, uint32_t pcOffset);
918     GateRef ArrayMap(GateRef thisValue, GateRef callBackFn, GateRef usingThis, GateRef frameState, uint32_t pcOffset);
919     GateRef ArraySome(GateRef thisValue, GateRef callBackFn, GateRef usingThis, GateRef frameState, uint32_t pcOffset);
920     GateRef ArrayFindOrFindIndex(GateRef thisValue, GateRef callBackFn,
921         GateRef usingThis, GateRef callIDRef, GateRef frameState, uint32_t pcOffset);
922     GateRef ArrayEvery(GateRef thisValue, GateRef callBackFn, GateRef usingThis, GateRef frameState, uint32_t pcOffset);
923     GateRef ArrayPop(GateRef thisValue, GateRef frameState);
924     GateRef ArrayPush(GateRef thisValue, GateRef value);
925     GateRef ArraySlice(GateRef thisValue, GateRef startIndex, GateRef endIndex, GateRef frameState);
926     GateRef ToNumber(GateRef gate, GateRef value, GateRef glue);
927     GateRef StringToNumber(GateRef gate, GateRef value, GateRef radix, GateRef glue);
928     GateRef IsASCIICharacter(GateRef gate);
929 
930     // for in
931     inline GateRef GetEnumCacheKindFromEnumCache(GateRef enumCache);
932     inline GateRef GetEnumCacheOwnFromEnumCache(GateRef glue, GateRef enumCache);
933     inline GateRef GetEnumCacheAllFromEnumCache(GateRef glue, GateRef enumCache);
934     inline GateRef GetProtoChainInfoEnumCacheFromEnumCache(GateRef glue, GateRef enumCache);
935 
936     GateRef IsEnumCacheValid(GateRef glue, GateRef receiver, GateRef cachedHclass, GateRef kind);
937     GateRef NeedCheckProperty(GateRef glue, GateRef receiver);
938 
939     // ElementsKind Array
940     GateRef MigrateFromRawValueToHeapValues(GateRef object, GateRef needCOW, GateRef isIntKind);
941     GateRef MigrateFromHeapValueToRawValue(GateRef object, GateRef needCOW, GateRef isIntKind);
942     GateRef MigrateFromHoleIntToHoleNumber(GateRef object);
943     GateRef MigrateFromHoleNumberToHoleInt(GateRef object);
944 
945     // **************************** Low IR *******************************
946     inline GateRef Equal(GateRef x, GateRef y, const char* comment = nullptr);
947     inline GateRef NotEqual(GateRef x, GateRef y, const char* comment = nullptr);
948     inline GateRef IntPtrAdd(GateRef x, GateRef y);
949     inline GateRef IntPtrSub(GateRef x, GateRef y);
950     inline GateRef IntPtrMul(GateRef x, GateRef y);
951     inline GateRef IntPtrDiv(GateRef x, GateRef y);
952     inline GateRef IntPtrOr(GateRef x, GateRef y);
953     inline GateRef IntPtrLSL(GateRef x, GateRef y);
954     inline GateRef IntPtrLSR(GateRef x, GateRef y);
955     inline GateRef Int64NotEqual(GateRef x, GateRef y);
956     inline GateRef Int32NotEqual(GateRef x, GateRef y);
957     inline GateRef Int64Equal(GateRef x, GateRef y);
958     inline GateRef Int8Equal(GateRef x, GateRef y);
959     inline GateRef Int32Equal(GateRef x, GateRef y);
960     inline GateRef IntPtrLessThan(GateRef x, GateRef y);
961     inline GateRef IntPtrLessThanOrEqual(GateRef x, GateRef y);
962     inline GateRef IntPtrGreaterThan(GateRef x, GateRef y);
963     inline GateRef IntPtrGreaterThanOrEqual(GateRef x, GateRef y);
964     inline GateRef IntPtrAnd(GateRef x, GateRef y);
965     inline GateRef IntPtrNot(GateRef x);
966     inline GateRef IntPtrEqual(GateRef x, GateRef y);
967     GateRef DoubleTrunc(GateRef glue, GateRef gate, GateRef value, const char* comment = nullptr);
968     GateRef AddWithOverflow(GateRef left, GateRef right);
969     GateRef SubWithOverflow(GateRef left, GateRef right);
970     GateRef MulWithOverflow(GateRef left, GateRef right);
971     GateRef ExtractValue(MachineType mt, GateRef pointer, GateRef index);
972     GateRef Sqrt(GateRef param);
973     MachineType GetMachineTypeOfValueType(ValueType type);
974     GateRef Alloca(size_t size);
975     GateRef ReadSp();
976     GateRef BinaryArithmetic(const GateMetaData* meta, MachineType machineType, GateRef left,
977                              GateRef right, GateType gateType = GateType::Empty(), const char* comment = nullptr);
978     GateRef BinaryCmp(const GateMetaData* meta, GateRef left, GateRef right, const char* comment = nullptr);
979 
980     GateRef NeedSkipReadBarrier(GateRef glue);
981 
982     // Load
983     GateRef Load(VariableType type, GateRef glue, GateRef base, GateRef offset,
984         MemoryAttribute mAttr = MemoryAttribute::NeedBarrier());
985     GateRef Load(VariableType type, GateRef glue, GateRef base, GateRef offset, GateRef depend,
986         MemoryAttribute mAttr = MemoryAttribute::NeedBarrier());
987 
988     // LoadWithoutBarrier
989     GateRef LoadWithoutBarrier(VariableType type, GateRef base, GateRef offset,
990         MemoryAttribute mAttr = MemoryAttribute::Default());
991     GateRef LoadWithoutBarrier(VariableType type, GateRef base, GateRef offset, GateRef depend,
992         MemoryAttribute mAttr = MemoryAttribute::Default());
993     GateRef LoadFromAddressWithoutBarrier(VariableType type, GateRef addr,
994         MemoryAttribute mAttr = MemoryAttribute::Default());
995 
996     void Store(VariableType type, GateRef glue, GateRef base, GateRef offset, GateRef value,
997                MemoryAttribute mAttr = MemoryAttribute::Default());
998     GateRef FetchOr(GateRef ptr, GateRef value, MemoryAttribute mAttr);
999     void StoreHClass(VariableType type, GateRef glue, GateRef base, GateRef offset, GateRef value, GateRef compValue,
1000                      MemoryAttribute mAttr = MemoryAttribute::Default());
1001     void StoreWithoutBarrier(VariableType type, GateRef addr, GateRef value,
1002                              MemoryAttribute mAttr = MemoryAttribute::Default());
1003     GateRef ThreeInt64Min(GateRef first, GateRef second, GateRef third);
1004 
1005     // cast operation
1006     inline GateRef Int16ToBigEndianInt16(GateRef x);
1007     inline GateRef Int32ToBigEndianInt32(GateRef x);
1008     inline GateRef Int64ToBigEndianInt64(GateRef x);
1009     inline GateRef GetInt64OfTInt(GateRef x);
1010     inline GateRef GetInt32OfTInt(GateRef x);
1011     inline GateRef GetInt32OfTNumber(GateRef x);
1012     inline GateRef TaggedCastToIntPtr(GateRef x);
1013     inline GateRef GetDoubleOfTInt(GateRef x);
1014     inline GateRef GetDoubleOfTDouble(GateRef x);
1015     inline GateRef GetBooleanOfTBoolean(GateRef x);
1016     GateRef GetDoubleOfTNumber(GateRef x);
1017     GateRef TruncDoubleToInt(GateRef glue, GateRef x, size_t typeBits);
1018     GateRef DoubleToIntOverflowCheck(GateRef x, size_t typeBits);
1019     GateRef SaturateTruncDoubleToInt32(GateRef glue, GateRef x);
1020     GateRef DoubleCheckINFInRangeInt32(GateRef x);
1021     GateRef DoubleInRangeInt32(GateRef x);
1022     inline GateRef Int32ToTaggedPtr(GateRef x);
1023     inline GateRef Int64ToTaggedPtr(GateRef x);
1024     inline GateRef Int32ToTaggedInt(GateRef x);
1025     inline GateRef ToTaggedInt(GateRef x);
1026     inline GateRef ToTaggedIntPtr(GateRef x);
1027     inline GateRef DoubleToTaggedDoublePtr(GateRef x);
1028     inline GateRef DoubleIsImpureNaN(GateRef x);
1029     inline GateRef BooleanToTaggedBooleanPtr(GateRef x);
1030     inline GateRef BooleanToInt32(GateRef x);
1031     inline GateRef BooleanToFloat64(GateRef x);
1032     inline GateRef Float32ToTaggedDoublePtr(GateRef x);
1033     inline GateRef TaggedDoublePtrToFloat32(GateRef x);
1034     inline GateRef TaggedIntPtrToFloat32(GateRef x);
1035     inline GateRef DoubleToTaggedDouble(GateRef x);
1036     inline GateRef DoubleToTagged(GateRef x);
1037     inline GateRef DoubleIsNAN(GateRef x);
1038     inline GateRef DoubleIsINF(GateRef x);
1039     inline GateRef DoubleIsNanOrInf(GateRef x);
1040     GateRef DoubleIsWithinInt32(GateRef x);
1041     static MachineType GetMachineTypeFromVariableType(VariableType type);
1042     GateRef FastToBoolean(GateRef glue, GateRef value);
1043 
1044     // Opcode with control and depend inputs from label and value inputs args
1045     GateRef BuildControlDependOp(const GateMetaData* op, std::vector<GateRef> args,
1046                                  std::vector<GateRef> frameStates = {});
1047     template<OpCode Op, MachineType Type>
1048     inline GateRef BinaryOp(GateRef x, GateRef y);
1049     template<OpCode Op, MachineType Type>
1050     inline GateRef BinaryOpWithOverflow(GateRef x, GateRef y);
1051 
1052     GateRef BuildTypedArrayIterator(GateRef gate, const GateMetaData* op);
1053     GateRef IsStableArrayLengthWriteable(GateRef glue, GateRef array);
1054 
1055 #define ARITHMETIC_BINARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID)                                        \
1056     inline GateRef NAME(GateRef x, GateRef y, GateType type = GateType::Empty(), const char* comment = nullptr)  \
1057     {                                                                                                            \
1058         return BinaryArithmetic(circuit_->OPCODEID(), MACHINETYPEID, x, y, type, comment);                       \
1059     }
1060 
1061     BINARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(ARITHMETIC_BINARY_OP_WITH_BITWIDTH)
1062 #undef ARITHMETIC_BINARY_OP_WITH_BITWIDTH
1063 
1064 #define ARITHMETIC_UNARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID)                                     \
1065     inline GateRef NAME(GateRef x, const char* comment = nullptr)                                            \
1066     {                                                                                                        \
1067         return circuit_->NewGate(circuit_->OPCODEID(), MACHINETYPEID, { x }, GateType::NJSValue(), comment); \
1068     }
1069 
1070     UNARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(ARITHMETIC_UNARY_OP_WITH_BITWIDTH)
1071 #undef ARITHMETIC_UNARY_OP_WITH_BITWIDTH
1072 
1073 #define CMP_BINARY_OP_WITHOUT_BITWIDTH(NAME, OPCODEID, CONDITION)                                \
1074     inline GateRef NAME(GateRef x, GateRef y, const char* comment = nullptr)                     \
1075     {                                                                                            \
1076         return BinaryCmp(circuit_->OPCODEID(static_cast<uint64_t>(CONDITION)), x, y, comment);   \
1077     }
1078 
1079     BINARY_CMP_METHOD_LIST_WITHOUT_BITWIDTH(CMP_BINARY_OP_WITHOUT_BITWIDTH)
1080 #undef CMP_BINARY_OP_WITHOUT_BITWIDTH
1081 
1082 private:
1083 
1084     std::vector<GateRef> ConcatParams(const std::vector<std::vector<GateRef>>& params);
1085     static constexpr uint32_t GATE_TWO_VALUESIN = 2;
1086 
1087     inline void SetDepend(GateRef depend);
1088     inline void SetState(GateRef state);
1089 
1090     template <class LabelPtrGetter>
1091     void SwitchGeneric(GateRef index, Label *defaultLabel, Span<const int64_t> keysValue,
1092                        LabelPtrGetter getIthLabelFn);
1093 
1094 #define ARITHMETIC_UNARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID)                                     \
1095     inline GateRef NAME(GateRef x, const char* comment = nullptr)                                            \
1096     {                                                                                                        \
1097         return circuit_->NewGate(circuit_->OPCODEID(), MACHINETYPEID, { x }, GateType::NJSValue(), comment); \
1098     }
1099 
1100 #undef ARITHMETIC_UNARY_OP_WITH_BITWIDTH
1101 
1102     Circuit *circuit_ {nullptr};
1103     GateAccessor acc_;
1104     Environment *env_ {nullptr};
1105     CompilationConfig *cmpCfg_ {nullptr};
1106     friend StubBuilder;
1107     friend BuiltinsStringStubBuilder;
1108     friend BuiltinsTypedArrayStubBuilder;
1109     friend TypedBytecodeLowering;
1110     friend NTypeBytecodeLowering;
1111     friend PGOHCRLowering;
1112     friend TSHCRLowering;
1113     friend NTypeHCRLowering;
1114     friend SlowPathLowering;
1115     friend NativeInlineLowering;
1116     friend TypedHCRLowering;
1117     friend TypedNativeInlineLowering;
1118     friend PostSchedule;
1119     friend TSHCROptPass;
1120     friend BuiltinLowering;
1121 };
1122 
1123 class LogicAndBuilder {
1124 public:
1125     inline LogicAndBuilder(Environment *env);
1126     inline ~LogicAndBuilder();
1127     NO_MOVE_SEMANTIC(LogicAndBuilder);
1128     NO_COPY_SEMANTIC(LogicAndBuilder);
1129 
1130     inline LogicAndBuilder &And(GateRef check);
1131 
1132     inline GateRef Done();
1133 private:
1134     Environment *env_ {nullptr};
1135     CircuitBuilder *builder_ {nullptr};
1136     Label *subentry_ {nullptr};
1137     Variable *result_ {nullptr};
1138     Label *exit_ {nullptr};
1139     std::vector<Label*> labels_;
1140 };
1141 
1142 class LogicOrBuilder {
1143 public:
1144     inline LogicOrBuilder(Environment *env);
1145     inline ~LogicOrBuilder();
1146     NO_MOVE_SEMANTIC(LogicOrBuilder);
1147     NO_COPY_SEMANTIC(LogicOrBuilder);
1148 
1149     inline LogicOrBuilder &Or(GateRef check);
1150 
1151     inline GateRef Done();
1152 private:
1153     Environment *env_ {nullptr};
1154     CircuitBuilder *builder_ {nullptr};
1155     Label *subentry_ {nullptr};
1156     Variable *result_ {nullptr};
1157     Label *exit_ {nullptr};
1158     std::vector<Label*> labels_;
1159 };
1160 }  // namespace panda::ecmascript::kungfu
1161 
1162 #endif  // ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H
1163