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