1 /*
2 * Copyright (c) 2023 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/message_string.h"
18 #include "ecmascript/stubs/runtime_stubs-inl.h"
19 #include "ecmascript/stubs/runtime_stubs.h"
20
21 #include "ecmascript/compiler/circuit_builder-inl.h"
22 #include "ecmascript/global_env.h"
23 #include "ecmascript/js_object.h"
24 #include "ecmascript/marker_cell.h"
25
26 namespace panda::ecmascript::kungfu {
27
ObjectTypeCheck(GateType type,bool isHeapObject,GateRef gate,GateRef hclassIndex,GateRef frameState)28 GateRef CircuitBuilder::ObjectTypeCheck(GateType type, bool isHeapObject, GateRef gate, GateRef hclassIndex,
29 GateRef frameState)
30 {
31 auto currentLabel = env_->GetCurrentLabel();
32 auto currentControl = currentLabel->GetControl();
33 auto currentDepend = currentLabel->GetDepend();
34 if (frameState == Circuit::NullGate()) {
35 frameState = acc_.FindNearestFrameState(currentDepend);
36 }
37 ObjectTypeAccessor accessor(type, isHeapObject);
38 GateRef ret = GetCircuit()->NewGate(circuit_->ObjectTypeCheck(accessor.ToValue()), MachineType::I1,
39 {currentControl, currentDepend, gate, hclassIndex, frameState}, GateType::NJSValue());
40 currentLabel->SetControl(ret);
41 currentLabel->SetDepend(ret);
42 return ret;
43 }
44
ObjectTypeCompare(GateType type,bool isHeapObject,GateRef gate,GateRef hclassIndex)45 GateRef CircuitBuilder::ObjectTypeCompare(GateType type, bool isHeapObject, GateRef gate, GateRef hclassIndex)
46 {
47 auto currentLabel = env_->GetCurrentLabel();
48 auto currentControl = currentLabel->GetControl();
49 auto currentDepend = currentLabel->GetDepend();
50 auto frameState = acc_.FindNearestFrameState(currentDepend);
51 ObjectTypeAccessor accessor(type, isHeapObject);
52 GateRef ret = GetCircuit()->NewGate(circuit_->ObjectTypeCompare(accessor.ToValue()), MachineType::I1,
53 {currentControl, currentDepend, gate, hclassIndex, frameState}, GateType::NJSValue());
54 currentLabel->SetControl(ret);
55 currentLabel->SetDepend(ret);
56 return ret;
57 }
58
HeapObjectCheck(GateRef gate,GateRef frameState)59 GateRef CircuitBuilder::HeapObjectCheck(GateRef gate, GateRef frameState)
60 {
61 auto currentLabel = env_->GetCurrentLabel();
62 auto currentControl = currentLabel->GetControl();
63 auto currentDepend = currentLabel->GetDepend();
64 GateRef ret = GetCircuit()->NewGate(circuit_->HeapObjectCheck(),
65 MachineType::I1,
66 {currentControl, currentDepend, gate, frameState},
67 GateType::NJSValue());
68 currentLabel->SetControl(ret);
69 currentLabel->SetDepend(ret);
70 return ret;
71 }
72
ProtoChangeMarkerCheck(GateRef gate,GateRef frameState)73 GateRef CircuitBuilder::ProtoChangeMarkerCheck(GateRef gate, GateRef frameState)
74 {
75 auto currentLabel = env_->GetCurrentLabel();
76 auto currentControl = currentLabel->GetControl();
77 auto currentDepend = currentLabel->GetDepend();
78 if (frameState == Circuit::NullGate()) {
79 frameState = acc_.FindNearestFrameState(currentDepend);
80 }
81 GateRef ret = GetCircuit()->NewGate(circuit_->ProtoChangeMarkerCheck(),
82 MachineType::I1,
83 {currentControl, currentDepend, gate, frameState},
84 GateType::NJSValue());
85 currentLabel->SetControl(ret);
86 currentLabel->SetDepend(ret);
87 return ret;
88 }
89
StableArrayCheck(GateRef gate,ElementsKind kind,ArrayMetaDataAccessor::Mode mode)90 GateRef CircuitBuilder::StableArrayCheck(GateRef gate, ElementsKind kind, ArrayMetaDataAccessor::Mode mode)
91 {
92 auto currentLabel = env_->GetCurrentLabel();
93 auto currentControl = currentLabel->GetControl();
94 auto currentDepend = currentLabel->GetDepend();
95 auto frameState = acc_.FindNearestFrameState(currentDepend);
96 ArrayMetaDataAccessor accessor(kind, mode);
97 GateRef ret = GetCircuit()->NewGate(circuit_->StableArrayCheck(accessor.ToValue()),
98 MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
99 currentLabel->SetControl(ret);
100 currentLabel->SetDepend(ret);
101 return ret;
102 }
103
COWArrayCheck(GateRef gate)104 GateRef CircuitBuilder::COWArrayCheck(GateRef gate)
105 {
106 auto currentLabel = env_->GetCurrentLabel();
107 auto currentControl = currentLabel->GetControl();
108 auto currentDepend = currentLabel->GetDepend();
109 auto frameState = acc_.FindNearestFrameState(currentDepend);
110 GateRef ret = GetCircuit()->NewGate(circuit_->COWArrayCheck(),
111 MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
112 currentLabel->SetControl(ret);
113 currentLabel->SetDepend(ret);
114 return ret;
115 }
116
EcmaStringCheck(GateRef gate)117 GateRef CircuitBuilder::EcmaStringCheck(GateRef gate)
118 {
119 auto currentLabel = env_->GetCurrentLabel();
120 auto currentControl = currentLabel->GetControl();
121 auto currentDepend = currentLabel->GetDepend();
122 auto frameState = acc_.FindNearestFrameState(currentDepend);
123 GateRef ret = GetCircuit()->NewGate(circuit_->EcmaStringCheck(),
124 MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
125 currentLabel->SetControl(ret);
126 currentLabel->SetDepend(ret);
127 return ret;
128 }
129
FlattenTreeStringCheck(GateRef gate)130 GateRef CircuitBuilder::FlattenTreeStringCheck(GateRef gate)
131 {
132 auto currentLabel = env_->GetCurrentLabel();
133 auto currentControl = currentLabel->GetControl();
134 auto currentDepend = currentLabel->GetDepend();
135 auto frameState = acc_.FindNearestFrameState(currentDepend);
136 GateRef ret = GetCircuit()->NewGate(circuit_->FlattenTreeStringCheck(),
137 MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
138 currentLabel->SetControl(ret);
139 currentLabel->SetDepend(ret);
140 return ret;
141 }
142
HClassStableArrayCheck(GateRef gate,GateRef frameState,ArrayMetaDataAccessor accessor)143 GateRef CircuitBuilder::HClassStableArrayCheck(GateRef gate, GateRef frameState, ArrayMetaDataAccessor accessor)
144 {
145 auto currentLabel = env_->GetCurrentLabel();
146 auto currentControl = currentLabel->GetControl();
147 auto currentDepend = currentLabel->GetDepend();
148 GateRef ret = GetCircuit()->NewGate(circuit_->HClassStableArrayCheck(accessor.ToValue()),
149 MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
150 currentLabel->SetControl(ret);
151 currentLabel->SetDepend(ret);
152 return ret;
153 }
154
ArrayGuardianCheck(GateRef frameState)155 GateRef CircuitBuilder::ArrayGuardianCheck(GateRef frameState)
156 {
157 auto currentLabel = env_->GetCurrentLabel();
158 auto currentControl = currentLabel->GetControl();
159 auto currentDepend = currentLabel->GetDepend();
160 GateRef ret = GetCircuit()->NewGate(circuit_->ArrayGuardianCheck(),
161 MachineType::I1, {currentControl, currentDepend, frameState}, GateType::NJSValue());
162 currentLabel->SetControl(ret);
163 currentLabel->SetDepend(ret);
164 return ret;
165 }
166
TypedArrayCheck(GateRef gate,GateType type,TypedArrayMetaDateAccessor::Mode mode,OnHeapMode onHeap)167 GateRef CircuitBuilder::TypedArrayCheck(GateRef gate, GateType type, TypedArrayMetaDateAccessor::Mode mode,
168 OnHeapMode onHeap)
169 {
170 auto currentLabel = env_->GetCurrentLabel();
171 auto currentControl = currentLabel->GetControl();
172 auto currentDepend = currentLabel->GetDepend();
173 auto frameState = acc_.FindNearestFrameState(currentDepend);
174 TypedArrayMetaDateAccessor accessor(type, mode, onHeap);
175 GateRef ret = GetCircuit()->NewGate(circuit_->TypedArrayCheck(accessor.ToValue()), MachineType::I1,
176 {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
177 currentLabel->SetControl(ret);
178 currentLabel->SetDepend(ret);
179 return ret;
180 }
181
LoadTypedArrayLength(GateRef gate,GateType type,OnHeapMode onHeap)182 GateRef CircuitBuilder::LoadTypedArrayLength(GateRef gate, GateType type, OnHeapMode onHeap)
183 {
184 auto currentLabel = env_->GetCurrentLabel();
185 auto currentControl = currentLabel->GetControl();
186 auto currentDepend = currentLabel->GetDepend();
187 TypedArrayMetaDateAccessor accessor(type, TypedArrayMetaDateAccessor::Mode::LOAD_LENGTH, onHeap);
188 GateRef ret = GetCircuit()->NewGate(circuit_->LoadTypedArrayLength(accessor.ToValue()), MachineType::I64,
189 {currentControl, currentDepend, gate}, GateType::IntType());
190 currentLabel->SetControl(ret);
191 currentLabel->SetDepend(ret);
192 return ret;
193 }
194
StringEqual(GateRef x,GateRef y)195 GateRef CircuitBuilder::StringEqual(GateRef x, GateRef y)
196 {
197 auto currentLabel = env_->GetCurrentLabel();
198 auto currentControl = currentLabel->GetControl();
199 auto currentDepend = currentLabel->GetDepend();
200 auto ret = GetCircuit()->NewGate(circuit_->StringEqual(), MachineType::I1,
201 { currentControl, currentDepend, x, y }, GateType::BooleanType());
202 currentLabel->SetControl(ret);
203 currentLabel->SetDepend(ret);
204 return ret;
205 }
206
StringAdd(GateRef x,GateRef y,uint32_t stringStatus)207 GateRef CircuitBuilder::StringAdd(GateRef x, GateRef y, uint32_t stringStatus)
208 {
209 auto currentLabel = env_->GetCurrentLabel();
210 auto currentControl = currentLabel->GetControl();
211 auto currentDepend = currentLabel->GetDepend();
212 StringStatusAccessor accessor(stringStatus);
213 auto ret = GetCircuit()->NewGate(circuit_->StringAdd(accessor.ToValue()), MachineType::I64,
214 { currentControl, currentDepend, x, y }, GateType::AnyType());
215 currentLabel->SetControl(ret);
216 currentLabel->SetDepend(ret);
217 return ret;
218 }
219
RangeGuard(GateRef gate,uint32_t left,uint32_t right)220 GateRef CircuitBuilder::RangeGuard(GateRef gate, uint32_t left, uint32_t right)
221 {
222 auto currentLabel = env_->GetCurrentLabel();
223 auto currentControl = currentLabel->GetControl();
224 auto currentDepend = currentLabel->GetDepend();
225 UInt32PairAccessor accessor(left, right);
226 GateRef ret = GetCircuit()->NewGate(circuit_->RangeGuard(accessor.ToValue()),
227 MachineType::I64, {currentControl, currentDepend, gate}, GateType::IntType());
228 currentLabel->SetControl(ret);
229 currentLabel->SetDepend(ret);
230 return ret;
231 }
232
BuiltinPrototypeHClassCheck(GateRef gate,BuiltinTypeId type)233 GateRef CircuitBuilder::BuiltinPrototypeHClassCheck(GateRef gate, BuiltinTypeId type)
234 {
235 auto currentLabel = env_->GetCurrentLabel();
236 auto currentControl = currentLabel->GetControl();
237 auto currentDepend = currentLabel->GetDepend();
238 auto frameState = acc_.FindNearestFrameState(currentDepend);
239 BuiltinPrototypeHClassAccessor accessor(type);
240 GateRef ret = GetCircuit()->NewGate(circuit_->BuiltinPrototypeHClassCheck(accessor.ToValue()),
241 MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
242 currentLabel->SetControl(ret);
243 currentLabel->SetDepend(ret);
244 return ret;
245 }
246
IndexCheck(GateRef gate,GateRef index)247 GateRef CircuitBuilder::IndexCheck(GateRef gate, GateRef index)
248 {
249 auto currentLabel = env_->GetCurrentLabel();
250 auto currentControl = currentLabel->GetControl();
251 auto currentDepend = currentLabel->GetDepend();
252 auto frameState = acc_.FindNearestFrameState(currentDepend);
253 GateRef ret = GetCircuit()->NewGate(circuit_->IndexCheck(),
254 MachineType::I64, {currentControl, currentDepend, gate, index, frameState}, GateType::IntType());
255 currentLabel->SetControl(ret);
256 currentLabel->SetDepend(ret);
257 return ret;
258 }
259
TypeOfCheck(GateRef gate,GateType type)260 GateRef CircuitBuilder::TypeOfCheck(GateRef gate, GateType type)
261 {
262 auto currentLabel = env_->GetCurrentLabel();
263 auto currentControl = currentLabel->GetControl();
264 auto currentDepend = currentLabel->GetDepend();
265 auto frameState = acc_.FindNearestFrameState(currentDepend);
266 GateRef ret = GetCircuit()->NewGate(circuit_->TypeOfCheck(static_cast<size_t>(type.Value())),
267 MachineType::I64, {currentControl, currentDepend, gate, frameState}, GateType::IntType());
268 currentLabel->SetControl(ret);
269 currentLabel->SetDepend(ret);
270 return ret;
271 }
272
TypedTypeOf(GateType type)273 GateRef CircuitBuilder::TypedTypeOf(GateType type)
274 {
275 auto currentLabel = env_->GetCurrentLabel();
276 auto currentControl = currentLabel->GetControl();
277 auto currentDepend = currentLabel->GetDepend();
278 GateRef ret = GetCircuit()->NewGate(circuit_->TypeOf(static_cast<size_t>(type.Value())),
279 MachineType::I64, {currentControl, currentDepend}, GateType::AnyType());
280 currentLabel->SetControl(ret);
281 currentLabel->SetDepend(ret);
282 return ret;
283 }
284
IsMarkerCellValid(GateRef cell)285 GateRef CircuitBuilder::IsMarkerCellValid(GateRef cell)
286 {
287 GateRef bitfield = Load(VariableType::INT32(), cell, IntPtr(MarkerCell::BIT_FIELD_OFFSET));
288 return Int32Equal(
289 Int32And(Int32LSR(bitfield, Int32(MarkerCell::IsDetectorInvalidBits::START_BIT)),
290 Int32((1LU << MarkerCell::IsDetectorInvalidBits::SIZE) - 1)),
291 Int32(0));
292 }
293
CheckAndConvert(GateRef gate,ValueType src,ValueType dst,ConvertSupport support)294 GateRef CircuitBuilder::CheckAndConvert(GateRef gate, ValueType src, ValueType dst, ConvertSupport support)
295 {
296 auto currentLabel = env_->GetCurrentLabel();
297 auto currentControl = currentLabel->GetControl();
298 auto currentDepend = currentLabel->GetDepend();
299 auto stateSplit = acc_.FindNearestStateSplit(currentDepend);
300 auto frameState = acc_.GetFrameState(stateSplit);
301 MachineType machineType = GetMachineTypeOfValueType(dst);
302 GateType gateType = GetGateTypeOfValueType(dst);
303 uint64_t value = ValuePairTypeAccessor::ToValue(src, dst, support);
304 GateRef ret = GetCircuit()->NewGate(circuit_->CheckAndConvert(value),
305 machineType, {currentControl, currentDepend, gate, frameState}, gateType);
306 currentLabel->SetControl(ret);
307 currentLabel->SetDepend(ret);
308 return ret;
309 }
310
Convert(GateRef gate,ValueType src,ValueType dst)311 GateRef CircuitBuilder::Convert(GateRef gate, ValueType src, ValueType dst)
312 {
313 MachineType machineType = GetMachineTypeOfValueType(dst);
314 GateType gateType = GetGateTypeOfValueType(dst);
315 uint64_t value = ValuePairTypeAccessor::ToValue(src, dst);
316 GateRef ret = GetCircuit()->NewGate(circuit_->Convert(value), machineType, {gate}, gateType);
317 return ret;
318 }
319
ConvertBoolToInt32(GateRef gate,ConvertSupport support)320 GateRef CircuitBuilder::ConvertBoolToInt32(GateRef gate, ConvertSupport support)
321 {
322 return CheckAndConvert(gate, ValueType::BOOL, ValueType::INT32, support);
323 }
324
ConvertBoolToFloat64(GateRef gate,ConvertSupport support)325 GateRef CircuitBuilder::ConvertBoolToFloat64(GateRef gate, ConvertSupport support)
326 {
327 return CheckAndConvert(gate, ValueType::BOOL, ValueType::FLOAT64, support);
328 }
329
ConvertCharToEcmaString(GateRef gate)330 GateRef CircuitBuilder::ConvertCharToEcmaString(GateRef gate)
331 {
332 return Convert(gate, ValueType::CHAR, ValueType::ECMA_STRING);
333 }
334
ConvertInt32ToFloat64(GateRef gate)335 GateRef CircuitBuilder::ConvertInt32ToFloat64(GateRef gate)
336 {
337 return Convert(gate, ValueType::INT32, ValueType::FLOAT64);
338 }
339
ConvertUInt32ToFloat64(GateRef gate)340 GateRef CircuitBuilder::ConvertUInt32ToFloat64(GateRef gate)
341 {
342 return Convert(gate, ValueType::UINT32, ValueType::FLOAT64);
343 }
344
ConvertFloat64ToInt32(GateRef gate)345 GateRef CircuitBuilder::ConvertFloat64ToInt32(GateRef gate)
346 {
347 return Convert(gate, ValueType::FLOAT64, ValueType::INT32);
348 }
349
ConvertBoolToTaggedBoolean(GateRef gate)350 GateRef CircuitBuilder::ConvertBoolToTaggedBoolean(GateRef gate)
351 {
352 return Convert(gate, ValueType::BOOL, ValueType::TAGGED_BOOLEAN);
353 }
354
ConvertTaggedBooleanToBool(GateRef gate)355 GateRef CircuitBuilder::ConvertTaggedBooleanToBool(GateRef gate)
356 {
357 return Convert(gate, ValueType::TAGGED_BOOLEAN, ValueType::BOOL);
358 }
359
ConvertInt32ToTaggedInt(GateRef gate)360 GateRef CircuitBuilder::ConvertInt32ToTaggedInt(GateRef gate)
361 {
362 return Convert(gate, ValueType::INT32, ValueType::TAGGED_INT);
363 }
364
ConvertUInt32ToTaggedNumber(GateRef gate)365 GateRef CircuitBuilder::ConvertUInt32ToTaggedNumber(GateRef gate)
366 {
367 return Convert(gate, ValueType::UINT32, ValueType::TAGGED_NUMBER);
368 }
369
ConvertInt32ToBool(GateRef gate)370 GateRef CircuitBuilder::ConvertInt32ToBool(GateRef gate)
371 {
372 return Convert(gate, ValueType::INT32, ValueType::BOOL);
373 }
374
ConvertUInt32ToBool(GateRef gate)375 GateRef CircuitBuilder::ConvertUInt32ToBool(GateRef gate)
376 {
377 return Convert(gate, ValueType::UINT32, ValueType::BOOL);
378 }
379
ConvertFloat64ToBool(GateRef gate)380 GateRef CircuitBuilder::ConvertFloat64ToBool(GateRef gate)
381 {
382 return Convert(gate, ValueType::FLOAT64, ValueType::BOOL);
383 }
384
CheckTaggedBooleanAndConvertToBool(GateRef gate)385 GateRef CircuitBuilder::CheckTaggedBooleanAndConvertToBool(GateRef gate)
386 {
387 return CheckAndConvert(gate, ValueType::TAGGED_BOOLEAN, ValueType::BOOL);
388 }
389
CheckTaggedNumberAndConvertToBool(GateRef gate)390 GateRef CircuitBuilder::CheckTaggedNumberAndConvertToBool(GateRef gate)
391 {
392 return CheckAndConvert(gate, ValueType::TAGGED_NUMBER, ValueType::BOOL);
393 }
394
ConvertFloat64ToTaggedDouble(GateRef gate)395 GateRef CircuitBuilder::ConvertFloat64ToTaggedDouble(GateRef gate)
396 {
397 return Convert(gate, ValueType::FLOAT64, ValueType::TAGGED_DOUBLE);
398 }
399
CheckUInt32AndConvertToInt32(GateRef gate)400 GateRef CircuitBuilder::CheckUInt32AndConvertToInt32(GateRef gate)
401 {
402 return CheckAndConvert(gate, ValueType::UINT32, ValueType::INT32);
403 }
404
CheckTaggedIntAndConvertToInt32(GateRef gate)405 GateRef CircuitBuilder::CheckTaggedIntAndConvertToInt32(GateRef gate)
406 {
407 return CheckAndConvert(gate, ValueType::TAGGED_INT, ValueType::INT32);
408 }
409
CheckTaggedDoubleAndConvertToInt32(GateRef gate)410 GateRef CircuitBuilder::CheckTaggedDoubleAndConvertToInt32(GateRef gate)
411 {
412 return CheckAndConvert(gate, ValueType::TAGGED_DOUBLE, ValueType::INT32);
413 }
414
CheckTaggedNumberAndConvertToInt32(GateRef gate)415 GateRef CircuitBuilder::CheckTaggedNumberAndConvertToInt32(GateRef gate)
416 {
417 return CheckAndConvert(gate, ValueType::TAGGED_NUMBER, ValueType::INT32);
418 }
419
CheckTaggedIntAndConvertToFloat64(GateRef gate)420 GateRef CircuitBuilder::CheckTaggedIntAndConvertToFloat64(GateRef gate)
421 {
422 return CheckAndConvert(gate, ValueType::TAGGED_INT, ValueType::FLOAT64);
423 }
424
CheckTaggedDoubleAndConvertToFloat64(GateRef gate)425 GateRef CircuitBuilder::CheckTaggedDoubleAndConvertToFloat64(GateRef gate)
426 {
427 return CheckAndConvert(gate, ValueType::TAGGED_DOUBLE, ValueType::FLOAT64);
428 }
429
CheckTaggedNumberAndConvertToFloat64(GateRef gate)430 GateRef CircuitBuilder::CheckTaggedNumberAndConvertToFloat64(GateRef gate)
431 {
432 return CheckAndConvert(gate, ValueType::TAGGED_NUMBER, ValueType::FLOAT64);
433 }
434
CheckNullAndConvertToInt32(GateRef gate)435 GateRef CircuitBuilder::CheckNullAndConvertToInt32(GateRef gate)
436 {
437 return CheckAndConvert(gate, ValueType::TAGGED_NULL, ValueType::INT32);
438 }
439
CheckTaggedBooleanAndConvertToInt32(GateRef gate)440 GateRef CircuitBuilder::CheckTaggedBooleanAndConvertToInt32(GateRef gate)
441 {
442 return CheckAndConvert(gate, ValueType::TAGGED_BOOLEAN, ValueType::INT32);
443 }
444
CheckNullAndConvertToFloat64(GateRef gate)445 GateRef CircuitBuilder::CheckNullAndConvertToFloat64(GateRef gate)
446 {
447 return CheckAndConvert(gate, ValueType::TAGGED_NULL, ValueType::FLOAT64);
448 }
449
CheckTaggedBooleanAndConvertToFloat64(GateRef gate)450 GateRef CircuitBuilder::CheckTaggedBooleanAndConvertToFloat64(GateRef gate)
451 {
452 return CheckAndConvert(gate, ValueType::TAGGED_BOOLEAN, ValueType::FLOAT64);
453 }
454
CheckUndefinedAndConvertToFloat64(GateRef gate)455 GateRef CircuitBuilder::CheckUndefinedAndConvertToFloat64(GateRef gate)
456 {
457 return CheckAndConvert(gate, ValueType::UNDEFINED, ValueType::FLOAT64);
458 }
459
CheckUndefinedAndConvertToBool(GateRef gate)460 GateRef CircuitBuilder::CheckUndefinedAndConvertToBool(GateRef gate)
461 {
462 return CheckAndConvert(gate, ValueType::UNDEFINED, ValueType::BOOL);
463 }
464
CheckNullAndConvertToBool(GateRef gate)465 GateRef CircuitBuilder::CheckNullAndConvertToBool(GateRef gate)
466 {
467 return CheckAndConvert(gate, ValueType::TAGGED_NULL, ValueType::BOOL);
468 }
469
CheckUndefinedAndConvertToInt32(GateRef gate)470 GateRef CircuitBuilder::CheckUndefinedAndConvertToInt32(GateRef gate)
471 {
472 return CheckAndConvert(gate, ValueType::UNDEFINED, ValueType::INT32);
473 }
474
TryPrimitiveTypeCheck(GateType type,GateRef gate)475 GateRef CircuitBuilder::TryPrimitiveTypeCheck(GateType type, GateRef gate)
476 {
477 if (acc_.GetOpCode(gate) == OpCode::CONSTANT) {
478 return Circuit::NullGate();
479 }
480 auto currentLabel = env_->GetCurrentLabel();
481 auto currentControl = currentLabel->GetControl();
482 auto currentDepend = currentLabel->GetDepend();
483 auto frameState = acc_.FindNearestFrameState(currentDepend);
484 GateRef ret = GetCircuit()->NewGate(circuit_->PrimitiveTypeCheck(static_cast<size_t>(type.Value())),
485 MachineType::I1, {currentControl, currentDepend, gate, frameState}, GateType::NJSValue());
486 currentLabel->SetControl(ret);
487 currentLabel->SetDepend(ret);
488 return ret;
489 }
490
CallTargetCheck(GateRef gate,GateRef function,GateRef id,GateRef param,const char * comment)491 GateRef CircuitBuilder::CallTargetCheck(GateRef gate, GateRef function, GateRef id, GateRef param, const char* comment)
492 {
493 auto currentLabel = env_->GetCurrentLabel();
494 auto currentControl = currentLabel->GetControl();
495 auto currentDepend = currentLabel->GetDepend();
496 GateRef frameState;
497 if (Bytecodes::IsCallOp(acc_.GetByteCodeOpcode(gate))) {
498 frameState = acc_.GetFrameState(gate);
499 } else {
500 frameState = acc_.FindNearestFrameState(currentDepend);
501 }
502 GateRef ret = GetCircuit()->NewGate(circuit_->TypedCallCheck(),
503 MachineType::I1,
504 { currentControl, currentDepend, function, id, param, frameState},
505 GateType::NJSValue(),
506 comment);
507 currentLabel->SetControl(ret);
508 currentLabel->SetDepend(ret);
509 return ret;
510 }
511
JSCallTargetFromDefineFuncCheck(GateType type,GateRef func,GateRef gate)512 GateRef CircuitBuilder::JSCallTargetFromDefineFuncCheck(GateType type, GateRef func, GateRef gate)
513 {
514 auto currentLabel = env_->GetCurrentLabel();
515 auto currentControl = currentLabel->GetControl();
516 auto currentDepend = currentLabel->GetDepend();
517 auto frameState = acc_.GetFrameState(gate);
518 GateRef ret = GetCircuit()->NewGate(circuit_->TypedCallTargetCheckOp(1, static_cast<size_t>(type.Value()),
519 TypedCallTargetCheckOp::JSCALL_IMMEDIATE_AFTER_FUNC_DEF),
520 MachineType::I1, {currentControl, currentDepend, func, frameState}, GateType::NJSValue());
521 currentLabel->SetControl(ret);
522 currentLabel->SetDepend(ret);
523 return ret;
524 }
TypedCallOperator(GateRef hirGate,MachineType type,const std::vector<GateRef> & inList)525 GateRef CircuitBuilder::TypedCallOperator(GateRef hirGate, MachineType type, const std::vector<GateRef> &inList)
526 {
527 ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE);
528 auto numValueIn = inList.size() - 3; // 3: state & depend & frame state
529 uint64_t pcOffset = acc_.TryGetPcOffset(hirGate);
530 ASSERT(pcOffset != 0);
531 return GetCircuit()->NewGate(circuit_->TypedCallBuiltin(numValueIn, pcOffset), type, inList.size(), inList.data(),
532 GateType::AnyType());
533 }
534
535
TypedNewAllocateThis(GateRef ctor,GateRef hclassIndex,GateRef frameState)536 GateRef CircuitBuilder::TypedNewAllocateThis(GateRef ctor, GateRef hclassIndex, GateRef frameState)
537 {
538 auto currentLabel = env_->GetCurrentLabel();
539 auto currentControl = currentLabel->GetControl();
540 auto currentDepend = currentLabel->GetDepend();
541 GateRef ret = GetCircuit()->NewGate(circuit_->TypedNewAllocateThis(),
542 MachineType::ANYVALUE, {currentControl, currentDepend, ctor, hclassIndex, frameState}, GateType::TaggedValue());
543 currentLabel->SetControl(ret);
544 currentLabel->SetDepend(ret);
545 return ret;
546 }
547
TypedSuperAllocateThis(GateRef superCtor,GateRef newTarget,GateRef frameState)548 GateRef CircuitBuilder::TypedSuperAllocateThis(GateRef superCtor, GateRef newTarget, GateRef frameState)
549 {
550 auto currentLabel = env_->GetCurrentLabel();
551 auto currentControl = currentLabel->GetControl();
552 auto currentDepend = currentLabel->GetDepend();
553 GateRef ret = GetCircuit()->NewGate(circuit_->TypedSuperAllocateThis(), MachineType::ANYVALUE,
554 {currentControl, currentDepend, superCtor, newTarget, frameState}, GateType::TaggedValue());
555 currentLabel->SetControl(ret);
556 currentLabel->SetDepend(ret);
557 return ret;
558 }
559
560
Int32CheckRightIsZero(GateRef right)561 GateRef CircuitBuilder::Int32CheckRightIsZero(GateRef right)
562 {
563 auto currentLabel = env_->GetCurrentLabel();
564 auto currentControl = currentLabel->GetControl();
565 auto currentDepend = currentLabel->GetDepend();
566 auto frameState = acc_.FindNearestFrameState(currentDepend);
567 GateRef ret = GetCircuit()->NewGate(circuit_->Int32CheckRightIsZero(),
568 MachineType::I1, {currentControl, currentDepend, right, frameState}, GateType::NJSValue());
569 currentLabel->SetControl(ret);
570 currentLabel->SetDepend(ret);
571 return ret;
572 }
573
RemainderIsNegativeZero(GateRef left,GateRef right)574 GateRef CircuitBuilder::RemainderIsNegativeZero(GateRef left, GateRef right)
575 {
576 auto currentLabel = env_->GetCurrentLabel();
577 auto currentControl = currentLabel->GetControl();
578 auto currentDepend = currentLabel->GetDepend();
579 auto frameState = acc_.FindNearestFrameState(currentDepend);
580 GateRef ret = GetCircuit()->NewGate(circuit_->RemainderIsNegativeZero(),
581 MachineType::I1,
582 {currentControl, currentDepend, left, right, frameState},
583 GateType::NJSValue());
584 currentLabel->SetControl(ret);
585 currentLabel->SetDepend(ret);
586 return ret;
587 }
588
Float64CheckRightIsZero(GateRef right)589 GateRef CircuitBuilder::Float64CheckRightIsZero(GateRef right)
590 {
591 auto currentLabel = env_->GetCurrentLabel();
592 auto currentControl = currentLabel->GetControl();
593 auto currentDepend = currentLabel->GetDepend();
594 auto frameState = acc_.FindNearestFrameState(currentDepend);
595 GateRef ret = GetCircuit()->NewGate(circuit_->Float64CheckRightIsZero(),
596 MachineType::I1, {currentControl, currentDepend, right, frameState}, GateType::NJSValue());
597 currentLabel->SetControl(ret);
598 currentLabel->SetDepend(ret);
599 return ret;
600 }
601
LexVarIsHoleCheck(GateRef value)602 GateRef CircuitBuilder::LexVarIsHoleCheck(GateRef value)
603 {
604 auto currentLabel = env_->GetCurrentLabel();
605 auto currentControl = currentLabel->GetControl();
606 auto currentDepend = currentLabel->GetDepend();
607 auto frameState = acc_.FindNearestFrameState(currentDepend);
608 GateRef ret = GetCircuit()->NewGate(circuit_->LexVarIsHoleCheck(),
609 MachineType::I1, {currentControl, currentDepend, value, frameState}, GateType::NJSValue());
610 currentLabel->SetControl(ret);
611 currentLabel->SetDepend(ret);
612 return ret;
613 }
614
ValueCheckNegOverflow(GateRef value)615 GateRef CircuitBuilder::ValueCheckNegOverflow(GateRef value)
616 {
617 auto currentLabel = env_->GetCurrentLabel();
618 auto currentControl = currentLabel->GetControl();
619 auto currentDepend = currentLabel->GetDepend();
620 auto frameState = acc_.FindNearestFrameState(currentDepend);
621 GateRef ret = GetCircuit()->NewGate(circuit_->ValueCheckNegOverflow(),
622 MachineType::I1, {currentControl, currentDepend, value, frameState}, GateType::NJSValue());
623 currentLabel->SetControl(ret);
624 currentLabel->SetDepend(ret);
625 return ret;
626 }
627
OverflowCheck(GateRef value)628 GateRef CircuitBuilder::OverflowCheck(GateRef value)
629 {
630 auto currentLabel = env_->GetCurrentLabel();
631 auto currentControl = currentLabel->GetControl();
632 auto currentDepend = currentLabel->GetDepend();
633 auto frameState = acc_.FindNearestFrameState(currentDepend);
634 GateRef ret = GetCircuit()->NewGate(circuit_->OverflowCheck(),
635 MachineType::I1, {currentControl, currentDepend, value, frameState}, GateType::IntType());
636 currentLabel->SetControl(ret);
637 currentLabel->SetDepend(ret);
638 return ret;
639 }
640
Int32UnsignedUpperBoundCheck(GateRef value,GateRef upperBound)641 GateRef CircuitBuilder::Int32UnsignedUpperBoundCheck(GateRef value, GateRef upperBound)
642 {
643 auto currentLabel = env_->GetCurrentLabel();
644 auto currentControl = currentLabel->GetControl();
645 auto currentDepend = currentLabel->GetDepend();
646 auto frameState = acc_.FindNearestFrameState(currentDepend);
647 GateRef ret = GetCircuit()->NewGate(circuit_->Int32UnsignedUpperBoundCheck(),
648 MachineType::I1, {currentControl, currentDepend, value, upperBound, frameState}, GateType::IntType());
649 currentLabel->SetControl(ret);
650 currentLabel->SetDepend(ret);
651 return ret;
652 }
653
Int32DivWithCheck(GateRef left,GateRef right)654 GateRef CircuitBuilder::Int32DivWithCheck(GateRef left, GateRef right)
655 {
656 auto currentLabel = env_->GetCurrentLabel();
657 auto currentControl = currentLabel->GetControl();
658 auto currentDepend = currentLabel->GetDepend();
659 auto frameState = acc_.FindNearestFrameState(currentDepend);
660 GateRef ret = GetCircuit()->NewGate(circuit_->Int32DivWithCheck(),
661 MachineType::I32, {currentControl, currentDepend, left, right, frameState}, GateType::NJSValue());
662 currentLabel->SetControl(ret);
663 currentLabel->SetDepend(ret);
664 return ret;
665 }
666
TypedConditionJump(MachineType type,TypedJumpOp jumpOp,uint32_t weight,GateType typeVal,const std::vector<GateRef> & inList)667 GateRef CircuitBuilder::TypedConditionJump(MachineType type, TypedJumpOp jumpOp, uint32_t weight,
668 GateType typeVal, const std::vector<GateRef>& inList)
669 {
670 uint64_t value = TypedJumpAccessor::ToValue(typeVal, jumpOp, weight);
671 return GetCircuit()->NewGate(circuit_->TypedConditionJump(value),
672 type, inList.size(), inList.data(), GateType::Empty());
673 }
674
TypeConvert(MachineType type,GateType typeFrom,GateType typeTo,const std::vector<GateRef> & inList)675 GateRef CircuitBuilder::TypeConvert(MachineType type, GateType typeFrom, GateType typeTo,
676 const std::vector<GateRef>& inList)
677 {
678 // merge types of valueIns before and after convertion
679 uint64_t operandTypes = GatePairTypeAccessor::ToValue(typeFrom, typeTo);
680 return GetCircuit()->NewGate(circuit_->TypedConvert(operandTypes),
681 type, inList.size(), inList.data(), GateType::AnyType());
682 }
683
StoreMemory(MemoryType Op,VariableType type,GateRef receiver,GateRef index,GateRef value)684 GateRef CircuitBuilder::StoreMemory(MemoryType Op, VariableType type, GateRef receiver, GateRef index, GateRef value)
685 {
686 auto opIdx = static_cast<uint64_t>(Op);
687 auto currentLabel = env_->GetCurrentLabel();
688 auto currentControl = currentLabel->GetControl();
689 auto currentDepend = currentLabel->GetDepend();
690 auto ret = GetCircuit()->NewGate(GetCircuit()->StoreMemory(opIdx), type.GetMachineType(),
691 {currentControl, currentDepend, receiver, index, value}, type.GetGateType());
692 currentLabel->SetControl(ret);
693 currentLabel->SetDepend(ret);
694 return ret;
695 }
696
LoadProperty(GateRef receiver,GateRef propertyLookupResult,bool isFunction)697 GateRef CircuitBuilder::LoadProperty(GateRef receiver, GateRef propertyLookupResult, bool isFunction)
698 {
699 auto currentLabel = env_->GetCurrentLabel();
700 auto currentControl = currentLabel->GetControl();
701 auto currentDepend = currentLabel->GetDepend();
702 auto ret = GetCircuit()->NewGate(circuit_->LoadProperty(isFunction), MachineType::I64,
703 { currentControl, currentDepend, receiver, propertyLookupResult },
704 GateType::AnyType());
705 currentLabel->SetControl(ret);
706 currentLabel->SetDepend(ret);
707 return ret;
708 }
709
StoreProperty(GateRef receiver,GateRef propertyLookupResult,GateRef value,uint32_t receiverHClassIndex)710 GateRef CircuitBuilder::StoreProperty(GateRef receiver, GateRef propertyLookupResult, GateRef value,
711 uint32_t receiverHClassIndex)
712 {
713 auto currentLabel = env_->GetCurrentLabel();
714 auto currentControl = currentLabel->GetControl();
715 auto currentDepend = currentLabel->GetDepend();
716 auto ret = GetCircuit()->NewGate(circuit_->StoreProperty(receiverHClassIndex), MachineType::I64,
717 { currentControl, currentDepend, receiver, propertyLookupResult, value },
718 GateType::AnyType());
719 currentLabel->SetControl(ret);
720 currentLabel->SetDepend(ret);
721 return ret;
722 }
723
LoadArrayLength(GateRef array)724 GateRef CircuitBuilder::LoadArrayLength(GateRef array)
725 {
726 auto currentLabel = env_->GetCurrentLabel();
727 auto currentControl = currentLabel->GetControl();
728 auto currentDepend = currentLabel->GetDepend();
729 auto ret = GetCircuit()->NewGate(circuit_->LoadArrayLength(), MachineType::I64,
730 { currentControl, currentDepend, array }, GateType::IntType());
731 currentLabel->SetControl(ret);
732 currentLabel->SetDepend(ret);
733 return ret;
734 }
735
LoadStringLength(GateRef string)736 GateRef CircuitBuilder::LoadStringLength(GateRef string)
737 {
738 auto currentLabel = env_->GetCurrentLabel();
739 auto currentControl = currentLabel->GetControl();
740 auto currentDepend = currentLabel->GetDepend();
741 auto ret = GetCircuit()->NewGate(circuit_->LoadStringLength(), MachineType::I64,
742 { currentControl, currentDepend, string }, GateType::IntType());
743 currentLabel->SetControl(ret);
744 currentLabel->SetDepend(ret);
745 return ret;
746 }
747
LoadConstOffset(VariableType type,GateRef receiver,size_t offset,MemoryOrder order)748 GateRef CircuitBuilder::LoadConstOffset(VariableType type, GateRef receiver, size_t offset, MemoryOrder order)
749 {
750 auto currentLabel = env_->GetCurrentLabel();
751 auto currentDepend = currentLabel->GetDepend();
752 auto bits = LoadStoreConstOffsetAccessor::ToValue(offset, order);
753 auto ret = GetCircuit()->NewGate(circuit_->LoadConstOffset(bits), type.GetMachineType(),
754 { currentDepend, receiver }, type.GetGateType());
755 currentLabel->SetDepend(ret);
756 return ret;
757 }
758
LoadHClassFromConstpool(GateRef constpool,size_t index)759 GateRef CircuitBuilder::LoadHClassFromConstpool(GateRef constpool, size_t index)
760 {
761 auto currentLabel = env_->GetCurrentLabel();
762 auto currentDepend = currentLabel->GetDepend();
763 auto ret = GetCircuit()->NewGate(circuit_->LoadHClassFromConstpool(index), MachineType::I64,
764 { currentDepend, constpool }, GateType::AnyType());
765 currentLabel->SetDepend(ret);
766 return ret;
767 }
768
StoreConstOffset(VariableType type,GateRef receiver,size_t offset,GateRef value,MemoryOrder order)769 GateRef CircuitBuilder::StoreConstOffset(VariableType type,
770 GateRef receiver, size_t offset, GateRef value, MemoryOrder order)
771 {
772 auto currentLabel = env_->GetCurrentLabel();
773 auto currentControl = currentLabel->GetControl();
774 auto currentDepend = currentLabel->GetDepend();
775 auto bits = LoadStoreConstOffsetAccessor::ToValue(offset, order);
776 auto ret = GetCircuit()->NewGate(circuit_->StoreConstOffset(bits), type.GetMachineType(),
777 { currentControl, currentDepend, receiver, value }, type.GetGateType());
778 currentLabel->SetControl(ret);
779 currentLabel->SetDepend(ret);
780 return ret;
781 }
782
TaggedIsHeapObjectOp(GateRef value)783 GateRef CircuitBuilder::TaggedIsHeapObjectOp(GateRef value)
784 {
785 auto currentLabel = env_->GetCurrentLabel();
786 auto currentControl = currentLabel->GetControl();
787 auto currentDepend = currentLabel->GetDepend();
788 auto newGate = GetCircuit()->NewGate(circuit_->TaggedIsHeapObject(), MachineType::I1,
789 { currentControl, currentDepend, value },
790 GateType::NJSValue());
791 currentLabel->SetDepend(newGate);
792 return newGate;
793 }
794
IsSpecificObjectType(GateRef obj,JSType type)795 GateRef CircuitBuilder::IsSpecificObjectType(GateRef obj, JSType type)
796 {
797 auto currentLabel = env_->GetCurrentLabel();
798 auto currentControl = currentLabel->GetControl();
799 auto currentDepend = currentLabel->GetDepend();
800 auto newGate = GetCircuit()->NewGate(circuit_->IsSpecificObjectType(static_cast<int32_t>(type)), MachineType::I1,
801 { currentControl, currentDepend, obj },
802 GateType::NJSValue());
803 currentLabel->SetDepend(newGate);
804 return newGate;
805 }
806
IsMarkerCellValidOp(GateRef cell)807 GateRef CircuitBuilder::IsMarkerCellValidOp(GateRef cell)
808 {
809 auto currentLabel = env_->GetCurrentLabel();
810 auto currentControl = currentLabel->GetControl();
811 auto currentDepend = currentLabel->GetDepend();
812 auto newGate = GetCircuit()->NewGate(circuit_->IsMarkerCellValid(), MachineType::I1,
813 { currentControl, currentDepend, cell },
814 GateType::NJSValue());
815 currentLabel->SetDepend(newGate);
816 return newGate;
817 }
818
ConvertHoleAsUndefined(GateRef receiver)819 GateRef CircuitBuilder::ConvertHoleAsUndefined(GateRef receiver)
820 {
821 auto currentLabel = env_->GetCurrentLabel();
822 auto currentControl = currentLabel->GetControl();
823 auto currentDepend = currentLabel->GetDepend();
824
825 auto ret = GetCircuit()->NewGate(circuit_->ConvertHoleAsUndefined(),
826 MachineType::I64, { currentControl, currentDepend, receiver }, GateType::AnyType());
827 currentLabel->SetControl(ret);
828 currentLabel->SetDepend(ret);
829 return ret;
830 }
831
TypedCall(GateRef hirGate,std::vector<GateRef> args,bool isNoGC)832 GateRef CircuitBuilder::TypedCall(GateRef hirGate, std::vector<GateRef> args, bool isNoGC)
833 {
834 ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE);
835 auto currentLabel = env_->GetCurrentLabel();
836 auto currentControl = currentLabel->GetControl();
837 auto currentDepend = currentLabel->GetDepend();
838 uint64_t bitfield = args.size();
839 uint64_t pcOffset = acc_.TryGetPcOffset(hirGate);
840 ASSERT(pcOffset != 0);
841 args.insert(args.begin(), currentDepend);
842 args.insert(args.begin(), currentControl);
843 AppendFrameArgs(args, hirGate);
844 auto callGate = GetCircuit()->NewGate(circuit_->TypedCall(bitfield, pcOffset, isNoGC), MachineType::I64,
845 args.size(), args.data(), GateType::AnyType());
846 currentLabel->SetControl(callGate);
847 currentLabel->SetDepend(callGate);
848 return callGate;
849 }
850
TypedFastCall(GateRef hirGate,std::vector<GateRef> args,bool isNoGC)851 GateRef CircuitBuilder::TypedFastCall(GateRef hirGate, std::vector<GateRef> args, bool isNoGC)
852 {
853 ASSERT(acc_.GetOpCode(hirGate) == OpCode::JS_BYTECODE);
854 auto currentLabel = env_->GetCurrentLabel();
855 auto currentControl = currentLabel->GetControl();
856 auto currentDepend = currentLabel->GetDepend();
857 uint64_t bitfield = args.size();
858 uint64_t pcOffset = acc_.TryGetPcOffset(hirGate);
859 ASSERT(pcOffset != 0);
860 args.insert(args.begin(), currentDepend);
861 args.insert(args.begin(), currentControl);
862 AppendFrameArgs(args, hirGate);
863 auto callGate = GetCircuit()->NewGate(circuit_->TypedFastCall(bitfield, pcOffset, isNoGC), MachineType::I64,
864 args.size(), args.data(), GateType::AnyType());
865 currentLabel->SetControl(callGate);
866 currentLabel->SetDepend(callGate);
867 return callGate;
868 }
869
StartAllocate()870 GateRef CircuitBuilder::StartAllocate()
871 {
872 auto currentLabel = env_->GetCurrentLabel();
873 auto currentDepend = currentLabel->GetDepend();
874 GateRef newGate = GetCircuit()->NewGate(circuit_->StartAllocate(), MachineType::I64,
875 { currentDepend }, GateType::NJSValue());
876 currentLabel->SetDepend(newGate);
877 return newGate;
878 }
879
FinishAllocate(GateRef value)880 GateRef CircuitBuilder::FinishAllocate(GateRef value)
881 {
882 auto currentLabel = env_->GetCurrentLabel();
883 auto currentDepend = currentLabel->GetDepend();
884 GateRef newGate = GetCircuit()->NewGate(circuit_->FinishAllocate(), MachineType::I64,
885 { currentDepend, value }, acc_.GetGateType(value));
886 currentLabel->SetDepend(newGate);
887 return newGate;
888 }
889
HeapAlloc(GateRef size,GateType type,RegionSpaceFlag flag)890 GateRef CircuitBuilder::HeapAlloc(GateRef size, GateType type, RegionSpaceFlag flag)
891 {
892 auto currentLabel = env_->GetCurrentLabel();
893 auto currentControl = currentLabel->GetControl();
894 auto currentDepend = currentLabel->GetDepend();
895 auto ret = GetCircuit()->NewGate(circuit_->HeapAlloc(flag), MachineType::I64,
896 { currentControl, currentDepend, size }, type);
897 currentLabel->SetControl(ret);
898 currentLabel->SetDepend(ret);
899 return ret;
900 }
901
GetGateTypeOfValueType(ValueType type)902 GateType CircuitBuilder::GetGateTypeOfValueType(ValueType type)
903 {
904 switch (type) {
905 case ValueType::BOOL:
906 case ValueType::INT32:
907 case ValueType::FLOAT64:
908 return GateType::NJSValue();
909 case ValueType::TAGGED_BOOLEAN:
910 return GateType::BooleanType();
911 case ValueType::TAGGED_INT:
912 return GateType::IntType();
913 case ValueType::TAGGED_DOUBLE:
914 return GateType::DoubleType();
915 case ValueType::TAGGED_NUMBER:
916 return GateType::NumberType();
917 default:
918 return GateType::Empty();
919 }
920 }
921
InsertTypedBinaryop(GateRef left,GateRef right,GateType leftType,GateType rightType,GateType gateType,PGOTypeRef pgoType,TypedBinOp op)922 GateRef CircuitBuilder::InsertTypedBinaryop(GateRef left, GateRef right, GateType leftType, GateType rightType,
923 GateType gateType, PGOTypeRef pgoType, TypedBinOp op)
924 {
925 auto currentLabel = env_->GetCurrentLabel();
926 auto currentControl = currentLabel->GetControl();
927 auto currentDepend = currentLabel->GetDepend();
928 uint64_t operandTypes = GatePairTypeAccessor::ToValue(leftType, rightType);
929 auto ret = GetCircuit()->NewGate(circuit_->TypedBinaryOp(operandTypes, op, pgoType),
930 MachineType::I64,
931 {currentControl, currentDepend, left, right},
932 gateType);
933 acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret);
934 currentLabel->SetControl(ret);
935 currentLabel->SetDepend(ret);
936 return ret;
937 }
938
InsertRangeCheckPredicate(GateRef left,TypedBinOp cond,GateRef right)939 GateRef CircuitBuilder::InsertRangeCheckPredicate(GateRef left, TypedBinOp cond, GateRef right)
940 {
941 auto currentLabel = env_->GetCurrentLabel();
942 auto currentControl = currentLabel->GetControl();
943 auto currentDepend = currentLabel->GetDepend();
944 auto frameState = acc_.FindNearestFrameState(currentDepend);
945 TypedBinaryAccessor accessor(GateType::IntType(), cond);
946 auto ret = GetCircuit()->NewGate(circuit_->RangeCheckPredicate(accessor.ToValue()),
947 MachineType::I32,
948 {currentControl, currentDepend, left, right, frameState},
949 GateType::IntType());
950 acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret);
951 currentLabel->SetControl(ret);
952 currentLabel->SetDepend(ret);
953 return ret;
954 }
955
InsertStableArrayCheck(GateRef array)956 GateRef CircuitBuilder::InsertStableArrayCheck(GateRef array)
957 {
958 auto currentLabel = env_->GetCurrentLabel();
959 auto currentControl = currentLabel->GetControl();
960 auto currentDepend = currentLabel->GetDepend();
961 GateRef frameState = acc_.FindNearestFrameState(currentDepend);
962 ElementsKind kind = acc_.TryGetElementsKind(array);
963 ArrayMetaDataAccessor::Mode mode = ArrayMetaDataAccessor::Mode::LOAD_LENGTH;
964 ArrayMetaDataAccessor accessor(kind, mode);
965 auto ret = GetCircuit()->NewGate(circuit_->StableArrayCheck(accessor.ToValue()),
966 MachineType::I1,
967 {currentControl, currentDepend, array, frameState},
968 GateType::NJSValue());
969 acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret);
970 currentLabel->SetControl(ret);
971 currentLabel->SetDepend(ret);
972 return ret;
973 }
974
InsertTypedArrayCheck(GateType type,GateRef array)975 GateRef CircuitBuilder::InsertTypedArrayCheck(GateType type, GateRef array)
976 {
977 auto currentLabel = env_->GetCurrentLabel();
978 auto currentControl = currentLabel->GetControl();
979 auto currentDepend = currentLabel->GetDepend();
980 GateRef frameState = acc_.FindNearestFrameState(currentDepend);
981 auto ret = GetCircuit()->NewGate(circuit_->TypedArrayCheck(static_cast<size_t>(type.Value())),
982 MachineType::I1,
983 {currentControl, currentDepend, array, frameState},
984 GateType::NJSValue());
985 acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret);
986 currentLabel->SetControl(ret);
987 currentLabel->SetDepend(ret);
988 return ret;
989 }
990
InsertLoadArrayLength(GateRef array,bool isTypedArray)991 GateRef CircuitBuilder::InsertLoadArrayLength(GateRef array, bool isTypedArray)
992 {
993 auto currentLabel = env_->GetCurrentLabel();
994 auto currentControl = currentLabel->GetControl();
995 auto currentDepend = currentLabel->GetDepend();
996 GateType arrayType = acc_.GetGateType(array);
997 if (isTypedArray) {
998 InsertTypedArrayCheck(arrayType, array);
999 currentControl = currentLabel->GetControl();
1000 currentDepend = currentLabel->GetDepend();
1001 auto ret = GetCircuit()->NewGate(circuit_->LoadTypedArrayLength(static_cast<size_t>(arrayType.Value())),
1002 MachineType::I64,
1003 { currentControl, currentDepend, array },
1004 GateType::IntType());
1005 acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret);
1006 currentLabel->SetControl(ret);
1007 currentLabel->SetDepend(ret);
1008 return ret;
1009 } else {
1010 InsertStableArrayCheck(array);
1011 currentControl = currentLabel->GetControl();
1012 currentDepend = currentLabel->GetDepend();
1013 auto ret = GetCircuit()->NewGate(circuit_->LoadArrayLength(),
1014 MachineType::I64,
1015 { currentControl, currentDepend, array },
1016 GateType::IntType());
1017 acc_.ReplaceInAfterInsert(currentControl, currentDepend, ret);
1018 currentLabel->SetControl(ret);
1019 currentLabel->SetDepend(ret);
1020 return ret;
1021 }
1022 UNREACHABLE();
1023 return Circuit::NullGate();
1024 }
1025
IsIntegerString(GateRef string)1026 GateRef CircuitBuilder::IsIntegerString(GateRef string)
1027 {
1028 // compressedStringsEnabled fixed to true constant
1029 GateRef hash = Load(VariableType::INT32(), string, IntPtr(EcmaString::MIX_HASHCODE_OFFSET));
1030 return Int32Equal(
1031 Int32And(hash, Int32(EcmaString::IS_INTEGER_MASK)),
1032 Int32(EcmaString::IS_INTEGER_MASK));
1033 }
1034
GetRawHashFromString(GateRef value)1035 GateRef CircuitBuilder::GetRawHashFromString(GateRef value)
1036 {
1037 GateRef hash = Load(VariableType::INT32(), value, IntPtr(EcmaString::MIX_HASHCODE_OFFSET));
1038 return Int32And(hash, Int32(~EcmaString::IS_INTEGER_MASK));
1039 }
1040
SetRawHashcode(GateRef glue,GateRef str,GateRef rawHashcode,GateRef isInteger)1041 void CircuitBuilder::SetRawHashcode(GateRef glue, GateRef str, GateRef rawHashcode, GateRef isInteger)
1042 {
1043 Label subentry(env_);
1044 SubCfgEntry(&subentry);
1045 Label integer(env_);
1046 Label notInteger(env_);
1047 Label exit(env_);
1048
1049 DEFVALUE(hash, env_, VariableType::INT32(), Int32(0));
1050 Branch(isInteger, &integer, ¬Integer);
1051 Bind(&integer);
1052 {
1053 hash = Int32Or(rawHashcode, Int32(EcmaString::IS_INTEGER_MASK));
1054 Jump(&exit);
1055 }
1056 Bind(¬Integer);
1057 {
1058 hash = Int32And(rawHashcode, Int32(~EcmaString::IS_INTEGER_MASK));
1059 Jump(&exit);
1060 }
1061 Bind(&exit);
1062 Store(VariableType::INT32(), glue, str, IntPtr(EcmaString::MIX_HASHCODE_OFFSET), *hash);
1063 SubCfgExit();
1064 return;
1065 }
1066
GetLengthFromString(GateRef value)1067 GateRef CircuitBuilder::GetLengthFromString(GateRef value)
1068 {
1069 GateRef len = Load(VariableType::INT32(), value, IntPtr(EcmaString::MIX_LENGTH_OFFSET));
1070 return Int32LSR(len, Int32(EcmaString::STRING_LENGTH_SHIFT_COUNT));
1071 }
1072
GetHashcodeFromString(GateRef glue,GateRef value)1073 GateRef CircuitBuilder::GetHashcodeFromString(GateRef glue, GateRef value)
1074 {
1075 ASSERT(!GetCircuit()->IsOptimizedJSFunctionFrame());
1076 Label subentry(env_);
1077 SubCfgEntry(&subentry);
1078 Label noRawHashcode(env_);
1079 Label exit(env_);
1080 DEFVALUE(hashcode, env_, VariableType::INT32(), Int32(0));
1081 hashcode = Load(VariableType::INT32(), value, IntPtr(EcmaString::MIX_HASHCODE_OFFSET));
1082 Branch(Int32Equal(*hashcode, Int32(0)), &noRawHashcode, &exit);
1083 Bind(&noRawHashcode);
1084 {
1085 hashcode = GetInt32OfTInt(
1086 CallRuntime(glue, RTSTUB_ID(ComputeHashcode), Gate::InvalidGateRef, { value }, Circuit::NullGate()));
1087 Store(VariableType::INT32(), glue, value, IntPtr(EcmaString::MIX_HASHCODE_OFFSET), *hashcode);
1088 Jump(&exit);
1089 }
1090 Bind(&exit);
1091 auto ret = *hashcode;
1092 SubCfgExit();
1093 return ret;
1094 }
1095
TryGetHashcodeFromString(GateRef string)1096 GateRef CircuitBuilder::TryGetHashcodeFromString(GateRef string)
1097 {
1098 Label subentry(env_);
1099 SubCfgEntry(&subentry);
1100 Label noRawHashcode(env_);
1101 Label storeHash(env_);
1102 Label exit(env_);
1103 DEFVALUE(result, env_, VariableType::INT64(), Int64(-1));
1104 GateRef hashCode = ZExtInt32ToInt64(Load(VariableType::INT32(), string, IntPtr(EcmaString::MIX_HASHCODE_OFFSET)));
1105 Branch(Int64Equal(hashCode, Int64(0)), &noRawHashcode, &storeHash);
1106 Bind(&noRawHashcode);
1107 {
1108 GateRef length = GetLengthFromString(string);
1109 Label lengthNotZero(env_);
1110 Branch(Int32Equal(length, Int32(0)), &storeHash, &exit);
1111 }
1112 Bind(&storeHash);
1113 result = hashCode;
1114 Jump(&exit);
1115 Bind(&exit);
1116 auto ret = *result;
1117 SubCfgExit();
1118 return ret;
1119 }
1120
GetStringDataFromLineOrConstantString(GateRef str)1121 GateRef CircuitBuilder::GetStringDataFromLineOrConstantString(GateRef str)
1122 {
1123 Label subentry(env_);
1124 SubCfgEntry(&subentry);
1125 Label exit(env_);
1126 Label isConstantString(env_);
1127 Label isLineString(env_);
1128 DEFVALUE(result, env_, VariableType::NATIVE_POINTER(), IntPtr(0));
1129 Branch(IsConstantString(str), &isConstantString, &isLineString);
1130 Bind(&isConstantString);
1131 {
1132 GateRef address = ChangeTaggedPointerToInt64(PtrAdd(str, IntPtr(ConstantString::CONSTANT_DATA_OFFSET)));
1133 result = Load(VariableType::NATIVE_POINTER(), address, IntPtr(0));
1134 Jump(&exit);
1135 }
1136 Bind(&isLineString);
1137 {
1138 result = ChangeTaggedPointerToInt64(PtrAdd(str, IntPtr(LineEcmaString::DATA_OFFSET)));
1139 Jump(&exit);
1140 }
1141 Bind(&exit);
1142 auto ret = *result;
1143 SubCfgExit();
1144 return ret;
1145 }
1146
CopyChars(GateRef glue,GateRef dst,GateRef source,GateRef sourceLength,GateRef charSize,VariableType type)1147 void CircuitBuilder::CopyChars(GateRef glue, GateRef dst, GateRef source,
1148 GateRef sourceLength, GateRef charSize, VariableType type)
1149 {
1150 Label subentry(env_);
1151 SubCfgEntry(&subentry);
1152 DEFVALUE(dstTmp, env_, VariableType::NATIVE_POINTER(), dst);
1153 DEFVALUE(sourceTmp, env_, VariableType::NATIVE_POINTER(), source);
1154 DEFVALUE(len, env_, VariableType::INT32(), sourceLength);
1155 Label loopHead(env_);
1156 Label loopEnd(env_);
1157 Label next(env_);
1158 Label exit(env_);
1159 Jump(&loopHead);
1160
1161 LoopBegin(&loopHead);
1162 {
1163 Branch(Int32GreaterThan(*len, Int32(0)), &next, &exit);
1164 Bind(&next);
1165 {
1166 len = Int32Sub(*len, Int32(1));
1167 GateRef i = Load(type, *sourceTmp, IntPtr(0));
1168 Store(type, glue, *dstTmp, IntPtr(0), i);
1169 Jump(&loopEnd);
1170 }
1171 }
1172 Bind(&loopEnd);
1173 sourceTmp = PtrAdd(*sourceTmp, charSize);
1174 dstTmp = PtrAdd(*dstTmp, charSize);
1175 LoopEnd(&loopHead);
1176
1177 Bind(&exit);
1178 SubCfgExit();
1179 return;
1180 }
1181
1182 // source is utf8, dst is utf16
CopyUtf8AsUtf16(GateRef glue,GateRef dst,GateRef src,GateRef sourceLength)1183 void CircuitBuilder::CopyUtf8AsUtf16(GateRef glue, GateRef dst, GateRef src,
1184
1185 GateRef sourceLength)
1186 {
1187 Label subentry(env_);
1188 SubCfgEntry(&subentry);
1189 DEFVALUE(dstTmp, env_, VariableType::NATIVE_POINTER(), dst);
1190 DEFVALUE(sourceTmp, env_, VariableType::NATIVE_POINTER(), src);
1191 DEFVALUE(len, env_, VariableType::INT32(), sourceLength);
1192 Label loopHead(env_);
1193 Label loopEnd(env_);
1194 Label next(env_);
1195 Label exit(env_);
1196 Jump(&loopHead);
1197 LoopBegin(&loopHead);
1198 {
1199 Branch(Int32GreaterThan(*len, Int32(0)), &next, &exit);
1200 Bind(&next);
1201 {
1202 len = Int32Sub(*len, Int32(1));
1203 GateRef i = Load(VariableType::INT8(), *sourceTmp, IntPtr(0));
1204 Store(VariableType::INT16(), glue, *dstTmp, IntPtr(0), ZExtInt8ToInt16(i));
1205 Jump(&loopEnd);
1206 }
1207 }
1208
1209 Bind(&loopEnd);
1210 sourceTmp = PtrAdd(*sourceTmp, IntPtr(sizeof(uint8_t)));
1211 dstTmp = PtrAdd(*dstTmp, IntPtr(sizeof(uint16_t)));
1212 LoopEnd(&loopHead);
1213
1214 Bind(&exit);
1215 SubCfgExit();
1216 return;
1217 }
1218
TaggedPointerToInt64(GateRef x)1219 GateRef CircuitBuilder::TaggedPointerToInt64(GateRef x)
1220 {
1221 return ChangeTaggedPointerToInt64(x);
1222 }
1223
ComputeTaggedArraySize(GateRef length)1224 GateRef CircuitBuilder::ComputeTaggedArraySize(GateRef length)
1225 {
1226 return PtrAdd(IntPtr(TaggedArray::DATA_OFFSET),
1227 PtrMul(IntPtr(JSTaggedValue::TaggedTypeSize()), length));
1228 }
1229
GetEnumCacheKind(GateRef glue,GateRef enumCache)1230 GateRef CircuitBuilder::GetEnumCacheKind(GateRef glue, GateRef enumCache)
1231 {
1232 Label entry(env_);
1233 SubCfgEntry(&entry);
1234 Label exit(env_);
1235 DEFVALUE(result, env_, VariableType::INT32(), Int32(static_cast<int32_t>(EnumCacheKind::NONE)));
1236
1237 Label enumCacheIsArray(env_);
1238 Label isEmptyArray(env_);
1239 Label notEmptyArray(env_);
1240
1241 Branch(TaggedIsUndefinedOrNull(enumCache), &exit, &enumCacheIsArray);
1242 Bind(&enumCacheIsArray);
1243 GateRef emptyArray = GetEmptyArray(glue);
1244 Branch(Int64Equal(enumCache, emptyArray), &isEmptyArray, ¬EmptyArray);
1245 Bind(&isEmptyArray);
1246 {
1247 result = Int32(static_cast<int32_t>(EnumCacheKind::SIMPLE));
1248 Jump(&exit);
1249 }
1250 Bind(¬EmptyArray);
1251 {
1252 GateRef taggedKind = GetValueFromTaggedArray(enumCache, Int32(EnumCache::ENUM_CACHE_KIND_OFFSET));
1253 result = TaggedGetInt(taggedKind);
1254 Jump(&exit);
1255 }
1256
1257 Bind(&exit);
1258 auto ret = *result;
1259 SubCfgExit();
1260 return ret;
1261 }
1262
IsEnumCacheValid(GateRef receiver,GateRef cachedHclass,GateRef kind)1263 GateRef CircuitBuilder::IsEnumCacheValid(GateRef receiver, GateRef cachedHclass, GateRef kind)
1264 {
1265 Label entry(env_);
1266 SubCfgEntry(&entry);
1267 Label exit(env_);
1268 DEFVALUE(result, env_, VariableType::BOOL(), False());
1269
1270 Label isSameHclass(env_);
1271 Label isSimpleEnumCache(env_);
1272 Label notSimpleEnumCache(env_);
1273 Label prototypeIsEcmaObj(env_);
1274 Label isProtoChangeMarker(env_);
1275 Label protoNotChanged(env_);
1276
1277 GateRef hclass = LoadHClass(receiver);
1278 Branch(Int64Equal(hclass, cachedHclass), &isSameHclass, &exit);
1279 Bind(&isSameHclass);
1280 Branch(Int32Equal(kind, Int32(static_cast<int32_t>(EnumCacheKind::SIMPLE))),
1281 &isSimpleEnumCache, ¬SimpleEnumCache);
1282 Bind(&isSimpleEnumCache);
1283 {
1284 result = True();
1285 Jump(&exit);
1286 }
1287 Bind(¬SimpleEnumCache);
1288 GateRef prototype = GetPrototypeFromHClass(hclass);
1289 Branch(IsEcmaObject(prototype), &prototypeIsEcmaObj, &exit);
1290 Bind(&prototypeIsEcmaObj);
1291 GateRef protoChangeMarker = GetProtoChangeMarkerFromHClass(hclass);
1292 Branch(TaggedIsProtoChangeMarker(protoChangeMarker), &isProtoChangeMarker, &exit);
1293 Bind(&isProtoChangeMarker);
1294 Branch(GetHasChanged(protoChangeMarker), &exit, &protoNotChanged);
1295 Bind(&protoNotChanged);
1296 {
1297 result = True();
1298 Jump(&exit);
1299 }
1300 Bind(&exit);
1301 auto ret = *result;
1302 SubCfgExit();
1303 return ret;
1304 }
1305
NeedCheckProperty(GateRef receiver)1306 GateRef CircuitBuilder::NeedCheckProperty(GateRef receiver)
1307 {
1308 Label entry(env_);
1309 SubCfgEntry(&entry);
1310 Label exit(env_);
1311
1312 Label loopHead(env_);
1313 Label loopEnd(env_);
1314 Label afterLoop(env_);
1315 Label isJSObject(env_);
1316 Label hasNoDeleteProperty(env_);
1317
1318 DEFVALUE(result, env_, VariableType::BOOL(), True());
1319 DEFVALUE(current, env_, VariableType::JS_ANY(), receiver);
1320
1321 Branch(TaggedIsHeapObject(*current), &loopHead, &afterLoop);
1322 LoopBegin(&loopHead);
1323 {
1324 Branch(IsJSObject(*current), &isJSObject, &exit);
1325 Bind(&isJSObject);
1326 GateRef hclass = LoadHClass(*current);
1327 Branch(HasDeleteProperty(hclass), &exit, &hasNoDeleteProperty);
1328 Bind(&hasNoDeleteProperty);
1329 current = GetPrototypeFromHClass(hclass);
1330 Branch(TaggedIsHeapObject(*current), &loopEnd, &afterLoop);
1331 }
1332 Bind(&loopEnd);
1333 LoopEnd(&loopHead);
1334 Bind(&afterLoop);
1335 {
1336 result = False();
1337 Jump(&exit);
1338 }
1339 Bind(&exit);
1340 auto ret = *result;
1341 SubCfgExit();
1342 return ret;
1343 }
1344
ArrayConstructorCheck(GateRef gate)1345 GateRef CircuitBuilder::ArrayConstructorCheck(GateRef gate)
1346 {
1347 auto currentLabel = env_->GetCurrentLabel();
1348 auto currentControl = currentLabel->GetControl();
1349 auto currentDepend = currentLabel->GetDepend();
1350 auto frameState = acc_.FindNearestFrameState(currentDepend);
1351 GateRef ret = GetCircuit()->NewGate(circuit_->ArrayConstructorCheck(),
1352 MachineType::I64, {currentControl, currentDepend, gate, frameState}, GateType::IntType());
1353 currentLabel->SetControl(ret);
1354 currentLabel->SetDepend(ret);
1355 return ret;
1356 }
1357
ObjectConstructorCheck(GateRef gate)1358 GateRef CircuitBuilder::ObjectConstructorCheck(GateRef gate)
1359 {
1360 auto currentLabel = env_->GetCurrentLabel();
1361 auto currentControl = currentLabel->GetControl();
1362 auto currentDepend = currentLabel->GetDepend();
1363 auto frameState = acc_.FindNearestFrameState(currentDepend);
1364 GateRef ret = GetCircuit()->NewGate(circuit_->ObjectConstructorCheck(),
1365 MachineType::I64, {currentControl, currentDepend, gate, frameState}, GateType::IntType());
1366 currentLabel->SetControl(ret);
1367 currentLabel->SetDepend(ret);
1368 return ret;
1369 }
1370
MonoLoadPropertyOnProto(GateRef receiver,GateRef plrGate,GateRef jsFunc,size_t hclassIndex)1371 GateRef CircuitBuilder::MonoLoadPropertyOnProto(GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex)
1372 {
1373 auto currentLabel = env_->GetCurrentLabel();
1374 auto currentControl = currentLabel->GetControl();
1375 auto currentDepend = currentLabel->GetDepend();
1376 auto frameState = acc_.FindNearestFrameState(currentDepend);
1377 auto ret = GetCircuit()->NewGate(circuit_->MonoLoadPropertyOnProto(), MachineType::I64,
1378 { currentControl, currentDepend, receiver, plrGate, Int32(hclassIndex), jsFunc,
1379 frameState },
1380 GateType::AnyType());
1381 currentLabel->SetControl(ret);
1382 currentLabel->SetDepend(ret);
1383 return ret;
1384 }
1385
MonoCallGetterOnProto(GateRef gate,GateRef receiver,GateRef plrGate,GateRef jsFunc,size_t hclassIndex)1386 GateRef CircuitBuilder::MonoCallGetterOnProto(GateRef gate, GateRef receiver, GateRef plrGate, GateRef jsFunc,
1387 size_t hclassIndex)
1388 {
1389 uint64_t pcOffset = acc_.TryGetPcOffset(gate);
1390 ASSERT(pcOffset != 0);
1391
1392 auto currentLabel = env_->GetCurrentLabel();
1393 auto currentControl = currentLabel->GetControl();
1394 auto currentDepend = currentLabel->GetDepend();
1395 auto frameState = acc_.FindNearestFrameState(currentDepend);
1396 std::vector<GateRef> args = { currentControl, currentDepend, receiver, plrGate, Int32(hclassIndex), jsFunc,
1397 frameState };
1398 auto callGate = GetCircuit()->NewGate(circuit_->MonoCallGetterOnProto(pcOffset),
1399 MachineType::I64,
1400 args.size(),
1401 args.data(),
1402 GateType::AnyType());
1403 currentLabel->SetControl(callGate);
1404 currentLabel->SetDepend(callGate);
1405 return callGate;
1406 }
1407
MonoStorePropertyLookUpProto(GateRef receiver,GateRef plrGate,GateRef jsFunc,size_t hclassIndex,GateRef value)1408 GateRef CircuitBuilder::MonoStorePropertyLookUpProto(GateRef receiver, GateRef plrGate, GateRef jsFunc,
1409 size_t hclassIndex, GateRef value)
1410 {
1411 auto currentLabel = env_->GetCurrentLabel();
1412 auto currentControl = currentLabel->GetControl();
1413 auto currentDepend = currentLabel->GetDepend();
1414 auto frameState = acc_.FindNearestFrameState(currentDepend);
1415 auto ret = GetCircuit()->NewGate(circuit_->MonoStorePropertyLookUpProto(false), MachineType::I64,
1416 { currentControl, currentDepend, receiver, plrGate, Int32(hclassIndex), jsFunc, value, frameState},
1417 GateType::AnyType());
1418 currentLabel->SetControl(ret);
1419 currentLabel->SetDepend(ret);
1420 return ret;
1421 }
1422
MonoStoreProperty(GateRef receiver,GateRef plrGate,GateRef jsFunc,size_t hclassIndex,GateRef value,GateRef key)1423 GateRef CircuitBuilder::MonoStoreProperty(GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex,
1424 GateRef value, GateRef key)
1425 {
1426 auto currentLabel = env_->GetCurrentLabel();
1427 auto currentControl = currentLabel->GetControl();
1428 auto currentDepend = currentLabel->GetDepend();
1429 auto ret = GetCircuit()->NewGate(circuit_->MonoStoreProperty(false), MachineType::I64,
1430 { currentControl, currentDepend, receiver, plrGate, Int32(hclassIndex), jsFunc, value, key },
1431 GateType::AnyType());
1432 currentLabel->SetControl(ret);
1433 currentLabel->SetDepend(ret);
1434 return ret;
1435 }
1436
TypedCreateObjWithBuffer(std::vector<GateRef> & valueIn)1437 GateRef CircuitBuilder::TypedCreateObjWithBuffer(std::vector<GateRef> &valueIn)
1438 {
1439 auto currentLabel = env_->GetCurrentLabel();
1440 auto currentControl = currentLabel->GetControl();
1441 auto currentDepend = currentLabel->GetDepend();
1442 std::vector<GateRef> vec { currentControl, currentDepend };
1443 vec.insert(vec.end(), valueIn.begin(), valueIn.end());
1444 GateRef ret = GetCircuit()->NewGate(circuit_->TypedCreateObjWithBuffer(valueIn.size()),
1445 MachineType::I64, vec, GateType::AnyType());
1446 currentLabel->SetControl(ret);
1447 currentLabel->SetDepend(ret);
1448 return ret;
1449 }
1450
ToNumber(GateRef gate,GateRef value,GateRef glue)1451 GateRef CircuitBuilder::ToNumber(GateRef gate, GateRef value, GateRef glue)
1452 {
1453 Label entry(env_);
1454 env_->SubCfgEntry(&entry);
1455 Label exit(env_);
1456 Label isNumber(env_);
1457 Label notNumber(env_);
1458 DEFVALUE(result, env_, VariableType::JS_ANY(), Hole());
1459 Branch(TaggedIsNumber(value), &isNumber, ¬Number);
1460 Bind(&isNumber);
1461 {
1462 result = value;
1463 Jump(&exit);
1464 }
1465 Bind(¬Number);
1466 {
1467 result = CallRuntime(glue, RTSTUB_ID(ToNumber), Gate::InvalidGateRef, { value }, gate);
1468 Jump(&exit);
1469 }
1470 Bind(&exit);
1471 auto ret = *result;
1472 env_->SubCfgExit();
1473 return ret;
1474 }
1475
StringFromSingleCharCode(GateRef gate)1476 GateRef CircuitBuilder::StringFromSingleCharCode(GateRef gate)
1477 {
1478 auto currentLabel = env_->GetCurrentLabel();
1479 auto currentControl = currentLabel->GetControl();
1480 auto currentDepend = currentLabel->GetDepend();
1481 GateRef ret =
1482 GetCircuit()->NewGate(circuit_->StringFromSingleCharCode(), MachineType::I64,
1483 { currentControl, currentDepend, gate }, GateType::AnyType());
1484 currentLabel->SetControl(ret);
1485 currentLabel->SetDepend(ret);
1486 return ret;
1487 }
1488
IsASCIICharacter(GateRef gate)1489 GateRef CircuitBuilder::IsASCIICharacter(GateRef gate)
1490 {
1491 return Int32UnsignedLessThan(Int32Sub(gate, Int32(1)), Int32(base::utf_helper::UTF8_1B_MAX));
1492 }
1493 }
1494