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