• 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/base/number_helper.h"
19 #include "ecmascript/compiler/access_object_stub_builder.h"
20 #include "ecmascript/compiler/interpreter_stub.h"
21 #include "ecmascript/compiler/llvm_ir_builder.h"
22 #include "ecmascript/compiler/new_object_stub_builder.h"
23 #include "ecmascript/compiler/operations_stub_builder.h"
24 #include "ecmascript/compiler/stub_builder-inl.h"
25 #include "ecmascript/compiler/variable_type.h"
26 #include "ecmascript/js_array.h"
27 #include "ecmascript/message_string.h"
28 #include "ecmascript/tagged_hash_table.h"
29 
30 namespace panda::ecmascript::kungfu {
31 using namespace panda::ecmascript;
32 
GenerateCircuit()33 void AddStubBuilder::GenerateCircuit()
34 {
35     GateRef glue = PtrArgument(0);
36     GateRef x = TaggedArgument(1);
37     GateRef y = TaggedArgument(2);
38     OperationsStubBuilder operationBuilder(this);
39     Return(operationBuilder.Add(glue, x, y));
40 }
41 
GenerateCircuit()42 void SubStubBuilder::GenerateCircuit()
43 {
44     GateRef glue = PtrArgument(0);
45     GateRef x = TaggedArgument(1);
46     GateRef y = TaggedArgument(2);
47     OperationsStubBuilder operationBuilder(this);
48     Return(operationBuilder.Sub(glue, x, y));
49 }
50 
GenerateCircuit()51 void MulStubBuilder::GenerateCircuit()
52 {
53     GateRef glue = PtrArgument(0);
54     GateRef x = TaggedArgument(1);
55     GateRef y = TaggedArgument(2);
56     OperationsStubBuilder operationBuilder(this);
57     Return(operationBuilder.Mul(glue, x, y));
58 }
59 
GenerateCircuit()60 void DivStubBuilder::GenerateCircuit()
61 {
62     GateRef glue = PtrArgument(0);
63     GateRef x = TaggedArgument(1);
64     GateRef y = TaggedArgument(2);
65     OperationsStubBuilder operationBuilder(this);
66     Return(operationBuilder.Div(glue, x, y));
67 }
68 
GenerateCircuit()69 void ModStubBuilder::GenerateCircuit()
70 {
71     GateRef glue = PtrArgument(0);
72     GateRef x = TaggedArgument(1);
73     GateRef y = TaggedArgument(2); // 2: 3rd argument
74     OperationsStubBuilder operationBuilder(this);
75     Return(operationBuilder.Mod(glue, x, y));
76 }
77 
GenerateCircuit()78 void TypeOfStubBuilder::GenerateCircuit()
79 {
80     GateRef glue = PtrArgument(0);
81     GateRef obj = TaggedArgument(1);
82     Return(FastTypeOf(glue, obj));
83 }
84 
GenerateCircuit()85 void EqualStubBuilder::GenerateCircuit()
86 {
87     GateRef glue = PtrArgument(0);
88     GateRef x = TaggedArgument(1);
89     GateRef y = TaggedArgument(2); // 2: 3rd argument
90     OperationsStubBuilder operationBuilder(this);
91     Return(operationBuilder.Equal(glue, x, y));
92 }
93 
GenerateCircuit()94 void NotEqualStubBuilder::GenerateCircuit()
95 {
96     GateRef glue = PtrArgument(0);
97     GateRef x = TaggedArgument(1);
98     GateRef y = TaggedArgument(2); // 2: 3rd argument
99     OperationsStubBuilder operationBuilder(this);
100     Return(operationBuilder.NotEqual(glue, x, y));
101 }
102 
GenerateCircuit()103 void LessStubBuilder::GenerateCircuit()
104 {
105     GateRef glue = PtrArgument(0);
106     GateRef x = TaggedArgument(1);
107     GateRef y = TaggedArgument(2); // 2: 3rd argument
108     OperationsStubBuilder operationBuilder(this);
109     Return(operationBuilder.Less(glue, x, y));
110 }
111 
GenerateCircuit()112 void LessEqStubBuilder::GenerateCircuit()
113 {
114     GateRef glue = PtrArgument(0);
115     GateRef x = TaggedArgument(1);
116     GateRef y = TaggedArgument(2); // 2: 3rd argument
117     OperationsStubBuilder operationBuilder(this);
118     Return(operationBuilder.LessEq(glue, x, y));
119 }
120 
GenerateCircuit()121 void GreaterStubBuilder::GenerateCircuit()
122 {
123     GateRef glue = PtrArgument(0);
124     GateRef x = TaggedArgument(1);
125     GateRef y = TaggedArgument(2); // 2: 3rd argument
126     OperationsStubBuilder operationBuilder(this);
127     Return(operationBuilder.Greater(glue, x, y));
128 }
129 
GenerateCircuit()130 void GreaterEqStubBuilder::GenerateCircuit()
131 {
132     GateRef glue = PtrArgument(0);
133     GateRef x = TaggedArgument(1);
134     GateRef y = TaggedArgument(2); // 2: 3rd argument
135     OperationsStubBuilder operationBuilder(this);
136     Return(operationBuilder.GreaterEq(glue, x, y));
137 }
138 
GenerateCircuit()139 void ShlStubBuilder::GenerateCircuit()
140 {
141     GateRef glue = PtrArgument(0);
142     GateRef x = TaggedArgument(1);
143     GateRef y = TaggedArgument(2); // 2: 3rd argument
144     OperationsStubBuilder operationBuilder(this);
145     Return(operationBuilder.Shl(glue, x, y));
146 }
147 
GenerateCircuit()148 void ShrStubBuilder::GenerateCircuit()
149 {
150     GateRef glue = PtrArgument(0);
151     GateRef x = TaggedArgument(1);
152     GateRef y = TaggedArgument(2); // 2: 3rd argument
153     OperationsStubBuilder operationBuilder(this);
154     Return(operationBuilder.Shr(glue, x, y));
155 }
156 
GenerateCircuit()157 void AshrStubBuilder::GenerateCircuit()
158 {
159     GateRef glue = PtrArgument(0);
160     GateRef x = TaggedArgument(1);
161     GateRef y = TaggedArgument(2); // 2: 3rd argument
162     OperationsStubBuilder operationBuilder(this);
163     Return(operationBuilder.Ashr(glue, x, y));
164 }
165 
GenerateCircuit()166 void AndStubBuilder::GenerateCircuit()
167 {
168     GateRef glue = PtrArgument(0);
169     GateRef x = TaggedArgument(1);
170     GateRef y = TaggedArgument(2); // 2: 3rd argument
171     OperationsStubBuilder operationBuilder(this);
172     Return(operationBuilder.And(glue, x, y));
173 }
174 
GenerateCircuit()175 void OrStubBuilder::GenerateCircuit()
176 {
177     GateRef glue = PtrArgument(0);
178     GateRef x = TaggedArgument(1);
179     GateRef y = TaggedArgument(2); // 2: 3rd argument
180     OperationsStubBuilder operationBuilder(this);
181     Return(operationBuilder.Or(glue, x, y));
182 }
183 
GenerateCircuit()184 void XorStubBuilder::GenerateCircuit()
185 {
186     GateRef glue = PtrArgument(0);
187     GateRef x = TaggedArgument(1);
188     GateRef y = TaggedArgument(2); // 2: 3rd argument
189     OperationsStubBuilder operationBuilder(this);
190     Return(operationBuilder.Xor(glue, x, y));
191 }
192 
GenerateCircuit()193 void InstanceofStubBuilder::GenerateCircuit()
194 {
195     GateRef glue = PtrArgument(0);
196     GateRef x = TaggedArgument(1);
197     GateRef y = TaggedArgument(2); // 2: 3rd argument
198     Return(InstanceOf(glue, x, y));
199 }
200 
GenerateCircuit()201 void IncStubBuilder::GenerateCircuit()
202 {
203     GateRef glue = PtrArgument(0);
204     GateRef x = TaggedArgument(1);
205     OperationsStubBuilder operationBuilder(this);
206     Return(operationBuilder.Inc(glue, x));
207 }
208 
GenerateCircuit()209 void DecStubBuilder::GenerateCircuit()
210 {
211     GateRef glue = PtrArgument(0);
212     GateRef x = TaggedArgument(1);
213     OperationsStubBuilder operationBuilder(this);
214     Return(operationBuilder.Dec(glue, x));
215 }
216 
GenerateCircuit()217 void NegStubBuilder::GenerateCircuit()
218 {
219     GateRef glue = PtrArgument(0);
220     GateRef x = TaggedArgument(1);
221     OperationsStubBuilder operationBuilder(this);
222     Return(operationBuilder.Neg(glue, x));
223 }
224 
GenerateCircuit()225 void NotStubBuilder::GenerateCircuit()
226 {
227     GateRef glue = PtrArgument(0);
228     GateRef x = TaggedArgument(1);
229     OperationsStubBuilder operationBuilder(this);
230     Return(operationBuilder.Not(glue, x));
231 }
232 
GenerateCircuit()233 void ToBooleanStubBuilder::GenerateCircuit()
234 {
235     GateRef glue = PtrArgument(0);
236     (void)glue;
237     GateRef x = TaggedArgument(1);
238     Return(FastToBoolean(x));
239 }
240 
GenerateCircuit()241 void NewLexicalEnvStubBuilder::GenerateCircuit()
242 {
243     auto env = GetEnvironment();
244     GateRef glue = PtrArgument(0);
245     GateRef parent = TaggedArgument(1);
246     GateRef numVars = Int32Argument(2); /* 2 : 3rd parameter is index */
247 
248     DEFVARIABLE(result, VariableType::JS_ANY(), Hole());
249     NewObjectStubBuilder newBuilder(this);
250     newBuilder.SetParameters(glue, 0);
251     Label afterNew(env);
252     newBuilder.NewLexicalEnv(&result, &afterNew, numVars, parent);
253     Bind(&afterNew);
254     Return(*result);
255 }
256 
GenerateCircuit()257 void GetUnmapedArgsStubBuilder::GenerateCircuit()
258 {
259     auto env = GetEnvironment();
260     GateRef glue = PtrArgument(0);
261     GateRef numArgs = Int32Argument(1);
262 
263     DEFVARIABLE(argumentsList, VariableType::JS_ANY(), Hole());
264     DEFVARIABLE(argumentsObj, VariableType::JS_ANY(), Hole());
265     Label afterArgumentsList(env);
266     Label newArgumentsObj(env);
267     Label exit(env);
268 
269     GateRef argv = CallNGCRuntime(glue, RTSTUB_ID(GetActualArgvNoGC), { glue });
270     GateRef args = PtrAdd(argv, IntPtr(NUM_MANDATORY_JSFUNC_ARGS * 8)); // 8: ptr size
271     GateRef actualArgc = Int32Sub(numArgs, Int32(NUM_MANDATORY_JSFUNC_ARGS));
272     GateRef startIdx = Int32(0);
273     NewObjectStubBuilder newBuilder(this);
274     newBuilder.SetParameters(glue, 0);
275     newBuilder.NewArgumentsList(&argumentsList, &afterArgumentsList, args, startIdx, actualArgc);
276     Bind(&afterArgumentsList);
277     Branch(TaggedIsException(*argumentsList), &exit, &newArgumentsObj);
278     Bind(&newArgumentsObj);
279     newBuilder.NewArgumentsObj(&argumentsObj, &exit, *argumentsList, actualArgc);
280     Bind(&exit);
281     Return(*argumentsObj);
282 }
283 
GenerateCircuit()284 void GetPropertyByIndexStubBuilder::GenerateCircuit()
285 {
286     GateRef glue = PtrArgument(0);
287     GateRef receiver = TaggedArgument(1);
288     GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */
289     Return(GetPropertyByIndex(glue, receiver, index));
290 }
291 
GenerateCircuit()292 void SetPropertyByIndexStubBuilder::GenerateCircuit()
293 {
294     GateRef glue = PtrArgument(0);
295     GateRef receiver = TaggedArgument(1);
296     GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */
297     GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
298     Return(SetPropertyByIndex(glue, receiver, index, value, false));
299 }
300 
GenerateCircuit()301 void SetPropertyByIndexWithOwnStubBuilder::GenerateCircuit()
302 {
303     GateRef glue = PtrArgument(0);
304     GateRef receiver = TaggedArgument(1);
305     GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */
306     GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
307     Return(SetPropertyByIndex(glue, receiver, index, value, true));
308 }
309 
GenerateCircuit()310 void GetPropertyByNameStubBuilder::GenerateCircuit()
311 {
312     GateRef glue = PtrArgument(0);
313     GateRef receiver = TaggedArgument(1);
314     GateRef prop = TaggedPointerArgument(2); // 2 : 3rd para
315     GateRef profileTypeInfo = TaggedPointerArgument(3); // 3 : 4th para
316     GateRef slotId = Int32Argument(4); // 4 : 5th para
317     AccessObjectStubBuilder builder(this);
318     StringIdInfo info = { 0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID };
319     Return(builder.LoadObjByName(glue, receiver, prop, info, profileTypeInfo, slotId));
320 }
321 
GenerateCircuit()322 void DeprecatedGetPropertyByNameStubBuilder::GenerateCircuit()
323 {
324     GateRef glue = PtrArgument(0);
325     GateRef receiver = TaggedArgument(1);
326     GateRef key = TaggedPointerArgument(2); // 2 : 3rd para
327     AccessObjectStubBuilder builder(this);
328     Return(builder.DeprecatedLoadObjByName(glue, receiver, key));
329 }
330 
GenerateCircuit()331 void SetPropertyByNameStubBuilder::GenerateCircuit()
332 {
333     GateRef glue = PtrArgument(0);
334     GateRef receiver = TaggedArgument(1);
335     GateRef prop = TaggedArgument(2); // 2 : 3rd para
336     GateRef value = TaggedPointerArgument(3); // 3 : 4th para
337     GateRef profileTypeInfo = TaggedPointerArgument(4); // 4 : 5th para
338     GateRef slotId = Int32Argument(5); // 5 : 6th para
339     AccessObjectStubBuilder builder(this);
340     StringIdInfo info = { 0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID };
341     Return(builder.StoreObjByName(glue, receiver, prop, info, value, profileTypeInfo, slotId));
342 }
343 
GenerateCircuit()344 void DeprecatedSetPropertyByNameStubBuilder::GenerateCircuit()
345 {
346     GateRef glue = PtrArgument(0);
347     GateRef receiver = TaggedArgument(1);
348     GateRef key = TaggedArgument(2); // 2 : 3rd para
349     GateRef value = TaggedArgument(3); // 3 : 4th para
350     Return(SetPropertyByName(glue, receiver, key, value, false));
351 }
352 
GenerateCircuit()353 void SetPropertyByNameWithOwnStubBuilder::GenerateCircuit()
354 {
355     GateRef glue = PtrArgument(0);
356     GateRef receiver = TaggedArgument(1);
357     GateRef key = TaggedArgument(2); // 2 : 3rd para
358     GateRef value = TaggedArgument(3); // 3 : 4th para
359     Return(SetPropertyByName(glue, receiver, key, value, true));
360 }
361 
GenerateCircuit()362 void GetPropertyByValueStubBuilder::GenerateCircuit()
363 {
364     GateRef glue = PtrArgument(0);
365     GateRef receiver = TaggedArgument(1);
366     GateRef key = TaggedArgument(2); // 2 : 3rd para
367     GateRef profileTypeInfo = TaggedPointerArgument(3); // 3 : 4th para
368     GateRef slotId = Int32Argument(4); // 4 : 5th para
369     AccessObjectStubBuilder builder(this);
370     Return(builder.LoadObjByValue(glue, receiver, key, profileTypeInfo, slotId));
371 }
372 
GenerateCircuit()373 void DeprecatedGetPropertyByValueStubBuilder::GenerateCircuit()
374 {
375     GateRef glue = PtrArgument(0);
376     GateRef receiver = TaggedArgument(1);
377     GateRef key = TaggedArgument(2); // 2 : 3rd para
378     Return(GetPropertyByValue(glue, receiver, key));
379 }
380 
GenerateCircuit()381 void SetPropertyByValueStubBuilder::GenerateCircuit()
382 {
383     GateRef glue = PtrArgument(0);
384     GateRef receiver = TaggedArgument(1);
385     GateRef key = TaggedArgument(2);              /* 2 : 3rd parameter is key */
386     GateRef value = TaggedArgument(3);            /* 3 : 4th parameter is value */
387     GateRef profileTypeInfo = TaggedPointerArgument(4); /* 4 : 5th parameter is profileTypeInfo */
388     GateRef slotId = Int32Argument(5); /* 5 : 6th parameter is slotId */
389     AccessObjectStubBuilder builder(this);
390     Return(builder.StoreObjByValue(glue, receiver, key, value, profileTypeInfo, slotId));
391 }
392 
GenerateCircuit()393 void DeprecatedSetPropertyByValueStubBuilder::GenerateCircuit()
394 {
395     GateRef glue = PtrArgument(0);
396     GateRef receiver = TaggedArgument(1);
397     GateRef key = TaggedArgument(2);              /* 2 : 3rd parameter is key */
398     GateRef value = TaggedArgument(3);            /* 3 : 4th parameter is value */
399     Return(SetPropertyByValue(glue, receiver, key, value, false));
400 }
401 
GenerateCircuit()402 void SetPropertyByValueWithOwnStubBuilder::GenerateCircuit()
403 {
404     GateRef glue = PtrArgument(0);
405     GateRef receiver = TaggedArgument(1);
406     GateRef key = TaggedArgument(2);              /* 2 : 3rd parameter is key */
407     GateRef value = TaggedArgument(3);            /* 3 : 4th parameter is value */
408     Return(SetPropertyByValue(glue, receiver, key, value, true));
409 }
410 
GenerateCircuit()411 void TryLdGlobalByNameStubBuilder::GenerateCircuit()
412 {
413     GateRef glue = PtrArgument(0);
414     GateRef prop = TaggedPointerArgument(1);
415     GateRef profileTypeInfo = TaggedPointerArgument(2); // 2 : 3rd para
416     GateRef slotId = Int32Argument(3); // 3 : 4th para
417     AccessObjectStubBuilder builder(this);
418     StringIdInfo info = { 0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID };
419     Return(builder.TryLoadGlobalByName(glue, prop, info, profileTypeInfo, slotId));
420 }
421 
GenerateCircuit()422 void TryStGlobalByNameStubBuilder::GenerateCircuit()
423 {
424     GateRef glue = PtrArgument(0);
425     GateRef prop = TaggedPointerArgument(1);
426     GateRef value = TaggedArgument(2); // 2 : 3rd para
427     GateRef profileTypeInfo = TaggedPointerArgument(3); // 3 : 4th para
428     GateRef slotId = Int32Argument(4);  // 4: 5th para
429     AccessObjectStubBuilder builder(this);
430     StringIdInfo info = { 0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID };
431     Return(builder.TryStoreGlobalByName(glue, prop, info, value, profileTypeInfo, slotId));
432 }
433 
GenerateCircuit()434 void LdGlobalVarStubBuilder::GenerateCircuit()
435 {
436     GateRef glue = PtrArgument(0);
437     GateRef prop = TaggedPointerArgument(1);
438     GateRef profileTypeInfo = TaggedPointerArgument(2); // 2 : 3rd para
439     GateRef slotId = Int32Argument(3); // 3 : 4th para
440     AccessObjectStubBuilder builder(this);
441     StringIdInfo info = { 0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID };
442     Return(builder.LoadGlobalVar(glue, prop, info, profileTypeInfo, slotId));
443 }
444 
GenerateCircuit()445 void StGlobalVarStubBuilder::GenerateCircuit()
446 {
447     GateRef glue = PtrArgument(0);
448     GateRef prop = TaggedPointerArgument(1);
449     GateRef value = TaggedArgument(2); // 2 : 3rd para
450     GateRef profileTypeInfo = TaggedPointerArgument(3); // 3 : 4th para
451     GateRef slotId = Int32Argument(4);  // 4: 5th para
452     AccessObjectStubBuilder builder(this);
453     StringIdInfo info = { 0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID };
454     Return(builder.StoreGlobalVar(glue, prop, info, value, profileTypeInfo, slotId));
455 }
456 
GenerateCircuit()457 void TryLoadICByNameStubBuilder::GenerateCircuit()
458 {
459     auto env = GetEnvironment();
460     GateRef glue = PtrArgument(0);
461     GateRef receiver = TaggedArgument(1);
462     GateRef firstValue = TaggedArgument(2); /* 2 : 3rd parameter is value */
463     GateRef secondValue = TaggedArgument(3); /* 3 : 4th parameter is value */
464 
465     Label receiverIsHeapObject(env);
466     Label receiverNotHeapObject(env);
467     Label hclassEqualFirstValue(env);
468     Label hclassNotEqualFirstValue(env);
469     Label cachedHandlerNotHole(env);
470     Branch(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject);
471     Bind(&receiverIsHeapObject);
472     {
473         GateRef hclass = LoadHClass(receiver);
474         Branch(Equal(LoadObjectFromWeakRef(firstValue), hclass),
475                &hclassEqualFirstValue,
476                &hclassNotEqualFirstValue);
477         Bind(&hclassEqualFirstValue);
478         {
479             Return(LoadICWithHandler(glue, receiver, receiver, secondValue));
480         }
481         Bind(&hclassNotEqualFirstValue);
482         {
483             GateRef cachedHandler = CheckPolyHClass(firstValue, hclass);
484             Branch(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole);
485             Bind(&cachedHandlerNotHole);
486             {
487                 Return(LoadICWithHandler(glue, receiver, receiver, cachedHandler));
488             }
489         }
490     }
491     Bind(&receiverNotHeapObject);
492     {
493         Return(Hole());
494     }
495 }
496 
GenerateCircuit()497 void TryLoadICByValueStubBuilder::GenerateCircuit()
498 {
499     auto env = GetEnvironment();
500     GateRef glue = PtrArgument(0);
501     GateRef receiver = TaggedArgument(1);
502     GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is value */
503     GateRef firstValue = TaggedArgument(3); /* 3 : 4th parameter is value */
504     GateRef secondValue = TaggedArgument(4); /* 4 : 5th parameter is value */
505 
506     Label receiverIsHeapObject(env);
507     Label receiverNotHeapObject(env);
508     Label hclassEqualFirstValue(env);
509     Label hclassNotEqualFirstValue(env);
510     Label firstValueEqualKey(env);
511     Label cachedHandlerNotHole(env);
512     Branch(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject);
513     Bind(&receiverIsHeapObject);
514     {
515         GateRef hclass = LoadHClass(receiver);
516         Branch(Equal(LoadObjectFromWeakRef(firstValue), hclass),
517                &hclassEqualFirstValue,
518                &hclassNotEqualFirstValue);
519         Bind(&hclassEqualFirstValue);
520         Return(LoadElement(receiver, key));
521         Bind(&hclassNotEqualFirstValue);
522         {
523             Branch(Int64Equal(firstValue, key), &firstValueEqualKey, &receiverNotHeapObject);
524             Bind(&firstValueEqualKey);
525             {
526                 auto cachedHandler = CheckPolyHClass(secondValue, hclass);
527                 Branch(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole);
528                 Bind(&cachedHandlerNotHole);
529                 Return(LoadICWithHandler(glue, receiver, receiver, cachedHandler));
530             }
531         }
532     }
533     Bind(&receiverNotHeapObject);
534     Return(Hole());
535 }
536 
GenerateCircuit()537 void TryStoreICByNameStubBuilder::GenerateCircuit()
538 {
539     auto env = GetEnvironment();
540     GateRef glue = PtrArgument(0);
541     GateRef receiver = TaggedArgument(1);
542     GateRef firstValue = TaggedArgument(2); /* 2 : 3rd parameter is value */
543     GateRef secondValue = TaggedArgument(3); /* 3 : 4th parameter is value */
544     GateRef value = TaggedArgument(4); /* 4 : 5th parameter is value */
545     Label receiverIsHeapObject(env);
546     Label receiverNotHeapObject(env);
547     Label hclassEqualFirstValue(env);
548     Label hclassNotEqualFirstValue(env);
549     Label cachedHandlerNotHole(env);
550     Branch(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject);
551     Bind(&receiverIsHeapObject);
552     {
553         GateRef hclass = LoadHClass(receiver);
554         Branch(Equal(LoadObjectFromWeakRef(firstValue), hclass),
555                &hclassEqualFirstValue,
556                &hclassNotEqualFirstValue);
557         Bind(&hclassEqualFirstValue);
558         {
559             Return(StoreICWithHandler(glue, receiver, receiver, value, secondValue));
560         }
561         Bind(&hclassNotEqualFirstValue);
562         {
563             GateRef cachedHandler = CheckPolyHClass(firstValue, hclass);
564             Branch(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole);
565             Bind(&cachedHandlerNotHole);
566             {
567                 Return(StoreICWithHandler(glue, receiver, receiver, value, cachedHandler));
568             }
569         }
570     }
571     Bind(&receiverNotHeapObject);
572     Return(Hole());
573 }
574 
GenerateCircuit()575 void TryStoreICByValueStubBuilder::GenerateCircuit()
576 {
577     auto env = GetEnvironment();
578     GateRef glue = PtrArgument(0);
579     GateRef receiver = TaggedArgument(1);
580     GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is value */
581     GateRef firstValue = TaggedArgument(3); /* 3 : 4th parameter is value */
582     GateRef secondValue = TaggedArgument(4); /* 4 : 5th parameter is value */
583     GateRef value = TaggedArgument(5); /* 5 : 6th parameter is value */
584     Label receiverIsHeapObject(env);
585     Label receiverNotHeapObject(env);
586     Label hclassEqualFirstValue(env);
587     Label hclassNotEqualFirstValue(env);
588     Label firstValueEqualKey(env);
589     Label cachedHandlerNotHole(env);
590     Branch(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject);
591     Bind(&receiverIsHeapObject);
592     {
593         GateRef hclass = LoadHClass(receiver);
594         Branch(Equal(LoadObjectFromWeakRef(firstValue), hclass),
595                &hclassEqualFirstValue,
596                &hclassNotEqualFirstValue);
597         Bind(&hclassEqualFirstValue);
598         Return(ICStoreElement(glue, receiver, key, value, secondValue));
599         Bind(&hclassNotEqualFirstValue);
600         {
601             Branch(Int64Equal(firstValue, key), &firstValueEqualKey, &receiverNotHeapObject);
602             Bind(&firstValueEqualKey);
603             {
604                 GateRef cachedHandler = CheckPolyHClass(secondValue, hclass);
605                 Branch(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole);
606                 Bind(&cachedHandlerNotHole);
607                 Return(StoreICWithHandler(glue, receiver, receiver, value, cachedHandler));
608             }
609         }
610     }
611     Bind(&receiverNotHeapObject);
612     Return(Hole());
613 }
614 
GenerateCircuit()615 void SetValueWithBarrierStubBuilder::GenerateCircuit()
616 {
617     GateRef glue = PtrArgument(0);
618     GateRef obj = TaggedArgument(1);
619     GateRef offset = PtrArgument(2); // 2 : 3rd para
620     GateRef value = TaggedArgument(3); // 3 : 4th para
621     SetValueWithBarrier(glue, obj, offset, value);
622     Return();
623 }
624 
GenerateCircuit()625 void NewThisObjectCheckedStubBuilder::GenerateCircuit()
626 {
627     GateRef glue = PtrArgument(0);
628     GateRef ctor = TaggedArgument(1);
629     NewObjectStubBuilder newBuilder(this);
630     Return(newBuilder.NewThisObjectChecked(glue, ctor));
631 }
632 
GenerateCircuit()633 void ConstructorCheckStubBuilder::GenerateCircuit()
634 {
635     GateRef glue = PtrArgument(0);
636     GateRef ctor = TaggedArgument(1);
637     GateRef value = TaggedArgument(2); // 2 : 3rd para
638     GateRef thisObj = TaggedArgument(3); // 3 : 4th para
639     Return(ConstructorCheck(glue, ctor, value, thisObj));
640 }
641 
GenerateCircuit()642 void JsProxyCallInternalStubBuilder::GenerateCircuit()
643 {
644     auto env = GetEnvironment();
645     Label exit(env);
646     Label isNull(env);
647     Label notNull(env);
648     Label isUndefined(env);
649     Label isNotUndefined(env);
650 
651     GateRef glue = PtrArgument(0);
652     GateRef argc = Int64Argument(1);
653     GateRef proxy = TaggedPointerArgument(2); // callTarget
654     GateRef argv = PtrArgument(3);
655 
656     DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
657 
658     GateRef handler = GetHandlerFromJSProxy(proxy);
659     Branch(TaggedIsNull(handler), &isNull, &notNull);
660     Bind(&isNull);
661     {
662         ThrowTypeAndReturn(glue, GET_MESSAGE_STRING_ID(NonCallable), Exception());
663     }
664     Bind(&notNull);
665     {
666         GateRef target = GetTargetFromJSProxy(proxy);
667         GateRef globalConstOffset = IntPtr(JSThread::GlueData::GetGlobalConstOffset(env->Is32Bit()));
668         GateRef keyOffset = PtrAdd(globalConstOffset,
669             PtrMul(IntPtr(static_cast<int64_t>(ConstantIndex::APPLY_STRING_INDEX)),
670             IntPtr(sizeof(JSTaggedValue))));
671         GateRef key = Load(VariableType::JS_ANY(), glue, keyOffset);
672         GateRef method = CallRuntime(glue, RTSTUB_ID(JSObjectGetMethod), {handler, key});
673         ReturnExceptionIfAbruptCompletion(glue);
674 
675         Branch(TaggedIsUndefined(method), &isUndefined, &isNotUndefined);
676         Bind(&isUndefined);
677         {
678             result = CallNGCRuntime(glue, RTSTUB_ID(JSProxyCallInternalWithArgV), {glue, argc, target, argv});
679             Return(*result);
680         }
681         Bind(&isNotUndefined);
682         {
683             const int JSPROXY_NUM_ARGS = 3;
684             GateRef arrHandle = CallRuntime(glue, RTSTUB_ID(CreateArrayFromList), argc, argv);
685             // 2: this offset
686             GateRef thisArg = Load(VariableType::JS_POINTER(), argv, IntPtr(2 * sizeof(JSTaggedValue)));
687             GateRef numArgs = Int64(JSPROXY_NUM_ARGS + NUM_MANDATORY_JSFUNC_ARGS);
688             GateRef lexEnv = Load(VariableType::JS_POINTER(), method, IntPtr(JSFunction::LEXICAL_ENV_OFFSET));
689             result = CallNGCRuntime(glue, RTSTUB_ID(JSCall),
690                 {glue, lexEnv, numArgs, method, Undefined(), handler, target, thisArg, arrHandle});
691             Jump(&exit);
692         }
693     }
694     Bind(&exit);
695     Return(*result);
696 }
697 
698 CallSignature CommonStubCSigns::callSigns_[CommonStubCSigns::NUM_OF_STUBS];
699 
Initialize()700 void CommonStubCSigns::Initialize()
701 {
702 #define INIT_SIGNATURES(name)                                                              \
703     name##CallSignature::Initialize(&callSigns_[name]);                                    \
704     callSigns_[name].SetID(name);                                                          \
705     callSigns_[name].SetName(std::string("COStub_") + #name);                              \
706     callSigns_[name].SetConstructor(                                                       \
707         [](void* env) {                                                                    \
708             return static_cast<void*>(                                                     \
709                 new name##StubBuilder(&callSigns_[name], static_cast<Environment*>(env))); \
710         });
711 
712     COMMON_STUB_ID_LIST(INIT_SIGNATURES)
713 #undef INIT_SIGNATURES
714 }
715 
GetCSigns(std::vector<const CallSignature * > & outCSigns)716 void CommonStubCSigns::GetCSigns(std::vector<const CallSignature*>& outCSigns)
717 {
718     for (size_t i = 0; i < NUM_OF_STUBS; i++) {
719         outCSigns.push_back(&callSigns_[i]);
720     }
721 }
722 }  // namespace panda::ecmascript::kungfu
723