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