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