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