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, &notFastCall);
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(&notFastCall);
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