• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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/circuit.h"
23 #include "ecmascript/compiler/call_signature.h"
24 #include "ecmascript/compiler/gate.h"
25 #include "ecmascript/compiler/gate_accessor.h"
26 #include "ecmascript/compiler/variable_type.h"
27 #include "ecmascript/global_env_constants.h"
28 #include "ecmascript/compiler/pgo_type/pgo_type_location.h"
29 #include "ecmascript/jspandafile/constpool_value.h"
30 #include "ecmascript/js_hclass.h"
31 #include "ecmascript/js_runtime_options.h"
32 #include "ecmascript/js_tagged_value.h"
33 #include "ecmascript/tagged_array.h"
34 #include <cstdint>
35 
36 namespace panda::ecmascript::kungfu {
37 using namespace panda::ecmascript;
38 #define DEFVALUE(varname, cirBuilder, type, val) \
39         Variable varname(cirBuilder, type, cirBuilder->NextVariableId(), val)
40 
41 class BuiltinsStringStubBuilder;
42 class CompilationConfig;
43 class Environment;
44 class Label;
45 class NTypeBytecodeLowering;
46 class SlowPathLowering;
47 class StubBuilder;
48 class TypedBytecodeLowering;
49 class PGOHCRLowering;
50 class NTypeHCRLowering;
51 class TSHCRLowering;
52 class Variable;
53 class NativeInlineLowering;
54 class TypedHCRLowering;
55 class StringBuilderOptimizer;
56 
57 #define BINARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(V)                    \
58     V(Int16Add, Add, MachineType::I16)                                    \
59     V(Int32Add, Add, MachineType::I32)                                    \
60     V(Int64Add, Add, MachineType::I64)                                    \
61     V(DoubleAdd, Add, MachineType::F64)                                   \
62     V(PtrAdd, Add, MachineType::ARCH)                                     \
63     V(Int16Sub, Sub, MachineType::I16)                                    \
64     V(Int32Sub, Sub, MachineType::I32)                                    \
65     V(Int64Sub, Sub, MachineType::I64)                                    \
66     V(DoubleSub, Sub, MachineType::F64)                                   \
67     V(PtrSub, Sub, MachineType::ARCH)                                     \
68     V(Int32Mul, Mul, MachineType::I32)                                    \
69     V(Int64Mul, Mul, MachineType::I64)                                    \
70     V(DoubleMul, Mul, MachineType::F64)                                   \
71     V(PtrMul, Mul, MachineType::ARCH)                                     \
72     V(Int32Div, Sdiv, MachineType::I32)                                   \
73     V(Int64Div, Sdiv, MachineType::I64)                                   \
74     V(DoubleDiv, Fdiv, MachineType::F64)                                  \
75     V(Int32Mod, Smod, MachineType::I32)                                   \
76     V(DoubleMod, Smod, MachineType::F64)                                  \
77     V(BoolAnd, And, MachineType::I1)                                      \
78     V(Int8And, And, MachineType::I8)                                      \
79     V(Int32And, And, MachineType::I32)                                    \
80     V(Int64And, And, MachineType::I64)                                    \
81     V(BoolOr, Or, MachineType::I1)                                        \
82     V(Int32Or, Or, MachineType::I32)                                      \
83     V(Int64Or, Or, MachineType::I64)                                      \
84     V(Int32Xor, Xor, MachineType::I32)                                    \
85     V(Int64Xor, Xor, MachineType::I64)                                    \
86     V(Int16LSL, Lsl, MachineType::I16)                                    \
87     V(Int32LSL, Lsl, MachineType::I32)                                    \
88     V(Int64LSL, Lsl, MachineType::I64)                                    \
89     V(Int8LSR, Lsr, MachineType::I8)                                      \
90     V(Int32LSR, Lsr, MachineType::I32)                                    \
91     V(Int64LSR, Lsr, MachineType::I64)                                    \
92     V(Int32ASR, Asr, MachineType::I32)                                    \
93     V(Int64ASR, Asr, MachineType::I64)
94 
95 #define UNARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(V)                  \
96     V(BoolNot, Rev, MachineType::I1)                                   \
97     V(Int32Not, Rev, MachineType::I32)                                 \
98     V(Int64Not, Rev, MachineType::I64)                                 \
99     V(CastDoubleToInt64, Bitcast, MachineType::I64)                    \
100     V(CastInt64ToFloat64, Bitcast, MachineType::F64)                   \
101     V(CastInt32ToFloat32, Bitcast, MachineType::F32)                   \
102     V(SExtInt32ToInt64, Sext, MachineType::I64)                        \
103     V(SExtInt1ToInt64, Sext, MachineType::I64)                         \
104     V(SExtInt1ToInt32, Sext, MachineType::I32)                         \
105     V(ZExtInt8ToInt16, Zext, MachineType::I16)                         \
106     V(ZExtInt32ToInt64, Zext, MachineType::I64)                        \
107     V(ZExtInt1ToInt64, Zext, MachineType::I64)                         \
108     V(ZExtInt1ToInt32, Zext, MachineType::I32)                         \
109     V(ZExtInt8ToInt32, Zext, MachineType::I32)                         \
110     V(ZExtInt8ToInt64, Zext, MachineType::I64)                         \
111     V(ZExtInt8ToPtr, Zext, MachineType::ARCH)                          \
112     V(ZExtInt16ToPtr, Zext, MachineType::ARCH)                         \
113     V(ZExtInt32ToPtr, Zext, MachineType::ARCH)                         \
114     V(SExtInt32ToPtr, Sext, MachineType::ARCH)                         \
115     V(ZExtInt16ToInt32, Zext, MachineType::I32)                        \
116     V(ZExtInt16ToInt64, Zext, MachineType::I64)                        \
117     V(TruncInt16ToInt8, Trunc, MachineType::I8)                        \
118     V(TruncInt64ToInt32, Trunc, MachineType::I32)                      \
119     V(TruncPtrToInt32, Trunc, MachineType::I32)                        \
120     V(TruncInt64ToInt1, Trunc, MachineType::I1)                        \
121     V(TruncInt64ToInt16, Trunc, MachineType::I16)                      \
122     V(TruncInt32ToInt1, Trunc, MachineType::I1)                        \
123     V(TruncInt32ToInt8, Trunc, MachineType::I8)                        \
124     V(TruncInt32ToInt16, Trunc, MachineType::I16)                      \
125     V(TruncFloatToInt64, TruncFloatToInt64, MachineType::I64)          \
126     V(TruncFloatToInt32, TruncFloatToInt32, MachineType::I32)          \
127     V(ExtFloat32ToDouble, Fext, MachineType::F64)                      \
128     V(TruncDoubleToFloat32, Ftrunc, MachineType::F32)                  \
129     V(ChangeInt32ToFloat64, SignedIntToFloat, MachineType::F64)        \
130     V(ChangeInt32ToFloat32, SignedIntToFloat, MachineType::F32)        \
131     V(ChangeUInt32ToFloat64, UnsignedIntToFloat, MachineType::F64)     \
132     V(ChangeFloat64ToInt32, FloatToSignedInt, MachineType::I32)        \
133     V(SExtInt16ToInt64, Sext, MachineType::I64)                        \
134     V(SExtInt16ToInt32, Sext, MachineType::I32)                        \
135     V(SExtInt8ToInt32, Sext, MachineType::I32)                         \
136     V(SExtInt8ToInt64, Sext, MachineType::I64)
137 
138 #define UNARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH_PRIVATE(V)          \
139     V(ChangeTaggedPointerToInt64, TaggedToInt64, MachineType::I64)
140 
141 #define BINARY_CMP_METHOD_LIST_WITHOUT_BITWIDTH(V)                                      \
142     V(DoubleLessThan, Fcmp, static_cast<BitField>(FCmpCondition::OLT))                  \
143     V(DoubleLessThanOrEqual, Fcmp, static_cast<BitField>(FCmpCondition::OLE))           \
144     V(DoubleGreaterThan, Fcmp, static_cast<BitField>(FCmpCondition::OGT))               \
145     V(DoubleGreaterThanOrEqual, Fcmp, static_cast<BitField>(FCmpCondition::OGE))        \
146     V(DoubleEqual, Fcmp, static_cast<BitField>(FCmpCondition::OEQ))                     \
147     V(DoubleNotEqual, Fcmp, static_cast<BitField>(FCmpCondition::ONE))                  \
148     V(Int32LessThan, Icmp, static_cast<BitField>(ICmpCondition::SLT))                   \
149     V(Int32LessThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SLE))            \
150     V(Int32GreaterThan, Icmp, static_cast<BitField>(ICmpCondition::SGT))                \
151     V(Int32GreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SGE))         \
152     V(Int32UnsignedLessThan, Icmp, static_cast<BitField>(ICmpCondition::ULT))           \
153     V(Int32UnsignedLessThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::ULE))    \
154     V(Int32UnsignedGreaterThan, Icmp, static_cast<BitField>(ICmpCondition::UGT))        \
155     V(Int32UnsignedGreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::UGE)) \
156     V(Int64LessThan, Icmp, static_cast<BitField>(ICmpCondition::SLT))                   \
157     V(Int64LessThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SLE))            \
158     V(Int64GreaterThan, Icmp, static_cast<BitField>(ICmpCondition::SGT))                \
159     V(Int64GreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SGE))         \
160     V(Int64UnsignedLessThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::ULE))
161 
162 class CircuitBuilder {
163 public:
CircuitBuilder(Circuit * circuit)164     explicit CircuitBuilder(Circuit *circuit) : circuit_(circuit), acc_(circuit) {}
CircuitBuilder(Circuit * circuit,CompilationConfig * cmpCfg)165     CircuitBuilder(Circuit *circuit, CompilationConfig *cmpCfg)
166         : circuit_(circuit), acc_(circuit), cmpCfg_(cmpCfg)
167     {
168     }
169     ~CircuitBuilder() = default;
170     NO_MOVE_SEMANTIC(CircuitBuilder);
171     NO_COPY_SEMANTIC(CircuitBuilder);
172 
173     enum JudgeMethodType {
174         HAS_AOT,
175         HAS_AOT_FASTCALL,
176         HAS_AOT_NOTFASTCALL,
177     };
178 
179     // **************************** Share IR *****************************
180     GateRef Arguments(size_t index);
181     GateRef DefaultCase(GateRef switchBranch);
182     GateRef DependRelay(GateRef state, GateRef depend);
183     GateRef DeoptCheck(GateRef condition, GateRef frameState, DeoptType type);
184     GateRef GetElementsArray(GateRef object);
185     GateRef GetLengthOfTaggedArray(GateRef array);
186     GateRef GetSuperConstructor(GateRef ctor);
187     GateRef Merge(const std::vector<GateRef> &inList);
188     GateRef Selector(OpCode opcode, MachineType machineType, GateRef control, const std::vector<GateRef> &values,
189         int valueCounts, VariableType type = VariableType::VOID());
190     GateRef Selector(OpCode opcode, GateRef control, const std::vector<GateRef> &values,
191         int valueCounts, VariableType type = VariableType::VOID());
192     GateRef Return(GateRef state, GateRef depend, GateRef value);
193     GateRef ReturnVoid(GateRef state, GateRef depend);
194     GateRef Goto(GateRef state);
195     GateRef LoopBegin(GateRef state);
196     GateRef LoopEnd(GateRef state);
197     GateRef LoopExit(GateRef state);
198     GateRef LoopExitDepend(GateRef state, GateRef depend);
199     GateRef LoopExitValue(GateRef state, GateRef value);
200     GateRef IfTrue(GateRef ifBranch);
201     GateRef IfFalse(GateRef ifBranch);
202     GateRef IsJsCOWArray(GateRef obj);
203     GateRef IsCOWArray(GateRef objectType);
204     GateRef IsTaggedArray(GateRef object);
205     GateRef IsMutantTaggedArray(GateRef objectType);
206     GateRef SwitchCase(GateRef switchBranch, int64_t value);
207     GateRef Int8(int8_t val);
208     GateRef Int16(int16_t val);
209     GateRef Int32(int32_t value);
210     GateRef Int64(int64_t value);
211     GateRef IntPtr(int64_t val);
212     GateRef StringPtr(std::string_view str);
213     GateRef StringPtr(const std::string &str);
214     GateRef Boolean(bool value);
215     GateRef Double(double value);
216     GateRef UndefineConstant();
217     GateRef HoleConstant();
218     GateRef SpecialHoleConstant();
219     GateRef NullPtrConstant();
220     GateRef NullConstant();
221     GateRef ExceptionConstant();
222     void ClearConstantCache(GateRef gate);
223     GateRef NanValue();
224     GateRef RelocatableData(uint64_t val);
225     GateRef Branch(GateRef state, GateRef condition, uint32_t leftWeight = 1, uint32_t rightWeight = 1,
226                    const char* comment = nullptr);  // 1: default branch weight
227     GateRef SwitchBranch(GateRef state, GateRef index, int caseCounts);
228     void AppendFrameArgs(std::vector<GateRef> &args, GateRef hirGate);
229     inline GateRef True();
230     inline GateRef False();
231     inline GateRef Undefined();
232     inline GateRef Hole();
233 
234     GateRef LoadBuiltinObject(size_t offset);
235 
236     // Get
237     GateRef GetConstPool(GateRef jsFunc);
238     GateRef GetConstPoolFromFunction(GateRef jsFunc);
239     GateRef GetCodeAddr(GateRef method);
240     GateRef GetObjectFromConstPool(GateRef glue, GateRef hirGate, GateRef jsFunc, GateRef index, ConstPoolType type);
241     GateRef GetObjectFromConstPool(GateRef glue, GateRef hirGate, GateRef constPool, GateRef module, GateRef index,
242                                    ConstPoolType type);
243     GateRef GetFunctionLexicalEnv(GateRef function);
244     GateRef GetGlobalEnv();
245     GateRef GetGlobalEnvObj(GateRef env, size_t index);
246     GateRef GetGlobalEnvObjHClass(GateRef env, size_t index);
247     GateRef GetGlobalConstantValue(ConstantIndex index);
248     GateRef GetGlobalEnvValue(VariableType type, GateRef env, size_t index);
249     GateRef GetGlobalObject(GateRef glue);
250     GateRef GetMethodFromFunction(GateRef function);
251     GateRef GetModuleFromFunction(GateRef function);
252     GateRef GetHomeObjectFromFunction(GateRef function);
253     GateRef GetHClassGateFromIndex(GateRef gate, int32_t index);
254     inline GateRef GetExpectedNumOfArgs(GateRef method);
255     inline GateRef GetGlobalConstantOffset(ConstantIndex index); // shareir
256     GateRef GetEmptyArray(GateRef glue);
257     GateRef GetPrototypeFromHClass(GateRef hClass);
258     GateRef GetEnumCacheFromHClass(GateRef hClass);
259     GateRef GetProtoChangeMarkerFromHClass(GateRef hClass);
260     GateRef GetLengthFromForInIterator(GateRef iter);
261     GateRef GetIndexFromForInIterator(GateRef iter);
262     GateRef GetKeysFromForInIterator(GateRef iter);
263     GateRef GetObjectFromForInIterator(GateRef iter);
264     GateRef GetCachedHclassFromForInIterator(GateRef iter);
265     void SetLengthOfForInIterator(GateRef glue, GateRef iter, GateRef length);
266     void SetIndexOfForInIterator(GateRef glue, GateRef iter, GateRef index);
267     void SetKeysOfForInIterator(GateRef glue, GateRef iter, GateRef keys);
268     void SetObjectOfForInIterator(GateRef glue, GateRef iter, GateRef object);
269     void SetCachedHclassOfForInIterator(GateRef glue, GateRef iter, GateRef hclass);
270     void IncreaseInteratorIndex(GateRef glue, GateRef iter, GateRef index);
271     void SetNextIndexOfArrayIterator(GateRef glue, GateRef iter, GateRef nextIndex);
272     void SetIteratedArrayOfArrayIterator(GateRef glue, GateRef iter, GateRef iteratedArray);
273     void SetBitFieldOfArrayIterator(GateRef glue, GateRef iter, GateRef kind);
274     GateRef GetHasChanged(GateRef object);
275     GateRef GetAccessorHasChanged(GateRef object);
276     GateRef HasDeleteProperty(GateRef hClass);
277     GateRef IsOnHeap(GateRef hClass);
278     GateRef IsEcmaObject(GateRef obj);
279 
280     // Set
281     void SetLengthToFunction(GateRef glue, GateRef function, GateRef value);
282     void SetLexicalEnvToFunction(GateRef glue, GateRef function, GateRef value);
283     void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value);
284 
285     inline GateRef LogicAnd(GateRef x, GateRef y);
286     inline GateRef LogicOr(GateRef x, GateRef y);
287     GateRef FunctionIsResolved(GateRef function);
288     GateRef HasPendingException(GateRef glue); // shareir
289     GateRef IsUtf8String(GateRef string);
290     GateRef IsUtf16String(GateRef string);
291     GateRef LoadObjectFromConstPool(GateRef jsFunc, GateRef index);
292     GateRef IsAccessorInternal(GateRef accessor);
293 
294     // label related
295     void NewEnvironment(GateRef hir);
296     void DeleteCurrentEnvironment();
297     inline int NextVariableId();
298     inline void HandleException(GateRef result, Label *success, Label *exception, Label *exit);
299     inline void HandleException(GateRef result, Label *success, Label *fail, Label *exit, GateRef exceptionVal);
300     inline void SubCfgEntry(Label *entry);
301     inline void SubCfgExit();
302     inline GateRef Return(GateRef value);
303     inline GateRef Return();
304     inline void Bind(Label *label);
305     inline void Bind(Label *label, bool justSlowPath);
306     void Jump(Label *label);
307     void Branch(GateRef condition, Label *trueLabel, Label *falseLabel,
308                 uint32_t trueWeight = 1, uint32_t falseWeight = 1);   // 1: default branch weight
309     void Switch(GateRef index, Label *defaultLabel, int64_t *keysValue, Label *keysLabel, int numberOfKeys);
310     void LoopBegin(Label *loopHead);
311     void LoopEnd(Label *loopHead);
312     void LoopExit(const std::vector<Variable*> &vars, size_t diff = 1);
313     inline Label *GetCurrentLabel() const;
314     inline GateRef GetState() const;
315     inline GateRef GetDepend() const;
316     inline StateDepend GetStateDepend() const;
317 
GetCircuit()318     Circuit *GetCircuit() const
319     {
320         return circuit_;
321     }
322 
SetEnvironment(Environment * env)323     void SetEnvironment(Environment *env)
324     {
325         env_ = env;
326     }
GetCurrentEnvironment()327     Environment *GetCurrentEnvironment() const
328     {
329         return env_;
330     }
SetCompilationConfig(CompilationConfig * cmpCfg)331     void SetCompilationConfig(CompilationConfig *cmpCfg)
332     {
333         cmpCfg_ = cmpCfg;
334     }
GetCompilationConfig()335     CompilationConfig *GetCompilationConfig() const
336     {
337         return cmpCfg_;
338     }
339 
340     // **************************** High IR ******************************
341     GateRef CreateArray(ElementsKind kind, uint32_t arraySize, GateRef elementsLength);
342     GateRef CreateArrayWithBuffer(ElementsKind kind, ArrayMetaDataAccessor::Mode mode, GateRef cpId,
343                                   GateRef constPoolIndex, GateRef elementIndex);
344     GateRef Construct(GateRef hirGate, std::vector<GateRef> args);
345     GateRef TypedCallNative(GateRef hirGate, GateRef thisObj, GateRef funcId);
346     GateRef IsBase(GateRef ctor);
347     GateRef ToLength(GateRef receiver);
348     GateRef StoreModuleVar(GateRef jsFunc, GateRef index, GateRef value);
349     GateRef LdLocalModuleVar(GateRef jsFunc, GateRef index);
350     GateRef BuiltinConstructor(BuiltinTypeId id, GateRef gate);
351 
352     inline GateRef GetMethodId(GateRef func);
353     inline GateRef GetBuiltinsId(GateRef func);
354     inline GateRef IsAOTLiteralInfo(GateRef x);
355 
356     // call operation
357     GateRef CallGetter(GateRef hirGate, GateRef receiver, GateRef holder,
358         GateRef propertyLookupResult, const char* comment = nullptr);
359     GateRef CallSetter(GateRef hirGate, GateRef receiver, GateRef holder, GateRef propertyLookupResult,
360                        GateRef value, const char* comment = nullptr);
361     GateRef CallBCHandler(GateRef glue, GateRef target, const std::vector<GateRef> &args,
362                           const char* comment = nullptr);
363     GateRef CallBCDebugger(GateRef glue, GateRef target, const std::vector<GateRef> &args,
364                            const char* comment = nullptr);
365     GateRef CallBuiltin(GateRef glue, GateRef target, const std::vector<GateRef> &args,
366                         const char* comment = nullptr);
367     GateRef CallBuiltinWithArgv(GateRef glue, GateRef target, const std::vector<GateRef> &args,
368                                 const char* comment = nullptr);
369     GateRef CallRuntimeVarargs(GateRef glue, int index, GateRef argc, GateRef argv, const char* comment = nullptr);
370     GateRef CallRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args, GateRef hirGate,
371                         const char* comment = nullptr);
372     GateRef CallNGCRuntime(GateRef glue, GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel);
373 
374     GateRef CallNGCRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args,
375                            GateRef hirGate, const char* comment = nullptr);
376     GateRef FastCallOptimized(GateRef glue, GateRef code, GateRef depend, const std::vector<GateRef> &args,
377                               GateRef hirGate);
378     GateRef CallOptimized(GateRef glue, GateRef code, GateRef depend, const std::vector<GateRef> &args,
379                           GateRef hirGate);
380     GateRef CallStub(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args,
381                      const char* comment = nullptr);
382     GateRef CallBuiltinRuntime(GateRef glue, GateRef depend, const std::vector<GateRef> &args,
383                                bool isNew = false, const char* comment = nullptr);
384     GateRef CallBuiltinRuntimeWithNewTarget(GateRef glue, GateRef depend, const std::vector<GateRef> &args,
385                                             const char* comment = nullptr);
386     GateRef Call(const CallSignature* cs, GateRef glue, GateRef target, GateRef depend,
387                  const std::vector<GateRef> &args, GateRef hirGate, const char* comment = nullptr);
388     GateRef NoLabelCallRuntime(GateRef glue, GateRef depend, size_t index, std::vector<GateRef> &args, GateRef hirGate);
389 
390     void StartCallTimer(GateRef glue, GateRef gate, const std::vector<GateRef> &args, bool useLabel);
391     void EndCallTimer(GateRef glue, GateRef gate, const std::vector<GateRef> &args, bool useLabel);
392     GateRef GetCallBuiltinId(GateRef method);
393 
394     // FastCall
395     inline GateRef CanFastCall(GateRef jsFunc);
396     inline GateRef CanFastCallWithMethod(GateRef method);
397 
398     // Js world
399     inline GateRef GetObjectType(GateRef hClass);
400     inline GateRef HasConstructor(GateRef object);
401     inline GateRef IsSpecial(GateRef x, JSTaggedType type);
402     inline GateRef IsJSFunction(GateRef obj);
403     inline GateRef IsDictionaryMode(GateRef object);
404     inline GateRef IsJsType(GateRef object, JSType type);
405     inline GateRef IsStableElements(GateRef hClass);
406     inline GateRef IsStableArguments(GateRef hClass);
407     inline GateRef IsStableArray(GateRef hClass);
408     inline GateRef IsDictionaryElement(GateRef hClass);
409     inline GateRef IsClassConstructor(GateRef object);
410     inline GateRef IsClassConstructorWithBitField(GateRef bitfield);
411     inline GateRef IsConstructor(GateRef object);
412     inline GateRef IsClassPrototype(GateRef object);
413     inline GateRef IsClassPrototypeWithBitField(GateRef object);
414     inline GateRef IsExtensible(GateRef object);
415     inline GateRef IsJSObject(GateRef obj);
416     inline GateRef IsCallable(GateRef obj);
417     inline GateRef IsCallableFromBitField(GateRef bitfield);
418     inline GateRef IsProtoTypeHClass(GateRef hclass);
419     inline GateRef IsJsProxy(GateRef obj);
420     GateRef IsJSHClass(GateRef obj);
421     inline void StoreHClass(GateRef glue, GateRef object, GateRef hClass);
422     GateRef IsStabelArray(GateRef glue, GateRef obj);
423     inline void StorePrototype(GateRef glue, GateRef hclass, GateRef prototype);
424     void SetExtensibleToBitfield(GateRef glue, GateRef obj, bool isExtensible);
425 
426     // WeakRef
427     inline GateRef CreateWeakRef(GateRef x);
428     inline GateRef LoadObjectFromWeakRef(GateRef x);
429 
430     // hClass
431     inline GateRef GetElementsKindByHClass(GateRef hClass);
432     inline GateRef GetObjectSizeFromHClass(GateRef hClass);
433     inline GateRef HasConstructorByHClass(GateRef hClass);
434     inline GateRef IsDictionaryModeByHClass(GateRef hClass);
435     inline GateRef LoadHClass(GateRef object);
436     inline GateRef LoadHClassByConstOffset(GateRef object);
437     inline GateRef LoadPrototype(GateRef hclass);
438     inline GateRef LoadPrototypeHClass(GateRef object);
439     void SetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass,
440                                  GateRef value, GateRef attrOffset, VariableType type);
441 
442     // Others
443     GateRef OrdinaryHasInstance(GateRef obj, GateRef target);
444 
445     // **************************** Middle IR ****************************
446     GateRef HeapObjectCheck(GateRef gate, GateRef frameState);
447     GateRef ProtoChangeMarkerCheck(GateRef gate, GateRef frameState = Gate::InvalidGateRef);
448     GateRef StableArrayCheck(GateRef gate, ElementsKind kind, ArrayMetaDataAccessor::Mode mode);
449     GateRef COWArrayCheck(GateRef gate);
450     GateRef EcmaStringCheck(GateRef gate);
451     GateRef FlattenTreeStringCheck(GateRef gate);
452     GateRef HClassStableArrayCheck(GateRef gate, GateRef frameState, ArrayMetaDataAccessor accessor);
453     GateRef ArrayGuardianCheck(GateRef frameState);
454     GateRef TypedArrayCheck(GateRef gate, GateType type, TypedArrayMetaDateAccessor::Mode mode,
455                             OnHeapMode onHeap = OnHeapMode::NONE);
456     GateRef LoadTypedArrayLength(GateRef gate, GateType type, OnHeapMode onHeap = OnHeapMode::NONE);
457     GateRef RangeGuard(GateRef gate, uint32_t left, uint32_t right);
458     GateRef BuiltinPrototypeHClassCheck(GateRef gate, BuiltinTypeId type);
459     GateRef OrdinaryHasInstanceCheck(GateRef target, GateRef jsFunc, std::vector<GateRef> &expectedHCIndexes);
460     GateRef IndexCheck(GateRef gate, GateRef index);
461     GateRef ObjectTypeCheck(GateType type, bool isHeapObject, GateRef gate, GateRef hclassIndex,
462                             GateRef frameState = Gate::InvalidGateRef);
463     GateRef ObjectTypeCompare(GateType type, bool isHeapObject, GateRef gate, GateRef hclassIndex);
464     GateRef TryPrimitiveTypeCheck(GateType type, GateRef gate);
465     GateRef CallTargetCheck(GateRef gate, GateRef function, GateRef id, GateRef param, const char* comment = nullptr);
466     GateRef JSCallTargetFromDefineFuncCheck(GateType type, GateRef func, GateRef gate);
467     template<TypedCallTargetCheckOp Op>
468     GateRef JSCallTargetTypeCheck(GateType type, GateRef func, GateRef methodIndex, GateRef gate);
469     template<TypedCallTargetCheckOp Op>
470     GateRef JSCallThisTargetTypeCheck(GateType type, GateRef func, GateRef gate);
471     template<TypedCallTargetCheckOp Op>
472     inline GateRef JSNoGCCallThisTargetTypeCheck(GateType type, GateRef func, GateRef methodId, GateRef gate);
473     GateRef TypeOfCheck(GateRef gate, GateType type);
474     GateRef TypedTypeOf(GateType type);
475     GateRef TypedCallOperator(GateRef hirGate, MachineType type, const std::vector<GateRef>& inList);
476     inline GateRef TypedCallBuiltin(GateRef hirGate, const std::vector<GateRef> &args, BuiltinsStubCSigns::ID id);
477     GateRef TypeConvert(MachineType type, GateType typeFrom, GateType typeTo, const std::vector<GateRef>& inList);
478     GateRef Int32CheckRightIsZero(GateRef right);
479     GateRef RemainderIsNegativeZero(GateRef left, GateRef right);
480     GateRef Float64CheckRightIsZero(GateRef right);
481     GateRef ValueCheckNegOverflow(GateRef value);
482     GateRef OverflowCheck(GateRef value);
483     GateRef LexVarIsHoleCheck(GateRef value);
484     GateRef Int32UnsignedUpperBoundCheck(GateRef value, GateRef upperBound);
485     GateRef Int32DivWithCheck(GateRef left, GateRef right);
486     GateType GetGateTypeOfValueType(ValueType type);
487     GateRef InsertStableArrayCheck(GateRef array);
488     GateRef InsertLoadArrayLength(GateRef array, bool isTypedArray);
489     GateRef InsertTypedArrayCheck(GateType type, GateRef array);
490     GateRef ArrayConstructorCheck(GateRef gate);
491     GateRef ObjectConstructorCheck(GateRef gate);
492     GateRef InsertTypedBinaryop(GateRef left, GateRef right, GateType leftType, GateType rightType,
493                                 GateType gateType, PGOTypeRef pgoType, TypedBinOp op);
494     GateRef InsertRangeCheckPredicate(GateRef left, TypedBinOp cond, GateRef right);
495     GateRef TypedConditionJump(MachineType type, TypedJumpOp jumpOp, uint32_t weight, GateType typeVal,
496                                const std::vector<GateRef>& inList);
497     GateRef TypedNewAllocateThis(GateRef ctor, GateRef hclassIndex, GateRef frameState);
498     GateRef TypedSuperAllocateThis(GateRef superCtor, GateRef newTarget, GateRef frameState);
499     template<TypedBinOp Op>
500     inline GateRef TypedBinaryOp(GateRef x, GateRef y, GateType xType, GateType yType, GateType gateType,
501                                  PGOTypeRef pgoType);
502     template<TypedUnOp Op>
503     inline GateRef TypedUnaryOp(GateRef x, GateType xType, GateType gateType);
504     template<TypedJumpOp Op>
505     inline GateRef TypedConditionJump(GateRef x, GateType xType, uint32_t weight);
506     GateRef Convert(GateRef gate, ValueType src, ValueType dst);
507     GateRef ConvertBoolToTaggedBoolean(GateRef gate);
508     GateRef ConvertTaggedBooleanToBool(GateRef gate);
509     GateRef ConvertInt32ToBool(GateRef gate);
510     GateRef ConvertFloat64ToBool(GateRef gate);
511     GateRef ConvertInt32ToTaggedInt(GateRef gate);
512     GateRef ConvertFloat64ToTaggedDouble(GateRef gate);
513     GateRef ConvertFloat64ToInt32(GateRef gate);
514     GateRef ConvertInt32ToFloat64(GateRef gate);
515     GateRef ConvertBoolToInt32(GateRef gate, ConvertSupport support);
516     GateRef ConvertBoolToFloat64(GateRef gate, ConvertSupport support);
517     GateRef ConvertUInt32ToBool(GateRef gate);
518     GateRef ConvertUInt32ToTaggedNumber(GateRef gate);
519     GateRef ConvertUInt32ToFloat64(GateRef gate);
520     GateRef ConvertCharToEcmaString(GateRef gate);
521     GateRef CheckAndConvert(
522         GateRef gate, ValueType src, ValueType dst, ConvertSupport support = ConvertSupport::ENABLE);
523     GateRef ConvertHoleAsUndefined(GateRef receiver);
524     GateRef CheckUInt32AndConvertToInt32(GateRef gate);
525     GateRef CheckTaggedIntAndConvertToInt32(GateRef gate);
526     GateRef CheckTaggedDoubleAndConvertToInt32(GateRef gate);
527     GateRef CheckTaggedNumberAndConvertToInt32(GateRef gate);
528     GateRef CheckTaggedIntAndConvertToFloat64(GateRef gate);
529     GateRef CheckTaggedDoubleAndConvertToFloat64(GateRef gate);
530     GateRef CheckTaggedNumberAndConvertToFloat64(GateRef gate);
531     GateRef CheckTaggedNumberAndConvertToBool(GateRef gate);
532     GateRef CheckTaggedBooleanAndConvertToBool(GateRef gate);
533     GateRef CheckNullAndConvertToInt32(GateRef gate);
534     GateRef CheckTaggedBooleanAndConvertToInt32(GateRef gate);
535     GateRef CheckNullAndConvertToFloat64(GateRef gate);
536     GateRef CheckTaggedBooleanAndConvertToFloat64(GateRef gate);
537     GateRef CheckUndefinedAndConvertToFloat64(GateRef gate);
538     GateRef CheckUndefinedAndConvertToBool(GateRef gate);
539     GateRef CheckNullAndConvertToBool(GateRef gate);
540     GateRef CheckUndefinedAndConvertToInt32(GateRef gate);
541     GateRef StartAllocate();
542     GateRef FinishAllocate(GateRef value);
543 
544     inline GateRef PrimitiveToNumber(GateRef x, VariableType type);
545     inline GateRef GetValueFromTaggedArray(GateRef array, GateRef index);
546     inline GateRef GetValueFromTaggedArray(VariableType valType, GateRef array, GateRef index);
547     template<TypedLoadOp Op>
548     GateRef LoadElement(GateRef receiver, GateRef index, OnHeapMode onHeap = OnHeapMode::NONE);
549     GateRef LoadProperty(GateRef receiver, GateRef propertyLookupResult, bool isFunction);
550     GateRef LoadArrayLength(GateRef array);
551     inline GateRef LoadFromTaggedArray(GateRef array, size_t index);
552     GateRef LoadStringLength(GateRef string);
553     GateRef LoadConstOffset(VariableType type, GateRef receiver, size_t offset,
554         MemoryOrder order = MemoryOrder::Default());
555     GateRef LoadHClassFromConstpool(GateRef constpool, size_t index);
556     GateRef TypedCall(GateRef hirGate, std::vector<GateRef> args, bool isNoGC);
557     GateRef TypedFastCall(GateRef hirGate, std::vector<GateRef> args, bool isNoGC);
558     inline void SetValueToTaggedArray(VariableType valType, GateRef glue, GateRef array, GateRef index, GateRef val);
559     GateRef StoreConstOffset(VariableType type, GateRef receiver, size_t offset, GateRef value,
560         MemoryOrder order = MemoryOrder::Default());
561     inline GateRef StoreToTaggedArray(GateRef array, size_t index, GateRef value);
562     GateRef StringEqual(GateRef x, GateRef y);
563     GateRef StringAdd(GateRef x, GateRef y, uint32_t stringStatus = 0);
564     template<TypedStoreOp Op>
565     GateRef StoreElement(GateRef receiver, GateRef index, GateRef value, OnHeapMode onHeap = OnHeapMode::NONE);
566     GateRef StoreMemory(MemoryType Op, VariableType type, GateRef receiver, GateRef index, GateRef value);
567     GateRef StoreProperty(GateRef receiver, GateRef propertyLookupResult, GateRef value, uint32_t receiverHClassIndex);
568     inline GateRef JudgeAotAndFastCall(GateRef jsFunc, JudgeMethodType type);
569     inline GateRef JudgeAotAndFastCallWithMethod(GateRef method, JudgeMethodType type);
570     GateRef ComputeTaggedArraySize(GateRef length);
571     GateRef HeapAlloc(GateRef size, GateType type, RegionSpaceFlag flag);
572     GateRef TaggedIsHeapObjectOp(GateRef value);
573     GateRef IsSpecificObjectType(GateRef obj, JSType type);
574     GateRef IsMarkerCellValid(GateRef cell);
575     GateRef IsMarkerCellValidOp(GateRef cell);
576     GateRef MonoLoadPropertyOnProto(GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex);
577     GateRef MonoCallGetterOnProto(GateRef gate, GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex);
578     GateRef MonoStorePropertyLookUpProto(GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex,
579                                          GateRef value);
580     GateRef MonoStoreProperty(GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex,
581                               GateRef value, GateRef key);
582     GateRef TypedCreateObjWithBuffer(std::vector<GateRef> &valueIn);
583 
584     // bit operation
585     inline GateRef TaggedIsInt(GateRef x);
586     inline GateRef TaggedIsDouble(GateRef x);
587     inline GateRef TaggedIsObject(GateRef x);
588     inline GateRef TaggedIsNumber(GateRef x);
589     inline GateRef TaggedIsNumeric(GateRef x);
590     inline GateRef TaggedIsNotHole(GateRef x);
591     inline GateRef TaggedIsHole(GateRef x);
592     inline GateRef TaggedIsNullPtr(GateRef x);
593     inline GateRef TaggedIsUndefined(GateRef x);
594     inline GateRef TaggedIsException(GateRef x);
595     inline GateRef TaggedIsSpecial(GateRef x);
596     inline GateRef TaggedIsHeapObject(GateRef x);
597     inline GateRef TaggedIsAsyncGeneratorObject(GateRef x);
598     inline GateRef TaggedIsJSGlobalObject(GateRef x);
599     inline GateRef TaggedIsGeneratorObject(GateRef x);
600     inline GateRef TaggedIsJSArray(GateRef obj);
601     inline GateRef TaggedIsPropertyBox(GateRef x);
602     inline GateRef TaggedIsWeak(GateRef x);
603     inline GateRef TaggedIsPrototypeHandler(GateRef x);
604     inline GateRef TaggedIsTransitionHandler(GateRef x);
605     inline GateRef TaggedIsStoreTSHandler(GateRef x);
606     inline GateRef TaggedIsTransWithProtoHandler(GateRef x);
607     inline GateRef TaggedIsUndefinedOrNull(GateRef x);
608     inline GateRef TaggedIsNotUndefinedAndNull(GateRef x);
609     inline GateRef TaggedIsTrue(GateRef x);
610     inline GateRef TaggedIsFalse(GateRef x);
611     inline GateRef TaggedIsNull(GateRef x);
612     inline GateRef TaggedIsNotNull(GateRef x);
613     inline GateRef TaggedIsBoolean(GateRef x);
614     inline GateRef TaggedIsBigInt(GateRef obj);
615     inline GateRef TaggedIsString(GateRef obj);
616     inline GateRef TaggedIsShared(GateRef obj);
617     inline GateRef TaggedIsStringOrSymbol(GateRef obj);
618     inline GateRef TaggedIsSymbol(GateRef obj);
619     inline GateRef TaggedIsProtoChangeMarker(GateRef obj);
620     inline GateRef TaggedObjectIsJSMap(GateRef obj);
621     inline GateRef TaggedObjectIsJSSet(GateRef obj);
622     inline GateRef TaggedObjectIsTypedArray(GateRef obj);
623     inline GateRef TaggedObjectIsJSArray(GateRef obj);
624     inline GateRef TaggedGetInt(GateRef x);
625     inline GateRef TaggedObjectIsString(GateRef obj);
626     inline GateRef TaggedObjectIsShared(GateRef obj);
627     inline GateRef TaggedObjectBothAreString(GateRef x, GateRef y);
628     inline GateRef TaggedObjectIsEcmaObject(GateRef obj);
629     inline GateRef TaggedTrue();
630     inline GateRef TaggedFalse();
631 
632     // String
633     inline GateRef BothAreString(GateRef x, GateRef y);
634     inline GateRef IsTreeString(GateRef obj);
635     inline GateRef IsSlicedString(GateRef obj);
636     inline GateRef IsSpecialSlicedString(GateRef obj);
637     inline GateRef IsLineString(GateRef obj);
638     inline GateRef IsConstantString(GateRef obj);
639     inline GateRef TreeStringIsFlat(GateRef string);
640     inline GateRef GetFirstFromTreeString(GateRef string);
641     inline GateRef GetSecondFromTreeString(GateRef string);
642     inline GateRef ComputeSizeUtf8(GateRef length);
643     inline GateRef ComputeSizeUtf16(GateRef length);
644     inline GateRef AlignUp(GateRef x, GateRef alignment);
645     GateRef TaggedPointerToInt64(GateRef x);
646     GateRef GetLengthFromString(GateRef value);
647     GateRef GetHashcodeFromString(GateRef glue, GateRef value);
648     GateRef TryGetHashcodeFromString(GateRef string);
649     GateRef IsIntegerString(GateRef string);
650     GateRef IsLiteralString(GateRef string);
651     GateRef CanBeConcat(GateRef leftString, GateRef rightString, GateRef isValidOpt);
652     GateRef CanBackStore(GateRef rightString, GateRef isValidOpt);
653     GateRef GetRawHashFromString(GateRef value);
654     GateRef GetStringDataFromLineOrConstantString(GateRef str);
655     void CopyUtf8AsUtf16(GateRef glue, GateRef dst, GateRef src, GateRef sourceLength);
656     void CopyChars(GateRef glue, GateRef dst, GateRef source, GateRef sourceLength,
657         GateRef charSize, VariableType type);
658     void SetRawHashcode(GateRef glue, GateRef str, GateRef rawHashcode, GateRef isInteger);
659     GateRef StringFromSingleCharCode(GateRef gate);
660     GateRef ToNumber(GateRef gate, GateRef value, GateRef glue);
661     GateRef IsASCIICharacter(GateRef gate);
662 
663     // for in
664     GateRef GetEnumCacheKind(GateRef glue, GateRef enumCache);
665     GateRef IsEnumCacheValid(GateRef receiver, GateRef cachedHclass, GateRef kind);
666     GateRef NeedCheckProperty(GateRef receiver);
667 
668     // **************************** Low IR *******************************
669     inline GateRef Equal(GateRef x, GateRef y, const char* comment = nullptr);
670     inline GateRef NotEqual(GateRef x, GateRef y, const char* comment = nullptr);
671     inline GateRef IntPtrDiv(GateRef x, GateRef y);
672     inline GateRef IntPtrOr(GateRef x, GateRef y);
673     inline GateRef IntPtrLSL(GateRef x, GateRef y);
674     inline GateRef IntPtrLSR(GateRef x, GateRef y);
675     inline GateRef Int64NotEqual(GateRef x, GateRef y);
676     inline GateRef Int32NotEqual(GateRef x, GateRef y);
677     inline GateRef Int64Equal(GateRef x, GateRef y);
678     inline GateRef Int8Equal(GateRef x, GateRef y);
679     inline GateRef Int32Equal(GateRef x, GateRef y);
680     inline GateRef IntPtrGreaterThan(GateRef x, GateRef y);
681     inline GateRef IntPtrAnd(GateRef x, GateRef y);
682     inline GateRef IntPtrNot(GateRef x);
683     GateRef AddWithOverflow(GateRef left, GateRef right);
684     GateRef SubWithOverflow(GateRef left, GateRef right);
685     GateRef MulWithOverflow(GateRef left, GateRef right);
686     GateRef ExtractValue(MachineType mt, GateRef pointer, GateRef index);
687     GateRef Sqrt(GateRef param);
688     MachineType GetMachineTypeOfValueType(ValueType type);
689     GateRef Alloca(size_t size);
690     GateRef ReadSp();
691     GateRef BinaryArithmetic(const GateMetaData* meta, MachineType machineType, GateRef left,
692                              GateRef right, GateType gateType = GateType::Empty(), const char* comment = nullptr);
693     GateRef BinaryCmp(const GateMetaData* meta, GateRef left, GateRef right, const char* comment = nullptr);
694     GateRef Load(VariableType type, GateRef base, GateRef offset, MemoryOrder order = MemoryOrder::Default());
695     GateRef Load(VariableType type, GateRef base, GateRef offset, GateRef depend,
696         MemoryOrder order = MemoryOrder::Default());
697     void Store(VariableType type, GateRef glue, GateRef base, GateRef offset, GateRef value,
698         MemoryOrder order = MemoryOrder::Default());
699     void StoreWithNoBarrier(VariableType type, GateRef base, GateRef offset, GateRef value,
700         MemoryOrder order = MemoryOrder::Default());
701 
702     // cast operation
703     inline GateRef GetInt64OfTInt(GateRef x);
704     inline GateRef GetInt32OfTInt(GateRef x);
705     inline GateRef TaggedCastToIntPtr(GateRef x);
706     inline GateRef GetDoubleOfTDouble(GateRef x);
707     inline GateRef GetBooleanOfTBoolean(GateRef x);
708     inline GateRef GetDoubleOfTNumber(GateRef x);
709     inline GateRef DoubleToInt(GateRef x, Label *exit);
710     inline GateRef DoubleToInt(GateRef glue, GateRef x, size_t typeBits);
711     inline GateRef Int32ToTaggedPtr(GateRef x);
712     inline GateRef Int64ToTaggedPtr(GateRef x);
713     inline GateRef Int32ToTaggedInt(GateRef x);
714     inline GateRef ToTaggedInt(GateRef x);
715     inline GateRef ToTaggedIntPtr(GateRef x);
716     inline GateRef DoubleToTaggedDoublePtr(GateRef x);
717     inline GateRef BooleanToTaggedBooleanPtr(GateRef x);
718     inline GateRef BooleanToInt32(GateRef x);
719     inline GateRef BooleanToFloat64(GateRef x);
720     inline GateRef Float32ToTaggedDoublePtr(GateRef x);
721     inline GateRef TaggedDoublePtrToFloat32(GateRef x);
722     inline GateRef TaggedIntPtrToFloat32(GateRef x);
723     inline GateRef DoubleToTaggedDouble(GateRef x);
724     inline GateRef DoubleToTagged(GateRef x);
725     inline GateRef DoubleIsNAN(GateRef x);
726     inline GateRef DoubleIsINF(GateRef x);
727     static MachineType GetMachineTypeFromVariableType(VariableType type);
728 
729     // Unary / BinaryOp
730     template<OpCode Op, MachineType Type>
731     inline GateRef BinaryOp(GateRef x, GateRef y);
732     template<OpCode Op, MachineType Type>
733     inline GateRef BinaryOpWithOverflow(GateRef x, GateRef y);
734 
735 #define ARITHMETIC_BINARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID)                                        \
736     inline GateRef NAME(GateRef x, GateRef y, GateType type = GateType::Empty(), const char* comment = nullptr)  \
737     {                                                                                                            \
738         return BinaryArithmetic(circuit_->OPCODEID(), MACHINETYPEID, x, y, type, comment);                       \
739     }
740 
741     BINARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(ARITHMETIC_BINARY_OP_WITH_BITWIDTH)
742 #undef ARITHMETIC_BINARY_OP_WITH_BITWIDTH
743 
744 #define ARITHMETIC_UNARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID)                                     \
745     inline GateRef NAME(GateRef x, const char* comment = nullptr)                                            \
746     {                                                                                                        \
747         return circuit_->NewGate(circuit_->OPCODEID(), MACHINETYPEID, { x }, GateType::NJSValue(), comment); \
748     }
749 
750     UNARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(ARITHMETIC_UNARY_OP_WITH_BITWIDTH)
751 #undef ARITHMETIC_UNARY_OP_WITH_BITWIDTH
752 
753 #define CMP_BINARY_OP_WITHOUT_BITWIDTH(NAME, OPCODEID, CONDITION)                                \
754     inline GateRef NAME(GateRef x, GateRef y, const char* comment = nullptr)                     \
755     {                                                                                            \
756         return BinaryCmp(circuit_->OPCODEID(static_cast<uint64_t>(CONDITION)), x, y, comment);   \
757     }
758 
759     BINARY_CMP_METHOD_LIST_WITHOUT_BITWIDTH(CMP_BINARY_OP_WITHOUT_BITWIDTH)
760 #undef CMP_BINARY_OP_WITHOUT_BITWIDTH
761 
762 private:
763     static constexpr uint32_t GATE_TWO_VALUESIN = 2;
764 
765     inline void SetDepend(GateRef depend);
766     inline void SetState(GateRef state);
767 
768 #define ARITHMETIC_UNARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID)                                     \
769     inline GateRef NAME(GateRef x, const char* comment = nullptr)                                            \
770     {                                                                                                        \
771         return circuit_->NewGate(circuit_->OPCODEID(), MACHINETYPEID, { x }, GateType::NJSValue(), comment); \
772     }
773 
UNARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH_PRIVATE(ARITHMETIC_UNARY_OP_WITH_BITWIDTH)774     UNARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH_PRIVATE(ARITHMETIC_UNARY_OP_WITH_BITWIDTH)
775 #undef ARITHMETIC_UNARY_OP_WITH_BITWIDTH
776 
777     Circuit *circuit_ {nullptr};
778     GateAccessor acc_;
779     Environment *env_ {nullptr};
780     CompilationConfig *cmpCfg_ {nullptr};
781     friend StubBuilder;
782     friend BuiltinsStringStubBuilder;
783     friend TypedBytecodeLowering;
784     friend NTypeBytecodeLowering;
785     friend PGOHCRLowering;
786     friend TSHCRLowering;
787     friend NTypeHCRLowering;
788     friend SlowPathLowering;
789     friend NativeInlineLowering;
790     friend TypedHCRLowering;
791 };
792 
793 }  // namespace panda::ecmascript::kungfu
794 
795 #endif  // ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H
796