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
33namespace panda::ecmascript::kungfu {
34using namespace panda::ecmascript;
35#define DEFVALUE(varname, cirBuilder, type, val) \
36        Variable varname(cirBuilder, type, cirBuilder->NextVariableId(), val)
37
38class BuiltinsTypedArrayStubBuilder;
39class BuiltinsStringStubBuilder;
40class CompilationConfig;
41class Environment;
42class Label;
43class NTypeBytecodeLowering;
44class SlowPathLowering;
45class StubBuilder;
46class TypedBytecodeLowering;
47class PGOHCRLowering;
48class NTypeHCRLowering;
49class TSHCRLowering;
50class Variable;
51class NativeInlineLowering;
52class TypedHCRLowering;
53class TypedNativeInlineLowering;
54class StringBuilderOptimizer;
55class PostSchedule;
56class 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
177class CircuitBuilder {
178public:
179    explicit CircuitBuilder(Circuit *circuit) : circuit_(circuit), acc_(circuit) {}
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    GateRef ElementsKindHasHole(GateRef kind);
275
276    GateRef LoadBuiltinObject(size_t offset);
277
278    // Get
279    GateRef GetConstPoolFromFunction(GateRef jsFunc);
280    GateRef GetUnsharedConstpoolFromGlue(GateRef glue, GateRef constpool);
281    GateRef GetUnsharedConstpoolIndex(GateRef constpool);
282    GateRef GetUnsharedConstpool(GateRef arrayAddr, GateRef index);
283    GateRef GetCodeAddr(GateRef jsFunc);
284    GateRef GetBaselineCodeAddr(GateRef baselineCode);
285    GateRef GetObjectByIndexFromConstPool(GateRef glue, GateRef hirGate, GateRef frameState, GateRef index,
286                                   ConstPoolType type);
287    GateRef GetObjectFromConstPool(GateRef glue, GateRef hirGate, GateRef shardConstPool, GateRef unsharedConstPool,
288                                   GateRef module, GateRef index, ConstPoolType type);
289    GateRef GetFunctionLexicalEnv(GateRef function);
290    GateRef GetGlobalEnv();
291    GateRef GetGlobalEnvObj(GateRef env, size_t index);
292    GateRef GetGlobalEnvObjHClass(GateRef env, size_t index);
293    GateRef GetGlobalConstantValue(ConstantIndex index);
294    GateRef GetGlobalEnvValue(VariableType type, GateRef env, size_t index);
295    GateRef GetGlobalObject(GateRef glue);
296    GateRef GetMethodFromFunction(GateRef function);
297    GateRef GetModuleFromFunction(GateRef function);
298    GateRef GetSendableEnvFromModule(GateRef module);
299    GateRef GetHomeObjectFromFunction(GateRef function);
300    GateRef GetHClassGateFromIndex(GateRef gate, int32_t index);
301    GateRef GetProfileTypeInfo(GateRef function);
302    inline GateRef GetExpectedNumOfArgs(GateRef method);
303    inline GateRef GetGlobalConstantOffset(ConstantIndex index); // shareir
304    GateRef GetEmptyArray(GateRef glue);
305    GateRef GetPrototypeFromHClass(GateRef hClass);
306    GateRef GetEnumCacheFromHClass(GateRef hClass);
307    GateRef GetProtoChangeMarkerFromHClass(GateRef hClass);
308    GateRef GetLengthFromForInIterator(GateRef iter);
309    GateRef GetIndexFromForInIterator(GateRef iter);
310    GateRef GetKeysFromForInIterator(GateRef iter);
311    GateRef GetObjectFromForInIterator(GateRef iter);
312    GateRef GetCachedHclassFromForInIterator(GateRef iter);
313    void SetLengthOfForInIterator(GateRef glue, GateRef iter, GateRef length);
314    void SetIndexOfForInIterator(GateRef glue, GateRef iter, GateRef index);
315    void SetKeysOfForInIterator(GateRef glue, GateRef iter, GateRef keys);
316    void SetObjectOfForInIterator(GateRef glue, GateRef iter, GateRef object);
317    void SetCachedHclassOfForInIterator(GateRef glue, GateRef iter, GateRef hclass);
318    void IncreaseInteratorIndex(GateRef glue, GateRef iter, GateRef index);
319    void SetNextIndexOfArrayIterator(GateRef glue, GateRef iter, GateRef nextIndex);
320    void SetIteratedArrayOfArrayIterator(GateRef glue, GateRef iter, GateRef iteratedArray);
321    void SetBitFieldOfArrayIterator(GateRef glue, GateRef iter, GateRef kind);
322    GateRef GetHasChanged(GateRef object);
323    GateRef GetAccessorHasChanged(GateRef object);
324    GateRef HasDeleteProperty(GateRef hClass);
325    GateRef IsOnHeap(GateRef hClass);
326    GateRef IsEcmaObject(GateRef obj);
327
328    // Set
329    void SetLengthToFunction(GateRef glue, GateRef function, GateRef value);
330    void SetLexicalEnvToFunction(GateRef glue, GateRef function, GateRef value);
331    void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value);
332    void SetModuleToFunction(GateRef glue, GateRef function, GateRef value);
333    void SetSendableEnvToModule(GateRef glue, GateRef module, GateRef value);
334    void SetRawProfileTypeInfoToFunction(GateRef glue, GateRef function, GateRef value);
335    void UpdateProfileTypeInfoCellToFunction(GateRef glue, GateRef function,
336                                             GateRef profileTypeInfo, GateRef slotId);
337    void UpdateProfileTypeInfoCellType(GateRef glue, GateRef profileTypeInfoCell);
338
339    GateRef FunctionIsResolved(GateRef function);
340    GateRef HasPendingException(GateRef glue); // shareir
341    GateRef IsUtf8String(GateRef string);
342    GateRef IsUtf16String(GateRef string);
343    GateRef LoadObjectFromConstPool(GateRef constPool, GateRef index);
344    GateRef IsAccessorInternal(GateRef accessor);
345
346    // label related
347    void NewEnvironment(GateRef hir);
348    void DeleteCurrentEnvironment();
349    inline int NextVariableId();
350    inline void HandleException(GateRef result, Label *success, Label *exception, Label *exit);
351    inline void HandleException(GateRef result, Label *success, Label *fail, Label *exit, GateRef exceptionVal);
352    inline void SubCfgEntry(Label *entry);
353    inline void SubCfgExit();
354    inline GateRef Return(GateRef value);
355    inline GateRef Return();
356    inline void Bind(Label *label);
357    inline void Bind(Label *label, bool justSlowPath);
358    void Jump(Label *label);
359    void Branch(GateRef condition, Label *trueLabel, Label *falseLabel,
360                uint32_t trueWeight = 1, uint32_t falseWeight = 1, const char* comment = nullptr);
361    void Switch(GateRef index, Label *defaultLabel, int64_t *keysValue, Label *keysLabel, int numberOfKeys);
362    void LoopBegin(Label *loopHead);
363    void LoopEnd(Label *loopHead);
364    void LoopExit(const std::vector<Variable*> &vars, size_t diff = 1);
365    inline Label *GetCurrentLabel() const;
366    inline GateRef GetState() const;
367    inline GateRef GetDepend() const;
368    inline StateDepend GetStateDepend() const;
369
370    Circuit *GetCircuit() const
371    {
372        return circuit_;
373    }
374
375    void SetEnvironment(Environment *env)
376    {
377        env_ = env;
378    }
379    Environment *GetCurrentEnvironment() const
380    {
381        return env_;
382    }
383    void SetCompilationConfig(CompilationConfig *cmpCfg)
384    {
385        cmpCfg_ = cmpCfg;
386    }
387    CompilationConfig *GetCompilationConfig() const
388    {
389        return cmpCfg_;
390    }
391
392    // **************************** High IR ******************************
393    GateRef CreateArray(ElementsKind kind, uint32_t arraySize, GateRef elementsLength, RegionSpaceFlag flag);
394    GateRef CreateArrayWithBuffer(ElementsKind kind, ArrayMetaDataAccessor::Mode mode, GateRef cpId,
395                                  GateRef constPoolIndex, RegionSpaceFlag flag);
396    GateRef CreateArguments(ElementsKind kind, CreateArgumentsAccessor::Mode mode, GateRef restIdx);
397    GateRef Construct(GateRef hirGate, std::vector<GateRef> args);
398    GateRef CallNew(GateRef hirGate, std::vector<GateRef> args, bool needPushArgv = false);
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 StringCharCodeAt(GateRef thisValue, GateRef posTag);
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    inline GateRef IntPtrEqual(GateRef x, GateRef y);
834    GateRef DoubleTrunc(GateRef gate, GateRef value, const char* comment = nullptr);
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
930private:
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
966class LogicAndBuilder {
967public:
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();
976private:
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
985class LogicOrBuilder {
986public:
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();
995private:
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