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