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, ¬FastCall);
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(¬FastCall);
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