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