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