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