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