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