1/*
2 * Copyright (c) 2023-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#include "libpandabase/utils/hash.h"
17
18#include "ecmascript/compiler/mcr_circuit_builder.h"
19
20#include "ecmascript/compiler/circuit_builder.h"
21#include "ecmascript/compiler/share_gate_meta_data.h"
22#include "ecmascript/message_string.h"
23#include "ecmascript/stubs/runtime_stubs-inl.h"
24
25#include "ecmascript/compiler/circuit_builder-inl.h"
26#include "ecmascript/global_env.h"
27#include "ecmascript/js_object.h"
28#include "ecmascript/marker_cell.h"
29
30namespace panda::ecmascript::kungfu {
31
32GateRef CircuitBuilder::ObjectTypeCheck(bool isHeapObject, GateRef gate, GateRef hclassIndex,
33                                        GateRef frameState)
34{
35    auto currentLabel = env_->GetCurrentLabel();
36    auto currentControl = currentLabel->GetControl();
37    auto currentDepend = currentLabel->GetDepend();
38    if (frameState == Circuit::NullGate()) {
39        frameState = acc_.FindNearestFrameState(currentDepend);
40    }
41    ObjectTypeAccessor accessor(isHeapObject);
42    GateRef ret = GetCircuit()->NewGate(circuit_->ObjectTypeCheck(accessor.ToValue()), MachineType::I1,
43        {currentControl, currentDepend, gate, hclassIndex, frameState}, GateType::NJSValue());
44    currentLabel->SetControl(ret);
45    currentLabel->SetDepend(ret);
46    return ret;
47}
48
49GateRef CircuitBuilder::HeapObjectCheck(GateRef gate, GateRef frameState)
50{
51    auto currentLabel = env_->GetCurrentLabel();
52    auto currentControl = currentLabel->GetControl();
53    auto currentDepend = currentLabel->GetDepend();
54    GateRef ret = GetCircuit()->NewGate(circuit_->HeapObjectCheck(),
55                                        MachineType::I1,
56                                        {currentControl, currentDepend, gate, frameState},
57                                        GateType::NJSValue());
58    currentLabel->SetControl(ret);
59    currentLabel->SetDepend(ret);
60    return ret;
61}
62
63GateRef CircuitBuilder::EcmaObjectCheck(GateRef value)
64{
65    auto currentLabel = env_->GetCurrentLabel();
66    auto currentControl = currentLabel->GetControl();
67    auto currentDepend = currentLabel->GetDepend();
68    auto frameState = acc_.FindNearestFrameState(currentDepend);
69    GateRef ret = GetCircuit()->NewGate(circuit_->EcmaObjectCheck(),
70        MachineType::I1, {currentControl, currentDepend, value, frameState}, GateType::NJSValue());
71    currentLabel->SetControl(ret);
72    currentLabel->SetDepend(ret);
73    return ret;
74}
75
76GateRef CircuitBuilder::HeapObjectIsEcmaObjectCheck(GateRef gate, GateRef frameState)
77{
78    auto currentLabel = env_->GetCurrentLabel();
79    auto currentControl = currentLabel->GetControl();
80    auto currentDepend = currentLabel->GetDepend();
81    GateRef ret = GetCircuit()->NewGate(circuit_->HeapObjectIsEcmaObjectCheck(),
82                                        MachineType::I1,
83                                        {currentControl, currentDepend, gate, frameState},
84                                        GateType::NJSValue());
85    currentLabel->SetControl(ret);
86    currentLabel->SetDepend(ret);
87    return ret;
88}
89
90GateRef CircuitBuilder::ProtoChangeMarkerCheck(GateRef gate, GateRef frameState)
91{
92    auto currentLabel = env_->GetCurrentLabel();
93    auto currentControl = currentLabel->GetControl();
94    auto currentDepend = currentLabel->GetDepend();
95    if (frameState == Circuit::NullGate()) {
96        frameState = acc_.FindNearestFrameState(currentDepend);
97    }
98    GateRef ret = GetCircuit()->NewGate(circuit_->ProtoChangeMarkerCheck(),
99                                        MachineType::I1,
100                                        {currentControl, currentDepend, gate, frameState},
101                                        GateType::NJSValue());
102    currentLabel->SetControl(ret);
103    currentLabel->SetDepend(ret);
104    return ret;
105}
106
107GateRef CircuitBuilder::StableArrayCheck(GateRef gate, ElementsKind kind, ArrayMetaDataAccessor::Mode mode)
108{
109    auto currentLabel = env_->GetCurrentLabel();
110    auto currentControl = currentLabel->GetControl();
111    auto currentDepend = currentLabel->GetDepend();
112    auto frameState = acc_.FindNearestFrameState(currentDepend);
113    ArrayMetaDataAccessor accessor(kind, mode);
114    GateRef ret = GetCircuit()->NewGate(circuit_->StableArrayCheck(accessor.ToValue()),
115        MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
116    currentLabel->SetControl(ret);
117    currentLabel->SetDepend(ret);
118    return ret;
119}
120
121GateRef CircuitBuilder::ElementsKindCheck(GateRef receiver, ElementsKind kind, ArrayMetaDataAccessor::Mode mode)
122{
123    // If elements kind is hole, no ElementsKindCheck is required.
124    if (Elements::IsHole(kind)) {
125        return Circuit::NullGate();
126    }
127    auto currentLabel = env_->GetCurrentLabel();
128    auto currentControl = currentLabel->GetControl();
129    auto currentDepend = currentLabel->GetDepend();
130    auto frameState = acc_.FindNearestFrameState(currentDepend);
131    ArrayMetaDataAccessor accessor(kind, mode);
132    GateRef ret = GetCircuit()->NewGate(circuit_->ElementsKindCheck(accessor.ToValue()),
133        MachineType::I1, {currentControl, currentDepend, receiver, frameState}, GateType::NJSValue());
134    currentLabel->SetControl(ret);
135    currentLabel->SetDepend(ret);
136    return ret;
137}
138
139GateRef CircuitBuilder::COWArrayCheck(GateRef gate)
140{
141    auto currentLabel = env_->GetCurrentLabel();
142    auto currentControl = currentLabel->GetControl();
143    auto currentDepend = currentLabel->GetDepend();
144    auto frameState = acc_.FindNearestFrameState(currentDepend);
145    GateRef ret = GetCircuit()->NewGate(circuit_->COWArrayCheck(),
146        MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
147    currentLabel->SetControl(ret);
148    currentLabel->SetDepend(ret);
149    return ret;
150}
151
152GateRef CircuitBuilder::EcmaStringCheck(GateRef gate)
153{
154    auto currentLabel = env_->GetCurrentLabel();
155    auto currentControl = currentLabel->GetControl();
156    auto currentDepend = currentLabel->GetDepend();
157    auto frameState = acc_.FindNearestFrameState(currentDepend);
158    GateRef ret = GetCircuit()->NewGate(circuit_->EcmaStringCheck(),
159        MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
160    currentLabel->SetControl(ret);
161    currentLabel->SetDepend(ret);
162    return ret;
163}
164
165GateRef CircuitBuilder::EcmaMapCheck(GateRef gate)
166{
167    auto currentLabel = env_->GetCurrentLabel();
168    auto currentControl = currentLabel->GetControl();
169    auto currentDepend = currentLabel->GetDepend();
170    auto frameState = acc_.FindNearestFrameState(currentDepend);
171    GateRef ret = GetCircuit()->NewGate(circuit_->EcmaMapCheck(),
172        MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
173    currentLabel->SetControl(ret);
174    currentLabel->SetDepend(ret);
175    return ret;
176}
177
178GateRef CircuitBuilder::FlattenTreeStringCheck(GateRef gate)
179{
180    auto currentLabel = env_->GetCurrentLabel();
181    auto currentControl = currentLabel->GetControl();
182    auto currentDepend = currentLabel->GetDepend();
183    auto frameState = acc_.FindNearestFrameState(currentDepend);
184    GateRef ret = GetCircuit()->NewGate(circuit_->FlattenTreeStringCheck(),
185        MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
186    currentLabel->SetControl(ret);
187    currentLabel->SetDepend(ret);
188    return ret;
189}
190
191GateRef CircuitBuilder::HClassStableArrayCheck(GateRef gate, GateRef frameState, ArrayMetaDataAccessor accessor)
192{
193    auto currentLabel = env_->GetCurrentLabel();
194    auto currentControl = currentLabel->GetControl();
195    auto currentDepend = currentLabel->GetDepend();
196    GateRef ret = GetCircuit()->NewGate(circuit_->HClassStableArrayCheck(accessor.ToValue()),
197        MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
198    currentLabel->SetControl(ret);
199    currentLabel->SetDepend(ret);
200    return ret;
201}
202
203GateRef CircuitBuilder::ArrayGuardianCheck(GateRef frameState)
204{
205    auto currentLabel = env_->GetCurrentLabel();
206    auto currentControl = currentLabel->GetControl();
207    auto currentDepend = currentLabel->GetDepend();
208    GateRef ret = GetCircuit()->NewGate(circuit_->ArrayGuardianCheck(),
209        MachineType::I1, {currentControl, currentDepend, frameState}, GateType::NJSValue());
210    currentLabel->SetControl(ret);
211    currentLabel->SetDepend(ret);
212    return ret;
213}
214
215GateRef CircuitBuilder::TypedArrayCheck(GateRef gate, ParamType type, TypedArrayMetaDataAccessor::Mode mode,
216                                        OnHeapMode onHeap)
217{
218    auto currentLabel = env_->GetCurrentLabel();
219    auto currentControl = currentLabel->GetControl();
220    auto currentDepend = currentLabel->GetDepend();
221    auto frameState = acc_.FindNearestFrameState(currentDepend);
222    uint64_t value = TypedArrayMetaDataAccessor::ToValue(type, mode, onHeap);
223    GateRef ret = GetCircuit()->NewGate(circuit_->TypedArrayCheck(value), MachineType::I1,
224                                        {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
225    currentLabel->SetControl(ret);
226    currentLabel->SetDepend(ret);
227    return ret;
228}
229
230GateRef CircuitBuilder::LoadTypedArrayLength(GateRef gate, ParamType paramType, OnHeapMode onHeap)
231{
232    auto currentLabel = env_->GetCurrentLabel();
233    auto currentControl = currentLabel->GetControl();
234    auto currentDepend = currentLabel->GetDepend();
235    uint64_t value = TypedArrayMetaDataAccessor::ToValue(paramType,
236        TypedArrayMetaDataAccessor::Mode::LOAD_LENGTH, onHeap);
237    GateRef ret = GetCircuit()->NewGate(circuit_->LoadTypedArrayLength(value), MachineType::I64,
238                                        {currentControl, currentDepend, gate}, GateType::IntType());
239    currentLabel->SetControl(ret);
240    currentLabel->SetDepend(ret);
241    return ret;
242}
243
244GateRef CircuitBuilder::StringEqual(GateRef x, GateRef y)
245{
246    auto currentLabel = env_->GetCurrentLabel();
247    auto currentControl = currentLabel->GetControl();
248    auto currentDepend = currentLabel->GetDepend();
249    auto ret = GetCircuit()->NewGate(circuit_->StringEqual(), MachineType::I1,
250                                     { currentControl, currentDepend, x, y }, GateType::NJSValue());
251    currentLabel->SetControl(ret);
252    currentLabel->SetDepend(ret);
253    return ret;
254}
255
256GateRef CircuitBuilder::StringAdd(GateRef x, GateRef y, uint32_t stringStatus)
257{
258    auto currentLabel = env_->GetCurrentLabel();
259    auto currentControl = currentLabel->GetControl();
260    auto currentDepend = currentLabel->GetDepend();
261    StringStatusAccessor accessor(stringStatus);
262    auto ret = GetCircuit()->NewGate(circuit_->StringAdd(accessor.ToValue()), MachineType::I64,
263                                     { currentControl, currentDepend, x, y }, GateType::AnyType());
264    currentLabel->SetControl(ret);
265    currentLabel->SetDepend(ret);
266    return ret;
267}
268
269GateRef CircuitBuilder::RangeGuard(GateRef gate, uint32_t left, uint32_t right)
270{
271    auto currentLabel = env_->GetCurrentLabel();
272    auto currentControl = currentLabel->GetControl();
273    auto currentDepend = currentLabel->GetDepend();
274    UInt32PairAccessor accessor(left, right);
275    GateRef ret = GetCircuit()->NewGate(circuit_->RangeGuard(accessor.ToValue()),
276        MachineType::I64, {currentControl, currentDepend, gate}, GateType::IntType());
277    currentLabel->SetControl(ret);
278    currentLabel->SetDepend(ret);
279    return ret;
280}
281
282GateRef CircuitBuilder::BuiltinPrototypeHClassCheck(GateRef gate, BuiltinTypeId type,
283                                                    ElementsKind kind, bool isPrototypeOfPrototype)
284{
285    auto currentLabel = env_->GetCurrentLabel();
286    auto currentControl = currentLabel->GetControl();
287    auto currentDepend = currentLabel->GetDepend();
288    auto frameState = acc_.FindNearestFrameState(currentDepend);
289    BuiltinPrototypeHClassAccessor accessor(type, kind, isPrototypeOfPrototype);
290    GateRef ret = GetCircuit()->NewGate(circuit_->BuiltinPrototypeHClassCheck(accessor.ToValue()),
291        MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
292    currentLabel->SetControl(ret);
293    currentLabel->SetDepend(ret);
294    return ret;
295}
296
297GateRef CircuitBuilder::IndexCheck(GateRef gate, GateRef index)
298{
299    auto currentLabel = env_->GetCurrentLabel();
300    auto currentControl = currentLabel->GetControl();
301    auto currentDepend = currentLabel->GetDepend();
302    auto frameState = acc_.FindNearestFrameState(currentDepend);
303    GateRef ret = GetCircuit()->NewGate(circuit_->IndexCheck(),
304        MachineType::I64, {currentControl, currentDepend, gate, index, frameState}, GateType::IntType());
305    currentLabel->SetControl(ret);
306    currentLabel->SetDepend(ret);
307    return ret;
308}
309
310GateRef CircuitBuilder::TypeOfCheck(GateRef gate, ParamType paramType)
311{
312    auto currentLabel = env_->GetCurrentLabel();
313    auto currentControl = currentLabel->GetControl();
314    auto currentDepend = currentLabel->GetDepend();
315    auto frameState = acc_.FindNearestFrameState(currentDepend);
316    GateRef ret = GetCircuit()->NewGate(circuit_->TypeOfCheck(static_cast<uint64_t>(paramType.Value())),
317        MachineType::I64, {currentControl, currentDepend, gate, frameState}, GateType::IntType());
318    currentLabel->SetControl(ret);
319    currentLabel->SetDepend(ret);
320    return ret;
321}
322
323GateRef CircuitBuilder::TypedTypeOf(ParamType paramType)
324{
325    auto currentLabel = env_->GetCurrentLabel();
326    auto currentControl = currentLabel->GetControl();
327    auto currentDepend = currentLabel->GetDepend();
328    GateRef ret = GetCircuit()->NewGate(circuit_->TypeOf(static_cast<uint64_t>(paramType.Value())),
329        MachineType::I64, {currentControl, currentDepend}, GateType::AnyType());
330    currentLabel->SetControl(ret);
331    currentLabel->SetDepend(ret);
332    return ret;
333}
334
335GateRef CircuitBuilder::IsMarkerCellValid(GateRef cell)
336{
337    GateRef bitfield = Load(VariableType::INT32(), cell, IntPtr(MarkerCell::BIT_FIELD_OFFSET));
338    return Int32Equal(
339        Int32And(Int32LSR(bitfield, Int32(MarkerCell::IsDetectorInvalidBits::START_BIT)),
340                 Int32((1LU << MarkerCell::IsDetectorInvalidBits::SIZE) - 1)),
341        Int32(0));
342}
343
344GateRef CircuitBuilder::CheckAndConvert(GateRef gate, ValueType src, ValueType dst, ConvertSupport support)
345{
346    auto currentLabel = env_->GetCurrentLabel();
347    auto currentControl = currentLabel->GetControl();
348    auto currentDepend = currentLabel->GetDepend();
349    auto stateSplit = acc_.FindNearestStateSplit(currentDepend);
350    auto frameState = acc_.GetFrameState(stateSplit);
351    MachineType machineType = GetMachineTypeOfValueType(dst);
352    GateType gateType = GetGateTypeOfValueType(dst);
353    uint64_t value = ValuePairTypeAccessor::ToValue(src, dst, support);
354    GateRef ret = GetCircuit()->NewGate(circuit_->CheckAndConvert(value),
355        machineType, {currentControl, currentDepend, gate, frameState}, gateType);
356    currentLabel->SetControl(ret);
357    currentLabel->SetDepend(ret);
358    return ret;
359}
360
361GateRef CircuitBuilder::Convert(GateRef gate, ValueType src, ValueType dst)
362{
363    MachineType machineType = GetMachineTypeOfValueType(dst);
364    GateType gateType = GetGateTypeOfValueType(dst);
365    uint64_t value = ValuePairTypeAccessor::ToValue(src, dst);
366    GateRef ret = GetCircuit()->NewGate(circuit_->Convert(value), machineType, {gate}, gateType);
367    return ret;
368}
369
370GateRef CircuitBuilder::ConvertBoolToInt32(GateRef gate, ConvertSupport support)
371{
372    return CheckAndConvert(gate, ValueType::BOOL, ValueType::INT32, support);
373}
374
375GateRef CircuitBuilder::ConvertBoolToFloat64(GateRef gate, ConvertSupport support)
376{
377    return CheckAndConvert(gate, ValueType::BOOL, ValueType::FLOAT64, support);
378}
379
380GateRef CircuitBuilder::ConvertCharToEcmaString(GateRef gate)
381{
382    return Convert(gate, ValueType::CHAR, ValueType::ECMA_STRING);
383}
384
385GateRef CircuitBuilder::ConvertCharToInt32(GateRef gate)
386{
387    return Convert(gate, ValueType::CHAR, ValueType::INT32);
388}
389
390GateRef CircuitBuilder::ConvertCharToDouble(GateRef gate)
391{
392    return Convert(gate, ValueType::CHAR, ValueType::FLOAT64);
393}
394
395GateRef CircuitBuilder::ConvertInt32ToFloat64(GateRef gate)
396{
397    return Convert(gate, ValueType::INT32, ValueType::FLOAT64);
398}
399
400GateRef CircuitBuilder::ConvertUInt32ToFloat64(GateRef gate)
401{
402    return Convert(gate, ValueType::UINT32, ValueType::FLOAT64);
403}
404
405GateRef CircuitBuilder::ConvertFloat64ToInt32(GateRef gate)
406{
407    return Convert(gate, ValueType::FLOAT64, ValueType::INT32);
408}
409
410GateRef CircuitBuilder::CheckFloat64AndConvertToInt32(GateRef gate)
411{
412    return CheckAndConvert(gate, ValueType::FLOAT64, ValueType::INT32);
413}
414
415GateRef CircuitBuilder::ConvertBoolToTaggedBoolean(GateRef gate)
416{
417    return Convert(gate, ValueType::BOOL, ValueType::TAGGED_BOOLEAN);
418}
419
420GateRef CircuitBuilder::ConvertTaggedBooleanToBool(GateRef gate)
421{
422    return Convert(gate, ValueType::TAGGED_BOOLEAN, ValueType::BOOL);
423}
424
425GateRef CircuitBuilder::ConvertInt32ToTaggedInt(GateRef gate)
426{
427    return Convert(gate, ValueType::INT32, ValueType::TAGGED_INT);
428}
429
430GateRef CircuitBuilder::ConvertUInt32ToTaggedNumber(GateRef gate)
431{
432    return Convert(gate, ValueType::UINT32, ValueType::TAGGED_NUMBER);
433}
434
435GateRef CircuitBuilder::ConvertInt32ToBool(GateRef gate)
436{
437    return Convert(gate, ValueType::INT32, ValueType::BOOL);
438}
439
440GateRef CircuitBuilder::ConvertUInt32ToBool(GateRef gate)
441{
442    return Convert(gate, ValueType::UINT32, ValueType::BOOL);
443}
444
445GateRef CircuitBuilder::ConvertFloat64ToBool(GateRef gate)
446{
447    return Convert(gate, ValueType::FLOAT64, ValueType::BOOL);
448}
449
450GateRef CircuitBuilder::CheckTaggedBooleanAndConvertToBool(GateRef gate)
451{
452    return CheckAndConvert(gate, ValueType::TAGGED_BOOLEAN, ValueType::BOOL);
453}
454
455GateRef CircuitBuilder::CheckTaggedNumberAndConvertToBool(GateRef gate)
456{
457    return CheckAndConvert(gate, ValueType::TAGGED_NUMBER, ValueType::BOOL);
458}
459
460GateRef CircuitBuilder::CheckHoleIntAndConvertToTaggedInt(GateRef gate)
461{
462    return CheckAndConvert(gate, ValueType::HOLE_INT, ValueType::TAGGED_INT);
463}
464
465GateRef CircuitBuilder::CheckHoleDoubleAndConvertToTaggedDouble(GateRef gate)
466{
467    return CheckAndConvert(gate, ValueType::HOLE_DOUBLE, ValueType::TAGGED_DOUBLE);
468}
469
470GateRef CircuitBuilder::ConvertFloat64ToTaggedDouble(GateRef gate)
471{
472    return Convert(gate, ValueType::FLOAT64, ValueType::TAGGED_DOUBLE);
473}
474
475GateRef CircuitBuilder::ConvertSpecialHoleIntToTagged(GateRef gate)
476{
477    return Convert(gate, ValueType::HOLE_INT, ValueType::TAGGED_INT);
478}
479
480GateRef CircuitBuilder::ConvertSpecialHoleDoubleToTagged(GateRef gate)
481{
482    return Convert(gate, ValueType::HOLE_DOUBLE, ValueType::TAGGED_DOUBLE);
483}
484
485GateRef CircuitBuilder::CheckUInt32AndConvertToInt32(GateRef gate)
486{
487    return CheckAndConvert(gate, ValueType::UINT32, ValueType::INT32);
488}
489
490GateRef CircuitBuilder::CheckTaggedIntAndConvertToInt32(GateRef gate)
491{
492    return CheckAndConvert(gate, ValueType::TAGGED_INT, ValueType::INT32);
493}
494
495GateRef CircuitBuilder::CheckTaggedDoubleAndConvertToInt32(GateRef gate)
496{
497    return CheckAndConvert(gate, ValueType::TAGGED_DOUBLE, ValueType::INT32);
498}
499
500GateRef CircuitBuilder::CheckTaggedNumberAndConvertToInt32(GateRef gate)
501{
502    return CheckAndConvert(gate, ValueType::TAGGED_NUMBER, ValueType::INT32);
503}
504
505GateRef CircuitBuilder::CheckTaggedIntAndConvertToFloat64(GateRef gate)
506{
507    return CheckAndConvert(gate, ValueType::TAGGED_INT, ValueType::FLOAT64);
508}
509
510GateRef CircuitBuilder::CheckTaggedDoubleAndConvertToFloat64(GateRef gate)
511{
512    return CheckAndConvert(gate, ValueType::TAGGED_DOUBLE, ValueType::FLOAT64);
513}
514
515GateRef CircuitBuilder::CheckTaggedNumberAndConvertToFloat64(GateRef gate)
516{
517    return CheckAndConvert(gate, ValueType::TAGGED_NUMBER, ValueType::FLOAT64);
518}
519
520GateRef CircuitBuilder::CheckNullAndConvertToInt32(GateRef gate)
521{
522    return CheckAndConvert(gate, ValueType::TAGGED_NULL, ValueType::INT32);
523}
524
525GateRef CircuitBuilder::CheckTaggedBooleanAndConvertToInt32(GateRef gate)
526{
527    return CheckAndConvert(gate, ValueType::TAGGED_BOOLEAN, ValueType::INT32);
528}
529
530GateRef CircuitBuilder::CheckNullAndConvertToFloat64(GateRef gate)
531{
532    return CheckAndConvert(gate, ValueType::TAGGED_NULL, ValueType::FLOAT64);
533}
534
535GateRef CircuitBuilder::CheckTaggedBooleanAndConvertToFloat64(GateRef gate)
536{
537    return CheckAndConvert(gate, ValueType::TAGGED_BOOLEAN, ValueType::FLOAT64);
538}
539
540GateRef CircuitBuilder::CheckUndefinedAndConvertToFloat64(GateRef gate)
541{
542    return CheckAndConvert(gate, ValueType::UNDEFINED, ValueType::FLOAT64);
543}
544
545GateRef CircuitBuilder::CheckUndefinedAndConvertToBool(GateRef gate)
546{
547    return CheckAndConvert(gate, ValueType::UNDEFINED, ValueType::BOOL);
548}
549
550GateRef CircuitBuilder::CheckNullAndConvertToBool(GateRef gate)
551{
552    return CheckAndConvert(gate, ValueType::TAGGED_NULL, ValueType::BOOL);
553}
554
555GateRef CircuitBuilder::CheckUndefinedAndConvertToInt32(GateRef gate)
556{
557    return CheckAndConvert(gate, ValueType::UNDEFINED, ValueType::INT32);
558}
559
560GateRef CircuitBuilder::CheckHoleIntAndConvertToInt32(GateRef gate)
561{
562    return CheckAndConvert(gate, ValueType::HOLE_INT, ValueType::INT32);
563}
564
565GateRef CircuitBuilder::CheckHoleDoubleAndConvertToInt32(GateRef gate)
566{
567    return CheckAndConvert(gate, ValueType::HOLE_DOUBLE, ValueType::INT32);
568}
569
570GateRef CircuitBuilder::CheckHoleIntAndConvertToFloat64(GateRef gate)
571{
572    return CheckAndConvert(gate, ValueType::HOLE_INT, ValueType::FLOAT64);
573}
574
575GateRef CircuitBuilder::CheckHoleDoubleAndConvertToFloat64(GateRef gate)
576{
577    return CheckAndConvert(gate, ValueType::HOLE_DOUBLE, ValueType::FLOAT64);
578}
579
580GateRef CircuitBuilder::TryPrimitiveTypeCheck(GateType type, GateRef gate)
581{
582    if (acc_.GetOpCode(gate) == OpCode::CONSTANT) {
583        return Circuit::NullGate();
584    }
585    auto currentLabel = env_->GetCurrentLabel();
586    auto currentControl = currentLabel->GetControl();
587    auto currentDepend = currentLabel->GetDepend();
588    auto frameState = acc_.FindNearestFrameState(currentDepend);
589    GateRef ret = GetCircuit()->NewGate(circuit_->PrimitiveTypeCheck(static_cast<size_t>(type.Value())),
590        MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
591    currentLabel->SetControl(ret);
592    currentLabel->SetDepend(ret);
593    return ret;
594}
595
596std::vector<GateRef> CircuitBuilder::ConcatParams(const std::vector<std::vector<GateRef>>& params)
597{
598    std::vector<GateRef> unionParams;
599    for (auto param: params) {
600        unionParams.insert(unionParams.end(), param.begin(), param.end());
601    }
602    return unionParams;
603}
604
605GateRef CircuitBuilder::CallTargetCheck(GateRef gate, GateRef function, GateRef id, const char* comment)
606{
607    return CallTargetCheck(gate, function, id, {}, comment);
608}
609
610GateRef CircuitBuilder::CallTargetCheck(GateRef gate, GateRef function, GateRef id, std::vector<GateRef> params,
611                                        const char* comment)
612{
613    auto currentLabel = env_->GetCurrentLabel();
614    auto currentControl = currentLabel->GetControl();
615    auto currentDepend = currentLabel->GetDepend();
616    GateRef frameState;
617    if (Bytecodes::IsCallOp(acc_.GetByteCodeOpcode(gate))) {
618        frameState = acc_.GetFrameState(gate);
619    } else {
620        frameState = acc_.FindNearestFrameState(currentDepend);
621    }
622    auto params_vec = ConcatParams({{ currentControl, currentDepend, function, id }, params, {frameState}});
623    GateRef ret = GetCircuit()->NewGate(circuit_->TypedCallCheck(params.size() + 2),
624                                        MachineType::I1,
625                                        params_vec,
626                                        GateType::NJSValue(),
627                                        comment);
628    currentLabel->SetControl(ret);
629    currentLabel->SetDepend(ret);
630    return ret;
631}
632
633GateRef CircuitBuilder::TypedCallOperator(GateRef hirGate, MachineType type, const std::vector<GateRef> &inList,
634                                          bool isSideEffect)
635{
636    ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE);
637    auto numValueIn = inList.size() - 3; // 3: state & depend & frame state
638    uint64_t pcOffset = acc_.TryGetPcOffset(hirGate);
639    ASSERT(pcOffset != 0);
640    if (!isSideEffect) {
641        return GetCircuit()->NewGate(circuit_->TypedCallBuiltin(numValueIn, pcOffset), type,
642                                     inList.size(), inList.data(), GateType::AnyType());
643    }
644    return GetCircuit()->NewGate(circuit_->TypedCallBuiltinSideEffect(numValueIn, pcOffset), type,
645                                 inList.size(), inList.data(), GateType::AnyType());
646}
647
648GateRef CircuitBuilder::TypedNewAllocateThis(GateRef ctor, GateRef hclass, GateRef size, GateRef frameState)
649{
650    auto currentLabel = env_->GetCurrentLabel();
651    auto currentControl = currentLabel->GetControl();
652    auto currentDepend = currentLabel->GetDepend();
653    GateRef ret = GetCircuit()->NewGate(circuit_->TypedNewAllocateThis(),
654        MachineType::ANYVALUE, {currentControl, currentDepend, ctor, hclass,
655        size, frameState}, GateType::TaggedValue());
656    currentLabel->SetControl(ret);
657    currentLabel->SetDepend(ret);
658    return ret;
659}
660
661GateRef CircuitBuilder::TypedSuperAllocateThis(GateRef superCtor, GateRef newTarget, GateRef frameState)
662{
663    auto currentLabel = env_->GetCurrentLabel();
664    auto currentControl = currentLabel->GetControl();
665    auto currentDepend = currentLabel->GetDepend();
666    GateRef ret = GetCircuit()->NewGate(circuit_->TypedSuperAllocateThis(), MachineType::ANYVALUE,
667        {currentControl, currentDepend, superCtor, newTarget, frameState}, GateType::TaggedValue());
668    currentLabel->SetControl(ret);
669    currentLabel->SetDepend(ret);
670    return ret;
671}
672
673
674GateRef CircuitBuilder::Int32CheckRightIsZero(GateRef right)
675{
676    auto currentLabel = env_->GetCurrentLabel();
677    auto currentControl = currentLabel->GetControl();
678    auto currentDepend = currentLabel->GetDepend();
679    auto frameState = acc_.FindNearestFrameState(currentDepend);
680    GateRef ret = GetCircuit()->NewGate(circuit_->Int32CheckRightIsZero(),
681    MachineType::I1, {currentControl, currentDepend, right, frameState}, GateType::NJSValue());
682    currentLabel->SetControl(ret);
683    currentLabel->SetDepend(ret);
684    return ret;
685}
686
687GateRef CircuitBuilder::RemainderIsNegativeZero(GateRef left, GateRef right)
688{
689    auto currentLabel = env_->GetCurrentLabel();
690    auto currentControl = currentLabel->GetControl();
691    auto currentDepend = currentLabel->GetDepend();
692    auto frameState = acc_.FindNearestFrameState(currentDepend);
693    GateRef ret = GetCircuit()->NewGate(circuit_->RemainderIsNegativeZero(),
694                                        MachineType::I1,
695                                        {currentControl, currentDepend, left, right, frameState},
696                                        GateType::NJSValue());
697    currentLabel->SetControl(ret);
698    currentLabel->SetDepend(ret);
699    return ret;
700}
701
702GateRef CircuitBuilder::Float64CheckRightIsZero(GateRef right)
703{
704    auto currentLabel = env_->GetCurrentLabel();
705    auto currentControl = currentLabel->GetControl();
706    auto currentDepend = currentLabel->GetDepend();
707    auto frameState = acc_.FindNearestFrameState(currentDepend);
708    GateRef ret = GetCircuit()->NewGate(circuit_->Float64CheckRightIsZero(),
709    MachineType::I1, {currentControl, currentDepend, right, frameState}, GateType::NJSValue());
710    currentLabel->SetControl(ret);
711    currentLabel->SetDepend(ret);
712    return ret;
713}
714
715GateRef CircuitBuilder::LexVarIsHoleCheck(GateRef value)
716{
717    auto currentLabel = env_->GetCurrentLabel();
718    auto currentControl = currentLabel->GetControl();
719    auto currentDepend = currentLabel->GetDepend();
720    auto frameState = acc_.FindNearestFrameState(currentDepend);
721    GateRef ret = GetCircuit()->NewGate(circuit_->LexVarIsHoleCheck(),
722    MachineType::I1, {currentControl, currentDepend, value, frameState}, GateType::NJSValue());
723    currentLabel->SetControl(ret);
724    currentLabel->SetDepend(ret);
725    return ret;
726}
727
728GateRef CircuitBuilder::IsUndefinedOrHoleCheck(GateRef value)
729{
730    auto currentLabel = env_->GetCurrentLabel();
731    auto currentControl = currentLabel->GetControl();
732    auto currentDepend = currentLabel->GetDepend();
733    auto frameState = acc_.FindNearestFrameState(currentDepend);
734    GateRef ret = GetCircuit()->NewGate(circuit_->IsUndefinedOrHoleCheck(),
735        MachineType::I1, {currentControl, currentDepend, value, frameState}, GateType::NJSValue());
736    currentLabel->SetControl(ret);
737    currentLabel->SetDepend(ret);
738    return ret;
739}
740
741GateRef CircuitBuilder::IsNotUndefinedOrHoleCheck(GateRef value)
742{
743    auto currentLabel = env_->GetCurrentLabel();
744    auto currentControl = currentLabel->GetControl();
745    auto currentDepend = currentLabel->GetDepend();
746    auto frameState = acc_.FindNearestFrameState(currentDepend);
747    GateRef ret = GetCircuit()->NewGate(circuit_->IsNotUndefinedOrHoleCheck(),
748        MachineType::I1, {currentControl, currentDepend, value, frameState}, GateType::NJSValue());
749    currentLabel->SetControl(ret);
750    currentLabel->SetDepend(ret);
751    return ret;
752}
753
754GateRef CircuitBuilder::IsCallableCheck(GateRef func)
755{
756    auto currentLabel = env_->GetCurrentLabel();
757    auto currentControl = currentLabel->GetControl();
758    auto currentDepend = currentLabel->GetDepend();
759    auto frameState = acc_.FindNearestFrameState(currentDepend);
760    GateRef ret = GetCircuit()->NewGate(circuit_->IsCallableCheck(),
761                                        MachineType::I1,
762                                        {currentControl, currentDepend, func, frameState},
763                                        GateType::NJSValue());
764    currentLabel->SetControl(ret);
765    currentLabel->SetDepend(ret);
766    return ret;
767}
768
769GateRef CircuitBuilder::IsDataViewCheck(GateRef gate)
770{
771    auto currentLabel = env_->GetCurrentLabel();
772    auto currentControl = currentLabel->GetControl();
773    auto currentDepend = currentLabel->GetDepend();
774    auto frameState = acc_.FindNearestFrameState(currentDepend);
775    GateRef ret = GetCircuit()->NewGate(circuit_->IsDataViewCheck(),
776                                        MachineType::I1,
777                                        {currentControl, currentDepend, gate, frameState},
778                                        GateType::NJSValue());
779    currentLabel->SetControl(ret);
780    currentLabel->SetDepend(ret);
781    return ret;
782}
783
784GateRef CircuitBuilder::ValueCheckNegOverflow(GateRef value)
785{
786    auto currentLabel = env_->GetCurrentLabel();
787    auto currentControl = currentLabel->GetControl();
788    auto currentDepend = currentLabel->GetDepend();
789    auto frameState = acc_.FindNearestFrameState(currentDepend);
790    GateRef ret = GetCircuit()->NewGate(circuit_->ValueCheckNegOverflow(),
791    MachineType::I1, {currentControl, currentDepend, value, frameState}, GateType::NJSValue());
792    currentLabel->SetControl(ret);
793    currentLabel->SetDepend(ret);
794    return ret;
795}
796
797GateRef CircuitBuilder::OverflowCheck(GateRef value)
798{
799    auto currentLabel = env_->GetCurrentLabel();
800    auto currentControl = currentLabel->GetControl();
801    auto currentDepend = currentLabel->GetDepend();
802    auto frameState = acc_.FindNearestFrameState(currentDepend);
803    GateRef ret = GetCircuit()->NewGate(circuit_->OverflowCheck(),
804        MachineType::I1, {currentControl, currentDepend, value, frameState}, GateType::IntType());
805    currentLabel->SetControl(ret);
806    currentLabel->SetDepend(ret);
807    return ret;
808}
809
810GateRef CircuitBuilder::Int32UnsignedUpperBoundCheck(GateRef value, GateRef upperBound)
811{
812    auto currentLabel = env_->GetCurrentLabel();
813    auto currentControl = currentLabel->GetControl();
814    auto currentDepend = currentLabel->GetDepend();
815    auto frameState = acc_.FindNearestFrameState(currentDepend);
816    GateRef ret = GetCircuit()->NewGate(circuit_->Int32UnsignedUpperBoundCheck(),
817        MachineType::I1, {currentControl, currentDepend, value, upperBound, frameState}, GateType::IntType());
818    currentLabel->SetControl(ret);
819    currentLabel->SetDepend(ret);
820    return ret;
821}
822
823GateRef CircuitBuilder::Int32DivWithCheck(GateRef left, GateRef right)
824{
825    auto currentLabel = env_->GetCurrentLabel();
826    auto currentControl = currentLabel->GetControl();
827    auto currentDepend = currentLabel->GetDepend();
828    auto frameState = acc_.FindNearestFrameState(currentDepend);
829    GateRef ret = GetCircuit()->NewGate(circuit_->Int32DivWithCheck(),
830        MachineType::I32, {currentControl, currentDepend, left, right, frameState}, GateType::NJSValue());
831    currentLabel->SetControl(ret);
832    currentLabel->SetDepend(ret);
833    return ret;
834}
835
836GateRef CircuitBuilder::TypedConditionJump(MachineType type, TypedJumpOp jumpOp, uint32_t weight,
837    ParamType paramType, const std::vector<GateRef>& inList)
838{
839    uint64_t value = TypedJumpAccessor::ToValue(paramType, jumpOp, weight);
840    return GetCircuit()->NewGate(circuit_->TypedConditionJump(value),
841        type, inList.size(), inList.data(), GateType::Empty());
842}
843
844GateRef CircuitBuilder::TypeConvert(MachineType type, ParamType typeFrom, GateType typeTo,
845                                    const std::vector<GateRef>& inList)
846{
847    // merge types of valueIns before and after convertion
848    uint64_t operandTypes = TypeConvertAccessor::ToValue(typeFrom, typeTo);
849    return GetCircuit()->NewGate(circuit_->TypedConvert(operandTypes),
850        type, inList.size(), inList.data(), GateType::AnyType());
851}
852
853GateRef CircuitBuilder::StoreMemory(MemoryType Op, VariableType type, GateRef receiver, GateRef index, GateRef value)
854{
855    auto opIdx = static_cast<uint64_t>(Op);
856    auto currentLabel = env_->GetCurrentLabel();
857    auto currentControl = currentLabel->GetControl();
858    auto currentDepend = currentLabel->GetDepend();
859    auto ret = GetCircuit()->NewGate(GetCircuit()->StoreMemory(opIdx), type.GetMachineType(),
860        {currentControl, currentDepend, receiver, index, value}, type.GetGateType());
861    currentLabel->SetControl(ret);
862    currentLabel->SetDepend(ret);
863    return ret;
864}
865
866GateRef CircuitBuilder::LoadProperty(GateRef receiver, GateRef propertyLookupResult, bool isFunction)
867{
868    auto currentLabel = env_->GetCurrentLabel();
869    auto currentControl = currentLabel->GetControl();
870    auto currentDepend = currentLabel->GetDepend();
871    auto ret = GetCircuit()->NewGate(circuit_->LoadProperty(isFunction), MachineType::I64,
872                                     { currentControl, currentDepend, receiver, propertyLookupResult },
873                                     GateType::AnyType());
874    currentLabel->SetControl(ret);
875    currentLabel->SetDepend(ret);
876    return ret;
877}
878
879GateRef CircuitBuilder::StoreProperty(GateRef receiver, GateRef propertyLookupResult, GateRef value,
880                                      uint32_t receiverHClassIndex)
881{
882    auto currentLabel = env_->GetCurrentLabel();
883    auto currentControl = currentLabel->GetControl();
884    auto currentDepend = currentLabel->GetDepend();
885    auto ret = GetCircuit()->NewGate(circuit_->StoreProperty(receiverHClassIndex), MachineType::I64,
886                                     { currentControl, currentDepend, receiver, propertyLookupResult, value },
887                                     GateType::AnyType());
888    currentLabel->SetControl(ret);
889    currentLabel->SetDepend(ret);
890    return ret;
891}
892
893GateRef CircuitBuilder::LoadArrayLength(GateRef gate, ElementsKind kind, ArrayMetaDataAccessor::Mode mode)
894{
895    auto currentLabel = env_->GetCurrentLabel();
896    auto currentControl = currentLabel->GetControl();
897    auto currentDepend = currentLabel->GetDepend();
898    ArrayMetaDataAccessor accessor(kind, mode);
899    auto ret = GetCircuit()->NewGate(circuit_->LoadArrayLength(accessor.ToValue()), MachineType::I64,
900                                     { currentControl, currentDepend, gate }, GateType::IntType());
901    currentLabel->SetControl(ret);
902    currentLabel->SetDepend(ret);
903    return ret;
904}
905
906GateRef CircuitBuilder::LoadStringLength(GateRef string)
907{
908    auto currentLabel = env_->GetCurrentLabel();
909    auto currentControl = currentLabel->GetControl();
910    auto currentDepend = currentLabel->GetDepend();
911    auto ret = GetCircuit()->NewGate(circuit_->LoadStringLength(), MachineType::I64,
912                                     { currentControl, currentDepend, string }, GateType::IntType());
913    currentLabel->SetControl(ret);
914    currentLabel->SetDepend(ret);
915    return ret;
916}
917
918GateRef CircuitBuilder::LoadMapSize(GateRef string)
919{
920    auto currentLabel = env_->GetCurrentLabel();
921    auto currentControl = currentLabel->GetControl();
922    auto currentDepend = currentLabel->GetDepend();
923    auto ret = GetCircuit()->NewGate(circuit_->LoadMapSize(), MachineType::I64,
924                                     { currentControl, currentDepend, string }, GateType::IntType());
925    currentLabel->SetControl(ret);
926    currentLabel->SetDepend(ret);
927    return ret;
928}
929
930GateRef CircuitBuilder::LoadConstOffset(VariableType type, GateRef receiver, size_t offset, MemoryAttribute mAttr)
931{
932    auto currentLabel = env_->GetCurrentLabel();
933    auto currentDepend = currentLabel->GetDepend();
934    auto bits = LoadStoreConstOffsetAccessor::ToValue(offset, mAttr);
935    auto ret = GetCircuit()->NewGate(circuit_->LoadConstOffset(bits), type.GetMachineType(),
936                                     { currentDepend, receiver }, type.GetGateType());
937    currentLabel->SetDepend(ret);
938    return ret;
939}
940
941GateRef CircuitBuilder::LoadHClassFromConstpool(GateRef constpool, size_t index)
942{
943    auto currentLabel = env_->GetCurrentLabel();
944    auto currentDepend = currentLabel->GetDepend();
945    auto ret = GetCircuit()->NewGate(circuit_->LoadHClassFromConstpool(index), MachineType::I64,
946                                     { currentDepend, constpool }, GateType::AnyType());
947    currentLabel->SetDepend(ret);
948    return ret;
949}
950
951GateRef CircuitBuilder::StoreConstOffset(VariableType type,
952                                         GateRef receiver, size_t offset, GateRef value, MemoryAttribute mAttr)
953{
954    auto currentLabel = env_->GetCurrentLabel();
955    auto currentDepend = currentLabel->GetDepend();
956    if (mAttr.GetBarrier() == MemoryAttribute::Barrier::UNKNOWN_BARRIER && acc_.IsConstant(value)) {
957        mAttr.SetBarrier(MemoryAttribute::Barrier::NO_BARRIER);
958    }
959    auto bits = LoadStoreConstOffsetAccessor::ToValue(offset, mAttr);
960    auto ret = GetCircuit()->NewGate(circuit_->StoreConstOffset(bits), type.GetMachineType(),
961        { currentDepend, receiver, value }, type.GetGateType());
962    currentLabel->SetDepend(ret);
963    return ret;
964}
965
966GateRef CircuitBuilder::TaggedIsHeapObjectOp(GateRef value)
967{
968    auto currentLabel = env_->GetCurrentLabel();
969    auto currentControl = currentLabel->GetControl();
970    auto currentDepend = currentLabel->GetDepend();
971    auto newGate = GetCircuit()->NewGate(circuit_->TaggedIsHeapObject(), MachineType::I1,
972                                         { currentControl, currentDepend, value },
973                                         GateType::NJSValue());
974    currentLabel->SetDepend(newGate);
975    return newGate;
976}
977
978GateRef CircuitBuilder::IsSpecificObjectType(GateRef obj, JSType type)
979{
980    auto currentLabel = env_->GetCurrentLabel();
981    auto currentControl = currentLabel->GetControl();
982    auto currentDepend = currentLabel->GetDepend();
983    auto newGate = GetCircuit()->NewGate(circuit_->IsSpecificObjectType(static_cast<int32_t>(type)), MachineType::I1,
984                                         { currentControl, currentDepend, obj },
985                                         GateType::NJSValue());
986    currentLabel->SetDepend(newGate);
987    return newGate;
988}
989
990GateRef CircuitBuilder::IsMarkerCellValidOp(GateRef cell)
991{
992    auto currentLabel = env_->GetCurrentLabel();
993    auto currentControl = currentLabel->GetControl();
994    auto currentDepend = currentLabel->GetDepend();
995    auto newGate = GetCircuit()->NewGate(circuit_->IsMarkerCellValid(), MachineType::I1,
996                                         { currentControl, currentDepend, cell },
997                                         GateType::NJSValue());
998    currentLabel->SetDepend(newGate);
999    return newGate;
1000}
1001
1002GateRef CircuitBuilder::ConvertHoleAsUndefined(GateRef receiver)
1003{
1004    auto currentLabel = env_->GetCurrentLabel();
1005    auto currentControl = currentLabel->GetControl();
1006    auto currentDepend = currentLabel->GetDepend();
1007
1008    auto ret = GetCircuit()->NewGate(circuit_->ConvertHoleAsUndefined(),
1009        MachineType::I64, { currentControl, currentDepend, receiver }, GateType::AnyType());
1010    currentLabel->SetControl(ret);
1011    currentLabel->SetDepend(ret);
1012    return ret;
1013}
1014
1015GateRef CircuitBuilder::TypedCall(GateRef hirGate, std::vector<GateRef> args, bool isNoGC)
1016{
1017    ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE);
1018    auto currentLabel = env_->GetCurrentLabel();
1019    auto currentControl = currentLabel->GetControl();
1020    auto currentDepend = currentLabel->GetDepend();
1021    uint64_t bitfield = args.size();
1022    uint64_t pcOffset = acc_.TryGetPcOffset(hirGate);
1023    ASSERT(pcOffset != 0);
1024    args.insert(args.begin(), currentDepend);
1025    args.insert(args.begin(), currentControl);
1026    AppendFrameArgs(args, hirGate);
1027    auto callGate = GetCircuit()->NewGate(circuit_->TypedCall(bitfield, pcOffset, isNoGC), MachineType::I64,
1028                                          args.size(), args.data(), GateType::AnyType());
1029    currentLabel->SetControl(callGate);
1030    currentLabel->SetDepend(callGate);
1031    return callGate;
1032}
1033
1034GateRef CircuitBuilder::TypedFastCall(GateRef hirGate, std::vector<GateRef> args, bool isNoGC)
1035{
1036    ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE);
1037    auto currentLabel = env_->GetCurrentLabel();
1038    auto currentControl = currentLabel->GetControl();
1039    auto currentDepend = currentLabel->GetDepend();
1040    uint64_t bitfield = args.size();
1041    uint64_t pcOffset = acc_.TryGetPcOffset(hirGate);
1042    ASSERT(pcOffset != 0);
1043    args.insert(args.begin(), currentDepend);
1044    args.insert(args.begin(), currentControl);
1045    AppendFrameArgs(args, hirGate);
1046    auto callGate = GetCircuit()->NewGate(circuit_->TypedFastCall(bitfield, pcOffset, isNoGC), MachineType::I64,
1047                                          args.size(), args.data(), GateType::AnyType());
1048    currentLabel->SetControl(callGate);
1049    currentLabel->SetDepend(callGate);
1050    return callGate;
1051}
1052
1053GateRef CircuitBuilder::StartAllocate()
1054{
1055    auto currentLabel = env_->GetCurrentLabel();
1056    auto currentDepend = currentLabel->GetDepend();
1057    GateRef newGate = GetCircuit()->NewGate(circuit_->StartAllocate(),  MachineType::I64,
1058                                            { currentDepend }, GateType::NJSValue());
1059    currentLabel->SetDepend(newGate);
1060    return newGate;
1061}
1062
1063GateRef CircuitBuilder::FinishAllocate(GateRef value)
1064{
1065    auto currentLabel = env_->GetCurrentLabel();
1066    auto currentDepend = currentLabel->GetDepend();
1067    GateRef newGate = GetCircuit()->NewGate(circuit_->FinishAllocate(),  MachineType::I64,
1068                                            { currentDepend, value }, acc_.GetGateType(value));
1069    currentLabel->SetDepend(newGate);
1070    return newGate;
1071}
1072
1073GateRef CircuitBuilder::HeapAlloc(GateRef glue, GateRef size, GateType type, RegionSpaceFlag flag)
1074{
1075    auto currentLabel = env_->GetCurrentLabel();
1076    auto currentDepend = currentLabel->GetDepend();
1077    auto ret = GetCircuit()->NewGate(circuit_->HeapAlloc(flag), MachineType::I64,
1078                                     { currentDepend, glue, size }, type);
1079    currentLabel->SetDepend(ret);
1080    return ret;
1081}
1082
1083GateType CircuitBuilder::GetGateTypeOfValueType(ValueType type)
1084{
1085    switch (type) {
1086        case ValueType::BOOL:
1087        case ValueType::INT32:
1088        case ValueType::FLOAT64:
1089            return GateType::NJSValue();
1090        case ValueType::TAGGED_BOOLEAN:
1091            return GateType::BooleanType();
1092        case ValueType::TAGGED_INT:
1093            return GateType::IntType();
1094        case ValueType::TAGGED_DOUBLE:
1095            return GateType::DoubleType();
1096        case ValueType::TAGGED_NUMBER:
1097            return GateType::NumberType();
1098        default:
1099            return GateType::Empty();
1100    }
1101}
1102
1103GateRef CircuitBuilder::InsertTypedBinaryop(GateRef left, GateRef right, TypedBinOp op)
1104{
1105    auto currentLabel = env_->GetCurrentLabel();
1106    auto currentControl = currentLabel->GetControl();
1107    auto currentDepend = currentLabel->GetDepend();
1108    uint64_t value = TypedBinaryAccessor::ToValue(ParamType::NumberType(), op);
1109    auto ret = GetCircuit()->NewGate(circuit_->TypedBinaryOp(value),
1110                                     MachineType::I64,
1111                                     {currentControl, currentDepend, left, right},
1112                                     GateType::AnyType());
1113    acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret);
1114    currentLabel->SetControl(ret);
1115    currentLabel->SetDepend(ret);
1116    return ret;
1117}
1118
1119GateRef CircuitBuilder::InsertRangeCheckPredicate(GateRef left, TypedBinOp cond, GateRef right)
1120{
1121    auto currentLabel = env_->GetCurrentLabel();
1122    auto currentControl = currentLabel->GetControl();
1123    auto currentDepend = currentLabel->GetDepend();
1124    auto frameState = acc_.FindNearestFrameState(currentDepend);
1125    uint64_t value = TypedBinaryAccessor::ToValue(ParamType::IntType(), cond);
1126    auto ret = GetCircuit()->NewGate(circuit_->RangeCheckPredicate(value),
1127                                     MachineType::I32,
1128                                     {currentControl, currentDepend, left, right, frameState},
1129                                     GateType::IntType());
1130    acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret);
1131    currentLabel->SetControl(ret);
1132    currentLabel->SetDepend(ret);
1133    return ret;
1134}
1135
1136GateRef CircuitBuilder::InsertStableArrayCheck(GateRef array, ArrayMetaDataAccessor accessor)
1137{
1138    auto currentLabel = env_->GetCurrentLabel();
1139    auto currentControl = currentLabel->GetControl();
1140    auto currentDepend = currentLabel->GetDepend();
1141    GateRef frameState = acc_.FindNearestFrameState(currentDepend);
1142    auto ret = GetCircuit()->NewGate(circuit_->StableArrayCheck(accessor.ToValue()),
1143                                     MachineType::I1,
1144                                     {currentControl, currentDepend, array, frameState},
1145                                     GateType::NJSValue());
1146    acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret);
1147    currentLabel->SetControl(ret);
1148    currentLabel->SetDepend(ret);
1149    return ret;
1150}
1151
1152GateRef CircuitBuilder::InsertTypedArrayCheck(GateRef array, TypedArrayMetaDataAccessor accessor)
1153{
1154    auto currentLabel = env_->GetCurrentLabel();
1155    auto currentControl = currentLabel->GetControl();
1156    auto currentDepend = currentLabel->GetDepend();
1157    GateRef frameState = acc_.FindNearestFrameState(currentDepend);
1158    auto ret = GetCircuit()->NewGate(circuit_->TypedArrayCheck(accessor.ToValue()),
1159                                     MachineType::I1,
1160                                     {currentControl, currentDepend, array, frameState},
1161                                     GateType::NJSValue());
1162    acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret);
1163    currentLabel->SetControl(ret);
1164    currentLabel->SetDepend(ret);
1165    return ret;
1166}
1167
1168GateRef CircuitBuilder::InsertLoadArrayLength(GateRef array, GateRef length, bool isTypedArray)
1169{
1170    auto currentLabel = env_->GetCurrentLabel();
1171    auto currentControl = currentLabel->GetControl();
1172    auto currentDepend = currentLabel->GetDepend();
1173    if (isTypedArray) {
1174        TypedArrayMetaDataAccessor accessor = acc_.GetTypedArrayMetaDataAccessor(length);
1175        InsertTypedArrayCheck(array, accessor);
1176        currentControl = currentLabel->GetControl();
1177        currentDepend = currentLabel->GetDepend();
1178        auto ret = GetCircuit()->NewGate(circuit_->LoadTypedArrayLength(accessor.ToValue()),
1179                                         MachineType::I64,
1180                                         { currentControl, currentDepend, array },
1181                                         GateType::IntType());
1182        acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret);
1183        currentLabel->SetControl(ret);
1184        currentLabel->SetDepend(ret);
1185        return ret;
1186    } else {
1187        ArrayMetaDataAccessor accessor = acc_.GetArrayMetaDataAccessor(length);
1188        InsertStableArrayCheck(array, accessor);
1189        currentControl = currentLabel->GetControl();
1190        currentDepend = currentLabel->GetDepend();
1191        auto ret = GetCircuit()->NewGate(circuit_->LoadArrayLength(accessor.ToValue()),
1192                                         MachineType::I64,
1193                                         { currentControl, currentDepend, array },
1194                                         GateType::IntType());
1195        acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret);
1196        currentLabel->SetControl(ret);
1197        currentLabel->SetDepend(ret);
1198        return ret;
1199    }
1200    UNREACHABLE();
1201    return Circuit::NullGate();
1202}
1203
1204GateRef CircuitBuilder::IsIntegerString(GateRef string)
1205{
1206    // compressedStringsEnabled fixed to true constant
1207    GateRef hash = Load(VariableType::INT32(), string, IntPtr(EcmaString::MIX_HASHCODE_OFFSET));
1208    return Int32Equal(
1209        Int32And(hash, Int32(EcmaString::IS_INTEGER_MASK)),
1210        Int32(EcmaString::IS_INTEGER_MASK));
1211}
1212
1213GateRef CircuitBuilder::GetRawHashFromString(GateRef value)
1214{
1215    GateRef hash = Load(VariableType::INT32(), value, IntPtr(EcmaString::MIX_HASHCODE_OFFSET));
1216    return Int32And(hash, Int32(~EcmaString::IS_INTEGER_MASK));
1217}
1218
1219void CircuitBuilder::SetRawHashcode(GateRef glue, GateRef str, GateRef rawHashcode, GateRef isInteger)
1220{
1221    Label subentry(env_);
1222    SubCfgEntry(&subentry);
1223    Label integer(env_);
1224    Label notInteger(env_);
1225    Label exit(env_);
1226
1227    DEFVALUE(hash, env_, VariableType::INT32(), Int32(0));
1228    BRANCH_CIR2(isInteger, &integer, &notInteger);
1229    Bind(&integer);
1230    {
1231        hash = Int32Or(rawHashcode, Int32(EcmaString::IS_INTEGER_MASK));
1232        Jump(&exit);
1233    }
1234    Bind(&notInteger);
1235    {
1236        hash = Int32And(rawHashcode, Int32(~EcmaString::IS_INTEGER_MASK));
1237        Jump(&exit);
1238    }
1239    Bind(&exit);
1240    Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::MIX_HASHCODE_OFFSET), *hash);
1241    SubCfgExit();
1242    return;
1243}
1244
1245GateRef CircuitBuilder::GetLengthFromString(GateRef value)
1246{
1247    GateRef len = Load(VariableType::INT32(), value, IntPtr(EcmaString::MIX_LENGTH_OFFSET));
1248    return Int32LSR(len, Int32(EcmaString::STRING_LENGTH_SHIFT_COUNT));
1249}
1250
1251GateRef CircuitBuilder::Rotl(GateRef word, uint32_t shift)
1252{
1253    static constexpr uint32_t MAX_BITS = 32;
1254    return Int32Or(Int32LSL(word, Int32(shift)), Int32LSR(word, Int32(MAX_BITS - shift)));
1255}
1256
1257GateRef CircuitBuilder::CalcHashcodeForInt(GateRef value)
1258{
1259    GateRef rawVal = ChangeTaggedPointerToInt64(value);
1260    GateRef low = TruncInt64ToInt32(rawVal);
1261    GateRef k1 = Int32Mul(low, Int32(MurmurHash32Const::C1));
1262    GateRef k2 = Rotl(k1, MurmurHash32Const::MAIN_FIRST_SHIFT);
1263    GateRef k3 = Int32Mul(k2, Int32(MurmurHash32Const::C2));
1264    GateRef hash1 = Int32Xor(Int32(DEFAULT_SEED), k3);
1265    GateRef hash2 = Rotl(hash1, MurmurHash32Const::MAIN_SECOND_SHIFT);
1266    GateRef hash3 = Int32Add(Int32Mul(hash2, Int32(MurmurHash32Const::MAIN_MULTIPLICATOR)),
1267        Int32(MurmurHash32Const::MAIN_CONSTANT));
1268
1269    GateRef high = TruncInt64ToInt32(Int64LSR(rawVal, Int64(32U)));
1270    GateRef k4 = Int32Mul(high, Int32(MurmurHash32Const::C1));
1271    GateRef k5 = Rotl(k4, MurmurHash32Const::MAIN_FIRST_SHIFT);
1272    GateRef k6 = Int32Mul(k5, Int32(MurmurHash32Const::C2));
1273    GateRef hash4 = Int32Xor(hash3, k6);
1274    GateRef hash5 = Rotl(hash4, MurmurHash32Const::MAIN_SECOND_SHIFT);
1275    GateRef hash6 = Int32Add(Int32Mul(hash5, Int32(MurmurHash32Const::MAIN_MULTIPLICATOR)),
1276        Int32(MurmurHash32Const::MAIN_CONSTANT));
1277
1278    GateRef hash7 = Int32Xor(hash6, Int32(8U));
1279    // Finalize
1280    GateRef hash8 = Int32Xor(hash7, Int32LSR(hash7, Int32(MurmurHash32Const::FINALIZE_FIRST_SHIFT)));
1281    GateRef hash9 = Int32Mul(hash8, Int32(MurmurHash32Const::FINALIZE_FIRST_MULTIPLICATOR));
1282    GateRef hash10 = Int32Xor(hash9, Int32LSR(hash9, Int32(MurmurHash32Const::FINALIZE_SECOND_SHIFT)));
1283    GateRef hash11 = Int32Mul(hash10, Int32(MurmurHash32Const::FINALIZE_SECOND_MULTIPLICATOR));
1284    GateRef hash12 = Int32Xor(hash11, Int32LSR(hash11, Int32(MurmurHash32Const::FINALIZE_THIRD_SHIFT)));
1285    return hash12;
1286}
1287
1288GateRef CircuitBuilder::GetHashcodeFromString(GateRef glue, GateRef value, GateRef hir)
1289{
1290    Label subentry(env_);
1291    SubCfgEntry(&subentry);
1292    Label noRawHashcode(env_);
1293    Label exit(env_);
1294    DEFVALUE(hashcode, env_, VariableType::INT32(), Int32(0));
1295    hashcode = Load(VariableType::INT32(), value, IntPtr(EcmaString::MIX_HASHCODE_OFFSET));
1296    BRANCH_CIR2(Int32Equal(*hashcode, Int32(0)), &noRawHashcode, &exit);
1297    Bind(&noRawHashcode);
1298    {
1299        hashcode = GetInt32OfTInt(
1300            CallRuntime(glue, RTSTUB_ID(ComputeHashcode), Gate::InvalidGateRef, { value }, hir));
1301        Store(VariableType::INT32(), glue, value, IntPtr(EcmaString::MIX_HASHCODE_OFFSET), *hashcode);
1302        Jump(&exit);
1303    }
1304    Bind(&exit);
1305    auto ret = *hashcode;
1306    SubCfgExit();
1307    return ret;
1308}
1309
1310GateRef CircuitBuilder::TryGetHashcodeFromString(GateRef string)
1311{
1312    Label subentry(env_);
1313    SubCfgEntry(&subentry);
1314    Label noRawHashcode(env_);
1315    Label storeHash(env_);
1316    Label exit(env_);
1317    DEFVALUE(result, env_, VariableType::INT64(), Int64(-1));
1318    GateRef hashCode = ZExtInt32ToInt64(Load(VariableType::INT32(), string, IntPtr(EcmaString::MIX_HASHCODE_OFFSET)));
1319    BRANCH_CIR2(Int64Equal(hashCode, Int64(0)), &noRawHashcode, &storeHash);
1320    Bind(&noRawHashcode);
1321    {
1322        GateRef length = GetLengthFromString(string);
1323        Label lengthNotZero(env_);
1324        BRANCH_CIR2(Int32Equal(length, Int32(0)), &storeHash, &exit);
1325    }
1326    Bind(&storeHash);
1327    result = hashCode;
1328    Jump(&exit);
1329    Bind(&exit);
1330    auto ret = *result;
1331    SubCfgExit();
1332    return ret;
1333}
1334
1335GateRef CircuitBuilder::GetStringDataFromLineOrConstantString(GateRef str)
1336{
1337    Label subentry(env_);
1338    SubCfgEntry(&subentry);
1339    Label exit(env_);
1340    Label isConstantString(env_);
1341    Label isLineString(env_);
1342    DEFVALUE(result, env_, VariableType::NATIVE_POINTER(), IntPtr(0));
1343    BRANCH_CIR2(IsConstantString(str), &isConstantString, &isLineString);
1344    Bind(&isConstantString);
1345    {
1346        GateRef address = ChangeTaggedPointerToInt64(PtrAdd(str, IntPtr(ConstantString::CONSTANT_DATA_OFFSET)));
1347        result = Load(VariableType::NATIVE_POINTER(), address, IntPtr(0));
1348        Jump(&exit);
1349    }
1350    Bind(&isLineString);
1351    {
1352        result = ChangeTaggedPointerToInt64(PtrAdd(str, IntPtr(LineEcmaString::DATA_OFFSET)));
1353        Jump(&exit);
1354    }
1355    Bind(&exit);
1356    auto ret = *result;
1357    SubCfgExit();
1358    return ret;
1359}
1360
1361void CircuitBuilder::CopyChars(GateRef glue, GateRef dst, GateRef source,
1362    GateRef sourceLength, GateRef charSize, VariableType type)
1363{
1364    Label subentry(env_);
1365    SubCfgEntry(&subentry);
1366    DEFVALUE(dstTmp, env_, VariableType::NATIVE_POINTER(), dst);
1367    DEFVALUE(sourceTmp, env_, VariableType::NATIVE_POINTER(), source);
1368    DEFVALUE(len, env_, VariableType::INT32(), sourceLength);
1369    Label loopHead(env_);
1370    Label loopEnd(env_);
1371    Label next(env_);
1372    Label exit(env_);
1373    Jump(&loopHead);
1374
1375    LoopBegin(&loopHead);
1376    {
1377        BRANCH_CIR2(Int32GreaterThan(*len, Int32(0)), &next, &exit);
1378        Bind(&next);
1379        {
1380            len = Int32Sub(*len, Int32(1));
1381            GateRef i = Load(type, *sourceTmp, IntPtr(0));
1382            Store(type, glue, *dstTmp, IntPtr(0), i);
1383            Jump(&loopEnd);
1384        }
1385    }
1386    Bind(&loopEnd);
1387    sourceTmp = PtrAdd(*sourceTmp, charSize);
1388    dstTmp = PtrAdd(*dstTmp, charSize);
1389    LoopEnd(&loopHead);
1390
1391    Bind(&exit);
1392    SubCfgExit();
1393    return;
1394}
1395
1396// source is utf8, dst is utf16
1397void CircuitBuilder::CopyUtf8AsUtf16(GateRef glue, GateRef dst, GateRef src,
1398
1399    GateRef sourceLength)
1400{
1401    Label subentry(env_);
1402    SubCfgEntry(&subentry);
1403    DEFVALUE(dstTmp, env_, VariableType::NATIVE_POINTER(), dst);
1404    DEFVALUE(sourceTmp, env_, VariableType::NATIVE_POINTER(), src);
1405    DEFVALUE(len, env_, VariableType::INT32(), sourceLength);
1406    Label loopHead(env_);
1407    Label loopEnd(env_);
1408    Label next(env_);
1409    Label exit(env_);
1410    Jump(&loopHead);
1411    LoopBegin(&loopHead);
1412    {
1413        BRANCH_CIR2(Int32GreaterThan(*len, Int32(0)), &next, &exit);
1414        Bind(&next);
1415        {
1416            len = Int32Sub(*len, Int32(1));
1417            GateRef i = Load(VariableType::INT8(), *sourceTmp, IntPtr(0));
1418            Store(VariableType::INT16(), glue, *dstTmp, IntPtr(0), ZExtInt8ToInt16(i));
1419            Jump(&loopEnd);
1420        }
1421    }
1422
1423    Bind(&loopEnd);
1424    sourceTmp = PtrAdd(*sourceTmp, IntPtr(sizeof(uint8_t)));
1425    dstTmp = PtrAdd(*dstTmp, IntPtr(sizeof(uint16_t)));
1426    LoopEnd(&loopHead);
1427
1428    Bind(&exit);
1429    SubCfgExit();
1430    return;
1431}
1432
1433GateRef CircuitBuilder::TaggedPointerToInt64(GateRef x)
1434{
1435    return ChangeTaggedPointerToInt64(x);
1436}
1437
1438GateRef CircuitBuilder::ComputeTaggedArraySize(GateRef length)
1439{
1440    return PtrAdd(IntPtr(TaggedArray::DATA_OFFSET),
1441        PtrMul(IntPtr(JSTaggedValue::TaggedTypeSize()), length));
1442}
1443
1444GateRef CircuitBuilder::GetEnumCacheKind(GateRef glue, GateRef enumCache)
1445{
1446    Label entry(env_);
1447    SubCfgEntry(&entry);
1448    Label exit(env_);
1449    DEFVALUE(result, env_, VariableType::INT32(), Int32(static_cast<int32_t>(EnumCacheKind::NONE)));
1450
1451    Label enumCacheIsArray(env_);
1452    Label isEmptyArray(env_);
1453    Label notEmptyArray(env_);
1454
1455    BRANCH_CIR2(TaggedIsUndefinedOrNull(enumCache), &exit, &enumCacheIsArray);
1456    Bind(&enumCacheIsArray);
1457    GateRef emptyArray = GetEmptyArray(glue);
1458    BRANCH_CIR2(Int64Equal(enumCache, emptyArray), &isEmptyArray, &notEmptyArray);
1459    Bind(&isEmptyArray);
1460    {
1461        result = Int32(static_cast<int32_t>(EnumCacheKind::SIMPLE));
1462        Jump(&exit);
1463    }
1464    Bind(&notEmptyArray);
1465    {
1466        GateRef taggedKind = GetValueFromTaggedArray(enumCache, Int32(EnumCache::ENUM_CACHE_KIND_OFFSET));
1467        result = TaggedGetInt(taggedKind);
1468        Jump(&exit);
1469    }
1470
1471    Bind(&exit);
1472    auto ret = *result;
1473    SubCfgExit();
1474    return ret;
1475}
1476
1477GateRef CircuitBuilder::IsEnumCacheValid(GateRef receiver, GateRef cachedHclass, GateRef kind)
1478{
1479    Label entry(env_);
1480    SubCfgEntry(&entry);
1481    Label exit(env_);
1482    DEFVALUE(result, env_, VariableType::BOOL(), False());
1483
1484    Label isSameHclass(env_);
1485    Label isSimpleEnumCache(env_);
1486    Label notSimpleEnumCache(env_);
1487    Label prototypeIsEcmaObj(env_);
1488    Label isProtoChangeMarker(env_);
1489    Label protoNotChanged(env_);
1490
1491    GateRef hclass = LoadHClass(receiver);
1492    BRANCH_CIR2(Int64Equal(hclass, cachedHclass), &isSameHclass, &exit);
1493    Bind(&isSameHclass);
1494    BRANCH_CIR2(Int32Equal(kind, Int32(static_cast<int32_t>(EnumCacheKind::SIMPLE))),
1495                &isSimpleEnumCache, &notSimpleEnumCache);
1496    Bind(&isSimpleEnumCache);
1497    {
1498        result = True();
1499        Jump(&exit);
1500    }
1501    Bind(&notSimpleEnumCache);
1502    GateRef prototype = GetPrototypeFromHClass(hclass);
1503    BRANCH_CIR2(IsEcmaObject(prototype), &prototypeIsEcmaObj, &exit);
1504    Bind(&prototypeIsEcmaObj);
1505    GateRef protoChangeMarker = GetProtoChangeMarkerFromHClass(hclass);
1506    BRANCH_CIR2(TaggedIsProtoChangeMarker(protoChangeMarker), &isProtoChangeMarker, &exit);
1507    Bind(&isProtoChangeMarker);
1508    BRANCH_CIR2(GetHasChanged(protoChangeMarker), &exit, &protoNotChanged);
1509    Bind(&protoNotChanged);
1510    {
1511        result = True();
1512        Jump(&exit);
1513    }
1514    Bind(&exit);
1515    auto ret = *result;
1516    SubCfgExit();
1517    return ret;
1518}
1519
1520GateRef CircuitBuilder::NeedCheckProperty(GateRef receiver)
1521{
1522    Label entry(env_);
1523    SubCfgEntry(&entry);
1524    Label exit(env_);
1525
1526    Label loopHead(env_);
1527    Label loopEnd(env_);
1528    Label afterLoop(env_);
1529    Label isJSObject(env_);
1530    Label hasNoDeleteProperty(env_);
1531
1532    DEFVALUE(result, env_, VariableType::BOOL(), True());
1533    DEFVALUE(current, env_, VariableType::JS_ANY(), receiver);
1534
1535    BRANCH_CIR2(TaggedIsHeapObject(*current), &loopHead, &afterLoop);
1536    LoopBegin(&loopHead);
1537    {
1538        BRANCH_CIR2(IsJSObject(*current), &isJSObject, &exit);
1539        Bind(&isJSObject);
1540        GateRef hclass = LoadHClass(*current);
1541        BRANCH_CIR2(HasDeleteProperty(hclass), &exit, &hasNoDeleteProperty);
1542        Bind(&hasNoDeleteProperty);
1543        current = GetPrototypeFromHClass(hclass);
1544        BRANCH_CIR2(TaggedIsHeapObject(*current), &loopEnd, &afterLoop);
1545    }
1546    Bind(&loopEnd);
1547    LoopEnd(&loopHead);
1548    Bind(&afterLoop);
1549    {
1550        result = False();
1551        Jump(&exit);
1552    }
1553    Bind(&exit);
1554    auto ret = *result;
1555    SubCfgExit();
1556    return ret;
1557}
1558
1559GateRef CircuitBuilder::ArrayConstructorCheck(GateRef gate)
1560{
1561    auto currentLabel = env_->GetCurrentLabel();
1562    auto currentControl = currentLabel->GetControl();
1563    auto currentDepend = currentLabel->GetDepend();
1564    auto frameState = acc_.FindNearestFrameState(currentDepend);
1565    GateRef ret = GetCircuit()->NewGate(circuit_->ArrayConstructorCheck(),
1566        MachineType::I64, {currentControl, currentDepend, gate, frameState}, GateType::IntType());
1567    currentLabel->SetControl(ret);
1568    currentLabel->SetDepend(ret);
1569    return ret;
1570}
1571
1572GateRef CircuitBuilder::Float32ArrayConstructorCheck(GateRef gate)
1573{
1574    auto currentLabel = env_->GetCurrentLabel();
1575    auto currentControl = currentLabel->GetControl();
1576    auto currentDepend = currentLabel->GetDepend();
1577    auto frameState = acc_.FindNearestFrameState(currentDepend);
1578    GateRef ret = GetCircuit()->NewGate(circuit_->Float32ArrayConstructorCheck(),
1579        MachineType::I64, {currentControl, currentDepend, gate, frameState}, GateType::IntType());
1580    currentLabel->SetControl(ret);
1581    currentLabel->SetDepend(ret);
1582    return ret;
1583}
1584
1585GateRef CircuitBuilder::ObjectConstructorCheck(GateRef gate)
1586{
1587    auto currentLabel = env_->GetCurrentLabel();
1588    auto currentControl = currentLabel->GetControl();
1589    auto currentDepend = currentLabel->GetDepend();
1590    auto frameState = acc_.FindNearestFrameState(currentDepend);
1591    GateRef ret = GetCircuit()->NewGate(circuit_->ObjectConstructorCheck(),
1592        MachineType::I64, {currentControl, currentDepend, gate, frameState}, GateType::IntType());
1593    currentLabel->SetControl(ret);
1594    currentLabel->SetDepend(ret);
1595    return ret;
1596}
1597
1598GateRef CircuitBuilder::BooleanConstructorCheck(GateRef gate)
1599{
1600    auto currentLabel = env_->GetCurrentLabel();
1601    auto currentControl = currentLabel->GetControl();
1602    auto currentDepend = currentLabel->GetDepend();
1603    auto frameState = acc_.FindNearestFrameState(currentDepend);
1604    GateRef ret = GetCircuit()->NewGate(circuit_->BooleanConstructorCheck(),
1605        MachineType::I64, {currentControl, currentDepend, gate, frameState}, GateType::IntType());
1606    currentLabel->SetControl(ret);
1607    currentLabel->SetDepend(ret);
1608    return ret;
1609}
1610
1611GateRef CircuitBuilder::MonoLoadPropertyOnProto(GateRef receiver, GateRef plrGate, GateRef unsharedConstPool,
1612                                                size_t hclassIndex)
1613{
1614    auto currentLabel = env_->GetCurrentLabel();
1615    auto currentControl = currentLabel->GetControl();
1616    auto currentDepend = currentLabel->GetDepend();
1617    auto frameState = acc_.FindNearestFrameState(currentDepend);
1618    auto ret = GetCircuit()->NewGate(circuit_->MonoLoadPropertyOnProto(), MachineType::I64,
1619                                     { currentControl, currentDepend, receiver, plrGate, Int32(hclassIndex),
1620                                       unsharedConstPool, frameState },
1621                                     GateType::AnyType());
1622    currentLabel->SetControl(ret);
1623    currentLabel->SetDepend(ret);
1624    return ret;
1625}
1626
1627GateRef CircuitBuilder::MonoCallGetterOnProto(GateRef gate, GateRef receiver, GateRef plrGate,
1628                                              GateRef unsharedConstPool, size_t hclassIndex)
1629{
1630    uint64_t pcOffset = acc_.TryGetPcOffset(gate);
1631    ASSERT(pcOffset != 0);
1632
1633    auto currentLabel = env_->GetCurrentLabel();
1634    auto currentControl = currentLabel->GetControl();
1635    auto currentDepend = currentLabel->GetDepend();
1636    auto frameState = acc_.FindNearestFrameState(currentDepend);
1637    std::vector<GateRef> args = { currentControl, currentDepend, receiver, plrGate, Int32(hclassIndex),
1638                                  unsharedConstPool, frameState };
1639    auto callGate = GetCircuit()->NewGate(circuit_->MonoCallGetterOnProto(pcOffset),
1640                                          MachineType::I64,
1641                                          args.size(),
1642                                          args.data(),
1643                                          GateType::AnyType());
1644    currentLabel->SetControl(callGate);
1645    currentLabel->SetDepend(callGate);
1646    return callGate;
1647}
1648
1649GateRef CircuitBuilder::MonoStorePropertyLookUpProto(GateRef receiver, GateRef plrGate, GateRef unsharedConstPool,
1650                                                     size_t hclassIndex, GateRef value)
1651{
1652    auto currentLabel = env_->GetCurrentLabel();
1653    auto currentControl = currentLabel->GetControl();
1654    auto currentDepend = currentLabel->GetDepend();
1655    auto frameState = acc_.FindNearestFrameState(currentDepend);
1656    auto ret = GetCircuit()->NewGate(circuit_->MonoStorePropertyLookUpProto(false), MachineType::I64,
1657        { currentControl, currentDepend, receiver, plrGate, Int32(hclassIndex), unsharedConstPool, value, frameState},
1658        GateType::AnyType());
1659    currentLabel->SetControl(ret);
1660    currentLabel->SetDepend(ret);
1661    return ret;
1662}
1663
1664GateRef CircuitBuilder::MonoStoreProperty(GateRef receiver, GateRef plrGate, GateRef unsharedConstPool,
1665                                          size_t hclassIndex, GateRef value, GateRef keyIndex, GateRef frameState)
1666{
1667    auto currentLabel = env_->GetCurrentLabel();
1668    auto currentControl = currentLabel->GetControl();
1669    auto currentDepend = currentLabel->GetDepend();
1670    auto ret = GetCircuit()->NewGate(circuit_->MonoStoreProperty(false), MachineType::I64,
1671                                     {currentControl, currentDepend, receiver, plrGate, Int32(hclassIndex),
1672                                      unsharedConstPool, value, keyIndex, frameState},
1673                                     GateType::AnyType());
1674    currentLabel->SetControl(ret);
1675    currentLabel->SetDepend(ret);
1676    return ret;
1677}
1678
1679GateRef CircuitBuilder::TypedCreateObjWithBuffer(std::vector<GateRef> &valueIn)
1680{
1681    auto currentLabel = env_->GetCurrentLabel();
1682    auto currentControl = currentLabel->GetControl();
1683    auto currentDepend = currentLabel->GetDepend();
1684    auto frameState = acc_.FindNearestFrameState(currentDepend);
1685    std::vector<GateRef> vec { currentControl, currentDepend };
1686    vec.insert(vec.end(), valueIn.begin(), valueIn.end());
1687    vec.emplace_back(frameState);
1688    GateRef ret = GetCircuit()->NewGate(circuit_->TypedCreateObjWithBuffer(valueIn.size()),
1689        MachineType::I64, vec, GateType::AnyType());
1690    currentLabel->SetControl(ret);
1691    currentLabel->SetDepend(ret);
1692    return ret;
1693}
1694
1695GateRef CircuitBuilder::ToNumber(GateRef gate, GateRef value, GateRef glue)
1696{
1697    Label entry(env_);
1698    env_->SubCfgEntry(&entry);
1699    Label exit(env_);
1700    Label isNumber(env_);
1701    Label notNumber(env_);
1702    DEFVALUE(result, env_, VariableType::JS_ANY(), Hole());
1703    BRANCH_CIR2(TaggedIsNumber(value), &isNumber, &notNumber);
1704    Bind(&isNumber);
1705    {
1706        result = value;
1707        Jump(&exit);
1708    }
1709    Bind(&notNumber);
1710    {
1711        result = CallRuntime(glue, RTSTUB_ID(ToNumber), Gate::InvalidGateRef, { value }, gate);
1712        Jump(&exit);
1713    }
1714    Bind(&exit);
1715    auto ret = *result;
1716    env_->SubCfgExit();
1717    return ret;
1718}
1719
1720GateRef CircuitBuilder::StringToNumber(GateRef gate, GateRef value, GateRef radix, GateRef glue)
1721{
1722    return CallNGCRuntime(glue, RTSTUB_ID(StringToNumber), Gate::InvalidGateRef, { value, radix }, gate);
1723}
1724
1725GateRef CircuitBuilder::BuildControlDependOp(const GateMetaData* op, std::vector<GateRef> args,
1726                                             std::vector<GateRef> frameStates)
1727{
1728    auto currentLabel = env_->GetCurrentLabel();
1729    auto currentControl = currentLabel->GetControl();
1730    auto currentDepend = currentLabel->GetDepend();
1731    GateRef ret =
1732        GetCircuit()->NewGate(op, MachineType::I64,
1733            ConcatParams({std::vector{ currentControl, currentDepend}, args, frameStates}), GateType::AnyType());
1734    currentLabel->SetControl(ret);
1735    currentLabel->SetDepend(ret);
1736    return ret;
1737}
1738
1739GateRef CircuitBuilder::StringFromSingleCharCode(GateRef gate)
1740{
1741    auto currentLabel = env_->GetCurrentLabel();
1742    auto currentControl = currentLabel->GetControl();
1743    auto currentDepend = currentLabel->GetDepend();
1744    GateRef ret =
1745        GetCircuit()->NewGate(circuit_->StringFromSingleCharCode(), MachineType::I64,
1746            { currentControl, currentDepend, gate }, GateType::AnyType());
1747    currentLabel->SetControl(ret);
1748    currentLabel->SetDepend(ret);
1749    return ret;
1750}
1751
1752GateRef CircuitBuilder::StringCharCodeAt(GateRef thisValue, GateRef posTag)
1753{
1754    auto currentLabel = env_->GetCurrentLabel();
1755    auto currentControl = currentLabel->GetControl();
1756    auto currentDepend = currentLabel->GetDepend();
1757    GateRef ret =
1758        GetCircuit()->NewGate(circuit_->StringCharCodeAt(), MachineType::I64,
1759            { currentControl, currentDepend, thisValue, posTag }, GateType::AnyType());
1760    currentLabel->SetControl(ret);
1761    currentLabel->SetDepend(ret);
1762    return ret;
1763}
1764
1765GateRef CircuitBuilder::StringSubstring(GateRef thisValue, GateRef startTag, GateRef endTag)
1766{
1767    auto currentLabel = env_->GetCurrentLabel();
1768    auto currentControl = currentLabel->GetControl();
1769    auto currentDepend = currentLabel->GetDepend();
1770    GateRef ret =
1771        GetCircuit()->NewGate(circuit_->StringSubstring(), MachineType::I64,
1772            { currentControl, currentDepend, thisValue, startTag, endTag }, GateType::AnyType());
1773    currentLabel->SetControl(ret);
1774    currentLabel->SetDepend(ret);
1775    return ret;
1776}
1777
1778GateRef CircuitBuilder::StringSubStr(GateRef thisValue, GateRef intStart, GateRef lengthTag)
1779{
1780    auto currentLabel = env_->GetCurrentLabel();
1781    auto currentControl = currentLabel->GetControl();
1782    auto currentDepend = currentLabel->GetDepend();
1783    GateRef ret =
1784        GetCircuit()->NewGate(circuit_->StringSubStr(), MachineType::I64,
1785            { currentControl, currentDepend, thisValue, intStart, lengthTag }, GateType::AnyType());
1786    currentLabel->SetControl(ret);
1787    currentLabel->SetDepend(ret);
1788    return ret;
1789}
1790
1791GateRef CircuitBuilder::StringSlice(GateRef thisValue, GateRef startTag, GateRef endTag)
1792{
1793    auto currentLabel = env_->GetCurrentLabel();
1794    auto currentControl = currentLabel->GetControl();
1795    auto currentDepend = currentLabel->GetDepend();
1796    GateRef ret =
1797        GetCircuit()->NewGate(circuit_->StringSlice(), MachineType::I64,
1798            { currentControl, currentDepend, thisValue, startTag, endTag }, GateType::AnyType());
1799    currentLabel->SetControl(ret);
1800    currentLabel->SetDepend(ret);
1801    return ret;
1802}
1803
1804GateRef CircuitBuilder::ArrayBufferIsView(GateRef gate)
1805{
1806    auto currentLabel = env_->GetCurrentLabel();
1807    auto currentControl = currentLabel->GetControl();
1808    auto currentDepend = currentLabel->GetDepend();
1809    GateRef ret = GetCircuit()->NewGate(
1810        circuit_->ArrayBufferIsView(), MachineType::I64, {currentControl, currentDepend, gate}, GateType::AnyType());
1811    currentLabel->SetControl(ret);
1812    currentLabel->SetDepend(ret);
1813    return ret;
1814}
1815
1816GateRef CircuitBuilder::DataViewGet(
1817    GateRef thisobj, GateRef index, GateRef dataViewCallID, GateRef isLittleEndian, GateRef frameState)
1818{
1819    auto currentLabel = env_->GetCurrentLabel();
1820    auto currentControl = currentLabel->GetControl();
1821    auto currentDepend = currentLabel->GetDepend();
1822    GateRef ret = GetCircuit()->NewGate(
1823        circuit_->DataViewGet(),
1824        MachineType::I64,
1825        {currentControl, currentDepend, thisobj, index, dataViewCallID, isLittleEndian, frameState},
1826        GateType::AnyType());
1827    currentLabel->SetControl(ret);
1828    currentLabel->SetDepend(ret);
1829    return ret;
1830}
1831
1832GateRef CircuitBuilder::DataViewSet(
1833    GateRef thisobj, GateRef index, GateRef value, GateRef dataViewCallID, GateRef isLittleEndian, GateRef frameState)
1834{
1835    auto currentLabel = env_->GetCurrentLabel();
1836    auto currentControl = currentLabel->GetControl();
1837    auto currentDepend = currentLabel->GetDepend();
1838    GateRef ret = GetCircuit()->NewGate(
1839        circuit_->DataViewSet(),
1840        MachineType::I64,
1841        {currentControl, currentDepend, thisobj, index, value, dataViewCallID, isLittleEndian, frameState},
1842        GateType::TaggedValue());
1843    currentLabel->SetControl(ret);
1844    currentLabel->SetDepend(ret);
1845    return ret;
1846}
1847
1848GateRef CircuitBuilder::ArrayIncludesIndexOf(
1849    GateRef thisArray, GateRef fromIndex, GateRef targetElement, GateRef callID, GateRef arrayKind)
1850{
1851    auto currentLabel = env_->GetCurrentLabel();
1852    auto currentControl = currentLabel->GetControl();
1853    auto currentDepend = currentLabel->GetDepend();
1854    GateRef ret =
1855        GetCircuit()->NewGate(circuit_->ArrayIncludesIndexOf(),
1856                              MachineType::I64,
1857                              {currentControl, currentDepend, thisArray, fromIndex, targetElement, callID, arrayKind},
1858                              GateType::AnyType());
1859    currentLabel->SetControl(ret);
1860    currentLabel->SetDepend(ret);
1861    return ret;
1862}
1863
1864GateRef CircuitBuilder::ArrayIteratorBuiltin(GateRef thisArray, GateRef callID)
1865{
1866    auto currentLabel = env_->GetCurrentLabel();
1867    auto currentControl = currentLabel->GetControl();
1868    auto currentDepend = currentLabel->GetDepend();
1869    auto ret = GetCircuit()->NewGate(circuit_->ArrayIteratorBuiltin(),
1870                                     MachineType::I64,
1871                                     {currentControl, currentDepend, thisArray, callID},
1872                                     GateType::TaggedValue());
1873    currentLabel->SetControl(ret);
1874    currentLabel->SetDepend(ret);
1875    return ret;
1876}
1877
1878GateRef CircuitBuilder::ArrayForEach(GateRef thisValue, GateRef callBackFn, GateRef usingThis, uint32_t pcOffset)
1879{
1880    auto currentLabel = env_->GetCurrentLabel();
1881    auto currentControl = currentLabel->GetControl();
1882    auto currentDepend = currentLabel->GetDepend();
1883    GateRef ret = GetCircuit()->NewGate(circuit_->ArrayForEach(static_cast<uint64_t>(pcOffset)),
1884                                        MachineType::I64,
1885                                        {currentControl, currentDepend, thisValue, callBackFn, usingThis},
1886                                        GateType::AnyType());
1887    currentLabel->SetControl(ret);
1888    currentLabel->SetDepend(ret);
1889    return ret;
1890}
1891
1892GateRef CircuitBuilder::ArraySort(GateRef thisValue, GateRef callBackFn)
1893{
1894    auto currentLabel = env_->GetCurrentLabel();
1895    auto currentControl = currentLabel->GetControl();
1896    auto currentDepend = currentLabel->GetDepend();
1897    GateRef ret = GetCircuit()->NewGate(circuit_->ArraySort(),
1898                                        MachineType::I64,
1899                                        {currentControl, currentDepend, thisValue, callBackFn},
1900                                        GateType::AnyType());
1901    currentLabel->SetControl(ret);
1902    currentLabel->SetDepend(ret);
1903    return ret;
1904}
1905
1906GateRef CircuitBuilder::ArrayFilter(
1907    GateRef thisValue, GateRef callBackFn, GateRef usingThis, GateRef frameState, uint32_t pcOffset)
1908{
1909    auto currentLabel = env_->GetCurrentLabel();
1910    auto currentControl = currentLabel->GetControl();
1911    auto currentDepend = currentLabel->GetDepend();
1912    GateRef ret = GetCircuit()->NewGate(circuit_->ArrayFilter(static_cast<uint64_t>(pcOffset)),
1913                                        MachineType::I64,
1914                                        {currentControl, currentDepend, thisValue, callBackFn, usingThis, frameState},
1915                                        GateType::AnyType());
1916    currentLabel->SetControl(ret);
1917    currentLabel->SetDepend(ret);
1918    return ret;
1919}
1920
1921GateRef CircuitBuilder::ArrayMap(
1922    GateRef thisValue, GateRef callBackFn, GateRef usingThis, GateRef frameState, uint32_t pcOffset)
1923{
1924    auto currentLabel = env_->GetCurrentLabel();
1925    auto currentControl = currentLabel->GetControl();
1926    auto currentDepend = currentLabel->GetDepend();
1927    GateRef ret = GetCircuit()->NewGate(circuit_->ArrayMap(static_cast<uint64_t>(pcOffset)),
1928                                        MachineType::I64,
1929                                        {currentControl, currentDepend, thisValue, callBackFn, usingThis, frameState},
1930                                        GateType::AnyType());
1931    currentLabel->SetControl(ret);
1932    currentLabel->SetDepend(ret);
1933    return ret;
1934}
1935
1936GateRef CircuitBuilder::ArraySome(GateRef thisValue, GateRef callBackFn, GateRef usingThis, uint32_t pcOffset)
1937{
1938    auto currentLabel = env_->GetCurrentLabel();
1939    auto currentControl = currentLabel->GetControl();
1940    auto currentDepend = currentLabel->GetDepend();
1941    GateRef ret = GetCircuit()->NewGate(circuit_->ArraySome(static_cast<uint64_t>(pcOffset)),
1942                                        MachineType::I64,
1943                                        {currentControl, currentDepend, thisValue, callBackFn, usingThis},
1944                                        GateType::AnyType());
1945    currentLabel->SetControl(ret);
1946    currentLabel->SetDepend(ret);
1947    return ret;
1948}
1949
1950GateRef CircuitBuilder::ArrayEvery(GateRef thisValue, GateRef callBackFn, GateRef usingThis, uint32_t pcOffset)
1951{
1952    auto currentLabel = env_->GetCurrentLabel();
1953    auto currentControl = currentLabel->GetControl();
1954    auto currentDepend = currentLabel->GetDepend();
1955    GateRef ret = GetCircuit()->NewGate(circuit_->ArrayEvery(static_cast<uint64_t>(pcOffset)),
1956                                        MachineType::I64,
1957                                        {currentControl, currentDepend, thisValue, callBackFn, usingThis},
1958                                        GateType::AnyType());
1959    currentLabel->SetControl(ret);
1960    currentLabel->SetDepend(ret);
1961    return ret;
1962}
1963
1964GateRef CircuitBuilder::ArrayPop(GateRef thisValue, GateRef frameState)
1965{
1966    auto currentLabel = env_->GetCurrentLabel();
1967    auto currentControl = currentLabel->GetControl();
1968    auto currentDepend = currentLabel->GetDepend();
1969    GateRef ret = GetCircuit()->NewGate(circuit_->ArrayPop(),
1970                                        MachineType::I64,
1971                                        {currentControl, currentDepend, thisValue, frameState},
1972                                        GateType::AnyType());
1973    currentLabel->SetControl(ret);
1974    currentLabel->SetDepend(ret);
1975    return ret;
1976}
1977
1978GateRef CircuitBuilder::ArraySlice(GateRef thisValue, GateRef startIndex, GateRef endIndex, GateRef frameState)
1979{
1980    auto currentLabel = env_->GetCurrentLabel();
1981    auto currentControl = currentLabel->GetControl();
1982    auto currentDepend = currentLabel->GetDepend();
1983    GateRef ret = GetCircuit()->NewGate(circuit_->ArraySlice(),
1984                                        MachineType::I64,
1985                                        {currentControl, currentDepend, thisValue, startIndex, endIndex, frameState},
1986                                        GateType::AnyType());
1987    currentLabel->SetControl(ret);
1988    currentLabel->SetDepend(ret);
1989    return ret;
1990}
1991
1992GateRef CircuitBuilder::ArrayFindOrFindIndex(
1993    GateRef thisValue, GateRef callBackFn, GateRef usingThis, GateRef callIDRef, uint32_t pcOffset)
1994{
1995    auto currentLabel = env_->GetCurrentLabel();
1996    auto currentControl = currentLabel->GetControl();
1997    auto currentDepend = currentLabel->GetDepend();
1998    GateRef ret = GetCircuit()->NewGate(circuit_->ArrayFindOrFindIndex(static_cast<uint64_t>(pcOffset)),
1999                                        MachineType::I64,
2000                                        {currentControl, currentDepend, thisValue, callBackFn, usingThis, callIDRef},
2001                                        GateType::AnyType());
2002    currentLabel->SetControl(ret);
2003    currentLabel->SetDepend(ret);
2004    return ret;
2005}
2006
2007GateRef CircuitBuilder::NumberIsFinite(GateRef gate)
2008{
2009    auto currentLabel = env_->GetCurrentLabel();
2010    auto currentControl = currentLabel->GetControl();
2011    auto currentDepend = currentLabel->GetDepend();
2012    GateRef ret =
2013        GetCircuit()->NewGate(circuit_->NumberIsFinite(), MachineType::I64,
2014            { currentControl, currentDepend, gate }, GateType::AnyType());
2015    currentLabel->SetControl(ret);
2016    currentLabel->SetDepend(ret);
2017    return ret;
2018}
2019
2020GateRef CircuitBuilder::NumberIsInteger(GateRef gate)
2021{
2022    auto currentLabel = env_->GetCurrentLabel();
2023    auto currentControl = currentLabel->GetControl();
2024    auto currentDepend = currentLabel->GetDepend();
2025    GateRef ret =
2026        GetCircuit()->NewGate(circuit_->NumberIsInteger(), MachineType::I64,
2027            { currentControl, currentDepend, gate }, GateType::AnyType());
2028    currentLabel->SetControl(ret);
2029    currentLabel->SetDepend(ret);
2030    return ret;
2031}
2032
2033GateRef CircuitBuilder::NumberIsNaN(GateRef gate)
2034{
2035    auto currentLabel = env_->GetCurrentLabel();
2036    auto currentControl = currentLabel->GetControl();
2037    auto currentDepend = currentLabel->GetDepend();
2038    GateRef ret =
2039        GetCircuit()->NewGate(circuit_->NumberIsNaN(), MachineType::I64,
2040            { currentControl, currentDepend, gate }, GateType::AnyType());
2041    currentLabel->SetControl(ret);
2042    currentLabel->SetDepend(ret);
2043    return ret;
2044}
2045
2046GateRef CircuitBuilder::NumberParseFloat(GateRef gate, GateRef frameState)
2047{
2048    auto currentLabel = env_->GetCurrentLabel();
2049    auto currentControl = currentLabel->GetControl();
2050    auto currentDepend = currentLabel->GetDepend();
2051    GateRef ret =
2052        GetCircuit()->NewGate(circuit_->NumberParseFloat(), MachineType::I64,
2053            { currentControl, currentDepend, gate, frameState }, GateType::AnyType());
2054    currentLabel->SetControl(ret);
2055    currentLabel->SetDepend(ret);
2056    return ret;
2057}
2058
2059GateRef CircuitBuilder::NumberParseInt(GateRef gate, GateRef radix)
2060{
2061    auto currentLabel = env_->GetCurrentLabel();
2062    auto currentControl = currentLabel->GetControl();
2063    auto currentDepend = currentLabel->GetDepend();
2064    GateRef ret =
2065        GetCircuit()->NewGate(circuit_->NumberParseInt(), MachineType::I64,
2066            { currentControl, currentDepend, gate, radix }, GateType::AnyType());
2067    currentLabel->SetControl(ret);
2068    currentLabel->SetDepend(ret);
2069    return ret;
2070}
2071
2072GateRef CircuitBuilder::NumberIsSafeInteger(GateRef gate)
2073{
2074    auto currentLabel = env_->GetCurrentLabel();
2075    auto currentControl = currentLabel->GetControl();
2076    auto currentDepend = currentLabel->GetDepend();
2077    GateRef ret =
2078        GetCircuit()->NewGate(circuit_->NumberIsSafeInteger(), MachineType::I64,
2079            { currentControl, currentDepend, gate }, GateType::AnyType());
2080    currentLabel->SetControl(ret);
2081    currentLabel->SetDepend(ret);
2082    return ret;
2083}
2084
2085GateRef CircuitBuilder::BuildBigIntAsIntN(const GateMetaData* op, std::vector<GateRef> &&args)
2086{
2087    auto currentLabel = env_->GetCurrentLabel();
2088    auto currentControl = currentLabel->GetControl();
2089    auto currentDepend = currentLabel->GetDepend();
2090    GateRef ret =
2091        GetCircuit()->NewGate(op, MachineType::I64,
2092            ConcatParams({std::vector{currentControl, currentDepend}, args}), GateType::TaggedValue());
2093    currentLabel->SetControl(ret);
2094    currentLabel->SetDepend(ret);
2095    return ret;
2096}
2097
2098GateRef CircuitBuilder::BuildTypedArrayIterator(GateRef gate, const GateMetaData* op)
2099{
2100    auto currentLabel = env_->GetCurrentLabel();
2101    auto currentControl = currentLabel->GetControl();
2102    auto currentDepend = currentLabel->GetDepend();
2103    GateRef ret =
2104        GetCircuit()->NewGate(op, MachineType::I64,
2105            { currentControl, currentDepend, gate }, GateType::AnyType());
2106    currentLabel->SetControl(ret);
2107    currentLabel->SetDepend(ret);
2108    return ret;
2109}
2110
2111GateRef CircuitBuilder::IsASCIICharacter(GateRef gate)
2112{
2113    return Int32UnsignedLessThan(Int32Sub(gate, Int32(1)), Int32(base::utf_helper::UTF8_1B_MAX));
2114}
2115
2116GateRef CircuitBuilder::MigrateFromRawValueToHeapValues(GateRef object, GateRef needCOW, GateRef isIntKind)
2117{
2118    auto currentLabel = env_->GetCurrentLabel();
2119    auto currentControl = currentLabel->GetControl();
2120    auto currentDepend = currentLabel->GetDepend();
2121    auto ret = GetCircuit()->NewGate(circuit_->MigrateFromRawValueToHeapValues(),
2122                                     MachineType::I64,
2123                                     { currentControl, currentDepend, object, needCOW, isIntKind },
2124                                     GateType::TaggedValue());
2125    currentLabel->SetControl(ret);
2126    currentLabel->SetDepend(ret);
2127    return ret;
2128}
2129
2130GateRef CircuitBuilder::MigrateFromHeapValueToRawValue(GateRef object, GateRef needCOW, GateRef isIntKind)
2131{
2132    auto currentLabel = env_->GetCurrentLabel();
2133    auto currentControl = currentLabel->GetControl();
2134    auto currentDepend = currentLabel->GetDepend();
2135    auto ret = GetCircuit()->NewGate(circuit_->MigrateFromHeapValueToRawValue(),
2136                                     MachineType::I64,
2137                                     { currentControl, currentDepend, object, needCOW, isIntKind },
2138                                     GateType::TaggedValue());
2139    currentLabel->SetControl(ret);
2140    currentLabel->SetDepend(ret);
2141    return ret;
2142}
2143
2144GateRef CircuitBuilder::MigrateFromHoleIntToHoleNumber(GateRef object)
2145{
2146    auto currentLabel = env_->GetCurrentLabel();
2147    auto currentControl = currentLabel->GetControl();
2148    auto currentDepend = currentLabel->GetDepend();
2149    auto ret = GetCircuit()->NewGate(circuit_->MigrateFromHoleIntToHoleNumber(),
2150                                     MachineType::I64,
2151                                     { currentControl, currentDepend, object },
2152                                     GateType::NJSValue());
2153    currentLabel->SetControl(ret);
2154    currentLabel->SetDepend(ret);
2155    return ret;
2156}
2157
2158GateRef CircuitBuilder::MigrateFromHoleNumberToHoleInt(GateRef object)
2159{
2160    auto currentLabel = env_->GetCurrentLabel();
2161    auto currentControl = currentLabel->GetControl();
2162    auto currentDepend = currentLabel->GetDepend();
2163    auto ret = GetCircuit()->NewGate(circuit_->MigrateFromHoleNumberToHoleInt(),
2164                                     MachineType::I64,
2165                                     { currentControl, currentDepend, object },
2166                                     GateType::NJSValue());
2167    currentLabel->SetControl(ret);
2168    currentLabel->SetDepend(ret);
2169    return ret;
2170}
2171}
2172