1/* 2 * Copyright (c) 2021 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/common_stubs.h" 17 18#include "ecmascript/base/number_helper.h" 19#include "ecmascript/compiler/access_object_stub_builder.h" 20#include "ecmascript/compiler/builtins/builtins_string_stub_builder.h" 21#include "ecmascript/compiler/builtins/linked_hashtable_stub_builder.h" 22#include "ecmascript/compiler/codegen/llvm/llvm_ir_builder.h" 23#include "ecmascript/compiler/interpreter_stub.h" 24#include "ecmascript/compiler/new_object_stub_builder.h" 25#include "ecmascript/compiler/operations_stub_builder.h" 26#include "ecmascript/compiler/stub_builder-inl.h" 27#include "ecmascript/compiler/variable_type.h" 28#include "ecmascript/js_array.h" 29#include "ecmascript/js_map.h" 30#include "ecmascript/js_map_iterator.h" 31#include "ecmascript/js_set.h" 32#include "ecmascript/js_set_iterator.h" 33#include "ecmascript/linked_hash_table.h" 34#include "ecmascript/message_string.h" 35#include "ecmascript/tagged_hash_table.h" 36 37namespace panda::ecmascript::kungfu { 38using namespace panda::ecmascript; 39 40void AddStubBuilder::GenerateCircuit() 41{ 42 GateRef glue = PtrArgument(0); 43 GateRef x = TaggedArgument(1); 44 GateRef y = TaggedArgument(2); 45 OperationsStubBuilder operationBuilder(this); 46 Return(operationBuilder.Add(glue, x, y)); 47} 48 49void SubStubBuilder::GenerateCircuit() 50{ 51 GateRef glue = PtrArgument(0); 52 GateRef x = TaggedArgument(1); 53 GateRef y = TaggedArgument(2); 54 OperationsStubBuilder operationBuilder(this); 55 Return(operationBuilder.Sub(glue, x, y)); 56} 57 58void DefineFieldStubBuilder::GenerateCircuit() 59{ 60 GateRef glue = PtrArgument(0); 61 GateRef receiver = TaggedArgument(1); 62 GateRef propKey = TaggedArgument(2); // 2: 3rd argument 63 GateRef acc = TaggedArgument(3); // 3: 4th argument 64 Return(DefineField(glue, receiver, propKey, acc)); 65} 66 67void DefinefuncStubBuilder::GenerateCircuit() 68{ 69 auto env = GetEnvironment(); 70 GateRef glue = PtrArgument(0); 71 GateRef jsFunc = TaggedArgument(1); 72 GateRef methodId = Int32Argument(2); // 2: 3rd argument 73 GateRef length = Int32Argument(3); // 3: 4th argument 74 GateRef lexEnv = TaggedArgument(4); // 4: 5th argument 75 GateRef slotId = Int32Argument(5); // 5: 6th argument 76 77 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined()); 78 Label exit(env); 79 Label failed(env); 80 NewObjectStubBuilder newBuilder(this); 81 newBuilder.NewJSFunction(glue, jsFunc, methodId, length, lexEnv, &result, &exit, &failed, slotId); 82 Bind(&failed); 83 { 84 result = Exception(); 85 Jump(&exit); 86 } 87 Bind(&exit); 88 Return(*result); 89} 90 91void ConvertCharToInt32StubBuilder::GenerateCircuit() 92{ 93 GateRef glue = PtrArgument(0); 94 GateRef charCode = Int32Argument(1); 95 BuiltinsStringStubBuilder builder(this); 96 // char to string 97 GateRef result = builder.CreateStringBySingleCharCode(glue, charCode); 98 // string to number 99 result = CallNGCRuntime(glue, RTSTUB_ID(StringToNumber), {result, Int32(0)}, charCode); 100 // get int from number 101 result = NumberGetInt(glue, result); 102 Return(result); 103} 104 105void ConvertCharToDoubleStubBuilder::GenerateCircuit() 106{ 107 GateRef glue = PtrArgument(0); 108 GateRef charCode = Int32Argument(1); 109 BuiltinsStringStubBuilder builder(this); 110 // char to string 111 GateRef result = builder.CreateStringBySingleCharCode(glue, charCode); 112 // string to number 113 result = CallNGCRuntime(glue, RTSTUB_ID(StringToNumber), {result, Int32(0)}, charCode); 114 // get double from number 115 result = GetDoubleOfTNumber(result); 116 Return(result); 117} 118 119void MulStubBuilder::GenerateCircuit() 120{ 121 GateRef glue = PtrArgument(0); 122 GateRef x = TaggedArgument(1); 123 GateRef y = TaggedArgument(2); 124 OperationsStubBuilder operationBuilder(this); 125 Return(operationBuilder.Mul(glue, x, y)); 126} 127 128void DivStubBuilder::GenerateCircuit() 129{ 130 GateRef glue = PtrArgument(0); 131 GateRef x = TaggedArgument(1); 132 GateRef y = TaggedArgument(2); 133 OperationsStubBuilder operationBuilder(this); 134 Return(operationBuilder.Div(glue, x, y)); 135} 136 137void ModStubBuilder::GenerateCircuit() 138{ 139 GateRef glue = PtrArgument(0); 140 GateRef x = TaggedArgument(1); 141 GateRef y = TaggedArgument(2); // 2: 3rd argument 142 OperationsStubBuilder operationBuilder(this); 143 Return(operationBuilder.Mod(glue, x, y)); 144} 145 146void TypeOfStubBuilder::GenerateCircuit() 147{ 148 GateRef glue = PtrArgument(0); 149 GateRef obj = TaggedArgument(1); 150 Return(FastTypeOf(glue, obj)); 151} 152 153void EqualStubBuilder::GenerateCircuit() 154{ 155 GateRef glue = PtrArgument(0); 156 GateRef x = TaggedArgument(1); 157 GateRef y = TaggedArgument(2); // 2: 3rd argument 158 OperationsStubBuilder operationBuilder(this); 159 Return(operationBuilder.Equal(glue, x, y)); 160} 161 162void NotEqualStubBuilder::GenerateCircuit() 163{ 164 GateRef glue = PtrArgument(0); 165 GateRef x = TaggedArgument(1); 166 GateRef y = TaggedArgument(2); // 2: 3rd argument 167 OperationsStubBuilder operationBuilder(this); 168 Return(operationBuilder.NotEqual(glue, x, y)); 169} 170 171void StrictEqualStubBuilder::GenerateCircuit() 172{ 173 GateRef glue = PtrArgument(0); 174 GateRef x = TaggedArgument(1); 175 GateRef y = TaggedArgument(2); // 2: 3rd argument 176 OperationsStubBuilder operationBuilder(this); 177 Return(operationBuilder.StrictEqual(glue, x, y)); 178} 179 180void StrictNotEqualStubBuilder::GenerateCircuit() 181{ 182 GateRef glue = PtrArgument(0); 183 GateRef x = TaggedArgument(1); 184 GateRef y = TaggedArgument(2); // 2: 3rd argument 185 OperationsStubBuilder operationBuilder(this); 186 Return(operationBuilder.StrictNotEqual(glue, x, y)); 187} 188 189void LessStubBuilder::GenerateCircuit() 190{ 191 GateRef glue = PtrArgument(0); 192 GateRef x = TaggedArgument(1); 193 GateRef y = TaggedArgument(2); // 2: 3rd argument 194 OperationsStubBuilder operationBuilder(this); 195 Return(operationBuilder.Less(glue, x, y)); 196} 197 198void LessEqStubBuilder::GenerateCircuit() 199{ 200 GateRef glue = PtrArgument(0); 201 GateRef x = TaggedArgument(1); 202 GateRef y = TaggedArgument(2); // 2: 3rd argument 203 OperationsStubBuilder operationBuilder(this); 204 Return(operationBuilder.LessEq(glue, x, y)); 205} 206 207void GreaterStubBuilder::GenerateCircuit() 208{ 209 GateRef glue = PtrArgument(0); 210 GateRef x = TaggedArgument(1); 211 GateRef y = TaggedArgument(2); // 2: 3rd argument 212 OperationsStubBuilder operationBuilder(this); 213 Return(operationBuilder.Greater(glue, x, y)); 214} 215 216void GreaterEqStubBuilder::GenerateCircuit() 217{ 218 GateRef glue = PtrArgument(0); 219 GateRef x = TaggedArgument(1); 220 GateRef y = TaggedArgument(2); // 2: 3rd argument 221 OperationsStubBuilder operationBuilder(this); 222 Return(operationBuilder.GreaterEq(glue, x, y)); 223} 224 225void ShlStubBuilder::GenerateCircuit() 226{ 227 GateRef glue = PtrArgument(0); 228 GateRef x = TaggedArgument(1); 229 GateRef y = TaggedArgument(2); // 2: 3rd argument 230 OperationsStubBuilder operationBuilder(this); 231 Return(operationBuilder.Shl(glue, x, y)); 232} 233 234void ShrStubBuilder::GenerateCircuit() 235{ 236 GateRef glue = PtrArgument(0); 237 GateRef x = TaggedArgument(1); 238 GateRef y = TaggedArgument(2); // 2: 3rd argument 239 OperationsStubBuilder operationBuilder(this); 240 Return(operationBuilder.Shr(glue, x, y)); 241} 242 243void AshrStubBuilder::GenerateCircuit() 244{ 245 GateRef glue = PtrArgument(0); 246 GateRef x = TaggedArgument(1); 247 GateRef y = TaggedArgument(2); // 2: 3rd argument 248 OperationsStubBuilder operationBuilder(this); 249 Return(operationBuilder.Ashr(glue, x, y)); 250} 251 252void AndStubBuilder::GenerateCircuit() 253{ 254 GateRef glue = PtrArgument(0); 255 GateRef x = TaggedArgument(1); 256 GateRef y = TaggedArgument(2); // 2: 3rd argument 257 OperationsStubBuilder operationBuilder(this); 258 Return(operationBuilder.And(glue, x, y)); 259} 260 261void OrStubBuilder::GenerateCircuit() 262{ 263 GateRef glue = PtrArgument(0); 264 GateRef x = TaggedArgument(1); 265 GateRef y = TaggedArgument(2); // 2: 3rd argument 266 OperationsStubBuilder operationBuilder(this); 267 Return(operationBuilder.Or(glue, x, y)); 268} 269 270void XorStubBuilder::GenerateCircuit() 271{ 272 GateRef glue = PtrArgument(0); 273 GateRef x = TaggedArgument(1); 274 GateRef y = TaggedArgument(2); // 2: 3rd argument 275 OperationsStubBuilder operationBuilder(this); 276 Return(operationBuilder.Xor(glue, x, y)); 277} 278 279void InstanceofStubBuilder::GenerateCircuit() 280{ 281 GateRef glue = PtrArgument(0); 282 GateRef object = TaggedArgument(1); 283 GateRef target = TaggedArgument(2); // 2: 3rd argument 284 GateRef jsFunc = TaggedArgument(3); // 3 : 4th para 285 GateRef slotId = Int32Argument(4); // 4 : 5th pars 286 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc); 287 Return(InstanceOf(glue, object, target, profileTypeInfo, slotId, ProfileOperation())); 288} 289 290void IncStubBuilder::GenerateCircuit() 291{ 292 GateRef glue = PtrArgument(0); 293 GateRef x = TaggedArgument(1); 294 OperationsStubBuilder operationBuilder(this); 295 Return(operationBuilder.Inc(glue, x)); 296} 297 298void DecStubBuilder::GenerateCircuit() 299{ 300 GateRef glue = PtrArgument(0); 301 GateRef x = TaggedArgument(1); 302 OperationsStubBuilder operationBuilder(this); 303 Return(operationBuilder.Dec(glue, x)); 304} 305 306void NegStubBuilder::GenerateCircuit() 307{ 308 GateRef glue = PtrArgument(0); 309 GateRef x = TaggedArgument(1); 310 OperationsStubBuilder operationBuilder(this); 311 Return(operationBuilder.Neg(glue, x)); 312} 313 314void NotStubBuilder::GenerateCircuit() 315{ 316 GateRef glue = PtrArgument(0); 317 GateRef x = TaggedArgument(1); 318 OperationsStubBuilder operationBuilder(this); 319 Return(operationBuilder.Not(glue, x)); 320} 321 322void ToBooleanTrueStubBuilder::GenerateCircuit() 323{ 324 GateRef glue = PtrArgument(0); 325 (void)glue; 326 GateRef x = TaggedArgument(1); 327 Return(FastToBoolean(x, true)); 328} 329 330void ToBooleanFalseStubBuilder::GenerateCircuit() 331{ 332 GateRef glue = PtrArgument(0); 333 (void)glue; 334 GateRef x = TaggedArgument(1); 335 Return(FastToBoolean(x, false)); 336} 337 338void NewLexicalEnvStubBuilder::GenerateCircuit() 339{ 340 auto env = GetEnvironment(); 341 GateRef glue = PtrArgument(0); 342 GateRef parent = TaggedArgument(1); 343 GateRef numVars = Int32Argument(2); /* 2 : 3rd parameter is index */ 344 345 DEFVARIABLE(result, VariableType::JS_ANY(), Hole()); 346 NewObjectStubBuilder newBuilder(this); 347 newBuilder.SetParameters(glue, 0); 348 Label afterNew(env); 349 newBuilder.NewLexicalEnv(&result, &afterNew, numVars, parent); 350 Bind(&afterNew); 351 Return(*result); 352} 353 354void CopyRestArgsStubBuilder::GenerateCircuit() 355{ 356 DEFVARIABLE(arrayObj, VariableType::JS_ANY(), Undefined()); 357 DEFVARIABLE(argv, VariableType::NATIVE_POINTER(), PtrArgument(1)); 358 DEFVARIABLE(i, VariableType::INT32(), Int32(0)); 359 DEFVARIABLE(actualRestNum, VariableType::INT32(), Int32(0)); 360 auto env = GetEnvironment(); 361 GateRef glue = PtrArgument(0); 362 GateRef startIdx = Int32Argument(2); /* 2 : 3rd parameter is startIdx */ 363 GateRef numArgs = Int32Argument(3); /* 3 : 4th parameter is numArgs */ 364 GateRef argvTaggedArray = TaggedArgument(4); /* 4 : 5th parameter is argvTaggedArray */ 365 366 Label numArgsGreater(env); 367 Label numArgsNotGreater(env); 368 Label afterCreateArrayObj(env); 369 370 GateRef actualArgc = Int32Sub(numArgs, Int32(NUM_MANDATORY_JSFUNC_ARGS)); 371 // 1. Calculate actual rest num. 372 BRANCH(Int32UnsignedGreaterThan(actualArgc, startIdx), &numArgsGreater, &numArgsNotGreater); 373 Bind(&numArgsGreater); 374 { 375 actualRestNum = Int32Sub(actualArgc, startIdx); 376 Jump(&numArgsNotGreater); 377 } 378 Bind(&numArgsNotGreater); 379 // 2. Construct RestArguments object. 380 NewObjectStubBuilder newBuilder(this); 381 newBuilder.SetParameters(glue, 0); 382 GateRef intialHClass = GetGlobalConstantValue(VariableType::JS_ANY(), glue, 383 ConstantIndex::ELEMENT_HOLE_TAGGED_HCLASS_INDEX); 384 arrayObj = newBuilder.NewJSArrayWithSize(intialHClass, *actualRestNum); 385 386 GateRef args = GetArgumentsElements(glue, argvTaggedArray, *argv); 387 newBuilder.AssignRestArg(&arrayObj, &afterCreateArrayObj, args, startIdx, *actualRestNum, intialHClass); 388 Bind(&afterCreateArrayObj); 389 Return(*arrayObj); 390} 391 392void GetUnmappedArgsStubBuilder::GenerateCircuit() 393{ 394 auto env = GetEnvironment(); 395 GateRef glue = PtrArgument(0); 396 GateRef numArgs = Int32Argument(2); /* 2 : 3rd parameter is numArgs */ 397 GateRef argvTaggedArray = TaggedArgument(3); /* 3 : 4th parameter is argvTaggedArray */ 398 399 DEFVARIABLE(argumentsList, VariableType::JS_ANY(), Hole()); 400 DEFVARIABLE(argumentsObj, VariableType::JS_ANY(), Hole()); 401 DEFVARIABLE(argv, VariableType::NATIVE_POINTER(), PtrArgument(1)); 402 Label afterArgumentsList(env); 403 Label newArgumentsObj(env); 404 Label exit(env); 405 406 GateRef actualArgc = Int32Sub(numArgs, Int32(NUM_MANDATORY_JSFUNC_ARGS)); 407 GateRef startIdx = Int32(0); 408 NewObjectStubBuilder newBuilder(this); 409 newBuilder.SetParameters(glue, 0); 410 411 Label fillArguments(env); 412 Label argumentsException(env); 413 GateRef argumentsListObj = newBuilder.NewArgumentsListObj(actualArgc); 414 argumentsList.WriteVariable(argumentsListObj); 415 Branch(TaggedIsException(*argumentsList), &argumentsException, &fillArguments); 416 Bind(&argumentsException); 417 argumentsObj.WriteVariable(*argumentsList); 418 Jump(&exit); 419 Bind(&fillArguments); 420 421 GateRef args = GetArgumentsElements(glue, argvTaggedArray, *argv); 422 newBuilder.FillArgumentsList(*argumentsList, args, startIdx, actualArgc); 423 newBuilder.NewArgumentsObj(&argumentsObj, &exit, *argumentsList, actualArgc); 424 Bind(&exit); 425 Return(*argumentsObj); 426} 427 428void GetCallSpreadArgsStubBuilder::GenerateCircuit() 429{ 430 GateRef glue = PtrArgument(0); 431 GateRef array = TaggedArgument(1); 432 Return(GetCallSpreadArgs(glue, array, ProfileOperation())); 433} 434 435void GetPropertyByIndexStubBuilder::GenerateCircuit() 436{ 437 GateRef glue = PtrArgument(0); 438 GateRef receiver = TaggedArgument(1); 439 GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */ 440 Return(GetPropertyByIndex(glue, receiver, index, ProfileOperation())); 441} 442 443void SetPropertyByIndexStubBuilder::GenerateCircuit() 444{ 445 GateRef glue = PtrArgument(0); 446 GateRef receiver = TaggedArgument(1); 447 GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */ 448 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */ 449 Return(SetPropertyByIndex(glue, receiver, index, value, false)); 450} 451 452void SetPropertyByIndexWithOwnStubBuilder::GenerateCircuit() 453{ 454 GateRef glue = PtrArgument(0); 455 GateRef receiver = TaggedArgument(1); 456 GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */ 457 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */ 458 Return(SetPropertyByIndex(glue, receiver, index, value, true)); 459} 460 461void GetPropertyByNameStubBuilder::GenerateCircuit() 462{ 463 GateRef glue = PtrArgument(0); 464 GateRef receiver = TaggedArgument(1); 465 GateRef id = Int64Argument(2); // 2 : 3rd para 466 GateRef jsFunc = TaggedArgument(3); // 3 : 4th para 467 GateRef slotId = Int32Argument(4); // 4 : 5th para 468 AccessObjectStubBuilder builder(this, jsFunc); 469 StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID); 470 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc); 471 Return(builder.LoadObjByName(glue, receiver, id, info, profileTypeInfo, slotId, ProfileOperation())); 472} 473 474void DeprecatedGetPropertyByNameStubBuilder::GenerateCircuit() 475{ 476 GateRef glue = PtrArgument(0); 477 GateRef receiver = TaggedArgument(1); 478 GateRef key = TaggedPointerArgument(2); // 2 : 3rd para 479 AccessObjectStubBuilder builder(this); 480 Return(builder.DeprecatedLoadObjByName(glue, receiver, key)); 481} 482 483void SetPropertyByNameStubBuilder::GenerateCircuit() 484{ 485 GateRef glue = PtrArgument(0); 486 GateRef receiver = TaggedArgument(1); 487 GateRef id = Int64Argument(2); // 2 : 3rd para 488 GateRef value = TaggedPointerArgument(3); // 3 : 4th para 489 GateRef jsFunc = TaggedArgument(4); // 4 : 5th para 490 GateRef slotId = Int32Argument(5); // 5 : 6th para 491 AccessObjectStubBuilder builder(this, jsFunc); 492 StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID); 493 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc); 494 Return(builder.StoreObjByName(glue, receiver, id, info, value, profileTypeInfo, slotId, ProfileOperation())); 495} 496 497void DeprecatedSetPropertyByNameStubBuilder::GenerateCircuit() 498{ 499 GateRef glue = PtrArgument(0); 500 GateRef receiver = TaggedArgument(1); 501 GateRef key = TaggedArgument(2); // 2 : 3rd para 502 GateRef value = TaggedArgument(3); // 3 : 4th para 503 Return(SetPropertyByName(glue, receiver, key, value, false, True())); 504} 505 506void SetPropertyByNameWithOwnStubBuilder::GenerateCircuit() 507{ 508 GateRef glue = PtrArgument(0); 509 GateRef receiver = TaggedArgument(1); 510 GateRef key = TaggedArgument(2); // 2 : 3rd para 511 GateRef value = TaggedArgument(3); // 3 : 4th para 512 Return(SetPropertyByName(glue, receiver, key, value, true, True())); 513} 514 515void GetPropertyByValueStubBuilder::GenerateCircuit() 516{ 517 GateRef glue = PtrArgument(0); 518 GateRef receiver = TaggedArgument(1); 519 GateRef key = TaggedArgument(2); // 2 : 3rd para 520 GateRef jsFunc = TaggedArgument(3); // 3 : 4th para 521 GateRef slotId = Int32Argument(4); // 4 : 5th para 522 AccessObjectStubBuilder builder(this); 523 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc); 524 Return(builder.LoadObjByValue(glue, receiver, key, profileTypeInfo, slotId)); 525} 526 527void DeprecatedGetPropertyByValueStubBuilder::GenerateCircuit() 528{ 529 GateRef glue = PtrArgument(0); 530 GateRef receiver = TaggedArgument(1); 531 GateRef key = TaggedArgument(2); // 2 : 3rd para 532 Return(GetPropertyByValue(glue, receiver, key, ProfileOperation())); 533} 534 535void SetPropertyByValueStubBuilder::GenerateCircuit() 536{ 537 GateRef glue = PtrArgument(0); 538 GateRef receiver = TaggedArgument(1); 539 GateRef key = TaggedArgument(2); // 2 : 3rd para 540 GateRef value = TaggedArgument(3); // 3 : 4th para 541 GateRef jsFunc = TaggedArgument(4); // 4 : 5th para 542 GateRef slotId = Int32Argument(5); // 5 : 6th para 543 AccessObjectStubBuilder builder(this); 544 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc); 545 Return(builder.StoreObjByValue(glue, receiver, key, value, profileTypeInfo, slotId)); 546} 547 548void DeprecatedSetPropertyByValueStubBuilder::GenerateCircuit() 549{ 550 GateRef glue = PtrArgument(0); 551 GateRef receiver = TaggedArgument(1); 552 GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is key */ 553 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */ 554 Return(SetPropertyByValue(glue, receiver, key, value, false)); 555} 556 557void SetPropertyByValueWithOwnStubBuilder::GenerateCircuit() 558{ 559 GateRef glue = PtrArgument(0); 560 GateRef receiver = TaggedArgument(1); 561 GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is key */ 562 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */ 563 Return(SetPropertyByValue(glue, receiver, key, value, true)); 564} 565 566void StOwnByIndexStubBuilder::GenerateCircuit() 567{ 568 GateRef glue = PtrArgument(0); 569 GateRef receiver = TaggedArgument(1); 570 GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */ 571 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */ 572 AccessObjectStubBuilder builder(this); 573 Return(builder.StOwnByIndex(glue, receiver, index, value)); 574} 575 576void StOwnByValueStubBuilder::GenerateCircuit() 577{ 578 GateRef glue = PtrArgument(0); 579 GateRef receiver = TaggedArgument(1); 580 GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is key */ 581 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */ 582 AccessObjectStubBuilder builder(this); 583 Return(builder.StOwnByValue(glue, receiver, key, value)); 584} 585 586void StOwnByNameStubBuilder::GenerateCircuit() 587{ 588 GateRef glue = PtrArgument(0); 589 GateRef receiver = TaggedArgument(1); 590 GateRef key = TaggedArgument(2); // 2 : 3rd para 591 GateRef value = TaggedArgument(3); // 3 : 4th para 592 AccessObjectStubBuilder builder(this); 593 Return(builder.StOwnByName(glue, receiver, key, value)); 594} 595 596void StOwnByValueWithNameSetStubBuilder::GenerateCircuit() 597{ 598 GateRef glue = PtrArgument(0); 599 GateRef receiver = TaggedArgument(1); 600 GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is key */ 601 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */ 602 AccessObjectStubBuilder builder(this); 603 Return(builder.StOwnByValueWithNameSet(glue, receiver, key, value)); 604} 605 606void StOwnByNameWithNameSetStubBuilder::GenerateCircuit() 607{ 608 GateRef glue = PtrArgument(0); 609 GateRef receiver = TaggedArgument(1); 610 GateRef key = TaggedArgument(2); // 2 : 3rd para 611 GateRef value = TaggedArgument(3); // 3 : 4th para 612 AccessObjectStubBuilder builder(this); 613 Return(builder.StOwnByNameWithNameSet(glue, receiver, key, value)); 614} 615 616void LdObjByIndexStubBuilder::GenerateCircuit() 617{ 618 GateRef glue = PtrArgument(0); 619 GateRef receiver = TaggedArgument(1); 620 GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */ 621 AccessObjectStubBuilder builder(this); 622 Return(builder.LdObjByIndex(glue, receiver, index)); 623} 624 625void StObjByIndexStubBuilder::GenerateCircuit() 626{ 627 GateRef glue = PtrArgument(0); 628 GateRef receiver = TaggedArgument(1); 629 GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */ 630 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */ 631 AccessObjectStubBuilder builder(this); 632 Return(builder.StObjByIndex(glue, receiver, index, value)); 633} 634 635void TryLdGlobalByNameStubBuilder::GenerateCircuit() 636{ 637 GateRef glue = PtrArgument(0); 638 GateRef id = Int64Argument(1); 639 GateRef jsFunc = TaggedArgument(2); // 2 : 3th para 640 GateRef slotId = Int32Argument(3); // 3 : 4th para 641 AccessObjectStubBuilder builder(this, jsFunc); 642 StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID); 643 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc); 644 Return(builder.TryLoadGlobalByName(glue, id, info, profileTypeInfo, slotId, ProfileOperation())); 645} 646 647void TryStGlobalByNameStubBuilder::GenerateCircuit() 648{ 649 GateRef glue = PtrArgument(0); 650 GateRef id = Int64Argument(1); 651 GateRef value = TaggedArgument(2); // 2 : 3rd para 652 GateRef jsFunc = TaggedArgument(3); // 3 : 4th para 653 GateRef slotId = Int32Argument(4); // 4: 5th para 654 AccessObjectStubBuilder builder(this, jsFunc); 655 StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID); 656 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc); 657 Return(builder.TryStoreGlobalByName(glue, id, info, value, profileTypeInfo, slotId, ProfileOperation())); 658} 659 660void LdGlobalVarStubBuilder::GenerateCircuit() 661{ 662 GateRef glue = PtrArgument(0); 663 GateRef id = Int64Argument(1); 664 GateRef jsFunc = TaggedArgument(2); // 2 : 3th para 665 GateRef slotId = Int32Argument(3); // 3 : 4th para 666 AccessObjectStubBuilder builder(this, jsFunc); 667 StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID); 668 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc); 669 Return(builder.LoadGlobalVar(glue, id, info, profileTypeInfo, slotId, ProfileOperation())); 670} 671 672void StGlobalVarStubBuilder::GenerateCircuit() 673{ 674 GateRef glue = PtrArgument(0); 675 GateRef id = Int64Argument(1); 676 GateRef value = TaggedArgument(2); // 2 : 3rd para 677 GateRef jsFunc = TaggedArgument(3); // 3 : 4th para 678 GateRef slotId = Int32Argument(4); // 4: 5th para 679 AccessObjectStubBuilder builder(this, jsFunc); 680 StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID); 681 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc); 682 Return(builder.StoreGlobalVar(glue, id, info, value, profileTypeInfo, slotId)); 683} 684 685void TryLoadICByNameStubBuilder::GenerateCircuit() 686{ 687 auto env = GetEnvironment(); 688 GateRef glue = PtrArgument(0); 689 GateRef receiver = TaggedArgument(1); 690 GateRef firstValue = TaggedArgument(2); /* 2 : 3rd parameter is value */ 691 GateRef secondValue = TaggedArgument(3); /* 3 : 4th parameter is value */ 692 693 Label receiverIsHeapObject(env); 694 Label receiverNotHeapObject(env); 695 Label hclassEqualFirstValue(env); 696 Label hclassNotEqualFirstValue(env); 697 Label cachedHandlerNotHole(env); 698 BRANCH(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject); 699 Bind(&receiverIsHeapObject); 700 { 701 GateRef hclass = LoadHClass(receiver); 702 BRANCH(Equal(LoadObjectFromWeakRef(firstValue), hclass), 703 &hclassEqualFirstValue, 704 &hclassNotEqualFirstValue); 705 Bind(&hclassEqualFirstValue); 706 { 707 Return(LoadICWithHandler(glue, receiver, receiver, secondValue, ProfileOperation())); 708 } 709 Bind(&hclassNotEqualFirstValue); 710 { 711 GateRef cachedHandler = CheckPolyHClass(firstValue, hclass); 712 BRANCH(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole); 713 Bind(&cachedHandlerNotHole); 714 { 715 Return(LoadICWithHandler(glue, receiver, receiver, cachedHandler, ProfileOperation())); 716 } 717 } 718 } 719 Bind(&receiverNotHeapObject); 720 { 721 Return(Hole()); 722 } 723} 724 725void TryLoadICByValueStubBuilder::GenerateCircuit() 726{ 727 auto env = GetEnvironment(); 728 GateRef glue = PtrArgument(0); 729 GateRef receiver = TaggedArgument(1); 730 GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is value */ 731 GateRef firstValue = TaggedArgument(3); /* 3 : 4th parameter is value */ 732 GateRef secondValue = TaggedArgument(4); /* 4 : 5th parameter is value */ 733 734 Label receiverIsHeapObject(env); 735 Label receiverNotHeapObject(env); 736 Label hclassEqualFirstValue(env); 737 Label hclassNotEqualFirstValue(env); 738 Label firstValueEqualKey(env); 739 Label cachedHandlerNotHole(env); 740 BRANCH(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject); 741 Bind(&receiverIsHeapObject); 742 { 743 GateRef hclass = LoadHClass(receiver); 744 BRANCH(Equal(LoadObjectFromWeakRef(firstValue), hclass), 745 &hclassEqualFirstValue, 746 &hclassNotEqualFirstValue); 747 Bind(&hclassEqualFirstValue); 748 Return(LoadElement(glue, receiver, key)); 749 Bind(&hclassNotEqualFirstValue); 750 { 751 BRANCH(Int64Equal(firstValue, key), &firstValueEqualKey, &receiverNotHeapObject); 752 Bind(&firstValueEqualKey); 753 { 754 auto cachedHandler = CheckPolyHClass(secondValue, hclass); 755 BRANCH(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole); 756 Bind(&cachedHandlerNotHole); 757 Return(LoadICWithHandler(glue, receiver, receiver, cachedHandler, ProfileOperation())); 758 } 759 } 760 } 761 Bind(&receiverNotHeapObject); 762 Return(Hole()); 763} 764 765void TryStoreICByNameStubBuilder::GenerateCircuit() 766{ 767 auto env = GetEnvironment(); 768 GateRef glue = PtrArgument(0); 769 GateRef receiver = TaggedArgument(1); 770 GateRef firstValue = TaggedArgument(2); /* 2 : 3rd parameter is value */ 771 GateRef secondValue = TaggedArgument(3); /* 3 : 4th parameter is value */ 772 GateRef value = TaggedArgument(4); /* 4 : 5th parameter is value */ 773 Label receiverIsHeapObject(env); 774 Label receiverNotHeapObject(env); 775 Label hclassEqualFirstValue(env); 776 Label hclassNotEqualFirstValue(env); 777 Label cachedHandlerNotHole(env); 778 BRANCH(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject); 779 Bind(&receiverIsHeapObject); 780 { 781 GateRef hclass = LoadHClass(receiver); 782 BRANCH(Equal(LoadObjectFromWeakRef(firstValue), hclass), 783 &hclassEqualFirstValue, 784 &hclassNotEqualFirstValue); 785 Bind(&hclassEqualFirstValue); 786 { 787 Return(StoreICWithHandler(glue, receiver, receiver, value, secondValue)); 788 } 789 Bind(&hclassNotEqualFirstValue); 790 { 791 GateRef cachedHandler = CheckPolyHClass(firstValue, hclass); 792 BRANCH(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole); 793 Bind(&cachedHandlerNotHole); 794 { 795 Return(StoreICWithHandler(glue, receiver, receiver, value, cachedHandler)); 796 } 797 } 798 } 799 Bind(&receiverNotHeapObject); 800 Return(Hole()); 801} 802 803void TryStoreICByValueStubBuilder::GenerateCircuit() 804{ 805 auto env = GetEnvironment(); 806 GateRef glue = PtrArgument(0); 807 GateRef receiver = TaggedArgument(1); 808 GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is value */ 809 GateRef firstValue = TaggedArgument(3); /* 3 : 4th parameter is value */ 810 GateRef secondValue = TaggedArgument(4); /* 4 : 5th parameter is value */ 811 GateRef value = TaggedArgument(5); /* 5 : 6th parameter is value */ 812 Label receiverIsHeapObject(env); 813 Label receiverNotHeapObject(env); 814 Label hclassEqualFirstValue(env); 815 Label hclassNotEqualFirstValue(env); 816 Label firstValueEqualKey(env); 817 Label cachedHandlerNotHole(env); 818 BRANCH(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject); 819 Bind(&receiverIsHeapObject); 820 { 821 GateRef hclass = LoadHClass(receiver); 822 BRANCH(Equal(LoadObjectFromWeakRef(firstValue), hclass), 823 &hclassEqualFirstValue, 824 &hclassNotEqualFirstValue); 825 Bind(&hclassEqualFirstValue); 826 Return(ICStoreElement(glue, receiver, key, value, secondValue)); 827 Bind(&hclassNotEqualFirstValue); 828 { 829 BRANCH(Int64Equal(firstValue, key), &firstValueEqualKey, &receiverNotHeapObject); 830 Bind(&firstValueEqualKey); 831 { 832 GateRef cachedHandler = CheckPolyHClass(secondValue, hclass); 833 BRANCH(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole); 834 Bind(&cachedHandlerNotHole); 835 Return(StoreICWithHandler(glue, receiver, receiver, value, cachedHandler)); 836 } 837 } 838 } 839 Bind(&receiverNotHeapObject); 840 Return(Hole()); 841} 842 843void SetValueWithBarrierStubBuilder::GenerateCircuit() 844{ 845 GateRef glue = PtrArgument(0); 846 GateRef obj = TaggedArgument(1); 847 GateRef offset = PtrArgument(2); // 2 : 3rd para 848 GateRef value = TaggedArgument(3); // 3 : 4th para 849 SetValueWithBarrier(glue, obj, offset, value); 850 Return(); 851} 852 853void SetNonSValueWithBarrierStubBuilder::GenerateCircuit() 854{ 855 GateRef glue = PtrArgument(0); 856 GateRef obj = TaggedArgument(1); 857 GateRef offset = PtrArgument(2); // 2 : 3rd para 858 GateRef value = TaggedArgument(3); // 3 : 4th para 859 SetValueWithBarrier(glue, obj, offset, value, false, MemoryAttribute::NON_SHARE); 860 Return(); 861} 862 863void SetValueWithEdenBarrierStubBuilder::GenerateCircuit() 864{ 865 GateRef glue = PtrArgument(0); 866 GateRef obj = TaggedArgument(1); 867 GateRef offset = PtrArgument(2); // 2 : 3rd para 868 GateRef value = TaggedArgument(3); // 3 : 4th para 869 SetValueWithBarrier(glue, obj, offset, value, true); 870 Return(); 871} 872 873void SetNonSValueWithEdenBarrierStubBuilder::GenerateCircuit() 874{ 875 GateRef glue = PtrArgument(0); 876 GateRef obj = TaggedArgument(1); 877 GateRef offset = PtrArgument(2); // 2 : 3rd para 878 GateRef value = TaggedArgument(3); // 3 : 4th para 879 SetValueWithBarrier(glue, obj, offset, value, true, MemoryAttribute::NON_SHARE); 880 Return(); 881} 882 883void SetSValueWithBarrierStubBuilder::GenerateCircuit() 884{ 885 GateRef glue = PtrArgument(0); 886 GateRef obj = TaggedArgument(1); 887 GateRef offset = PtrArgument(2); // 2 : 3rd para 888 GateRef value = TaggedArgument(3); // 3 : 4th para 889 SetValueWithBarrier(glue, obj, offset, value, false, MemoryAttribute::SHARED); 890 Return(); 891} 892 893void VerifyBarrierStubBuilder::GenerateCircuit() 894{ 895 GateRef glue = PtrArgument(0); 896 GateRef obj = TaggedArgument(1); 897 GateRef offset = PtrArgument(2); // 2 : 3rd para 898 GateRef value = TaggedArgument(3); // 3 : 4th para 899 VerifyBarrier(glue, obj, offset, value); 900 Return(); 901} 902 903void NewThisObjectCheckedStubBuilder::GenerateCircuit() 904{ 905 GateRef glue = PtrArgument(0); 906 GateRef ctor = TaggedArgument(1); 907 NewObjectStubBuilder newBuilder(this); 908 Return(newBuilder.NewThisObjectChecked(glue, ctor)); 909} 910 911void ConstructorCheckStubBuilder::GenerateCircuit() 912{ 913 GateRef glue = PtrArgument(0); 914 GateRef ctor = TaggedArgument(1); 915 GateRef value = TaggedArgument(2); // 2 : 3rd para 916 GateRef thisObj = TaggedArgument(3); // 3 : 4th para 917 Return(ConstructorCheck(glue, ctor, value, thisObj)); 918} 919 920void CreateEmptyArrayStubBuilder::GenerateCircuit() 921{ 922 GateRef glue = PtrArgument(0); 923 NewObjectStubBuilder newBuilder(this); 924 Return(newBuilder.CreateEmptyArray(glue)); 925} 926 927void CreateArrayWithBufferStubBuilder::GenerateCircuit() 928{ 929 GateRef glue = PtrArgument(0); 930 GateRef index = Int32Argument(1); 931 GateRef jsFunc = TaggedArgument(2); // 2 : 3rd para 932 GateRef slotId = Int32Argument(5); // 5 : 6th para 933 NewObjectStubBuilder newBuilder(this); 934 Return(newBuilder.CreateArrayWithBuffer( 935 glue, index, jsFunc, { IntPtr(0), 0, true }, Undefined(), slotId, ProfileOperation())); 936} 937 938void NewJSObjectStubBuilder::GenerateCircuit() 939{ 940 GateRef glue = PtrArgument(0); 941 GateRef ctor = TaggedArgument(1); 942 NewObjectStubBuilder newBuilder(this); 943 Return(newBuilder.FastNewThisObject(glue, ctor)); 944} 945 946void JsBoundCallInternalStubBuilder::GenerateCircuit() 947{ 948 auto env = GetEnvironment(); 949 Label exit(env); 950 Label fastCall(env); 951 Label notFastCall(env); 952 Label methodIsFastCall(env); 953 Label fastCallBridge(env); 954 Label slowCall(env); 955 Label slowCallBridge(env); 956 957 GateRef glue = PtrArgument(0); 958 GateRef argc = Int64Argument(1); 959 GateRef func = TaggedPointerArgument(2); // callTarget 960 GateRef argv = PtrArgument(3); 961 GateRef thisValue = TaggedPointerArgument(4); // this 962 GateRef newTarget = TaggedPointerArgument(5); // new target 963 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined()); 964 GateRef method = GetMethodFromFunction(func); 965 GateRef callfield = Load(VariableType::INT64(), method, IntPtr(Method::CALL_FIELD_OFFSET)); 966 GateRef expectedNum = Int64And(Int64LSR(callfield, Int64(MethodLiteral::NumArgsBits::START_BIT)), 967 Int64((1LU << MethodLiteral::NumArgsBits::SIZE) - 1)); 968 GateRef expectedArgc = Int64Add(expectedNum, Int64(NUM_MANDATORY_JSFUNC_ARGS)); 969 GateRef actualArgc = Int64Sub(argc, IntPtr(NUM_MANDATORY_JSFUNC_ARGS)); 970 BRANCH(JudgeAotAndFastCall(func, CircuitBuilder::JudgeMethodType::HAS_AOT_FASTCALL), 971 &methodIsFastCall, ¬FastCall); 972 Bind(&methodIsFastCall); 973 { 974 BRANCH(Int64Equal(expectedArgc, argc), &fastCall, &fastCallBridge); 975 Bind(&fastCall); 976 { 977 result = CallNGCRuntime(glue, RTSTUB_ID(JSFastCallWithArgV), 978 { glue, func, thisValue, actualArgc, argv }); 979 Jump(&exit); 980 } 981 Bind(&fastCallBridge); 982 { 983 result = CallNGCRuntime(glue, RTSTUB_ID(JSFastCallWithArgVAndPushArgv), 984 { glue, func, thisValue, actualArgc, argv, expectedNum }); 985 Jump(&exit); 986 } 987 } 988 Bind(¬FastCall); 989 { 990 BRANCH(Int64Equal(expectedArgc, argc), &slowCall, &slowCallBridge); 991 Bind(&slowCall); 992 { 993 result = CallNGCRuntime(glue, RTSTUB_ID(JSCallWithArgV), 994 { glue, actualArgc, func, newTarget, thisValue, argv }); 995 Jump(&exit); 996 } 997 Bind(&slowCallBridge); 998 { 999 result = CallNGCRuntime(glue, RTSTUB_ID(JSCallWithArgVAndPushArgv), 1000 { glue, actualArgc, func, newTarget, thisValue, argv }); 1001 Jump(&exit); 1002 } 1003 } 1004 Bind(&exit); 1005 Return(*result); 1006} 1007 1008void GetSingleCharCodeByIndexStubBuilder::GenerateCircuit() 1009{ 1010 GateRef str = TaggedArgument(1); 1011 GateRef index = Int32Argument(2); 1012 BuiltinsStringStubBuilder builder(this); 1013 GateRef result = builder.GetSingleCharCodeByIndex(str, index); 1014 Return(result); 1015} 1016 1017void CreateStringBySingleCharCodeStubBuilder::GenerateCircuit() 1018{ 1019 GateRef glue = PtrArgument(0); 1020 GateRef charCode = Int32Argument(1); 1021 BuiltinsStringStubBuilder builder(this); 1022 GateRef result = builder.CreateStringBySingleCharCode(glue, charCode); 1023 Return(result); 1024} 1025 1026void FastStringEqualStubBuilder::GenerateCircuit() 1027{ 1028 auto env = GetEnvironment(); 1029 GateRef glue = PtrArgument(0); 1030 GateRef str1 = TaggedArgument(1); 1031 GateRef str2 = Int32Argument(2); 1032 1033 Label leftEqualRight(env); 1034 Label leftNotEqualRight(env); 1035 Label exit(env); 1036 DEFVARIABLE(result, VariableType::BOOL(), False()); 1037 BRANCH(Equal(str1, str2), &leftEqualRight, &leftNotEqualRight); 1038 Bind(&leftEqualRight); 1039 { 1040 result = True(); 1041 Jump(&exit); 1042 } 1043 Bind(&leftNotEqualRight); 1044 { 1045 result = FastStringEqual(glue, str1, str2); 1046 Jump(&exit); 1047 } 1048 Bind(&exit); 1049 Return(*result); 1050} 1051 1052void FastStringAddStubBuilder::GenerateCircuit() 1053{ 1054 GateRef glue = PtrArgument(0); 1055 GateRef str1 = TaggedArgument(1); 1056 GateRef str2 = Int32Argument(2); 1057 1058 BuiltinsStringStubBuilder builtinsStringStubBuilder(this); 1059 GateRef result = builtinsStringStubBuilder.StringConcat(glue, str1, str2); 1060 Return(result); 1061} 1062 1063void DeleteObjectPropertyStubBuilder::GenerateCircuit() 1064{ 1065 GateRef glue = PtrArgument(0); 1066 GateRef object = TaggedArgument(1); 1067 GateRef prop = TaggedArgument(2); 1068 GateRef result = DeletePropertyOrThrow(glue, object, prop); 1069 Return(result); 1070} 1071 1072void GetpropiteratorStubBuilder::GenerateCircuit() 1073{ 1074 GateRef glue = PtrArgument(0); 1075 GateRef object = TaggedArgument(1); 1076 NewObjectStubBuilder newBuilder(this); 1077 GateRef result = newBuilder.EnumerateObjectProperties(glue, object); 1078 Return(result); 1079} 1080 1081void GetnextpropnameStubBuilder::GenerateCircuit() 1082{ 1083 GateRef glue = PtrArgument(0); 1084 GateRef iter = TaggedArgument(1); 1085 GateRef result = NextInternal(glue, iter); 1086 Return(result); 1087} 1088 1089#define CREATE_ITERATOR_STUB_BUILDER(name, collection, iterationKind) \ 1090void name##StubBuilder::GenerateCircuit() \ 1091{ \ 1092 auto env = GetEnvironment(); \ 1093 Label exit(env); \ 1094 \ 1095 GateRef glue = PtrArgument(0); \ 1096 GateRef obj = TaggedArgument(1); \ 1097 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined()); \ 1098 \ 1099 NewObjectStubBuilder newBuilder(this); \ 1100 newBuilder.SetGlue(glue); \ 1101 GateRef kind = Int32(static_cast<int32_t>(IterationKind::iterationKind)); \ 1102 newBuilder.CreateJSCollectionIterator<JS##collection##Iterator, JS##collection>(&result, &exit, obj, kind); \ 1103 Bind(&exit); \ 1104 Return(*result); \ 1105} 1106 1107CREATE_ITERATOR_STUB_BUILDER(CreateJSSetIterator, Set, VALUE) 1108CREATE_ITERATOR_STUB_BUILDER(JSSetEntries, Set, KEY_AND_VALUE) 1109CREATE_ITERATOR_STUB_BUILDER(JSMapKeys, Map, KEY) 1110CREATE_ITERATOR_STUB_BUILDER(JSMapValues, Map, VALUE) 1111CREATE_ITERATOR_STUB_BUILDER(CreateJSMapIterator, Map, KEY_AND_VALUE) 1112 1113void StringIteratorNextStubBuilder::GenerateCircuit() 1114{ 1115 auto env = GetEnvironment(); \ 1116 Label exit(env); 1117 Label slowpath(env); 1118 1119 GateRef glue = PtrArgument(0); 1120 GateRef obj = TaggedArgument(1); 1121 1122 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined()); 1123 1124 BuiltinsStringStubBuilder builder(this); 1125 builder.StringIteratorNext(glue, obj, Gate::InvalidGateRef, &result, &exit, &slowpath); 1126 Bind(&slowpath); 1127 { 1128 result = CallRuntime(glue, RTSTUB_ID(StringIteratorNext), { obj }); 1129 Jump(&exit); 1130 } 1131 Bind(&exit); 1132 Return(*result); 1133} 1134 1135void JSMapGetStubBuilder::GenerateCircuit() 1136{ 1137 GateRef glue = PtrArgument(0); 1138 GateRef obj = TaggedArgument(1); 1139 GateRef key = TaggedArgument(2U); 1140 1141 LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> builder(this, glue); 1142 GateRef linkedTable = builder.GetLinked(obj); 1143 Return(builder.Get(linkedTable, key)); 1144} 1145 1146void JSMapHasStubBuilder::GenerateCircuit() 1147{ 1148 GateRef glue = PtrArgument(0); 1149 GateRef obj = TaggedArgument(1); 1150 GateRef key = TaggedArgument(2U); 1151 1152 LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> builder(this, glue); 1153 GateRef linkedTable = builder.GetLinked(obj); 1154 Return(builder.Has(linkedTable, key)); 1155} 1156 1157void JSSetHasStubBuilder::GenerateCircuit() 1158{ 1159 GateRef glue = PtrArgument(0); 1160 GateRef obj = TaggedArgument(1); 1161 GateRef key = TaggedArgument(2U); 1162 1163 LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> builder(this, glue); 1164 GateRef linkedTable = builder.GetLinked(obj); 1165 Return(builder.Has(linkedTable, key)); 1166} 1167 1168void CreateJSTypedArrayEntriesStubBuilder::GenerateCircuit() 1169{ 1170 auto env = GetEnvironment(); 1171 Label exit(env); 1172 1173 GateRef glue = PtrArgument(0); 1174 GateRef obj = TaggedArgument(1); 1175 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined()); 1176 1177 NewObjectStubBuilder newBuilder(this); 1178 newBuilder.SetGlue(glue); 1179 GateRef kind = Int32(static_cast<int32_t>(IterationKind::KEY_AND_VALUE)); 1180 newBuilder.CreateJSTypedArrayIterator(&result, &exit, obj, kind); 1181 Bind(&exit); 1182 Return(*result); 1183} 1184 1185void CreateJSTypedArrayKeysStubBuilder::GenerateCircuit() 1186{ 1187 auto env = GetEnvironment(); 1188 Label exit(env); 1189 1190 GateRef glue = PtrArgument(0); 1191 GateRef obj = TaggedArgument(1); 1192 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined()); 1193 1194 NewObjectStubBuilder newBuilder(this); 1195 newBuilder.SetGlue(glue); 1196 GateRef kind = Int32(static_cast<int32_t>(IterationKind::KEY)); 1197 newBuilder.CreateJSTypedArrayIterator(&result, &exit, obj, kind); 1198 Bind(&exit); 1199 Return(*result); 1200} 1201 1202void CreateJSTypedArrayValuesStubBuilder::GenerateCircuit() 1203{ 1204 auto env = GetEnvironment(); 1205 Label exit(env); 1206 1207 GateRef glue = PtrArgument(0); 1208 GateRef obj = TaggedArgument(1); 1209 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined()); 1210 1211 NewObjectStubBuilder newBuilder(this); 1212 newBuilder.SetGlue(glue); 1213 GateRef kind = Int32(static_cast<int32_t>(IterationKind::VALUE)); 1214 newBuilder.CreateJSTypedArrayIterator(&result, &exit, obj, kind); 1215 Bind(&exit); 1216 Return(*result); 1217} 1218 1219void JSMapDeleteStubBuilder::GenerateCircuit() 1220{ 1221 GateRef glue = PtrArgument(0); 1222 GateRef obj = TaggedArgument(1); 1223 GateRef key = TaggedArgument(2U); 1224 1225 LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> builder(this, glue); 1226 GateRef linkedTable = builder.GetLinked(obj); 1227 Return(builder.Delete(linkedTable, key)); 1228} 1229 1230void JSSetDeleteStubBuilder::GenerateCircuit() 1231{ 1232 GateRef glue = PtrArgument(0); 1233 GateRef obj = TaggedArgument(1); 1234 GateRef key = TaggedArgument(2U); 1235 1236 LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> builder(this, glue); 1237 GateRef linkedTable = builder.GetLinked(obj); 1238 Return(builder.Delete(linkedTable, key)); 1239} 1240 1241void JSSetAddStubBuilder::GenerateCircuit() 1242{ 1243 GateRef glue = PtrArgument(0); 1244 GateRef obj = TaggedArgument(1); 1245 GateRef key = TaggedArgument(2U); 1246 1247 LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> builder(this, glue); 1248 GateRef linkedTable = builder.GetLinked(obj); 1249 GateRef newTable = builder.Insert(linkedTable, key, key); 1250 builder.Store(VariableType::JS_ANY(), glue, obj, IntPtr(JSSet::LINKED_SET_OFFSET), newTable); 1251 Return(obj); 1252} 1253 1254void SameValueStubBuilder::GenerateCircuit() 1255{ 1256 GateRef glue = PtrArgument(0); 1257 GateRef left = TaggedArgument(1); 1258 GateRef right = TaggedArgument(2U); 1259 GateRef result = SameValue(glue, left, right); 1260 Return(result); 1261} 1262 1263CallSignature CommonStubCSigns::callSigns_[CommonStubCSigns::NUM_OF_STUBS]; 1264 1265void CommonStubCSigns::Initialize() 1266{ 1267#define INIT_SIGNATURES(name) \ 1268 name##CallSignature::Initialize(&callSigns_[name]); \ 1269 callSigns_[name].SetID(name); \ 1270 callSigns_[name].SetName(std::string("COStub_") + #name); \ 1271 callSigns_[name].SetConstructor( \ 1272 [](void* env) { \ 1273 return static_cast<void*>( \ 1274 new name##StubBuilder(&callSigns_[name], static_cast<Environment*>(env))); \ 1275 }); 1276 1277 COMMON_STUB_ID_LIST(INIT_SIGNATURES) 1278#undef INIT_SIGNATURES 1279} 1280 1281void CommonStubCSigns::GetCSigns(std::vector<const CallSignature*>& outCSigns) 1282{ 1283 for (size_t i = 0; i < NUM_OF_STUBS; i++) { 1284 outCSigns.push_back(&callSigns_[i]); 1285 } 1286} 1287} // namespace panda::ecmascript::kungfu 1288