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
37 namespace panda::ecmascript::kungfu {
38 using namespace panda::ecmascript;
39
GenerateCircuit()40 void 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
GenerateCircuit()49 void 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
GenerateCircuit()58 void 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
GenerateCircuit()67 void 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
GenerateCircuit()91 void 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
GenerateCircuit()105 void 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
GenerateCircuit()119 void 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
GenerateCircuit()128 void 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
GenerateCircuit()137 void 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
GenerateCircuit()146 void TypeOfStubBuilder::GenerateCircuit()
147 {
148 GateRef glue = PtrArgument(0);
149 GateRef obj = TaggedArgument(1);
150 Return(FastTypeOf(glue, obj));
151 }
152
GenerateCircuit()153 void 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
GenerateCircuit()162 void 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
GenerateCircuit()171 void 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
GenerateCircuit()180 void 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
GenerateCircuit()189 void 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
GenerateCircuit()198 void 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
GenerateCircuit()207 void 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
GenerateCircuit()216 void 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
GenerateCircuit()225 void 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
GenerateCircuit()234 void 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
GenerateCircuit()243 void 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
GenerateCircuit()252 void 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
GenerateCircuit()261 void 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
GenerateCircuit()270 void 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
GenerateCircuit()279 void 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
GenerateCircuit()290 void 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
GenerateCircuit()298 void 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
GenerateCircuit()306 void 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
GenerateCircuit()314 void 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
GenerateCircuit()322 void ToBooleanTrueStubBuilder::GenerateCircuit()
323 {
324 GateRef glue = PtrArgument(0);
325 (void)glue;
326 GateRef x = TaggedArgument(1);
327 Return(FastToBoolean(x, true));
328 }
329
GenerateCircuit()330 void ToBooleanFalseStubBuilder::GenerateCircuit()
331 {
332 GateRef glue = PtrArgument(0);
333 (void)glue;
334 GateRef x = TaggedArgument(1);
335 Return(FastToBoolean(x, false));
336 }
337
GenerateCircuit()338 void 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
GenerateCircuit()354 void 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
GenerateCircuit()392 void 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
GenerateCircuit()428 void GetCallSpreadArgsStubBuilder::GenerateCircuit()
429 {
430 GateRef glue = PtrArgument(0);
431 GateRef array = TaggedArgument(1);
432 Return(GetCallSpreadArgs(glue, array, ProfileOperation()));
433 }
434
GenerateCircuit()435 void 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
GenerateCircuit()443 void 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
GenerateCircuit()452 void 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
GenerateCircuit()461 void 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
GenerateCircuit()474 void 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
GenerateCircuit()483 void 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
GenerateCircuit()497 void 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
GenerateCircuit()506 void 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
GenerateCircuit()515 void 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
GenerateCircuit()527 void 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
GenerateCircuit()535 void 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
GenerateCircuit()548 void 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
GenerateCircuit()557 void 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
GenerateCircuit()566 void 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
GenerateCircuit()576 void 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
GenerateCircuit()586 void 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
GenerateCircuit()596 void 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
GenerateCircuit()606 void 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
GenerateCircuit()616 void 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
GenerateCircuit()625 void 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
GenerateCircuit()635 void 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
GenerateCircuit()647 void 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
GenerateCircuit()660 void 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
GenerateCircuit()672 void 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
GenerateCircuit()685 void 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
GenerateCircuit()725 void 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
GenerateCircuit()765 void 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
GenerateCircuit()803 void 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
GenerateCircuit()843 void 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
GenerateCircuit()853 void 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
GenerateCircuit()863 void 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
GenerateCircuit()873 void 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
GenerateCircuit()883 void 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
GenerateCircuit()893 void 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
GenerateCircuit()903 void 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
GenerateCircuit()911 void 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
GenerateCircuit()920 void CreateEmptyArrayStubBuilder::GenerateCircuit()
921 {
922 GateRef glue = PtrArgument(0);
923 NewObjectStubBuilder newBuilder(this);
924 Return(newBuilder.CreateEmptyArray(glue));
925 }
926
GenerateCircuit()927 void 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
GenerateCircuit()938 void 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
GenerateCircuit()946 void 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
GenerateCircuit()1008 void 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
GenerateCircuit()1017 void 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
GenerateCircuit()1026 void 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
GenerateCircuit()1052 void 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
GenerateCircuit()1063 void 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
GenerateCircuit()1072 void 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
GenerateCircuit()1081 void 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) \
1090 void 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
1107 CREATE_ITERATOR_STUB_BUILDER(CreateJSSetIterator, Set, VALUE)
1108 CREATE_ITERATOR_STUB_BUILDER(JSSetEntries, Set, KEY_AND_VALUE)
1109 CREATE_ITERATOR_STUB_BUILDER(JSMapKeys, Map, KEY)
1110 CREATE_ITERATOR_STUB_BUILDER(JSMapValues, Map, VALUE)
1111 CREATE_ITERATOR_STUB_BUILDER(CreateJSMapIterator, Map, KEY_AND_VALUE)
1112
GenerateCircuit()1113 void 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
GenerateCircuit()1135 void 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
GenerateCircuit()1146 void 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
GenerateCircuit()1157 void 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
GenerateCircuit()1168 void 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
GenerateCircuit()1185 void 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
GenerateCircuit()1202 void 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
GenerateCircuit()1219 void 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
GenerateCircuit()1230 void 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
GenerateCircuit()1241 void 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
GenerateCircuit()1254 void 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
1263 CallSignature CommonStubCSigns::callSigns_[CommonStubCSigns::NUM_OF_STUBS];
1264
Initialize()1265 void 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
GetCSigns(std::vector<const CallSignature*>& outCSigns)1281 void 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