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/builtins_proxy_stub_builder.h"
23 #include "ecmascript/compiler/builtins/linked_hashtable_stub_builder.h"
24 #include "ecmascript/compiler/call_signature.h"
25 #include "ecmascript/compiler/call_stub_builder.h"
26 #include "ecmascript/compiler/gate.h"
27 #include "ecmascript/compiler/new_object_stub_builder.h"
28 #include "ecmascript/compiler/operations_stub_builder.h"
29 #include "ecmascript/compiler/share_gate_meta_data.h"
30 #include "ecmascript/js_set.h"
31 #include "ecmascript/js_set_iterator.h"
32 #include "ecmascript/linked_hash_table.h"
33 #include "ecmascript/mem/tagged_object.h"
34 #include "ecmascript/runtime_call_id.h"
35 #include "ecmascript/global_env_constants.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 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
46 OperationsStubBuilder operationBuilder(this, globalEnv);
47 Return(operationBuilder.Add(glue, x, y));
48 }
49
GenerateCircuit()50 void SubStubBuilder::GenerateCircuit()
51 {
52 GateRef glue = PtrArgument(0);
53 GateRef x = TaggedArgument(1);
54 GateRef y = TaggedArgument(2);
55 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
56 OperationsStubBuilder operationBuilder(this, globalEnv);
57 Return(operationBuilder.Sub(glue, x, y));
58 }
59
GenerateCircuit()60 void DefineFieldStubBuilder::GenerateCircuit()
61 {
62 GateRef glue = PtrArgument(0);
63 GateRef receiver = TaggedArgument(1);
64 GateRef propKey = TaggedArgument(2); // 2: 3rd argument
65 GateRef acc = TaggedArgument(3); // 3: 4th argument
66 GateRef globalEnv = TaggedArgument(4); // 4: 5th argument
67 SetCurrentGlobalEnv(globalEnv);
68 Return(DefineField(glue, receiver, propKey, acc));
69 }
70
GenerateCircuit()71 void DefinefuncStubBuilder::GenerateCircuit()
72 {
73 auto env = GetEnvironment();
74 GateRef glue = PtrArgument(0);
75 GateRef jsFunc = TaggedArgument(1);
76 GateRef methodId = Int32Argument(2); // 2: 3rd argument
77 GateRef length = Int32Argument(3); // 3: 4th argument
78 GateRef lexEnv = TaggedArgument(4); // 4: 5th argument
79 GateRef slotId = Int32Argument(5); // 5: 6th argument
80 GateRef globalEnv = TaggedArgument(6); // 6: 7th argument
81
82 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
83 Label exit(env);
84 Label failed(env);
85 NewObjectStubBuilder newBuilder(this, globalEnv);
86 newBuilder.NewJSFunction(glue, jsFunc, methodId, length, lexEnv, &result, &exit, &failed, slotId);
87 Bind(&failed);
88 {
89 result = Exception();
90 Jump(&exit);
91 }
92 Bind(&exit);
93 Return(*result);
94 }
95
96 #define JIT_DEFINEFUNC_STUB_GENERATOR(Name, kind) \
97 void Define##Name##ForJitStubBuilder::GenerateCircuit() \
98 { \
99 auto env = GetEnvironment(); \
100 GateRef glue = PtrArgument(0); \
101 GateRef jsFunc = TaggedArgument(1); \
102 GateRef hclass = TaggedArgument(2); /* 2: 3rd argument */ \
103 GateRef method = TaggedArgument(3); /* 3: 4th argument */ \
104 GateRef length = Int32Argument(4); /* 4: 5th argument */ \
105 GateRef lexEnv = TaggedArgument(5); /* 5: 6th argument */ \
106 GateRef slotId = Int32Argument(6); /* 6: 7th argument */ \
107 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined()); \
108 Label exit(env); \
109 Label failed(env); \
110 NewObjectStubBuilder newBuilder(this); \
111 newBuilder.NewJSFunctionForJit(glue, jsFunc, hclass, method, length, lexEnv, &result, &exit, &failed, slotId, \
112 kind); \
113 Bind(&failed); \
114 { \
115 result = Exception(); \
116 Jump(&exit); \
117 } \
118 Bind(&exit); \
119 Return(*result); \
120 }
121
JIT_DEFINEFUNC_STUB_GENERATOR(NormalFunc,FunctionKind::NORMAL_FUNCTION)122 JIT_DEFINEFUNC_STUB_GENERATOR(NormalFunc, FunctionKind::NORMAL_FUNCTION)
123 JIT_DEFINEFUNC_STUB_GENERATOR(ArrowFunc, FunctionKind::ARROW_FUNCTION)
124 JIT_DEFINEFUNC_STUB_GENERATOR(BaseConstructor, FunctionKind::BASE_CONSTRUCTOR)
125
126 void CallArg0StubStubBuilder::GenerateCircuit()
127 {
128 CallCoStubBuilder callBuilder(this, EcmaOpcode::CALLARG0_IMM8);
129 Return(callBuilder.CallStubDispatch(!GetCallSignature()->IsStwCopyStub()));
130 }
131
GenerateCircuit()132 void CallArg1StubStubBuilder::GenerateCircuit()
133 {
134 CallCoStubBuilder callBuilder(this, EcmaOpcode::CALLARG1_IMM8_V8);
135 Return(callBuilder.CallStubDispatch(!GetCallSignature()->IsStwCopyStub()));
136 }
137
GenerateCircuit()138 void CallArg2StubStubBuilder::GenerateCircuit()
139 {
140 CallCoStubBuilder callBuilder(this, EcmaOpcode::CALLARGS2_IMM8_V8_V8);
141 Return(callBuilder.CallStubDispatch(!GetCallSignature()->IsStwCopyStub()));
142 }
143
GenerateCircuit()144 void CallArg3StubStubBuilder::GenerateCircuit()
145 {
146 CallCoStubBuilder callBuilder(this, EcmaOpcode::CALLARGS3_IMM8_V8_V8_V8);
147 Return(callBuilder.CallStubDispatch(!GetCallSignature()->IsStwCopyStub()));
148 }
149
GenerateCircuit()150 void CallThis0StubStubBuilder::GenerateCircuit()
151 {
152 CallCoStubBuilder callBuilder(this, EcmaOpcode::CALLTHIS0_IMM8_V8);
153 Return(callBuilder.CallStubDispatch(!GetCallSignature()->IsStwCopyStub()));
154 }
155
GenerateCircuit()156 void CallThis1StubStubBuilder::GenerateCircuit()
157 {
158 CallCoStubBuilder callBuilder(this, EcmaOpcode::CALLTHIS1_IMM8_V8_V8);
159 Return(callBuilder.CallStubDispatch(!GetCallSignature()->IsStwCopyStub()));
160 }
161
GenerateCircuit()162 void CallThis2StubStubBuilder::GenerateCircuit()
163 {
164 CallCoStubBuilder callBuilder(this, EcmaOpcode::CALLTHIS2_IMM8_V8_V8_V8);
165 Return(callBuilder.CallStubDispatch(!GetCallSignature()->IsStwCopyStub()));
166 }
167
GenerateCircuit()168 void CallThis3StubStubBuilder::GenerateCircuit()
169 {
170 CallCoStubBuilder callBuilder(this, EcmaOpcode::CALLTHIS3_IMM8_V8_V8_V8_V8);
171 Return(callBuilder.CallStubDispatch(!GetCallSignature()->IsStwCopyStub()));
172 }
173
GenerateCircuit()174 void NewFloat32ArrayWithNoArgsStubBuilder::GenerateCircuit()
175 {
176 auto env = GetEnvironment();
177 GateRef glue = PtrArgument(0);
178 GateRef globalEnv = TaggedArgument(1); // 1: global env
179 NewObjectStubBuilder objBuilder(env, globalEnv);
180 objBuilder.SetParameters(glue, 0);
181 GateRef res = objBuilder.NewFloat32ArrayWithSize(glue, Int32(0));
182 Return(res);
183 }
184
GenerateCircuit()185 void NewFloat32ArrayStubBuilder::GenerateCircuit()
186 {
187 auto env = GetEnvironment();
188 GateRef glue = PtrArgument(0);
189 GateRef ctor = TaggedArgument(1);
190 GateRef arg0 = TaggedArgument(2); /* 2 : length */
191 GateRef globalEnv = TaggedArgument(3); /* 3 : global env */
192
193 DEFVARIABLE(res, VariableType::JS_ANY(), Undefined());
194
195 Label slowPath(env);
196 Label exit(env);
197 DEFVALUE(arrayLength, (env), VariableType::INT64(), Int64(0));
198 Label arrayCreateByLength(env);
199 Label argIsNumber(env);
200 BRANCH(TaggedIsNumber(arg0), &argIsNumber, &slowPath);
201 Bind(&argIsNumber);
202 {
203 Label argIsInt(env);
204 Label argIsDouble(env);
205 BRANCH(TaggedIsInt(arg0), &argIsInt, &argIsDouble);
206 Bind(&argIsInt);
207 {
208 Label validIntLength(env);
209 GateRef intLen = GetInt64OfTInt(arg0);
210 GateRef isGEZero = Int64GreaterThanOrEqual(intLen, Int64(0));
211 GateRef isLEMaxLen = Int64LessThanOrEqual(intLen, Int64(JSObject::MAX_GAP));
212 BRANCH(BitAnd(isGEZero, isLEMaxLen), &validIntLength, &slowPath);
213 Bind(&validIntLength);
214 {
215 arrayLength = intLen;
216 Jump(&arrayCreateByLength);
217 }
218 }
219 Bind(&argIsDouble);
220 {
221 Label validDoubleLength(env);
222 GateRef doubleLength = GetDoubleOfTDouble(arg0);
223 GateRef doubleToInt = DoubleToInt(glue, doubleLength, base::INT32_BITS);
224 GateRef intToDouble = CastInt64ToFloat64(SExtInt32ToInt64(doubleToInt));
225 GateRef doubleEqual = DoubleEqual(doubleLength, intToDouble);
226 GateRef doubleLEMaxLen = DoubleLessThanOrEqual(doubleLength, Double(JSObject::MAX_GAP));
227 BRANCH(BitAnd(doubleEqual, doubleLEMaxLen), &validDoubleLength, &slowPath);
228 Bind(&validDoubleLength);
229 {
230 arrayLength = SExtInt32ToInt64(doubleToInt);
231 Jump(&arrayCreateByLength);
232 }
233 }
234 }
235 Bind(&arrayCreateByLength);
236 {
237 NewObjectStubBuilder newBuilder(env, globalEnv);
238 newBuilder.SetParameters(glue, 0);
239 GateRef truncedLength = TruncInt64ToInt32(*arrayLength);
240 res = newBuilder.NewFloat32ArrayWithSize(glue, truncedLength);
241 Jump(&exit);
242 }
243 Bind(&slowPath);
244 {
245 // no need to alloc in slowpath.
246 GateRef thisObj = Undefined();
247 GateRef argc = Int64(4); // 4: means func newtarget thisObj arg0
248 GateRef argv = IntPtr(0);
249 Label isEnableCMCGC(env);
250 Label skipReadBarrier(env);
251 BRANCH_UNLIKELY(LoadPrimitive(VariableType::BOOL(), glue,
252 IntPtr(JSThread::GlueData::GetIsEnableCMCGCOffset(env->Is32Bit()))),
253 &isEnableCMCGC, &skipReadBarrier);
254 Bind(&isEnableCMCGC);
255 {
256 Label readBarrier(env);
257 BRANCH_LIKELY(NeedSkipReadBarrier(glue), &skipReadBarrier, &readBarrier);
258 Bind(&readBarrier);
259
260 CallNGCRuntime(glue, RTSTUB_ID(CopyCallTarget), {glue, ctor});
261 Jump(&skipReadBarrier);
262 }
263 Bind(&skipReadBarrier);
264 std::vector<GateRef> args { glue, argc, argv, ctor, ctor, thisObj, arg0 };
265 const CallSignature *cs = RuntimeStubCSigns::Get(RTSTUB_ID(JSCallNew));
266 GateRef target = IntPtr(RTSTUB_ID(JSCallNew));
267 auto depend = env->GetCurrentLabel()->GetDepend();
268 res = env->GetBuilder()->Call(cs, glue, target, depend, args,
269 Circuit::NullGate(), "NewFloat32Array stub slowpath");
270 Jump(&exit);
271 }
272 Bind(&exit);
273 Return(*res);
274 }
275
GenerateCircuit()276 void StringLoadElementStubBuilder::GenerateCircuit()
277 {
278 GateRef glue = PtrArgument(0); // 0: first argument glue
279 GateRef string = TaggedArgument(1); // 1: second argument string
280 GateRef index = Int32Argument(2); // 2: 3rd argument index
281 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument global env
282 BuiltinsStringStubBuilder builder(this, globalEnv);
283 GateRef result = builder.GetSingleCharCodeByIndex(glue, string, index);
284 Return(result);
285 }
286
GenerateCircuit()287 void GetStringFromConstPoolStubBuilder::GenerateCircuit()
288 {
289 GateRef glue = PtrArgument(0);
290 GateRef constpool = TaggedArgument(1);
291 GateRef index = Int32Argument(2); // index
292 GateRef result = GetStringFromConstPool(glue, constpool, index);
293 Return(result);
294 }
295
GenerateCircuit()296 void GetPrototypeStubBuilder::GenerateCircuit()
297 {
298 auto env = GetEnvironment();
299 auto &builder = *env->GetBuilder();
300 GateRef glue = PtrArgument(0);
301 GateRef func = TaggedArgument(1);
302 Return(builder.GetPrototype(glue, func));
303 }
304
GenerateCircuit()305 void FastCallSelectorStubBuilder::GenerateCircuit()
306 {
307 auto env = GetEnvironment();
308 auto &builder = *env->GetBuilder();
309 GateRef glue = PtrArgument(0);
310 GateRef func = TaggedArgument(1);
311 GateRef actualArgc = Int64Argument(2); /* 2 : 3rd parameter is actualArgc */
312
313 Label entry(env);
314 Label exit(env);
315 env->SubCfgEntry(&entry);
316 DEFVARIABLE(result, VariableType::INT32(), builder.Int32(static_cast<int32_t>(FastCallType::SLOW_CALL)));
317 CallCoStubBuilder::FastCallSelector(builder, glue, func, actualArgc, &result, &exit);
318 Bind(&exit);
319 auto ret = *result;
320 env->SubCfgExit();
321 Return(ret);
322 }
323
GenerateCircuit()324 void CheckSuperAndNewStubBuilder::GenerateCircuit()
325 {
326 auto env = GetEnvironment();
327 GateRef glue = PtrArgument(0);
328 GateRef super = TaggedArgument(1);
329 GateRef newTarget = TaggedArgument(2); /* 2 : 3rd parameter is newTarget */
330 NewObjectStubBuilder objBuilder(env);
331 Label isHeapObj(env);
332 Label isJsFunc(env);
333 Label isCtor(env);
334 Label needAllocateThis(env);
335 Label defaultThis(env);
336 Label exit(env);
337
338 BRANCH(TaggedIsHeapObject(super), &isHeapObj, &exit);
339 Bind(&isHeapObj);
340 BRANCH(IsJSFunction(glue, super), &isJsFunc, &exit);
341 Bind(&isJsFunc);
342 BRANCH(IsConstructor(glue, super), &isCtor, &exit);
343 Bind(&isCtor);
344 BRANCH(IsBase(glue, super), &needAllocateThis, &defaultThis);
345 Bind(&needAllocateThis);
346 Return(objBuilder.FastSuperAllocateThis(glue, super, newTarget));
347 Bind(&defaultThis);
348 Return(Undefined());
349 Bind(&exit);
350 Return(Hole());
351 }
352
GenerateCircuit()353 void SuperCallAndConstructorCheckStubBuilder::GenerateCircuit()
354 {
355 auto env = GetEnvironment();
356 GateRef glue = PtrArgument(0);
357 GateRef super = TaggedArgument(1);
358 GateRef newTarget = TaggedArgument(2); /* 2 : 3rd parameter is newtarget */
359 GateRef thisObj = TaggedArgument(3); /* 3 : 4th parameter is thisObj */
360 GateRef argc = Int64Argument(4); /* 4 : 5th parameter is argc */
361 GateRef argv = PtrArgument(5); /* 5 : 6th parameter is argv */
362
363 GateRef gate = Circuit::NullGate();
364 auto &builder = *env->GetBuilder();
365 NewObjectStubBuilder objBuilder(env);
366
367 Label entry(env);
368 Label exit(env);
369
370 env->SubCfgEntry(&entry);
371 DEFVARIABLE(result, VariableType::JS_ANY(), Hole());
372 auto args = {gate, super, newTarget, thisObj, argc};
373 CallCoStubBuilder::LowerFastSuperCall(glue, builder, args, argv, result, exit);
374 Bind(&exit);
375 result = objBuilder.ConstructorCheck(glue, super, *result, thisObj);
376 auto ret = *result;
377 env->SubCfgExit();
378 Return(ret);
379 }
380
GenerateCircuit()381 void ConvertCharToInt32StubBuilder::GenerateCircuit()
382 {
383 GateRef glue = PtrArgument(0);
384 GateRef charCode = Int32Argument(1);
385 GateRef globalEnv = TaggedArgument(2); // 2: 3rd argument global env
386 BuiltinsStringStubBuilder builder(this, globalEnv);
387 // char to string
388 GateRef result = builder.CreateStringBySingleCharCode(glue, charCode);
389 // string to number
390 result = CallNGCRuntime(glue, RTSTUB_ID(StringToNumber), {glue, result, Int32(0)}, charCode);
391 // get int from number
392 result = NumberGetInt(glue, result);
393 Return(result);
394 }
395
GenerateCircuit()396 void ConvertCharToDoubleStubBuilder::GenerateCircuit()
397 {
398 GateRef glue = PtrArgument(0);
399 GateRef charCode = Int32Argument(1);
400 GateRef globalEnv = TaggedArgument(2); // 2: 3rd argument global env
401 BuiltinsStringStubBuilder builder(this, globalEnv);
402 // char to string
403 GateRef result = builder.CreateStringBySingleCharCode(glue, charCode);
404 // string to number
405 result = CallNGCRuntime(glue, RTSTUB_ID(StringToNumber), {glue, result, Int32(0)}, charCode);
406 // get double from number
407 result = GetDoubleOfTNumber(result);
408 Return(result);
409 }
410
GenerateCircuit()411 void ConvertCharToStringStubBuilder::GenerateCircuit()
412 {
413 GateRef glue = PtrArgument(0);
414 GateRef charCode = Int32Argument(1);
415 GateRef globalEnv = TaggedArgument(2); // 2: 3rd argument global env
416 BuiltinsStringStubBuilder builder(this, globalEnv);
417 // char to string
418 GateRef result = builder.CreateStringBySingleCharCode(glue, charCode);
419 Return(result);
420 }
421
GenerateCircuit()422 void MulStubBuilder::GenerateCircuit()
423 {
424 GateRef glue = PtrArgument(0);
425 GateRef x = TaggedArgument(1);
426 GateRef y = TaggedArgument(2);
427 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
428 OperationsStubBuilder operationBuilder(this, globalEnv);
429 Return(operationBuilder.Mul(glue, x, y));
430 }
431
GenerateCircuit()432 void DivStubBuilder::GenerateCircuit()
433 {
434 GateRef glue = PtrArgument(0);
435 GateRef x = TaggedArgument(1);
436 GateRef y = TaggedArgument(2);
437 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
438 OperationsStubBuilder operationBuilder(this, globalEnv);
439 Return(operationBuilder.Div(glue, x, y));
440 }
441
GenerateCircuit()442 void ModStubBuilder::GenerateCircuit()
443 {
444 GateRef glue = PtrArgument(0);
445 GateRef x = TaggedArgument(1);
446 GateRef y = TaggedArgument(2); // 2: 3rd argument
447 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
448 OperationsStubBuilder operationBuilder(this, globalEnv);
449 Return(operationBuilder.Mod(glue, x, y));
450 }
451
GenerateCircuit()452 void TypeOfStubBuilder::GenerateCircuit()
453 {
454 GateRef glue = PtrArgument(0);
455 GateRef obj = TaggedArgument(1);
456 Return(FastTypeOf(glue, obj));
457 }
458
GenerateCircuit()459 void EqualStubBuilder::GenerateCircuit()
460 {
461 GateRef glue = PtrArgument(0);
462 GateRef x = TaggedArgument(1);
463 GateRef y = TaggedArgument(2); // 2: 3rd argument
464 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
465 OperationsStubBuilder operationBuilder(this, globalEnv);
466 Return(operationBuilder.Equal(glue, x, y));
467 }
468
GenerateCircuit()469 void NotEqualStubBuilder::GenerateCircuit()
470 {
471 GateRef glue = PtrArgument(0);
472 GateRef x = TaggedArgument(1);
473 GateRef y = TaggedArgument(2); // 2: 3rd argument
474 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
475 OperationsStubBuilder operationBuilder(this, globalEnv);
476 Return(operationBuilder.NotEqual(glue, x, y));
477 }
478
GenerateCircuit()479 void StrictEqualStubBuilder::GenerateCircuit()
480 {
481 GateRef glue = PtrArgument(0);
482 GateRef x = TaggedArgument(1);
483 GateRef y = TaggedArgument(2); // 2: 3rd argument
484 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
485 OperationsStubBuilder operationBuilder(this, globalEnv);
486 Return(operationBuilder.StrictEqual(glue, x, y));
487 }
488
GenerateCircuit()489 void StrictNotEqualStubBuilder::GenerateCircuit()
490 {
491 GateRef glue = PtrArgument(0);
492 GateRef x = TaggedArgument(1);
493 GateRef y = TaggedArgument(2); // 2: 3rd argument
494 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
495 OperationsStubBuilder operationBuilder(this, globalEnv);
496 Return(operationBuilder.StrictNotEqual(glue, x, y));
497 }
498
GenerateCircuit()499 void LessStubBuilder::GenerateCircuit()
500 {
501 GateRef glue = PtrArgument(0);
502 GateRef x = TaggedArgument(1);
503 GateRef y = TaggedArgument(2); // 2: 3rd argument
504 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
505 OperationsStubBuilder operationBuilder(this, globalEnv);
506 Return(operationBuilder.Less(glue, x, y));
507 }
508
GenerateCircuit()509 void LessEqStubBuilder::GenerateCircuit()
510 {
511 GateRef glue = PtrArgument(0);
512 GateRef x = TaggedArgument(1);
513 GateRef y = TaggedArgument(2); // 2: 3rd argument
514 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
515 OperationsStubBuilder operationBuilder(this, globalEnv);
516 Return(operationBuilder.LessEq(glue, x, y));
517 }
518
GenerateCircuit()519 void GreaterStubBuilder::GenerateCircuit()
520 {
521 GateRef glue = PtrArgument(0);
522 GateRef x = TaggedArgument(1);
523 GateRef y = TaggedArgument(2); // 2: 3rd argument
524 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
525 OperationsStubBuilder operationBuilder(this, globalEnv);
526 Return(operationBuilder.Greater(glue, x, y));
527 }
528
GenerateCircuit()529 void GreaterEqStubBuilder::GenerateCircuit()
530 {
531 GateRef glue = PtrArgument(0);
532 GateRef x = TaggedArgument(1);
533 GateRef y = TaggedArgument(2); // 2: 3rd argument
534 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
535 OperationsStubBuilder operationBuilder(this, globalEnv);
536 Return(operationBuilder.GreaterEq(glue, x, y));
537 }
538
GenerateCircuit()539 void ShlStubBuilder::GenerateCircuit()
540 {
541 GateRef glue = PtrArgument(0);
542 GateRef x = TaggedArgument(1);
543 GateRef y = TaggedArgument(2); // 2: 3rd argument
544 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
545 OperationsStubBuilder operationBuilder(this, globalEnv);
546 Return(operationBuilder.Shl(glue, x, y));
547 }
548
GenerateCircuit()549 void ShrStubBuilder::GenerateCircuit()
550 {
551 GateRef glue = PtrArgument(0);
552 GateRef x = TaggedArgument(1);
553 GateRef y = TaggedArgument(2); // 2: 3rd argument
554 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
555 OperationsStubBuilder operationBuilder(this, globalEnv);
556 Return(operationBuilder.Shr(glue, x, y));
557 }
558
GenerateCircuit()559 void AshrStubBuilder::GenerateCircuit()
560 {
561 GateRef glue = PtrArgument(0);
562 GateRef x = TaggedArgument(1);
563 GateRef y = TaggedArgument(2); // 2: 3rd argument
564 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
565 OperationsStubBuilder operationBuilder(this, globalEnv);
566 Return(operationBuilder.Ashr(glue, x, y));
567 }
568
GenerateCircuit()569 void AndStubBuilder::GenerateCircuit()
570 {
571 GateRef glue = PtrArgument(0);
572 GateRef x = TaggedArgument(1);
573 GateRef y = TaggedArgument(2); // 2: 3rd argument
574 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
575 OperationsStubBuilder operationBuilder(this, globalEnv);
576 Return(operationBuilder.And(glue, x, y));
577 }
578
GenerateCircuit()579 void OrStubBuilder::GenerateCircuit()
580 {
581 GateRef glue = PtrArgument(0);
582 GateRef x = TaggedArgument(1);
583 GateRef y = TaggedArgument(2); // 2: 3rd argument
584 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
585 OperationsStubBuilder operationBuilder(this, globalEnv);
586 Return(operationBuilder.Or(glue, x, y));
587 }
588
GenerateCircuit()589 void XorStubBuilder::GenerateCircuit()
590 {
591 GateRef glue = PtrArgument(0);
592 GateRef x = TaggedArgument(1);
593 GateRef y = TaggedArgument(2); // 2: 3rd argument
594 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
595 OperationsStubBuilder operationBuilder(this, globalEnv);
596 Return(operationBuilder.Xor(glue, x, y));
597 }
598
GenerateCircuit()599 void IsInStubBuilder::GenerateCircuit()
600 {
601 GateRef glue = PtrArgument(0);
602 GateRef prop = TaggedArgument(1); // 1: 2nd argument
603 GateRef obj = TaggedArgument(2); // 2: 3rd argument
604 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
605 SetCurrentGlobalEnv(globalEnv);
606 Return(IsIn(glue, prop, obj));
607 }
608
GenerateCircuit()609 void InstanceofStubBuilder::GenerateCircuit()
610 {
611 GateRef glue = PtrArgument(0);
612 GateRef object = TaggedArgument(1);
613 GateRef target = TaggedArgument(2); // 2: 3rd argument
614 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
615 GateRef jsFunc = TaggedArgument(4); // 4 : 5th para
616 GateRef slotId = Int32Argument(5); // 5 : 6th pars
617 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc);
618 SetCurrentGlobalEnv(globalEnv);
619 Return(InstanceOf(glue, object, target, profileTypeInfo, slotId, ProfileOperation()));
620 }
621
GenerateCircuit()622 void OrdinaryHasInstanceStubBuilder::GenerateCircuit()
623 {
624 GateRef glue = PtrArgument(0);
625 GateRef object = TaggedArgument(1);
626 GateRef target = TaggedArgument(2); // 2: 3rd argument
627 GateRef globalEnv = TaggedArgument(3); // 3: 4th argument
628 SetCurrentGlobalEnv(globalEnv);
629 Return(OrdinaryHasInstance(glue, target, object));
630 }
631
GenerateCircuit()632 void IncStubBuilder::GenerateCircuit()
633 {
634 GateRef glue = PtrArgument(0);
635 GateRef x = TaggedArgument(1);
636 OperationsStubBuilder operationBuilder(this);
637 Return(operationBuilder.Inc(glue, x));
638 }
639
GenerateCircuit()640 void DecStubBuilder::GenerateCircuit()
641 {
642 GateRef glue = PtrArgument(0);
643 GateRef x = TaggedArgument(1);
644 OperationsStubBuilder operationBuilder(this);
645 Return(operationBuilder.Dec(glue, x));
646 }
647
GenerateCircuit()648 void NegStubBuilder::GenerateCircuit()
649 {
650 GateRef glue = PtrArgument(0);
651 GateRef x = TaggedArgument(1);
652 OperationsStubBuilder operationBuilder(this);
653 Return(operationBuilder.Neg(glue, x));
654 }
655
GenerateCircuit()656 void NotStubBuilder::GenerateCircuit()
657 {
658 GateRef glue = PtrArgument(0);
659 GateRef x = TaggedArgument(1);
660 OperationsStubBuilder operationBuilder(this);
661 Return(operationBuilder.Not(glue, x));
662 }
663
GenerateCircuit()664 void ToBooleanTrueStubBuilder::GenerateCircuit()
665 {
666 GateRef glue = PtrArgument(0);
667 (void)glue;
668 GateRef x = TaggedArgument(1);
669 Return(FastToBoolean(glue, x, true));
670 }
671
GenerateCircuit()672 void ToBooleanFalseStubBuilder::GenerateCircuit()
673 {
674 GateRef glue = PtrArgument(0);
675 (void)glue;
676 GateRef x = TaggedArgument(1);
677 Return(FastToBoolean(glue, x, false));
678 }
679
GenerateCircuit()680 void NewLexicalEnvStubBuilder::GenerateCircuit()
681 {
682 auto env = GetEnvironment();
683 GateRef glue = PtrArgument(0);
684 GateRef parent = TaggedArgument(1);
685 GateRef numVars = Int32Argument(2); /* 2 : 3rd parameter is index */
686
687 DEFVARIABLE(result, VariableType::JS_ANY(), Hole());
688 NewObjectStubBuilder newBuilder(this);
689 newBuilder.SetParameters(glue, 0);
690 Label afterNew(env);
691 newBuilder.NewLexicalEnv(&result, &afterNew, numVars, parent);
692 Bind(&afterNew);
693 Return(*result);
694 }
695
GenerateCircuit()696 void CreateObjectHavingMethodStubBuilder::GenerateCircuit()
697 {
698 GateRef glue = PtrArgument(0);
699 GateRef obj = TaggedArgument(1);
700 GateRef env = Int32Argument(2); /* 2 : 3rd parameter is index */
701 GateRef globalEnv = GetCurrentGlobalEnv(glue, env);
702 NewObjectStubBuilder newBuilder(this, globalEnv);
703 newBuilder.SetParameters(glue, 0);
704 GateRef result = newBuilder.CreateObjectHavingMethod(glue, obj, env);
705 Return(result);
706 }
707
GenerateCircuit()708 void CopyRestArgsStubBuilder::GenerateCircuit()
709 {
710 DEFVARIABLE(arrayObj, VariableType::JS_ANY(), Undefined());
711 DEFVARIABLE(argv, VariableType::NATIVE_POINTER(), PtrArgument(1));
712 DEFVARIABLE(i, VariableType::INT32(), Int32(0));
713 DEFVARIABLE(actualRestNum, VariableType::INT32(), Int32(0));
714 auto env = GetEnvironment();
715 GateRef glue = PtrArgument(0);
716 GateRef startIdx = Int32Argument(2); /* 2 : 3rd parameter is startIdx */
717 GateRef numArgs = Int32Argument(3); /* 3 : 4th parameter is numArgs */
718 GateRef argvTaggedArray = TaggedArgument(4); /* 4 : 5th parameter is argvTaggedArray */
719 GateRef globalEnv = TaggedArgument(5); /* 5 : 6th parameter is globalEnv */
720
721 Label numArgsGreater(env);
722 Label numArgsNotGreater(env);
723 Label afterCreateArrayObj(env);
724
725 GateRef actualArgc = Int32Sub(numArgs, Int32(NUM_MANDATORY_JSFUNC_ARGS));
726 // 1. Calculate actual rest num.
727 BRANCH(Int32UnsignedGreaterThan(actualArgc, startIdx), &numArgsGreater, &numArgsNotGreater);
728 Bind(&numArgsGreater);
729 {
730 actualRestNum = Int32Sub(actualArgc, startIdx);
731 Jump(&numArgsNotGreater);
732 }
733 Bind(&numArgsNotGreater);
734 // 2. Construct RestArguments object.
735 NewObjectStubBuilder newBuilder(this, globalEnv);
736 newBuilder.SetParameters(glue, 0);
737 GateRef intialHClass = GetGlobalEnvValue(VariableType::JS_ANY(), glue, globalEnv,
738 static_cast<size_t>(GlobalEnvField::ELEMENT_HOLE_TAGGED_HCLASS_INDEX));
739 arrayObj = newBuilder.NewJSArrayWithSize(intialHClass, *actualRestNum);
740
741 GateRef args = GetArgumentsElements(glue, argvTaggedArray, *argv);
742 newBuilder.AssignRestArg(&arrayObj, &afterCreateArrayObj, args, startIdx, *actualRestNum);
743 Bind(&afterCreateArrayObj);
744 Return(*arrayObj);
745 }
746
GenerateCircuit()747 void GetUnmappedArgsStubBuilder::GenerateCircuit()
748 {
749 auto env = GetEnvironment();
750 GateRef glue = PtrArgument(0);
751 GateRef numArgs = Int32Argument(2); /* 2 : 3rd parameter is numArgs */
752 GateRef argvTaggedArray = TaggedArgument(3); /* 3 : 4th parameter is argvTaggedArray */
753 GateRef globalEnv = TaggedArgument(4); /* 4 : 5th parameter is globalEnv */
754
755 DEFVARIABLE(argumentsList, VariableType::JS_ANY(), Hole());
756 DEFVARIABLE(argumentsObj, VariableType::JS_ANY(), Hole());
757 DEFVARIABLE(argv, VariableType::NATIVE_POINTER(), PtrArgument(1));
758 Label afterArgumentsList(env);
759 Label newArgumentsObj(env);
760 Label exit(env);
761
762 GateRef actualArgc = Int32Sub(numArgs, Int32(NUM_MANDATORY_JSFUNC_ARGS));
763 GateRef startIdx = Int32(0);
764 NewObjectStubBuilder newBuilder(this, globalEnv);
765 newBuilder.SetParameters(glue, 0);
766
767 Label fillArguments(env);
768 Label argumentsException(env);
769 GateRef argumentsListObj = newBuilder.NewArgumentsListObj(actualArgc);
770 argumentsList.WriteVariable(argumentsListObj);
771 Branch(TaggedIsException(*argumentsList), &argumentsException, &fillArguments);
772 Bind(&argumentsException);
773 argumentsObj.WriteVariable(*argumentsList);
774 Jump(&exit);
775 Bind(&fillArguments);
776
777 GateRef args = GetArgumentsElements(glue, argvTaggedArray, *argv);
778 newBuilder.FillArgumentsList(*argumentsList, args, startIdx, actualArgc);
779 newBuilder.NewArgumentsObj(&argumentsObj, &exit, *argumentsList, actualArgc);
780 Bind(&exit);
781 Return(*argumentsObj);
782 }
783
GenerateCircuit()784 void GetCallSpreadArgsStubBuilder::GenerateCircuit()
785 {
786 GateRef glue = PtrArgument(0);
787 GateRef array = TaggedArgument(1);
788 GateRef globalEnv = TaggedArgument(2); // 2 : 3rd parameter is globalEnv
789 SetCurrentGlobalEnv(globalEnv);
790 Return(GetCallSpreadArgs(glue, array, ProfileOperation()));
791 }
792
GenerateCircuit()793 void GetPropertyByIndexStubBuilder::GenerateCircuit()
794 {
795 GateRef glue = PtrArgument(0);
796 GateRef receiver = TaggedArgument(1);
797 GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */
798 GateRef globalEnv = TaggedArgument(3); // 3: 4th parameter is globalEnv
799 SetCurrentGlobalEnv(globalEnv);
800 Return(GetPropertyByIndex(glue, receiver, index, ProfileOperation()));
801 }
802
GenerateCircuit()803 void SetPropertyByIndexStubBuilder::GenerateCircuit()
804 {
805 GateRef glue = PtrArgument(0);
806 GateRef receiver = TaggedArgument(1);
807 GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */
808 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
809 GateRef globalEnv = TaggedArgument(4); // 4: 5th parameter is globalEnv
810 SetCurrentGlobalEnv(globalEnv);
811 Return(SetPropertyByIndex(glue, receiver, index, value, false));
812 }
813
GenerateCircuit()814 void SetPropertyByIndexWithOwnStubBuilder::GenerateCircuit()
815 {
816 GateRef glue = PtrArgument(0);
817 GateRef receiver = TaggedArgument(1);
818 GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */
819 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
820 GateRef globalEnv = TaggedArgument(4); // 4: 5th parameter is globalEnv
821 SetCurrentGlobalEnv(globalEnv);
822 Return(SetPropertyByIndex(glue, receiver, index, value, true));
823 }
824
GenerateCircuit()825 void JSTaggedValueHasPropertyStubBuilder::GenerateCircuit()
826 {
827 GateRef glue = PtrArgument(0);
828 GateRef obj = TaggedArgument(1);
829 GateRef key = TaggedArgument(2); // 2 : 3rd para
830 GateRef globalEnv = TaggedArgument(3); // 3: 4th parameter is globalEnv
831 SetCurrentGlobalEnv(globalEnv);
832 Return(HasProperty(glue, obj, key));
833 }
834
GenerateCircuit()835 void GetPropertyByNameStubBuilder::GenerateCircuit()
836 {
837 GateRef glue = PtrArgument(0);
838 GateRef receiver = TaggedArgument(1);
839 GateRef id = Int64Argument(2); // 2 : 3rd para
840 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
841 GateRef jsFunc = TaggedArgument(4); // 4 : 5th para
842 GateRef slotId = Int32Argument(5); // 5 : 6th para
843 AccessObjectStubBuilder builder(this, globalEnv, jsFunc);
844 StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID);
845 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc);
846 Return(builder.LoadObjByName(glue, receiver, id, info, profileTypeInfo, slotId, ProfileOperation()));
847 }
848
GenerateCircuit()849 void DeprecatedGetPropertyByNameStubBuilder::GenerateCircuit()
850 {
851 GateRef glue = PtrArgument(0);
852 GateRef receiver = TaggedArgument(1);
853 GateRef key = TaggedPointerArgument(2); // 2 : 3rd para
854 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
855 AccessObjectStubBuilder builder(this, globalEnv);
856 Return(builder.DeprecatedLoadObjByName(glue, receiver, key));
857 }
858
GenerateCircuit()859 void SetPropertyByNameStubBuilder::GenerateCircuit()
860 {
861 GateRef glue = PtrArgument(0);
862 GateRef receiver = TaggedArgument(1);
863 GateRef id = Int64Argument(2); // 2 : 3rd para
864 GateRef value = TaggedPointerArgument(3); // 3 : 4th para
865 GateRef globalEnv = TaggedArgument(4); // 4: 5th para
866 GateRef jsFunc = TaggedArgument(5); // 5 : 6th para
867 GateRef slotId = Int32Argument(6); // 6 : 7th para
868 AccessObjectStubBuilder builder(this, globalEnv, jsFunc);
869 StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID);
870 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc);
871 Return(builder.StoreObjByName(glue, receiver, id, info, value, profileTypeInfo, slotId, ProfileOperation()));
872 }
873
GenerateCircuit()874 void GetPropertyByNameWithMegaStubBuilder::GenerateCircuit()
875 {
876 GateRef glue = PtrArgument(0);
877 GateRef receiver = TaggedArgument(1);
878 GateRef megaStubCache = PtrArgument(3);
879 GateRef prop = TaggedArgument(4);
880 GateRef globalEnv = TaggedArgument(5); // 5: 6th para
881 GateRef jsFunc = TaggedArgument(6); // 6 : 7th para
882 GateRef slotId = Int32Argument(7); // 7 : 8th para
883 AccessObjectStubBuilder builder(this, globalEnv, jsFunc);
884 Return(builder.LoadObjByNameWithMega(glue, receiver, megaStubCache, prop, jsFunc, slotId,
885 ProfileOperation()));
886 }
887
GenerateCircuit()888 void SetPropertyByNameWithMegaStubBuilder::GenerateCircuit()
889 {
890 GateRef glue = PtrArgument(0);
891 GateRef receiver = TaggedArgument(1);
892 GateRef value = TaggedPointerArgument(3); // 3 : 4th para
893 GateRef megaStubCache = PtrArgument(4); // 4 : 5th para
894 GateRef prop = TaggedArgument(5); // 5 : 6th para
895 GateRef globalEnv = TaggedArgument(6); // 6: 7th para
896 GateRef jsFunc = TaggedArgument(7); // 7 : 8th para
897 GateRef slotId = Int32Argument(8); // 8 : 9th para
898 AccessObjectStubBuilder builder(this, globalEnv, jsFunc);
899 Return(builder.StoreObjByNameWithMega(glue, receiver, value, megaStubCache, prop, jsFunc, slotId,
900 ProfileOperation()));
901 }
902
GenerateCircuit()903 void DeprecatedSetPropertyByNameStubBuilder::GenerateCircuit()
904 {
905 GateRef glue = PtrArgument(0);
906 GateRef receiver = TaggedArgument(1);
907 GateRef key = TaggedArgument(2); // 2 : 3rd para
908 GateRef value = TaggedArgument(3); // 3 : 4th para
909 GateRef globalEnv = TaggedArgument(4); // 4: 5th para
910 SetCurrentGlobalEnv(globalEnv);
911 Return(SetPropertyByName(glue, receiver, key, value, false, True()));
912 }
913
GenerateCircuit()914 void SetPropertyByNameWithOwnStubBuilder::GenerateCircuit()
915 {
916 GateRef glue = PtrArgument(0);
917 GateRef receiver = TaggedArgument(1);
918 GateRef key = TaggedArgument(2); // 2 : 3rd para
919 GateRef value = TaggedArgument(3); // 3 : 4th para
920 GateRef globalEnv = TaggedArgument(4); // 4: 5th para
921 SetCurrentGlobalEnv(globalEnv);
922 Return(SetPropertyByName(glue, receiver, key, value, true, True()));
923 }
924
GenerateCircuit()925 void GetPropertyByValueStubBuilder::GenerateCircuit()
926 {
927 GateRef glue = PtrArgument(0);
928 GateRef receiver = TaggedArgument(1);
929 GateRef key = TaggedArgument(2); // 2 : 3rd para
930 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
931 GateRef jsFunc = TaggedArgument(4); // 4 : 5th para
932 GateRef slotId = Int32Argument(5); // 5 : 6th para
933 AccessObjectStubBuilder builder(this, globalEnv);
934 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc);
935 Return(builder.LoadObjByValue(glue, receiver, key, profileTypeInfo, slotId));
936 }
937
GenerateCircuit()938 void DeprecatedGetPropertyByValueStubBuilder::GenerateCircuit()
939 {
940 GateRef glue = PtrArgument(0);
941 GateRef receiver = TaggedArgument(1);
942 GateRef key = TaggedArgument(2); // 2 : 3rd para
943 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
944 SetCurrentGlobalEnv(globalEnv);
945 Return(GetPropertyByValue(glue, receiver, key));
946 }
947
GenerateCircuit()948 void SetPropertyByValueStubBuilder::GenerateCircuit()
949 {
950 GateRef glue = PtrArgument(0);
951 GateRef receiver = TaggedArgument(1);
952 GateRef key = TaggedArgument(2); // 2 : 3rd para
953 GateRef value = TaggedArgument(3); // 3 : 4th para
954 GateRef globalEnv = TaggedArgument(4); // 4: 5th para
955 GateRef jsFunc = TaggedArgument(5); // 5 : 6th para
956 GateRef slotId = Int32Argument(6); // 6 : 7th para
957 AccessObjectStubBuilder builder(this, globalEnv);
958 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc);
959 Return(builder.StoreObjByValue(glue, receiver, key, value, profileTypeInfo, slotId));
960 }
961
GenerateCircuit()962 void DeprecatedSetPropertyByValueStubBuilder::GenerateCircuit()
963 {
964 GateRef glue = PtrArgument(0);
965 GateRef receiver = TaggedArgument(1);
966 GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is key */
967 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
968 GateRef globalEnv = TaggedArgument(4); // 4: 5th parameter is globalEnv
969 SetCurrentGlobalEnv(globalEnv);
970 Return(SetPropertyByValue(glue, receiver, key, value, false));
971 }
972
GenerateCircuit()973 void SetPropertyByValueWithOwnStubBuilder::GenerateCircuit()
974 {
975 GateRef glue = PtrArgument(0);
976 GateRef receiver = TaggedArgument(1);
977 GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is key */
978 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
979 GateRef globalEnv = TaggedArgument(4); // 4: 5th parameter is globalEnv
980 SetCurrentGlobalEnv(globalEnv);
981 Return(SetPropertyByValue(glue, receiver, key, value, true));
982 }
983
GenerateCircuit()984 void StOwnByIndexStubBuilder::GenerateCircuit()
985 {
986 GateRef glue = PtrArgument(0);
987 GateRef receiver = TaggedArgument(1);
988 GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */
989 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
990 GateRef globalEnv = TaggedArgument(4); // 4: 5th parameter is globalEnv
991 AccessObjectStubBuilder builder(this, globalEnv);
992 Return(builder.StOwnByIndex(glue, receiver, index, value));
993 }
994
GenerateCircuit()995 void StOwnByValueStubBuilder::GenerateCircuit()
996 {
997 GateRef glue = PtrArgument(0);
998 GateRef receiver = TaggedArgument(1);
999 GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is key */
1000 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
1001 GateRef globalEnv = TaggedArgument(4); // 4: 5th parameter is globalEnv
1002 AccessObjectStubBuilder builder(this, globalEnv);
1003 Return(builder.StOwnByValue(glue, receiver, key, value));
1004 }
1005
GenerateCircuit()1006 void StOwnByNameStubBuilder::GenerateCircuit()
1007 {
1008 GateRef glue = PtrArgument(0);
1009 GateRef receiver = TaggedArgument(1);
1010 GateRef key = TaggedArgument(2); // 2 : 3rd para
1011 GateRef value = TaggedArgument(3); // 3 : 4th para
1012 GateRef globalEnv = TaggedArgument(4); // 4: 5th para
1013 AccessObjectStubBuilder builder(this, globalEnv);
1014 Return(builder.StOwnByName(glue, receiver, key, value));
1015 }
1016
GenerateCircuit()1017 void StOwnByValueWithNameSetStubBuilder::GenerateCircuit()
1018 {
1019 GateRef glue = PtrArgument(0);
1020 GateRef receiver = TaggedArgument(1);
1021 GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is key */
1022 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
1023 GateRef globalEnv = TaggedArgument(4); // 4: 5th parameter is globalEnv
1024 AccessObjectStubBuilder builder(this, globalEnv);
1025 Return(builder.StOwnByValueWithNameSet(glue, receiver, key, value));
1026 }
1027
GenerateCircuit()1028 void StOwnByNameWithNameSetStubBuilder::GenerateCircuit()
1029 {
1030 GateRef glue = PtrArgument(0);
1031 GateRef receiver = TaggedArgument(1);
1032 GateRef key = TaggedArgument(2); // 2 : 3rd para
1033 GateRef value = TaggedArgument(3); // 3 : 4th para
1034 GateRef globalEnv = TaggedArgument(4); // 4: 5th para
1035 AccessObjectStubBuilder builder(this, globalEnv);
1036 Return(builder.StOwnByNameWithNameSet(glue, receiver, key, value));
1037 }
1038
GenerateCircuit()1039 void LdObjByIndexStubBuilder::GenerateCircuit()
1040 {
1041 GateRef glue = PtrArgument(0);
1042 GateRef receiver = TaggedArgument(1);
1043 GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */
1044 GateRef globalEnv = TaggedArgument(3); // 3: 4th parameter is globalEnv
1045 AccessObjectStubBuilder builder(this, globalEnv);
1046 Return(builder.LdObjByIndex(glue, receiver, index));
1047 }
1048
GenerateCircuit()1049 void StObjByIndexStubBuilder::GenerateCircuit()
1050 {
1051 GateRef glue = PtrArgument(0);
1052 GateRef receiver = TaggedArgument(1);
1053 GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */
1054 GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
1055 GateRef globalEnv = TaggedArgument(4); // 4: 5th parameter is globalEnv
1056 AccessObjectStubBuilder builder(this, globalEnv);
1057 Return(builder.StObjByIndex(glue, receiver, index, value));
1058 }
1059
GenerateCircuit()1060 void TryLdGlobalByNameStubBuilder::GenerateCircuit()
1061 {
1062 GateRef glue = PtrArgument(0);
1063 GateRef id = Int64Argument(1);
1064 GateRef globalEnv = TaggedArgument(2); // 2 : 3rd para
1065 GateRef jsFunc = TaggedArgument(3); // 3 : 4th para
1066 GateRef slotId = Int32Argument(4); // 4 : 5th para
1067 AccessObjectStubBuilder builder(this, globalEnv, jsFunc);
1068 StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID);
1069 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc);
1070 Return(builder.TryLoadGlobalByName(glue, id, info, profileTypeInfo, slotId, ProfileOperation()));
1071 }
1072
GenerateCircuit()1073 void TryStGlobalByNameStubBuilder::GenerateCircuit()
1074 {
1075 GateRef glue = PtrArgument(0);
1076 GateRef id = Int64Argument(1);
1077 GateRef value = TaggedArgument(2); // 2 : 3rd para
1078 GateRef globalEnv = TaggedArgument(3); // 3 : 4th para
1079 GateRef jsFunc = TaggedArgument(4); // 4 : 5th para
1080 GateRef slotId = Int32Argument(5); // 5: 6th para
1081 AccessObjectStubBuilder builder(this, globalEnv, jsFunc);
1082 StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID);
1083 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc);
1084 Return(builder.TryStoreGlobalByName(glue, id, info, value, profileTypeInfo, slotId, ProfileOperation()));
1085 }
1086
GenerateCircuit()1087 void LdGlobalVarStubBuilder::GenerateCircuit()
1088 {
1089 GateRef glue = PtrArgument(0);
1090 GateRef id = Int64Argument(1);
1091 GateRef globalEnv = TaggedArgument(2); // 2 : 3rd para
1092 GateRef jsFunc = TaggedArgument(3); // 3 : 4th para
1093 GateRef slotId = Int32Argument(4); // 4 : 5th para
1094 AccessObjectStubBuilder builder(this, globalEnv, jsFunc);
1095 StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID);
1096 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc);
1097 Return(builder.LoadGlobalVar(glue, id, info, profileTypeInfo, slotId, ProfileOperation()));
1098 }
1099
GenerateCircuit()1100 void StGlobalVarStubBuilder::GenerateCircuit()
1101 {
1102 GateRef glue = PtrArgument(0);
1103 GateRef id = Int64Argument(1);
1104 GateRef value = TaggedArgument(2); // 2 : 3rd para
1105 GateRef globalEnv = TaggedArgument(3); // 3 : 4th para
1106 GateRef jsFunc = TaggedArgument(4); // 4 : 5th para
1107 GateRef slotId = Int32Argument(5); // 5: 6th para
1108 AccessObjectStubBuilder builder(this, globalEnv, jsFunc);
1109 StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID);
1110 GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc);
1111 Return(builder.StoreGlobalVar(glue, id, info, value, profileTypeInfo, slotId));
1112 }
1113
GenerateCircuit()1114 void TryLoadICByNameStubBuilder::GenerateCircuit()
1115 {
1116 auto env = GetEnvironment();
1117 GateRef glue = PtrArgument(0);
1118 GateRef receiver = TaggedArgument(1);
1119 GateRef firstValue = TaggedArgument(2); /* 2 : 3rd parameter is value */
1120 GateRef secondValue = TaggedArgument(3); /* 3 : 4th parameter is value */
1121
1122 Label receiverIsHeapObject(env);
1123 Label receiverNotHeapObject(env);
1124 Label hclassEqualFirstValue(env);
1125 Label hclassNotEqualFirstValue(env);
1126 Label cachedHandlerNotHole(env);
1127 BRANCH(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject);
1128 Bind(&receiverIsHeapObject);
1129 {
1130 GateRef hclass = LoadHClass(glue, receiver);
1131 BRANCH(Equal(LoadObjectFromWeakRef(firstValue), hclass),
1132 &hclassEqualFirstValue,
1133 &hclassNotEqualFirstValue);
1134 Bind(&hclassEqualFirstValue);
1135 {
1136 Return(LoadICWithHandler(glue, receiver, receiver, secondValue, ProfileOperation()));
1137 }
1138 Bind(&hclassNotEqualFirstValue);
1139 {
1140 GateRef cachedHandler = CheckPolyHClass(glue, firstValue, hclass);
1141 BRANCH(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole);
1142 Bind(&cachedHandlerNotHole);
1143 {
1144 Return(LoadICWithHandler(glue, receiver, receiver, cachedHandler, ProfileOperation()));
1145 }
1146 }
1147 }
1148 Bind(&receiverNotHeapObject);
1149 {
1150 Return(Hole());
1151 }
1152 }
1153
GenerateCircuit()1154 void TryLoadICByValueStubBuilder::GenerateCircuit()
1155 {
1156 auto env = GetEnvironment();
1157 GateRef glue = PtrArgument(0);
1158 GateRef receiver = TaggedArgument(1);
1159 GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is value */
1160 GateRef firstValue = TaggedArgument(3); /* 3 : 4th parameter is value */
1161 GateRef secondValue = TaggedArgument(4); /* 4 : 5th parameter is value */
1162 GateRef globalEnv = TaggedArgument(5); // 5: 6th parameter is globalEnv
1163
1164 Label receiverIsHeapObject(env);
1165 Label receiverNotHeapObject(env);
1166 Label hclassEqualFirstValue(env);
1167 Label hclassNotEqualFirstValue(env);
1168 Label firstValueEqualKey(env);
1169 Label cachedHandlerNotHole(env);
1170 BRANCH(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject);
1171 Bind(&receiverIsHeapObject);
1172 {
1173 GateRef hclass = LoadHClass(glue, receiver);
1174 BRANCH(Equal(LoadObjectFromWeakRef(firstValue), hclass),
1175 &hclassEqualFirstValue,
1176 &hclassNotEqualFirstValue);
1177 Bind(&hclassEqualFirstValue);
1178 SetCurrentGlobalEnv(globalEnv);
1179 Return(LoadElement(glue, receiver, key));
1180 Bind(&hclassNotEqualFirstValue);
1181 {
1182 BRANCH(Int64Equal(firstValue, key), &firstValueEqualKey, &receiverNotHeapObject);
1183 Bind(&firstValueEqualKey);
1184 {
1185 auto cachedHandler = CheckPolyHClass(glue, secondValue, hclass);
1186 BRANCH(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole);
1187 Bind(&cachedHandlerNotHole);
1188 Return(LoadICWithHandler(glue, receiver, receiver, cachedHandler, ProfileOperation()));
1189 }
1190 }
1191 }
1192 Bind(&receiverNotHeapObject);
1193 Return(Hole());
1194 }
1195
GenerateCircuit()1196 void TryStoreICByNameStubBuilder::GenerateCircuit()
1197 {
1198 auto env = GetEnvironment();
1199 GateRef glue = PtrArgument(0);
1200 GateRef receiver = TaggedArgument(1);
1201 GateRef firstValue = TaggedArgument(2); /* 2 : 3rd parameter is value */
1202 GateRef secondValue = TaggedArgument(3); /* 3 : 4th parameter is value */
1203 GateRef value = TaggedArgument(4); /* 4 : 5th parameter is value */
1204 Label receiverIsHeapObject(env);
1205 Label receiverNotHeapObject(env);
1206 Label hclassEqualFirstValue(env);
1207 Label hclassNotEqualFirstValue(env);
1208 Label cachedHandlerNotHole(env);
1209 BRANCH(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject);
1210 Bind(&receiverIsHeapObject);
1211 {
1212 GateRef hclass = LoadHClass(glue, receiver);
1213 BRANCH(Equal(LoadObjectFromWeakRef(firstValue), hclass),
1214 &hclassEqualFirstValue,
1215 &hclassNotEqualFirstValue);
1216 Bind(&hclassEqualFirstValue);
1217 {
1218 Return(StoreICWithHandler(glue, receiver, receiver, value, secondValue));
1219 }
1220 Bind(&hclassNotEqualFirstValue);
1221 {
1222 GateRef cachedHandler = CheckPolyHClass(glue, firstValue, hclass);
1223 BRANCH(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole);
1224 Bind(&cachedHandlerNotHole);
1225 {
1226 Return(StoreICWithHandler(glue, receiver, receiver, value, cachedHandler));
1227 }
1228 }
1229 }
1230 Bind(&receiverNotHeapObject);
1231 Return(Hole());
1232 }
1233
GenerateCircuit()1234 void TryStoreICByValueStubBuilder::GenerateCircuit()
1235 {
1236 auto env = GetEnvironment();
1237 GateRef glue = PtrArgument(0);
1238 GateRef receiver = TaggedArgument(1);
1239 GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is value */
1240 GateRef firstValue = TaggedArgument(3); /* 3 : 4th parameter is value */
1241 GateRef secondValue = TaggedArgument(4); /* 4 : 5th parameter is value */
1242 GateRef value = TaggedArgument(5); /* 5 : 6th parameter is value */
1243 GateRef globalEnv = TaggedArgument(6); // 6: 7th parameter is globalEnv
1244 Label receiverIsHeapObject(env);
1245 Label receiverNotHeapObject(env);
1246 Label hclassEqualFirstValue(env);
1247 Label hclassNotEqualFirstValue(env);
1248 Label firstValueEqualKey(env);
1249 Label cachedHandlerNotHole(env);
1250 BRANCH(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject);
1251 Bind(&receiverIsHeapObject);
1252 {
1253 GateRef hclass = LoadHClass(glue, receiver);
1254 BRANCH(Equal(LoadObjectFromWeakRef(firstValue), hclass),
1255 &hclassEqualFirstValue,
1256 &hclassNotEqualFirstValue);
1257 Bind(&hclassEqualFirstValue);
1258 SetCurrentGlobalEnv(globalEnv);
1259 Return(ICStoreElement(glue, receiver, key, value, secondValue));
1260 Bind(&hclassNotEqualFirstValue);
1261 {
1262 BRANCH(Int64Equal(firstValue, key), &firstValueEqualKey, &receiverNotHeapObject);
1263 Bind(&firstValueEqualKey);
1264 {
1265 GateRef cachedHandler = CheckPolyHClass(glue, secondValue, hclass);
1266 BRANCH(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole);
1267 Bind(&cachedHandlerNotHole);
1268 Return(StoreICWithHandler(glue, receiver, receiver, value, cachedHandler));
1269 }
1270 }
1271 }
1272 Bind(&receiverNotHeapObject);
1273 Return(Hole());
1274 }
1275
GenerateCircuit()1276 void SetValueWithBarrierStubBuilder::GenerateCircuit()
1277 {
1278 GateRef glue = PtrArgument(0);
1279 GateRef obj = TaggedArgument(1);
1280 GateRef offset = PtrArgument(2); // 2 : 3rd para
1281 GateRef value = TaggedArgument(3); // 3 : 4th para
1282 SetValueWithBarrier(glue, obj, offset, value);
1283 Return();
1284 }
1285
GenerateCircuit()1286 void CMCSetValueWithBarrierStubBuilder::GenerateCircuit()
1287 {
1288 GateRef glue = PtrArgument(0);
1289 GateRef obj = TaggedArgument(1);
1290 GateRef offset = PtrArgument(2); // 2 : 3rd para
1291 GateRef value = TaggedArgument(3); // 3 : 4th para
1292 CMCSetValueWithBarrier(glue, obj, offset, value);
1293 Return();
1294 }
1295
GenerateCircuit()1296 void SetNonSValueWithBarrierStubBuilder::GenerateCircuit()
1297 {
1298 GateRef glue = PtrArgument(0);
1299 GateRef obj = TaggedArgument(1);
1300 GateRef offset = PtrArgument(2); // 2 : 3rd para
1301 GateRef value = TaggedArgument(3); // 3 : 4th para
1302 SetValueWithBarrier(glue, obj, offset, value, MemoryAttribute::NON_SHARE);
1303 Return();
1304 }
1305
GenerateCircuit()1306 void SetSValueWithBarrierStubBuilder::GenerateCircuit()
1307 {
1308 GateRef glue = PtrArgument(0);
1309 GateRef obj = TaggedArgument(1);
1310 GateRef offset = PtrArgument(2); // 2 : 3rd para
1311 GateRef value = TaggedArgument(3); // 3 : 4th para
1312 SetValueWithBarrier(glue, obj, offset, value, MemoryAttribute::SHARED);
1313 Return();
1314 }
1315
GenerateCircuit()1316 void VerifyBarrierStubBuilder::GenerateCircuit()
1317 {
1318 GateRef glue = PtrArgument(0);
1319 GateRef obj = TaggedArgument(1);
1320 GateRef offset = PtrArgument(2); // 2 : 3rd para
1321 GateRef value = TaggedArgument(3); // 3 : 4th para
1322 VerifyBarrier(glue, obj, offset, value);
1323 Return();
1324 }
1325
GenerateCircuit()1326 void GetValueWithBarrierStubBuilder::GenerateCircuit()
1327 {
1328 GateRef glue = PtrArgument(0);
1329 GateRef addr = TaggedArgument(1);
1330 GateRef value = GetValueWithBarrier(glue, addr);
1331 Return(value);
1332 }
1333
GenerateCircuit()1334 void NewThisObjectCheckedStubBuilder::GenerateCircuit()
1335 {
1336 GateRef glue = PtrArgument(0);
1337 GateRef ctor = TaggedArgument(1);
1338 NewObjectStubBuilder newBuilder(this);
1339 Return(newBuilder.NewThisObjectChecked(glue, ctor));
1340 }
1341
GenerateCircuit()1342 void ConstructorCheckStubBuilder::GenerateCircuit()
1343 {
1344 GateRef glue = PtrArgument(0);
1345 GateRef ctor = TaggedArgument(1);
1346 GateRef value = TaggedArgument(2); // 2 : 3rd para
1347 GateRef thisObj = TaggedArgument(3); // 3 : 4th para
1348 Return(ConstructorCheck(glue, ctor, value, thisObj));
1349 }
1350
GenerateCircuit()1351 void CreateEmptyArrayStubBuilder::GenerateCircuit()
1352 {
1353 GateRef glue = PtrArgument(0);
1354 GateRef globalEnv = TaggedArgument(1); // 1 : 2nd para
1355 NewObjectStubBuilder newBuilder(this, globalEnv);
1356 Return(newBuilder.CreateEmptyArray(glue));
1357 }
1358
GenerateCircuit()1359 void CreateArrayWithBufferStubBuilder::GenerateCircuit()
1360 {
1361 GateRef glue = PtrArgument(0);
1362 GateRef index = Int32Argument(1);
1363 GateRef jsFunc = TaggedArgument(2); // 2 : 3rd para
1364 GateRef slotId = Int32Argument(3); // 3 : 4th para
1365 GateRef globalEnv = TaggedArgument(4); // 4: 5th para
1366 NewObjectStubBuilder newBuilder(this, globalEnv);
1367 Return(newBuilder.CreateArrayWithBuffer(
1368 glue, index, jsFunc, { IntPtr(0), 0, true }, Undefined(), slotId, ProfileOperation()));
1369 }
1370
GenerateCircuit()1371 void NewJSObjectStubBuilder::GenerateCircuit()
1372 {
1373 GateRef glue = PtrArgument(0);
1374 GateRef hclass = TaggedArgument(1);
1375 GateRef size = Int64Argument(2); // size
1376 NewObjectStubBuilder newBuilder(this);
1377 Return(newBuilder.NewJSObject(glue, hclass, size));
1378 }
1379
GenerateCircuit()1380 void FastNewThisObjectStubBuilder::GenerateCircuit()
1381 {
1382 GateRef glue = PtrArgument(0);
1383 GateRef ctor = TaggedArgument(1);
1384 NewObjectStubBuilder newBuilder(this);
1385 Return(newBuilder.FastNewThisObject(glue, ctor));
1386 }
1387
GenerateCircuit()1388 void FastSuperAllocateThisStubBuilder::GenerateCircuit()
1389 {
1390 GateRef glue = PtrArgument(0);
1391 GateRef superCtor = TaggedArgument(1);
1392 GateRef newtarget = TaggedArgument(2);
1393 NewObjectStubBuilder newBuilder(this);
1394 Return(newBuilder.FastSuperAllocateThis(glue, superCtor, newtarget));
1395 }
1396
GenerateCircuit()1397 void JsBoundCallInternalStubBuilder::GenerateCircuit()
1398 {
1399 auto env = GetEnvironment();
1400 Label exit(env);
1401 Label fastCall(env);
1402 Label notFastCall(env);
1403 Label methodIsFastCall(env);
1404 Label fastCallBridge(env);
1405 Label slowCall(env);
1406 Label slowCallBridge(env);
1407
1408 GateRef glue = PtrArgument(0);
1409 GateRef argc = Int64Argument(1);
1410 GateRef func = TaggedPointerArgument(2); // callTarget
1411 GateRef argv = PtrArgument(3);
1412 GateRef thisValue = TaggedPointerArgument(4); // this
1413 GateRef newTarget = TaggedPointerArgument(5); // new target
1414 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
1415 GateRef method = GetMethodFromFunction(glue, func);
1416 GateRef callfield = LoadPrimitive(VariableType::INT64(), method, IntPtr(Method::CALL_FIELD_OFFSET));
1417 GateRef expectedNum = Int64And(Int64LSR(callfield, Int64(MethodLiteral::NumArgsBits::START_BIT)),
1418 Int64((1LU << MethodLiteral::NumArgsBits::SIZE) - 1));
1419 GateRef expectedArgc = Int64Add(expectedNum, Int64(NUM_MANDATORY_JSFUNC_ARGS));
1420 GateRef actualArgc = Int64Sub(argc, IntPtr(NUM_MANDATORY_JSFUNC_ARGS));
1421
1422 Label isEnableCMCGC(env);
1423 Label skipReadBarrier(env);
1424 BRANCH_UNLIKELY(
1425 LoadPrimitive(VariableType::BOOL(), glue, IntPtr(JSThread::GlueData::GetIsEnableCMCGCOffset(env->Is32Bit()))),
1426 &isEnableCMCGC, &skipReadBarrier);
1427 Bind(&isEnableCMCGC);
1428 {
1429 Label readBarrier(env);
1430 BRANCH_LIKELY(NeedSkipReadBarrier(glue), &skipReadBarrier, &readBarrier);
1431 Bind(&readBarrier);
1432 CallNGCRuntime(glue, RTSTUB_ID(CopyCallTarget), {glue, func});
1433 CallNGCRuntime(glue, RTSTUB_ID(CopyArgvArray), {glue, argv, argc});
1434 Jump(&skipReadBarrier);
1435 }
1436
1437 Bind(&skipReadBarrier);
1438 BRANCH(JudgeAotAndFastCall(func, CircuitBuilder::JudgeMethodType::HAS_AOT_FASTCALL),
1439 &methodIsFastCall, ¬FastCall);
1440 Bind(&methodIsFastCall);
1441 {
1442 BRANCH(Int64Equal(expectedArgc, argc), &fastCall, &fastCallBridge);
1443 Bind(&fastCall);
1444 {
1445 result = CallNGCRuntime(glue, RTSTUB_ID(JSFastCallWithArgV),
1446 { glue, func, thisValue, actualArgc, argv });
1447 Jump(&exit);
1448 }
1449 Bind(&fastCallBridge);
1450 {
1451 result = CallNGCRuntime(glue, RTSTUB_ID(JSFastCallWithArgVAndPushArgv),
1452 { glue, func, thisValue, actualArgc, argv, expectedNum });
1453 Jump(&exit);
1454 }
1455 }
1456 Bind(¬FastCall);
1457 {
1458 BRANCH(Int64Equal(expectedArgc, argc), &slowCall, &slowCallBridge);
1459 Bind(&slowCall);
1460 {
1461 result = CallNGCRuntime(glue, RTSTUB_ID(JSCallWithArgV),
1462 { glue, actualArgc, func, newTarget, thisValue, argv });
1463 Jump(&exit);
1464 }
1465 Bind(&slowCallBridge);
1466 {
1467 result = CallNGCRuntime(glue, RTSTUB_ID(JSCallWithArgVAndPushArgv),
1468 { glue, actualArgc, func, newTarget, thisValue, argv });
1469 Jump(&exit);
1470 }
1471 }
1472 Bind(&exit);
1473 Return(*result);
1474 }
1475
GenerateCircuit()1476 void GetSingleCharCodeByIndexStubBuilder::GenerateCircuit()
1477 {
1478 GateRef glue = PtrArgument(0);
1479 GateRef str = TaggedArgument(1);
1480 GateRef index = Int32Argument(2);
1481 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
1482 BuiltinsStringStubBuilder builder(this, globalEnv);
1483 GateRef result = builder.GetSingleCharCodeByIndex(glue, str, index);
1484 Return(result);
1485 }
1486
GenerateCircuit()1487 void CreateStringBySingleCharCodeStubBuilder::GenerateCircuit()
1488 {
1489 GateRef glue = PtrArgument(0);
1490 GateRef charCode = Int32Argument(1);
1491 GateRef globalEnv = TaggedArgument(2); // 2: 3rd para
1492 BuiltinsStringStubBuilder builder(this, globalEnv);
1493 GateRef result = builder.CreateStringBySingleCharCode(glue, charCode);
1494 Return(result);
1495 }
1496
GenerateCircuit()1497 void FastStringEqualStubBuilder::GenerateCircuit()
1498 {
1499 auto env = GetEnvironment();
1500 GateRef glue = PtrArgument(0);
1501 GateRef str1 = TaggedArgument(1);
1502 GateRef str2 = Int32Argument(2);
1503 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
1504
1505 Label leftEqualRight(env);
1506 Label leftNotEqualRight(env);
1507 Label exit(env);
1508 DEFVARIABLE(result, VariableType::BOOL(), False());
1509 BRANCH(Equal(str1, str2), &leftEqualRight, &leftNotEqualRight);
1510 Bind(&leftEqualRight);
1511 {
1512 result = True();
1513 Jump(&exit);
1514 }
1515 Bind(&leftNotEqualRight);
1516 {
1517 SetCurrentGlobalEnv(globalEnv);
1518 result = FastStringEqual(glue, str1, str2);
1519 Jump(&exit);
1520 }
1521 Bind(&exit);
1522 Return(*result);
1523 }
1524
GenerateCircuit()1525 void FastStringAddStubBuilder::GenerateCircuit()
1526 {
1527 GateRef glue = PtrArgument(0);
1528 GateRef str1 = TaggedArgument(1);
1529 GateRef str2 = Int32Argument(2);
1530 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
1531
1532 BuiltinsStringStubBuilder builtinsStringStubBuilder(this, globalEnv);
1533 GateRef result = builtinsStringStubBuilder.StringConcat(glue, str1, str2);
1534 Return(result);
1535 }
1536
GenerateCircuit()1537 void StringAddStubBuilder::GenerateCircuit()
1538 {
1539 GateRef glue = PtrArgument(0);
1540 GateRef str1 = TaggedArgument(1);
1541 GateRef str2 = TaggedArgument(2); // 2: 3rd argument
1542 GateRef status = Int32Argument(3); // 3: 4th argument
1543 GateRef globalEnv = TaggedArgument(4); // 4: 5th argument
1544
1545 BuiltinsStringStubBuilder builtinsStringStubBuilder(this, globalEnv);
1546 GateRef result = builtinsStringStubBuilder.StringAdd(glue, str1, str2, status);
1547 Return(result);
1548 }
1549
GenerateCircuit()1550 void DeleteObjectPropertyStubBuilder::GenerateCircuit()
1551 {
1552 GateRef glue = PtrArgument(0);
1553 GateRef object = TaggedArgument(1);
1554 GateRef prop = TaggedArgument(2);
1555 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
1556 SetCurrentGlobalEnv(globalEnv);
1557 GateRef result = DeletePropertyOrThrow(glue, object, prop);
1558 Return(result);
1559 }
1560
GenerateCircuit()1561 void GetpropiteratorStubBuilder::GenerateCircuit()
1562 {
1563 GateRef glue = PtrArgument(0);
1564 GateRef object = TaggedArgument(1);
1565 GateRef globalEnv = TaggedArgument(2); // 2: 3rd para
1566 NewObjectStubBuilder newBuilder(this, globalEnv);
1567 GateRef result = newBuilder.EnumerateObjectProperties(glue, object);
1568 Return(result);
1569 }
1570
GenerateCircuit()1571 void GetnextpropnameStubBuilder::GenerateCircuit()
1572 {
1573 GateRef glue = PtrArgument(0);
1574 GateRef iter = TaggedArgument(1);
1575 GateRef result = NextInternal(glue, iter);
1576 Return(result);
1577 }
1578
1579 #define CREATE_ITERATOR_STUB_BUILDER(name, collection, iterationKind) \
1580 void name##StubBuilder::GenerateCircuit() \
1581 { \
1582 auto env = GetEnvironment(); \
1583 Label exit(env); \
1584 \
1585 GateRef glue = PtrArgument(0); \
1586 GateRef obj = TaggedArgument(1); \
1587 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined()); \
1588 \
1589 NewObjectStubBuilder newBuilder(this); \
1590 newBuilder.SetGlue(glue); \
1591 GateRef kind = Int32(static_cast<int32_t>(IterationKind::iterationKind)); \
1592 newBuilder.CreateJSCollectionIterator<JS##collection##Iterator, JS##collection>(&result, &exit, obj, kind); \
1593 Bind(&exit); \
1594 Return(*result); \
1595 }
1596
CREATE_ITERATOR_STUB_BUILDER(CreateJSSetIterator,Set,VALUE)1597 CREATE_ITERATOR_STUB_BUILDER(CreateJSSetIterator, Set, VALUE)
1598 CREATE_ITERATOR_STUB_BUILDER(JSSetEntries, Set, KEY_AND_VALUE)
1599 CREATE_ITERATOR_STUB_BUILDER(JSMapKeys, Map, KEY)
1600 CREATE_ITERATOR_STUB_BUILDER(JSMapValues, Map, VALUE)
1601 CREATE_ITERATOR_STUB_BUILDER(CreateJSMapIterator, Map, KEY_AND_VALUE)
1602
1603 void StringIteratorNextStubBuilder::GenerateCircuit()
1604 {
1605 auto env = GetEnvironment();
1606 Label exit(env);
1607 Label slowpath(env);
1608
1609 GateRef glue = PtrArgument(0);
1610 GateRef obj = TaggedArgument(1);
1611 GateRef globalEnv = TaggedArgument(2); // 2: 3rd para
1612
1613 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
1614
1615 BuiltinsStringStubBuilder builder(this, globalEnv);
1616 builder.StringIteratorNext(glue, obj, Gate::InvalidGateRef, &result, &exit, &slowpath);
1617 Bind(&slowpath);
1618 {
1619 result = CallRuntime(glue, RTSTUB_ID(StringIteratorNext), { obj });
1620 Jump(&exit);
1621 }
1622 Bind(&exit);
1623 Return(*result);
1624 }
1625
GenerateCircuit()1626 void ArrayIteratorNextStubBuilder::GenerateCircuit()
1627 {
1628 auto env = GetEnvironment();
1629 Label exit(env);
1630 Label slowpath(env);
1631
1632 GateRef glue = PtrArgument(0);
1633 GateRef obj = TaggedArgument(1);
1634 GateRef globalEnv = TaggedArgument(2); // 2: 3rd para
1635
1636 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
1637
1638 BuiltinsArrayStubBuilder builder(this, globalEnv);
1639 builder.ArrayIteratorNext(glue, obj, Gate::InvalidGateRef, &result, &exit, &slowpath);
1640 Bind(&slowpath);
1641 {
1642 result = CallRuntime(glue, RTSTUB_ID(ArrayIteratorNext), { obj });
1643 Jump(&exit);
1644 }
1645 Bind(&exit);
1646 Return(*result);
1647 }
1648
GenerateCircuit()1649 void MapIteratorNextStubBuilder::GenerateCircuit()
1650 {
1651 auto env = GetEnvironment();
1652 Label exit(env);
1653
1654 GateRef glue = PtrArgument(0);
1655 GateRef obj = TaggedArgument(1);
1656 GateRef globalEnv = TaggedArgument(2); // 2: 3rd para
1657
1658 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
1659
1660 BuiltinsCollectionIteratorStubBuilder<JSMapIterator> builder(this, glue, obj, Gate::InvalidGateRef, globalEnv);
1661 builder.Next(&result, &exit);
1662 Bind(&exit);
1663 Return(*result);
1664 }
1665
GenerateCircuit()1666 void SetIteratorNextStubBuilder::GenerateCircuit()
1667 {
1668 auto env = GetEnvironment();
1669 Label exit(env);
1670
1671 GateRef glue = PtrArgument(0);
1672 GateRef obj = TaggedArgument(1);
1673 GateRef globalEnv = TaggedArgument(2); // 2: 3rd para
1674
1675 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
1676
1677 BuiltinsCollectionIteratorStubBuilder<JSSetIterator> builder(this, glue, obj, Gate::InvalidGateRef, globalEnv);
1678 builder.Next(&result, &exit);
1679 Bind(&exit);
1680 Return(*result);
1681 }
1682
GenerateCircuit()1683 void GetIteratorStubBuilder::GenerateCircuit()
1684 {
1685 GateRef glue = PtrArgument(0);
1686 GateRef obj = TaggedArgument(1);
1687 GateRef globalEnv = TaggedArgument(2); // 2: 3rd para
1688
1689 SetCurrentGlobalEnv(globalEnv);
1690 GateRef res = GetIterator(glue, obj, ProfileOperation());
1691 Return(res);
1692 }
1693
GenerateCircuit()1694 void JSMapGetStubBuilder::GenerateCircuit()
1695 {
1696 GateRef glue = PtrArgument(0);
1697 GateRef obj = TaggedArgument(1);
1698 GateRef key = TaggedArgument(2U);
1699 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
1700
1701 LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> builder(this, glue, globalEnv);
1702 GateRef linkedTable = builder.GetLinked(obj);
1703 Return(builder.Get(linkedTable, key));
1704 }
1705
GenerateCircuit()1706 void JSMapHasStubBuilder::GenerateCircuit()
1707 {
1708 GateRef glue = PtrArgument(0);
1709 GateRef obj = TaggedArgument(1);
1710 GateRef key = TaggedArgument(2U);
1711 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
1712
1713 LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> builder(this, glue, globalEnv);
1714 GateRef linkedTable = builder.GetLinked(obj);
1715 Return(builder.Has(linkedTable, key));
1716 }
1717
GenerateCircuit()1718 void JSSetHasStubBuilder::GenerateCircuit()
1719 {
1720 GateRef glue = PtrArgument(0);
1721 GateRef obj = TaggedArgument(1);
1722 GateRef key = TaggedArgument(2U);
1723 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
1724
1725 LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> builder(this, glue, globalEnv);
1726 GateRef linkedTable = builder.GetLinked(obj);
1727 Return(builder.Has(linkedTable, key));
1728 }
1729
GenerateCircuit()1730 void JSProxyGetPropertyStubBuilder::GenerateCircuit()
1731 {
1732 GateRef glue = PtrArgument(0);
1733 GateRef holder = TaggedArgument(1);
1734 GateRef key = TaggedArgument(2U);
1735 GateRef receiver = TaggedArgument(3U);
1736 GateRef globalEnv = TaggedArgument(4U);
1737 BuiltinsProxyStubBuilder proxyStubBuilder(this, glue, globalEnv);
1738 GateRef result = proxyStubBuilder.GetProperty(holder, key, receiver);
1739 Return(result);
1740 }
1741
GenerateCircuit()1742 void JSProxySetPropertyStubBuilder::GenerateCircuit()
1743 {
1744 GateRef glue = PtrArgument(0);
1745 GateRef holder = TaggedArgument(1);
1746 GateRef key = TaggedArgument(2U);
1747 GateRef value = TaggedArgument(3U);
1748 GateRef receiver = TaggedArgument(4U);
1749 GateRef globalEnv = TaggedArgument(5U);
1750 BuiltinsProxyStubBuilder proxyStubBuilder(this, glue, globalEnv);
1751 GateRef result = proxyStubBuilder.SetProperty(holder, key, value, receiver, true);
1752 Return(result);
1753 }
1754
GenerateCircuit()1755 void JSProxySetPropertyNoThrowStubBuilder::GenerateCircuit()
1756 {
1757 GateRef glue = PtrArgument(0);
1758 GateRef holder = TaggedArgument(1);
1759 GateRef key = TaggedArgument(2U);
1760 GateRef value = TaggedArgument(3U);
1761 GateRef receiver = TaggedArgument(4U);
1762 GateRef globalEnv = TaggedArgument(5U);
1763 BuiltinsProxyStubBuilder proxyStubBuilder(this, glue, globalEnv);
1764 GateRef result = proxyStubBuilder.SetProperty(holder, key, value, receiver, false);
1765 Return(result);
1766 }
1767
GenerateCircuit()1768 void CreateJSTypedArrayEntriesStubBuilder::GenerateCircuit()
1769 {
1770 auto env = GetEnvironment();
1771 Label exit(env);
1772
1773 GateRef glue = PtrArgument(0);
1774 GateRef obj = TaggedArgument(1);
1775 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
1776
1777 NewObjectStubBuilder newBuilder(this);
1778 newBuilder.SetGlue(glue);
1779 GateRef kind = Int32(static_cast<int32_t>(IterationKind::KEY_AND_VALUE));
1780 newBuilder.CreateJSTypedArrayIterator(&result, &exit, obj, kind);
1781 Bind(&exit);
1782 Return(*result);
1783 }
1784
GenerateCircuit()1785 void CreateJSTypedArrayKeysStubBuilder::GenerateCircuit()
1786 {
1787 auto env = GetEnvironment();
1788 Label exit(env);
1789
1790 GateRef glue = PtrArgument(0);
1791 GateRef obj = TaggedArgument(1);
1792 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
1793
1794 NewObjectStubBuilder newBuilder(this);
1795 newBuilder.SetGlue(glue);
1796 GateRef kind = Int32(static_cast<int32_t>(IterationKind::KEY));
1797 newBuilder.CreateJSTypedArrayIterator(&result, &exit, obj, kind);
1798 Bind(&exit);
1799 Return(*result);
1800 }
1801
GenerateCircuit()1802 void CreateJSTypedArrayValuesStubBuilder::GenerateCircuit()
1803 {
1804 auto env = GetEnvironment();
1805 Label exit(env);
1806
1807 GateRef glue = PtrArgument(0);
1808 GateRef obj = TaggedArgument(1);
1809 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
1810
1811 NewObjectStubBuilder newBuilder(this);
1812 newBuilder.SetGlue(glue);
1813 GateRef kind = Int32(static_cast<int32_t>(IterationKind::VALUE));
1814 newBuilder.CreateJSTypedArrayIterator(&result, &exit, obj, kind);
1815 Bind(&exit);
1816 Return(*result);
1817 }
1818
GenerateCircuit()1819 void JSMapDeleteStubBuilder::GenerateCircuit()
1820 {
1821 GateRef glue = PtrArgument(0);
1822 GateRef obj = TaggedArgument(1);
1823 GateRef key = TaggedArgument(2U);
1824 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
1825
1826 LinkedHashTableStubBuilder<LinkedHashMap, LinkedHashMapObject> builder(this, glue, globalEnv);
1827 GateRef linkedTable = builder.GetLinked(obj);
1828 Return(builder.Delete(linkedTable, key));
1829 }
1830
GenerateCircuit()1831 void JSSetDeleteStubBuilder::GenerateCircuit()
1832 {
1833 GateRef glue = PtrArgument(0);
1834 GateRef obj = TaggedArgument(1);
1835 GateRef key = TaggedArgument(2U);
1836 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
1837
1838 LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> builder(this, glue, globalEnv);
1839 GateRef linkedTable = builder.GetLinked(obj);
1840 Return(builder.Delete(linkedTable, key));
1841 }
1842
GenerateCircuit()1843 void JSSetAddStubBuilder::GenerateCircuit()
1844 {
1845 GateRef glue = PtrArgument(0);
1846 GateRef obj = TaggedArgument(1);
1847 GateRef key = TaggedArgument(2U);
1848 GateRef globalEnv = TaggedArgument(3); // 3: 4th para
1849
1850 LinkedHashTableStubBuilder<LinkedHashSet, LinkedHashSetObject> builder(this, glue, globalEnv);
1851 GateRef linkedTable = builder.GetLinked(obj);
1852 GateRef newTable = builder.Insert(linkedTable, key, key);
1853 builder.Store(VariableType::JS_ANY(), glue, obj, IntPtr(JSSet::LINKED_SET_OFFSET), newTable);
1854 Return(obj);
1855 }
1856
GenerateCircuit()1857 void GrowElementsCapacityStubBuilder::GenerateCircuit()
1858 {
1859 GateRef glue = PtrArgument(0);
1860 GateRef thisValue = TaggedArgument(1);
1861 GateRef globalEnv = TaggedArgument(2U);
1862 GateRef newLength = Int32Argument(3U);
1863 DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
1864 BuiltinsArrayStubBuilder builder(this, globalEnv);
1865 result = builder.GrowElementsCapacity(glue, thisValue, newLength);
1866 Return(*result);
1867 }
1868
GenerateCircuit()1869 void SameValueStubBuilder::GenerateCircuit()
1870 {
1871 GateRef glue = PtrArgument(0);
1872 GateRef left = TaggedArgument(1);
1873 GateRef right = TaggedArgument(2U);
1874 GateRef globalEnv = TaggedArgument(3U); // 3 : 4th para
1875 SetCurrentGlobalEnv(globalEnv);
1876 GateRef result = SameValue(glue, left, right);
1877 Return(result);
1878 }
1879
GenerateCircuit()1880 void BatchBarrierStubBuilder::GenerateCircuit()
1881 {
1882 GateRef glue = PtrArgument(0);
1883 GateRef dstObj = PtrArgument(1);
1884 GateRef dstAddr = PtrArgument(2);
1885 GateRef taggedValueCount = TaggedArgument(3);
1886 BarrierStubBuilder barrierBuilder(this, glue, dstObj, dstAddr, taggedValueCount);
1887 barrierBuilder.DoBatchBarrier();
1888 Return();
1889 }
1890
GenerateCircuit()1891 void ReverseBarrierStubBuilder::GenerateCircuit()
1892 {
1893 GateRef glue = PtrArgument(0);
1894 GateRef dstObj = PtrArgument(1);
1895 GateRef dstAddr = PtrArgument(2);
1896 GateRef taggedValueCount = TaggedArgument(3);
1897 BarrierStubBuilder barrierBuilder(this, glue, dstObj, dstAddr, taggedValueCount);
1898 barrierBuilder.DoReverseBarrier();
1899 Return();
1900 }
1901
GenerateCircuit()1902 void MoveBarrierInRegionStubBuilder::GenerateCircuit()
1903 {
1904 GateRef glue = PtrArgument(0);
1905 GateRef dstObj = PtrArgument(1);
1906 GateRef dstAddr = PtrArgument(2);
1907 GateRef count = Int32Argument(3);
1908 GateRef srcAddr = PtrArgument(4);
1909 BarrierStubBuilder barrierBuilder(this, glue, dstObj, dstAddr, count);
1910 barrierBuilder.DoMoveBarrierInRegion(srcAddr);
1911 Return();
1912 }
1913
GenerateCircuit()1914 void MoveBarrierCrossRegionStubBuilder::GenerateCircuit()
1915 {
1916 GateRef glue = PtrArgument(0);
1917 GateRef dstObj = PtrArgument(1);
1918 GateRef dstAddr = PtrArgument(2);
1919 GateRef count = Int32Argument(3);
1920 GateRef srcAddr = PtrArgument(4);
1921 GateRef srcObj = PtrArgument(5);
1922 BarrierStubBuilder barrierBuilder(this, glue, dstObj, dstAddr, count);
1923 barrierBuilder.DoMoveBarrierCrossRegion(srcAddr, srcObj);
1924 Return();
1925 }
1926
GenerateCircuit()1927 void FindEntryFromNameDictionaryStubBuilder::GenerateCircuit()
1928 {
1929 GateRef glue = PtrArgument(0);
1930 GateRef taggedArray = PtrArgument(1);
1931 GateRef key = PtrArgument(2);
1932 GateRef entry = FindEntryFromHashTable<NameDictionary>(glue, taggedArray, key);
1933 Return(entry);
1934 }
1935
1936 CallSignature CommonStubCSigns::callSigns_[CommonStubCSigns::NUM_OF_STUBS];
1937
Initialize()1938 void CommonStubCSigns::Initialize()
1939 {
1940 #define INIT_SIGNATURES(name) \
1941 name##CallSignature::Initialize(&callSigns_[name]); \
1942 callSigns_[name].SetID(name); \
1943 callSigns_[name].SetName(std::string("COStub_") + #name); \
1944 callSigns_[name].SetConstructor( \
1945 [](void* env) { \
1946 return static_cast<void*>( \
1947 new name##StubBuilder(&callSigns_[name], static_cast<Environment*>(env))); \
1948 });
1949
1950 COMMON_STUB_ID_LIST(INIT_SIGNATURES)
1951 #undef INIT_SIGNATURES
1952
1953 #define INIT_SIGNATURES_DYN(name, base) \
1954 base##CallSignature::Initialize(&callSigns_[name]); \
1955 callSigns_[name].SetID(name); \
1956 callSigns_[name].SetName(std::string("COStub_") + #name); \
1957 callSigns_[name].SetConstructor( \
1958 [](void* env) { \
1959 return static_cast<void*>( \
1960 new name##StubBuilder(&callSigns_[name], static_cast<Environment*>(env))); \
1961 }); \
1962 callSigns_[name].SetStwCopyStub(true); \
1963 callSigns_[name].SetTargetKind(CallSignature::TargetKind::COMMON_STW_COPY_STUB);
1964
1965 #define INIT_SIGNATURES_DYN_SECOND(base) \
1966 INIT_SIGNATURES_DYN(base##StwCopy, base)
1967
1968 COMMON_STW_COPY_STUB_LIST(INIT_SIGNATURES_DYN_SECOND)
1969 #undef INIT_SIGNATURES_DYN_SECOND
1970 #undef INIT_SIGNATURES_DYN
1971 }
1972
GetCSigns(std::vector<const CallSignature * > & outCSigns)1973 void CommonStubCSigns::GetCSigns(std::vector<const CallSignature*>& outCSigns)
1974 {
1975 for (size_t i = 0; i < NUM_OF_STUBS; i++) {
1976 outCSigns.push_back(&callSigns_[i]);
1977 }
1978 }
1979 } // namespace panda::ecmascript::kungfu
1980