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