1 /*
2 * Copyright (c) 2024 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/call_stub_builder.h"
17
18 #include "ecmascript/compiler/assembler_module.h"
19 #include "ecmascript/compiler/stub_builder-inl.h"
20
21 namespace panda::ecmascript::kungfu {
22
JSCallDispatchForBaseline(Label *exit, Label *noNeedCheckException)23 void CallStubBuilder::JSCallDispatchForBaseline(Label *exit, Label *noNeedCheckException)
24 {
25 this->isForBaseline_ = true;
26 auto env = GetEnvironment();
27 baselineBuiltinFp_ = CallNGCRuntime(glue_, RTSTUB_ID(GetBaselineBuiltinFp), {glue_});
28
29 // 1. call initialize
30 Label funcIsHeapObject(env);
31 Label funcIsCallable(env);
32 Label funcNotCallable(env);
33 JSCallInit(exit, &funcIsHeapObject, &funcIsCallable, &funcNotCallable);
34
35 // 2. dispatch
36 Label methodIsNative(env);
37 Label methodNotNative(env);
38 BRANCH(Int64NotEqual(Int64And(callField_, isNativeMask_), Int64(0)), &methodIsNative, &methodNotNative);
39
40 // 3. call native
41 Bind(&methodIsNative);
42 {
43 JSCallNative(exit);
44 }
45
46 // 4. call nonNative
47 Bind(&methodNotNative);
48 {
49 JSCallJSFunction(exit, noNeedCheckException);
50 }
51 }
52
JSCallDispatch()53 GateRef CallStubBuilder::JSCallDispatch()
54 {
55 this->isForBaseline_ = false;
56 auto env = GetEnvironment();
57 Label entryPass(env);
58 Label exit(env);
59 env->SubCfgEntry(&entryPass);
60 DEFVARIABLE(result, VariableType::JS_ANY(), Exception());
61
62 this->result_ = &result;
63
64 // 1. call initialize
65 Label funcIsHeapObject(env);
66 Label funcIsCallable(env);
67 Label funcNotCallable(env);
68 JSCallInit(&exit, &funcIsHeapObject, &funcIsCallable, &funcNotCallable);
69
70 // 2. dispatch
71 Label methodIsNative(env);
72 Label methodNotNative(env);
73 BRANCH(Int64NotEqual(Int64And(callField_, isNativeMask_), Int64(0)), &methodIsNative, &methodNotNative);
74
75 // 3. call native
76 Bind(&methodIsNative);
77 {
78 JSCallNative(&exit);
79 }
80 // 4. call nonNative
81 Bind(&methodNotNative);
82 {
83 JSCallJSFunction(&exit);
84 }
85
86 Bind(&exit);
87 auto ret = *result;
88 env->SubCfgExit();
89 return ret;
90 }
91
JSCallInit(Label *exit, Label *funcIsHeapObject, Label *funcIsCallable, Label *funcNotCallable)92 void CallStubBuilder::JSCallInit(Label *exit, Label *funcIsHeapObject, Label *funcIsCallable, Label *funcNotCallable)
93 {
94 if (!isForBaseline_) {
95 // save pc
96 SavePcIfNeeded(glue_);
97 }
98 #if ECMASCRIPT_ENABLE_FUNCTION_CALL_TIMER
99 CallNGCRuntime(glue_, RTSTUB_ID(StartCallTimer, { glue_, func_, False()}));
100 #endif
101 if (checkIsCallable_) {
102 BRANCH(TaggedIsHeapObject(func_), funcIsHeapObject, funcNotCallable);
103 Bind(funcIsHeapObject);
104 GateRef hclass = LoadHClass(func_);
105 bitfield_ = Load(VariableType::INT32(), hclass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
106 BRANCH(IsCallableFromBitField(bitfield_), funcIsCallable, funcNotCallable);
107 Bind(funcNotCallable);
108 {
109 CallRuntime(glue_, RTSTUB_ID(ThrowNotCallableException), {});
110 Jump(exit);
111 }
112 Bind(funcIsCallable);
113 } else {
114 GateRef hclass = LoadHClass(func_);
115 bitfield_ = Load(VariableType::INT32(), hclass, IntPtr(JSHClass::BIT_FIELD_OFFSET));
116 }
117 method_ = GetMethodFromJSFunctionOrProxy(func_);
118 callField_ = GetCallFieldFromMethod(method_);
119 isNativeMask_ = Int64(static_cast<uint64_t>(1) << MethodLiteral::IsNativeBit::START_BIT);
120 }
121
JSCallNative(Label *exit)122 void CallStubBuilder::JSCallNative(Label *exit)
123 {
124 HandleProfileNativeCall();
125 GateRef ret;
126 nativeCode_ = Load(VariableType::NATIVE_POINTER(), method_,
127 IntPtr(Method::NATIVE_POINTER_OR_BYTECODE_ARRAY_OFFSET));
128 newTarget_ = Undefined();
129 thisValue_ = Undefined();
130 numArgs_ = Int32Add(actualNumArgs_, Int32(NUM_MANDATORY_JSFUNC_ARGS));
131 GateRef numArgsKeeper;
132
133 int idxForNative = PrepareIdxForNative();
134 std::vector<GateRef> argsForNative = PrepareArgsForNative();
135 auto env = GetEnvironment();
136 Label notFastBuiltins(env);
137 switch (callArgs_.mode) {
138 case JSCallMode::CALL_THIS_ARG0:
139 case JSCallMode::CALL_THIS_ARG1:
140 case JSCallMode::CALL_THIS_ARG2:
141 case JSCallMode::CALL_THIS_ARG3:
142 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
143 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
144 numArgsKeeper = numArgs_;
145 CallFastBuiltin(¬FastBuiltins, exit);
146 Bind(¬FastBuiltins);
147 numArgs_ = numArgsKeeper;
148 [[fallthrough]];
149 case JSCallMode::CALL_ARG0:
150 case JSCallMode::CALL_ARG1:
151 case JSCallMode::CALL_ARG2:
152 case JSCallMode::CALL_ARG3:
153 case JSCallMode::CALL_WITH_ARGV:
154 case JSCallMode::CALL_THIS_WITH_ARGV:
155 case JSCallMode::DEPRECATED_CALL_ARG0:
156 case JSCallMode::DEPRECATED_CALL_ARG1:
157 case JSCallMode::DEPRECATED_CALL_ARG2:
158 case JSCallMode::DEPRECATED_CALL_ARG3:
159 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
160 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
161 case JSCallMode::CALL_GETTER:
162 case JSCallMode::CALL_SETTER:
163 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
164 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
165 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
166 ret = CallNGCRuntime(glue_, idxForNative, argsForNative, hir_);
167 break;
168 case JSCallMode::SUPER_CALL_WITH_ARGV:
169 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
170 ret = CallRuntime(glue_, idxForNative, argsForNative);
171 break;
172 default:
173 LOG_ECMA(FATAL) << "this branch is unreachable";
174 UNREACHABLE();
175 }
176 result_->WriteVariable(ret);
177 Jump(exit);
178 }
179
JSCallJSFunction(Label *exit, Label *noNeedCheckException)180 void CallStubBuilder::JSCallJSFunction(Label *exit, Label *noNeedCheckException)
181 {
182 auto env = GetEnvironment();
183
184 Label funcIsClassConstructor(env);
185 Label funcNotClassConstructor(env);
186 Label methodNotAot(env);
187
188 if (!AssemblerModule::IsCallNew(callArgs_.mode)) {
189 BRANCH(IsClassConstructorFromBitField(bitfield_), &funcIsClassConstructor, &funcNotClassConstructor);
190 Bind(&funcIsClassConstructor);
191 {
192 CallRuntime(glue_, RTSTUB_ID(ThrowCallConstructorException), {});
193 Jump(exit);
194 }
195 Bind(&funcNotClassConstructor);
196 }
197 HandleProfileCall();
198 if (isForBaseline_ && env->IsBaselineBuiltin()) {
199 sp_ = Argument(static_cast<size_t>(BaselineCallInputs::SP));
200 }
201 if (!isForBaseline_ && env->IsAsmInterp()) {
202 sp_ = Argument(static_cast<size_t>(InterpreterHandlerInputs::SP));
203 }
204 Label methodisAot(env);
205 Label funcHasBaselineCode(env);
206 Label funcCheckBaselineCode(env);
207 Label checkIsBaselineCompiling(env);
208 Label methodIsFastCall(env);
209 Label methodNotFastCall(env);
210 Label checkAot(env);
211 {
212 newTarget_ = Undefined();
213 thisValue_ = Undefined();
214 realNumArgs_ = Int64Add(ZExtInt32ToInt64(actualNumArgs_), Int64(NUM_MANDATORY_JSFUNC_ARGS));
215 BRANCH(IsJsProxy(func_), &methodNotAot, &checkAot);
216 Bind(&checkAot);
217 BRANCH(JudgeAotAndFastCall(func_, CircuitBuilder::JudgeMethodType::HAS_AOT_FASTCALL), &methodIsFastCall,
218 &methodNotFastCall);
219 Bind(&methodIsFastCall);
220 {
221 JSFastAotCall(exit);
222 }
223
224 Bind(&methodNotFastCall);
225 BRANCH(JudgeAotAndFastCall(func_, CircuitBuilder::JudgeMethodType::HAS_AOT), &methodisAot,
226 &funcCheckBaselineCode);
227 Bind(&methodisAot);
228 {
229 JSSlowAotCall(exit);
230 }
231
232 Bind(&funcCheckBaselineCode);
233 GateRef baselineCodeOffset = IntPtr(JSFunction::BASELINECODE_OFFSET);
234 GateRef baselineCode = Load(VariableType::JS_POINTER(), func_, baselineCodeOffset);
235
236 Branch(NotEqual(baselineCode, Undefined()), &checkIsBaselineCompiling, &methodNotAot);
237 Bind(&checkIsBaselineCompiling);
238 Branch(NotEqual(baselineCode, Hole()), &funcHasBaselineCode, &methodNotAot);
239
240 Bind(&funcHasBaselineCode);
241 {
242 GateRef res = result_->Value();
243 JSCallAsmInterpreter(true, &methodNotAot, exit, noNeedCheckException);
244 if (!isForBaseline_) {
245 ASSERT(CheckResultValueChangedWithReturn(res));
246 }
247 (void) res;
248 }
249
250 Bind(&methodNotAot);
251 {
252 JSCallAsmInterpreter(false, &methodNotAot, exit, noNeedCheckException);
253 }
254 }
255 }
256
JSFastAotCall(Label *exit)257 void CallStubBuilder::JSFastAotCall(Label *exit)
258 {
259 auto env = GetEnvironment();
260 Label fastCall(env);
261 Label fastCallBridge(env);
262 isFast_ = true;
263
264 GateRef expectedNum = Int64And(Int64LSR(callField_, Int64(MethodLiteral::NumArgsBits::START_BIT)),
265 Int64((1LU << MethodLiteral::NumArgsBits::SIZE) - 1));
266 GateRef expectedArgc = Int64Add(expectedNum, Int64(NUM_MANDATORY_JSFUNC_ARGS));
267 BRANCH(Int64Equal(expectedArgc, realNumArgs_), &fastCall, &fastCallBridge);
268 GateRef code;
269 Bind(&fastCall);
270 {
271 isBridge_ = false;
272 code = GetAotCodeAddr(func_);
273 CallBridge(code, expectedNum, exit);
274 }
275 Bind(&fastCallBridge);
276 {
277 isBridge_ = true;
278 CallBridge(code, expectedNum, exit);
279 }
280 }
281
JSSlowAotCall(Label *exit)282 void CallStubBuilder::JSSlowAotCall(Label *exit)
283 {
284 auto env = GetEnvironment();
285 Label slowCall(env);
286 Label slowCallBridge(env);
287 isFast_ = false;
288
289 GateRef expectedNum = Int64And(Int64LSR(callField_, Int64(MethodLiteral::NumArgsBits::START_BIT)),
290 Int64((1LU << MethodLiteral::NumArgsBits::SIZE) - 1));
291 GateRef expectedArgc = Int64Add(expectedNum, Int64(NUM_MANDATORY_JSFUNC_ARGS));
292 BRANCH(Int64Equal(expectedArgc, realNumArgs_), &slowCall, &slowCallBridge);
293 GateRef code;
294 Bind(&slowCall);
295 {
296 isBridge_ = false;
297 code = GetAotCodeAddr(func_);
298 CallBridge(code, expectedNum, exit);
299 }
300 Bind(&slowCallBridge);
301 {
302 isBridge_ = true;
303 CallBridge(code, expectedNum, exit);
304 }
305 }
306
CallConstructorBridge(const int idxForAot, const std::vector<GateRef> &argsForAot)307 GateRef CallStubBuilder::CallConstructorBridge(const int idxForAot, const std::vector<GateRef> &argsForAot)
308 {
309 GateRef ret;
310 switch (callArgs_.mode) {
311 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
312 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
313 ret = CallNGCRuntime(glue_, idxForAot, argsForAot);
314 ret = ConstructorCheck(glue_, func_, ret, callArgs_.callConstructorArgs.thisObj);
315 break;
316 case JSCallMode::SUPER_CALL_WITH_ARGV:
317 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
318 ret = CallNGCRuntime(glue_, idxForAot, argsForAot, hir_);
319 ret = ConstructorCheck(glue_, func_, ret, callArgs_.superCallArgs.thisObj);
320 break;
321 default:
322 LOG_ECMA(FATAL) << "this branch is unreachable";
323 UNREACHABLE();
324 }
325 return ret;
326 }
327
CallBridge(GateRef code, GateRef expectedNum, Label *exit)328 void CallStubBuilder::CallBridge(GateRef code, GateRef expectedNum, Label *exit)
329 {
330 int idxForAot = PrepareIdxForAot();
331 std::vector<GateRef> argsForAot = PrepareArgsForAot(expectedNum);
332 GateRef ret;
333 switch (callArgs_.mode) {
334 case JSCallMode::CALL_ARG0:
335 case JSCallMode::CALL_ARG1:
336 case JSCallMode::CALL_ARG2:
337 case JSCallMode::CALL_ARG3:
338 case JSCallMode::CALL_THIS_ARG0:
339 case JSCallMode::CALL_THIS_ARG1:
340 case JSCallMode::CALL_THIS_ARG2:
341 case JSCallMode::CALL_THIS_ARG3:
342 case JSCallMode::DEPRECATED_CALL_ARG0:
343 case JSCallMode::DEPRECATED_CALL_ARG1:
344 case JSCallMode::DEPRECATED_CALL_ARG2:
345 case JSCallMode::DEPRECATED_CALL_ARG3:
346 case JSCallMode::CALL_GETTER:
347 case JSCallMode::CALL_SETTER:
348 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
349 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
350 if (IsFastAotCall()) {
351 ret = FastCallOptimized(glue_, code, argsForAot, hir_);
352 } else if (IsSlowAotCall()) {
353 ret = CallOptimized(glue_, code, argsForAot, hir_);
354 } else {
355 ret = CallNGCRuntime(glue_, idxForAot, argsForAot, hir_);
356 }
357 break;
358 case JSCallMode::CALL_WITH_ARGV:
359 case JSCallMode::CALL_THIS_WITH_ARGV:
360 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
361 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
362 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
363 ret = CallNGCRuntime(glue_, idxForAot, argsForAot);
364 break;
365 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
366 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
367 case JSCallMode::SUPER_CALL_WITH_ARGV:
368 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
369 ret = CallConstructorBridge(idxForAot, argsForAot);
370 break;
371 default:
372 LOG_ECMA(FATAL) << "this branch is unreachable";
373 UNREACHABLE();
374 }
375 result_->WriteVariable(ret);
376 Jump(exit);
377 }
378
JSCallAsmInterpreter(bool hasBaselineCode, Label *methodNotAot, Label *exit, Label *noNeedCheckException)379 void CallStubBuilder::JSCallAsmInterpreter(bool hasBaselineCode, Label *methodNotAot, Label *exit,
380 Label *noNeedCheckException)
381 {
382 if (jumpSize_ != 0) {
383 SaveJumpSizeIfNeeded(glue_, jumpSize_);
384 }
385 SaveHotnessCounterIfNeeded(glue_, sp_, hotnessCounter_, callArgs_.mode);
386
387 int idxForAsmInterpreter = isForBaseline_ ?
388 (hasBaselineCode ?
389 PrepareIdxForAsmInterpreterForBaselineWithBaselineCode() :
390 PrepareIdxForAsmInterpreterForBaselineWithoutBaselineCode()) :
391 (hasBaselineCode ?
392 PrepareIdxForAsmInterpreterWithBaselineCode() :
393 PrepareIdxForAsmInterpreterWithoutBaselineCode());
394 std::vector<GateRef> argsForAsmInterpreter = PrepareArgsForAsmInterpreter();
395
396 switch (callArgs_.mode) {
397 case JSCallMode::CALL_ARG0:
398 case JSCallMode::CALL_ARG1:
399 case JSCallMode::CALL_ARG2:
400 case JSCallMode::CALL_ARG3:
401 case JSCallMode::CALL_THIS_ARG0:
402 case JSCallMode::CALL_THIS_ARG1:
403 case JSCallMode::CALL_THIS_ARG2:
404 case JSCallMode::CALL_THIS_ARG3:
405 case JSCallMode::DEPRECATED_CALL_ARG0:
406 case JSCallMode::DEPRECATED_CALL_ARG1:
407 case JSCallMode::DEPRECATED_CALL_ARG2:
408 case JSCallMode::DEPRECATED_CALL_ARG3:
409 case JSCallMode::CALL_WITH_ARGV:
410 case JSCallMode::CALL_THIS_WITH_ARGV:
411 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
412 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
413 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
414 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
415 case JSCallMode::SUPER_CALL_WITH_ARGV:
416 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
417 *result_ = CallNGCRuntime(glue_, idxForAsmInterpreter, argsForAsmInterpreter);
418 if (!isForBaseline_) {
419 Return();
420 }
421 break;
422 case JSCallMode::CALL_GETTER:
423 case JSCallMode::CALL_SETTER:
424 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
425 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
426 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
427 if (isForBaseline_) {
428 *result_ = CallNGCRuntime(glue_, idxForAsmInterpreter, argsForAsmInterpreter);
429 } else if (hasBaselineCode) {
430 Jump(methodNotAot);
431 } else {
432 *result_ = CallNGCRuntime(glue_, idxForAsmInterpreter, argsForAsmInterpreter, hir_);
433 Jump(exit);
434 }
435 break;
436 default:
437 LOG_ECMA(FATAL) << "this branch is unreachable";
438 UNREACHABLE();
439 }
440
441 if (isForBaseline_) {
442 if (noNeedCheckException != nullptr) {
443 Jump(noNeedCheckException);
444 } else {
445 Jump(exit);
446 }
447 }
448 }
449
PrepareIdxForNative()450 int CallStubBuilder::PrepareIdxForNative()
451 {
452 switch (callArgs_.mode) {
453 case JSCallMode::CALL_ARG0:
454 case JSCallMode::CALL_ARG1:
455 case JSCallMode::CALL_ARG2:
456 case JSCallMode::CALL_ARG3:
457 case JSCallMode::CALL_THIS_ARG0:
458 case JSCallMode::CALL_THIS_ARG1:
459 case JSCallMode::CALL_THIS_ARG2:
460 case JSCallMode::CALL_THIS_ARG3:
461 case JSCallMode::DEPRECATED_CALL_ARG0:
462 case JSCallMode::DEPRECATED_CALL_ARG1:
463 case JSCallMode::DEPRECATED_CALL_ARG2:
464 case JSCallMode::DEPRECATED_CALL_ARG3:
465 case JSCallMode::CALL_GETTER:
466 case JSCallMode::CALL_SETTER:
467 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
468 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
469 return RTSTUB_ID(PushCallArgsAndDispatchNative);
470 case JSCallMode::CALL_WITH_ARGV:
471 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
472 case JSCallMode::CALL_THIS_WITH_ARGV:
473 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
474 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
475 return RTSTUB_ID(PushCallRangeAndDispatchNative);
476 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
477 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
478 return RTSTUB_ID(PushCallNewAndDispatchNative);
479 case JSCallMode::SUPER_CALL_WITH_ARGV:
480 return RTSTUB_ID(SuperCall);
481 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
482 return RTSTUB_ID(SuperCallSpread);
483 default:
484 LOG_ECMA(FATAL) << "this branch is unreachable";
485 UNREACHABLE();
486 }
487 }
488
PrepareArgsForNative()489 std::vector<GateRef> CallStubBuilder::PrepareArgsForNative()
490 {
491 std::vector<GateRef> basicArgs = PrepareBasicArgsForNative();
492 std::vector<GateRef> appendArgs = PrepareAppendArgsForNative();
493
494 basicArgs.insert(basicArgs.end(), appendArgs.begin(), appendArgs.end());
495 return basicArgs;
496 }
497
PrepareBasicArgsForNative()498 std::vector<GateRef> CallStubBuilder::PrepareBasicArgsForNative()
499 {
500 switch (callArgs_.mode) {
501 case JSCallMode::CALL_ARG0:
502 case JSCallMode::CALL_ARG1:
503 case JSCallMode::CALL_ARG2:
504 case JSCallMode::CALL_ARG3:
505 case JSCallMode::DEPRECATED_CALL_ARG0:
506 case JSCallMode::DEPRECATED_CALL_ARG1:
507 case JSCallMode::DEPRECATED_CALL_ARG2:
508 case JSCallMode::DEPRECATED_CALL_ARG3:
509 return { nativeCode_, glue_, numArgs_, func_, newTarget_, thisValue_ };
510 case JSCallMode::CALL_THIS_ARG0:
511 case JSCallMode::CALL_THIS_ARG1:
512 case JSCallMode::CALL_THIS_ARG2:
513 case JSCallMode::CALL_THIS_ARG3:
514 case JSCallMode::CALL_GETTER:
515 case JSCallMode::CALL_SETTER:
516 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
517 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
518 return { nativeCode_, glue_, numArgs_, func_, newTarget_ };
519 case JSCallMode::CALL_WITH_ARGV:
520 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
521 return { glue_, nativeCode_, func_, thisValue_ };
522 case JSCallMode::CALL_THIS_WITH_ARGV:
523 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
524 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
525 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
526 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
527 return { glue_, nativeCode_, func_ };
528 case JSCallMode::SUPER_CALL_WITH_ARGV:
529 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
530 return {};
531 default:
532 LOG_ECMA(FATAL) << "this branch is unreachable";
533 UNREACHABLE();
534 }
535 }
536
PrepareAppendArgsForNative()537 std::vector<GateRef> CallStubBuilder::PrepareAppendArgsForNative()
538 {
539 switch (callArgs_.mode) {
540 case JSCallMode::CALL_ARG0:
541 case JSCallMode::DEPRECATED_CALL_ARG0:
542 return {};
543 case JSCallMode::CALL_ARG1:
544 case JSCallMode::DEPRECATED_CALL_ARG1:
545 return {
546 callArgs_.callArgs.arg0
547 };
548 case JSCallMode::CALL_ARG2:
549 case JSCallMode::DEPRECATED_CALL_ARG2:
550 return {
551 callArgs_.callArgs.arg0,
552 callArgs_.callArgs.arg1
553 };
554 case JSCallMode::CALL_ARG3:
555 case JSCallMode::DEPRECATED_CALL_ARG3:
556 return {
557 callArgs_.callArgs.arg0,
558 callArgs_.callArgs.arg1,
559 callArgs_.callArgs.arg2
560 };
561 case JSCallMode::CALL_THIS_ARG0:
562 return {
563 callArgs_.callArgsWithThis.thisValue
564 };
565 case JSCallMode::CALL_THIS_ARG1:
566 return {
567 callArgs_.callArgsWithThis.thisValue,
568 callArgs_.callArgsWithThis.arg0
569 };
570 case JSCallMode::CALL_THIS_ARG2:
571 return {
572 callArgs_.callArgsWithThis.thisValue,
573 callArgs_.callArgsWithThis.arg0,
574 callArgs_.callArgsWithThis.arg1
575 };
576 case JSCallMode::CALL_THIS_ARG3:
577 return {
578 callArgs_.callArgsWithThis.thisValue,
579 callArgs_.callArgsWithThis.arg0,
580 callArgs_.callArgsWithThis.arg1,
581 callArgs_.callArgsWithThis.arg2
582 };
583 case JSCallMode::CALL_GETTER:
584 return {
585 callArgs_.callGetterArgs.receiver
586 };
587 case JSCallMode::CALL_SETTER:
588 return {
589 callArgs_.callSetterArgs.receiver,
590 callArgs_.callSetterArgs.value
591 };
592 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
593 return {
594 callArgs_.callThisArg2WithReturnArgs.thisValue,
595 callArgs_.callThisArg2WithReturnArgs.arg0,
596 callArgs_.callThisArg2WithReturnArgs.arg1
597 };
598 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
599 return {
600 callArgs_.callThisArg3WithReturnArgs.argHandle,
601 callArgs_.callThisArg3WithReturnArgs.value,
602 callArgs_.callThisArg3WithReturnArgs.key,
603 callArgs_.callThisArg3WithReturnArgs.thisValue
604 };
605 case JSCallMode::CALL_WITH_ARGV:
606 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
607 return {
608 callArgs_.callArgv.argc,
609 callArgs_.callArgv.argv
610 };
611 case JSCallMode::CALL_THIS_WITH_ARGV:
612 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
613 return {
614 callArgs_.callArgvWithThis.thisValue,
615 callArgs_.callArgvWithThis.argc,
616 callArgs_.callArgvWithThis.argv
617 };
618 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
619 return {
620 callArgs_.callThisArgvWithReturnArgs.thisValue,
621 callArgs_.callThisArgvWithReturnArgs.argc,
622 callArgs_.callThisArgvWithReturnArgs.argv
623 };
624 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
625 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
626 return {
627 callArgs_.callConstructorArgs.thisObj,
628 callArgs_.callConstructorArgs.argc,
629 callArgs_.callConstructorArgs.argv
630 };
631 case JSCallMode::SUPER_CALL_WITH_ARGV:
632 return {
633 callArgs_.superCallArgs.thisFunc,
634 callArgs_.superCallArgs.array,
635 IntToTaggedInt(callArgs_.superCallArgs.argc)
636 };
637 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
638 return {
639 callArgs_.superCallArgs.thisFunc,
640 callArgs_.superCallArgs.array
641 };
642 default:
643 LOG_ECMA(FATAL) << "this branch is unreachable";
644 UNREACHABLE();
645 }
646 }
647
PrepareIdxForAot()648 int CallStubBuilder::PrepareIdxForAot()
649 {
650 switch (callArgs_.mode) {
651 case JSCallMode::CALL_ARG0:
652 case JSCallMode::CALL_ARG1:
653 case JSCallMode::CALL_ARG2:
654 case JSCallMode::CALL_ARG3:
655 case JSCallMode::CALL_THIS_ARG0:
656 case JSCallMode::CALL_THIS_ARG1:
657 case JSCallMode::CALL_THIS_ARG2:
658 case JSCallMode::CALL_THIS_ARG3:
659 case JSCallMode::DEPRECATED_CALL_ARG0:
660 case JSCallMode::DEPRECATED_CALL_ARG1:
661 case JSCallMode::DEPRECATED_CALL_ARG2:
662 case JSCallMode::DEPRECATED_CALL_ARG3:
663 case JSCallMode::CALL_GETTER:
664 case JSCallMode::CALL_SETTER:
665 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
666 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
667 if (isFast_) {
668 return RTSTUB_ID(OptimizedFastCallAndPushArgv);
669 } else {
670 return RTSTUB_ID(OptimizedCallAndPushArgv);
671 }
672 case JSCallMode::CALL_WITH_ARGV:
673 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
674 case JSCallMode::CALL_THIS_WITH_ARGV:
675 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
676 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
677 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
678 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
679 case JSCallMode::SUPER_CALL_WITH_ARGV:
680 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
681 if (IsFastAotCall()) {
682 return RTSTUB_ID(JSFastCallWithArgV);
683 } else if (IsFastAotCallWithBridge()) {
684 return RTSTUB_ID(JSFastCallWithArgVAndPushArgv);
685 } else if (IsSlowAotCall()) {
686 return RTSTUB_ID(JSCallWithArgV);
687 } else {
688 return RTSTUB_ID(JSCallWithArgVAndPushArgv);
689 }
690 default:
691 LOG_ECMA(FATAL) << "this branch is unreachable";
692 UNREACHABLE();
693 }
694 }
695
PrepareArgsForAot(GateRef expectedNum)696 std::vector<GateRef> CallStubBuilder::PrepareArgsForAot(GateRef expectedNum)
697 {
698 std::vector<GateRef> basicArgs = PrepareBasicArgsForAot();
699
700 std::vector<GateRef> appendArgs = PrepareAppendArgsForAotStep1();
701 basicArgs.insert(basicArgs.end(), appendArgs.begin(), appendArgs.end());
702
703 appendArgs = PrepareAppendArgsForAotStep2();
704 basicArgs.insert(basicArgs.end(), appendArgs.begin(), appendArgs.end());
705
706 appendArgs = PrepareAppendArgsForAotStep3(expectedNum);
707 basicArgs.insert(basicArgs.end(), appendArgs.begin(), appendArgs.end());
708
709 return basicArgs;
710 }
711
PrepareBasicArgsForAot()712 std::vector<GateRef> CallStubBuilder::PrepareBasicArgsForAot()
713 {
714 switch (callArgs_.mode) {
715 case JSCallMode::CALL_ARG0:
716 case JSCallMode::CALL_ARG1:
717 case JSCallMode::CALL_ARG2:
718 case JSCallMode::CALL_ARG3:
719 case JSCallMode::DEPRECATED_CALL_ARG0:
720 case JSCallMode::DEPRECATED_CALL_ARG1:
721 case JSCallMode::DEPRECATED_CALL_ARG2:
722 case JSCallMode::DEPRECATED_CALL_ARG3:
723 if (IsFastAotCall()) {
724 return { glue_, func_, thisValue_ };
725 } else {
726 return { glue_, realNumArgs_, IntPtr(0), func_, newTarget_, thisValue_ };
727 }
728 case JSCallMode::CALL_THIS_ARG0:
729 case JSCallMode::CALL_THIS_ARG1:
730 case JSCallMode::CALL_THIS_ARG2:
731 case JSCallMode::CALL_THIS_ARG3:
732 case JSCallMode::CALL_GETTER:
733 case JSCallMode::CALL_SETTER:
734 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
735 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
736 if (IsFastAotCall()) {
737 return { glue_, func_ };
738 } else {
739 return { glue_, realNumArgs_, IntPtr(0), func_, newTarget_ };
740 }
741 case JSCallMode::CALL_WITH_ARGV:
742 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
743 if (isFast_) {
744 return { glue_, func_, thisValue_, ZExtInt32ToInt64(actualNumArgs_) };
745 } else {
746 return { glue_, ZExtInt32ToInt64(actualNumArgs_), func_, newTarget_, thisValue_ };
747 }
748 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
749 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
750 if (!isFast_) {
751 return { glue_, ZExtInt32ToInt64(actualNumArgs_), func_, func_ };
752 }
753 [[fallthrough]];
754 case JSCallMode::CALL_THIS_WITH_ARGV:
755 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
756 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
757 if (isFast_) {
758 return { glue_, func_ };
759 } else {
760 return { glue_, ZExtInt32ToInt64(actualNumArgs_), func_, newTarget_ };
761 }
762 case JSCallMode::SUPER_CALL_WITH_ARGV:
763 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
764 if (isFast_) {
765 return { glue_, func_ };
766 } else {
767 return { glue_, ZExtInt32ToInt64(actualNumArgs_), func_};
768 }
769 default:
770 LOG_ECMA(FATAL) << "this branch is unreachable";
771 UNREACHABLE();
772 }
773 }
774
PrepareAppendArgsForAotStep1()775 std::vector<GateRef> CallStubBuilder::PrepareAppendArgsForAotStep1()
776 {
777 switch (callArgs_.mode) {
778 case JSCallMode::CALL_ARG0:
779 case JSCallMode::DEPRECATED_CALL_ARG0:
780 return {};
781 case JSCallMode::CALL_ARG1:
782 case JSCallMode::DEPRECATED_CALL_ARG1:
783 return { callArgs_.callArgs.arg0 };
784 case JSCallMode::CALL_ARG2:
785 case JSCallMode::DEPRECATED_CALL_ARG2:
786 return {
787 callArgs_.callArgs.arg0,
788 callArgs_.callArgs.arg1
789 };
790 case JSCallMode::CALL_ARG3:
791 case JSCallMode::DEPRECATED_CALL_ARG3:
792 return {
793 callArgs_.callArgs.arg0,
794 callArgs_.callArgs.arg1,
795 callArgs_.callArgs.arg2
796 };
797 case JSCallMode::CALL_THIS_ARG0:
798 return { callArgs_.callArgsWithThis.thisValue };
799 case JSCallMode::CALL_THIS_ARG1:
800 return {
801 callArgs_.callArgsWithThis.thisValue,
802 callArgs_.callArgsWithThis.arg0
803 };
804 case JSCallMode::CALL_THIS_ARG2:
805 return {
806 callArgs_.callArgsWithThis.thisValue,
807 callArgs_.callArgsWithThis.arg0,
808 callArgs_.callArgsWithThis.arg1
809 };
810 case JSCallMode::CALL_THIS_ARG3:
811 return {
812 callArgs_.callArgsWithThis.thisValue,
813 callArgs_.callArgsWithThis.arg0,
814 callArgs_.callArgsWithThis.arg1,
815 callArgs_.callArgsWithThis.arg2
816 };
817 case JSCallMode::CALL_GETTER:
818 return { callArgs_.callGetterArgs.receiver };
819 case JSCallMode::CALL_SETTER:
820 return {
821 callArgs_.callSetterArgs.receiver,
822 callArgs_.callSetterArgs.value
823 };
824 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
825 return {
826 callArgs_.callThisArg2WithReturnArgs.thisValue,
827 callArgs_.callThisArg2WithReturnArgs.arg0,
828 callArgs_.callThisArg2WithReturnArgs.arg1
829 };
830 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
831 return {
832 callArgs_.callThisArg3WithReturnArgs.argHandle,
833 callArgs_.callThisArg3WithReturnArgs.value,
834 callArgs_.callThisArg3WithReturnArgs.key,
835 callArgs_.callThisArg3WithReturnArgs.thisValue
836 };
837 case JSCallMode::CALL_WITH_ARGV:
838 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
839 return { callArgs_.callArgv.argv };
840 case JSCallMode::CALL_THIS_WITH_ARGV:
841 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
842 return { callArgs_.callArgvWithThis.thisValue };
843 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
844 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
845 return { callArgs_.callConstructorArgs.thisObj };
846 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
847 return { callArgs_.callThisArgvWithReturnArgs.thisValue };
848 case JSCallMode::SUPER_CALL_WITH_ARGV:
849 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
850 return {};
851 default:
852 LOG_ECMA(FATAL) << "this branch is unreachable";
853 UNREACHABLE();
854 }
855 }
856
PrepareAppendArgsForAotStep2()857 std::vector<GateRef> CallStubBuilder::PrepareAppendArgsForAotStep2()
858 {
859 switch (callArgs_.mode) {
860 case JSCallMode::CALL_THIS_WITH_ARGV:
861 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
862 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
863 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
864 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
865 if (isFast_) {
866 return { ZExtInt32ToInt64(actualNumArgs_) };
867 }
868 [[fallthrough]];
869 case JSCallMode::CALL_WITH_ARGV:
870 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
871 case JSCallMode::CALL_ARG0:
872 case JSCallMode::CALL_ARG1:
873 case JSCallMode::CALL_ARG2:
874 case JSCallMode::CALL_ARG3:
875 case JSCallMode::CALL_THIS_ARG0:
876 case JSCallMode::CALL_THIS_ARG1:
877 case JSCallMode::CALL_THIS_ARG2:
878 case JSCallMode::CALL_THIS_ARG3:
879 case JSCallMode::DEPRECATED_CALL_ARG0:
880 case JSCallMode::DEPRECATED_CALL_ARG1:
881 case JSCallMode::DEPRECATED_CALL_ARG2:
882 case JSCallMode::DEPRECATED_CALL_ARG3:
883 case JSCallMode::CALL_GETTER:
884 case JSCallMode::CALL_SETTER:
885 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
886 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
887 return {};
888 case JSCallMode::SUPER_CALL_WITH_ARGV:
889 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
890 if (isFast_) {
891 return {
892 callArgs_.superCallArgs.thisObj,
893 callArgs_.superCallArgs.argc,
894 callArgs_.superCallArgs.argv
895 };
896 } else {
897 return {
898 callArgs_.superCallArgs.newTarget,
899 callArgs_.superCallArgs.thisObj,
900 callArgs_.superCallArgs.argv
901 };
902 }
903 default:
904 LOG_ECMA(FATAL) << "this branch is unreachable";
905 UNREACHABLE();
906 }
907 }
908
PrepareAppendArgsForAotStep3(GateRef expectedNum)909 std::vector<GateRef> CallStubBuilder::PrepareAppendArgsForAotStep3(GateRef expectedNum)
910 {
911 std::vector<GateRef> retArgs {};
912 switch (callArgs_.mode) {
913 case JSCallMode::CALL_ARG0:
914 case JSCallMode::CALL_ARG1:
915 case JSCallMode::CALL_ARG2:
916 case JSCallMode::CALL_ARG3:
917 case JSCallMode::CALL_THIS_ARG0:
918 case JSCallMode::CALL_THIS_ARG1:
919 case JSCallMode::CALL_THIS_ARG2:
920 case JSCallMode::CALL_THIS_ARG3:
921 case JSCallMode::DEPRECATED_CALL_ARG0:
922 case JSCallMode::DEPRECATED_CALL_ARG1:
923 case JSCallMode::DEPRECATED_CALL_ARG2:
924 case JSCallMode::DEPRECATED_CALL_ARG3:
925 case JSCallMode::CALL_GETTER:
926 case JSCallMode::CALL_SETTER:
927 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
928 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
929 return {};
930 case JSCallMode::CALL_THIS_WITH_ARGV:
931 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
932 retArgs.push_back(callArgs_.callArgvWithThis.argv);
933 break;
934 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
935 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
936 retArgs.push_back(callArgs_.callConstructorArgs.argv);
937 break;
938 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
939 retArgs.push_back(callArgs_.callThisArgvWithReturnArgs.argv);
940 break;
941 case JSCallMode::CALL_WITH_ARGV:
942 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
943 case JSCallMode::SUPER_CALL_WITH_ARGV:
944 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
945 break;
946 default:
947 LOG_ECMA(FATAL) << "this branch is unreachable";
948 UNREACHABLE();
949 }
950
951 if (IsFastAotCallWithBridge()) {
952 retArgs.push_back(expectedNum);
953 }
954 return retArgs;
955 }
956
PrepareIdxForAsmInterpreterForBaselineWithBaselineCode()957 int CallStubBuilder::PrepareIdxForAsmInterpreterForBaselineWithBaselineCode()
958 {
959 switch (callArgs_.mode) {
960 case JSCallMode::CALL_ARG0:
961 case JSCallMode::DEPRECATED_CALL_ARG0:
962 return RTSTUB_ID(CallArg0AndCheckToBaselineFromBaseline);
963 case JSCallMode::CALL_ARG1:
964 case JSCallMode::DEPRECATED_CALL_ARG1:
965 return RTSTUB_ID(CallArg1AndCheckToBaselineFromBaseline);
966 case JSCallMode::CALL_ARG2:
967 case JSCallMode::DEPRECATED_CALL_ARG2:
968 return RTSTUB_ID(CallArgs2AndCheckToBaselineFromBaseline);
969 case JSCallMode::CALL_ARG3:
970 case JSCallMode::DEPRECATED_CALL_ARG3:
971 return RTSTUB_ID(CallArgs3AndCheckToBaselineFromBaseline);
972 case JSCallMode::CALL_THIS_ARG0:
973 return RTSTUB_ID(CallThisArg0AndCheckToBaselineFromBaseline);
974 case JSCallMode::CALL_THIS_ARG1:
975 return RTSTUB_ID(CallThisArg1AndCheckToBaselineFromBaseline);
976 case JSCallMode::CALL_THIS_ARG2:
977 return RTSTUB_ID(CallThisArgs2AndCheckToBaselineFromBaseline);
978 case JSCallMode::CALL_THIS_ARG3:
979 return RTSTUB_ID(CallThisArgs3AndCheckToBaselineFromBaseline);
980 case JSCallMode::CALL_WITH_ARGV:
981 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
982 return RTSTUB_ID(CallRangeAndCheckToBaselineFromBaseline);
983 case JSCallMode::CALL_THIS_WITH_ARGV:
984 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
985 return RTSTUB_ID(CallThisRangeAndCheckToBaselineFromBaseline);
986 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
987 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
988 return RTSTUB_ID(CallNewAndCheckToBaselineFromBaseline);
989 case JSCallMode::SUPER_CALL_WITH_ARGV:
990 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
991 return RTSTUB_ID(SuperCallAndCheckToBaselineFromBaseline);
992 case JSCallMode::CALL_GETTER:
993 return RTSTUB_ID(CallGetter);
994 case JSCallMode::CALL_SETTER:
995 return RTSTUB_ID(CallSetter);
996 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
997 return RTSTUB_ID(CallContainersArgs2);
998 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
999 return RTSTUB_ID(CallContainersArgs3);
1000 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
1001 return RTSTUB_ID(CallReturnWithArgv);
1002 default:
1003 LOG_ECMA(FATAL) << "this branch is unreachable";
1004 UNREACHABLE();
1005 }
1006 }
1007
PrepareIdxForAsmInterpreterForBaselineWithoutBaselineCode()1008 int CallStubBuilder::PrepareIdxForAsmInterpreterForBaselineWithoutBaselineCode()
1009 {
1010 switch (callArgs_.mode) {
1011 case JSCallMode::CALL_ARG0:
1012 case JSCallMode::DEPRECATED_CALL_ARG0:
1013 return RTSTUB_ID(CallArg0AndDispatchFromBaseline);
1014 case JSCallMode::CALL_ARG1:
1015 case JSCallMode::DEPRECATED_CALL_ARG1:
1016 return RTSTUB_ID(CallArg1AndDispatchFromBaseline);
1017 case JSCallMode::CALL_ARG2:
1018 case JSCallMode::DEPRECATED_CALL_ARG2:
1019 return RTSTUB_ID(CallArgs2AndDispatchFromBaseline);
1020 case JSCallMode::CALL_ARG3:
1021 case JSCallMode::DEPRECATED_CALL_ARG3:
1022 return RTSTUB_ID(CallArgs3AndDispatchFromBaseline);
1023 case JSCallMode::CALL_THIS_ARG0:
1024 return RTSTUB_ID(CallThisArg0AndDispatchFromBaseline);
1025 case JSCallMode::CALL_THIS_ARG1:
1026 return RTSTUB_ID(CallThisArg1AndDispatchFromBaseline);
1027 case JSCallMode::CALL_THIS_ARG2:
1028 return RTSTUB_ID(CallThisArgs2AndDispatchFromBaseline);
1029 case JSCallMode::CALL_THIS_ARG3:
1030 return RTSTUB_ID(CallThisArgs3AndDispatchFromBaseline);
1031 case JSCallMode::CALL_WITH_ARGV:
1032 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
1033 return RTSTUB_ID(CallRangeAndDispatchFromBaseline);
1034 case JSCallMode::CALL_THIS_WITH_ARGV:
1035 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
1036 return RTSTUB_ID(CallThisRangeAndDispatchFromBaseline);
1037 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
1038 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
1039 return RTSTUB_ID(CallNewAndDispatchFromBaseline);
1040 case JSCallMode::SUPER_CALL_WITH_ARGV:
1041 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
1042 return RTSTUB_ID(SuperCallAndDispatchFromBaseline);
1043 case JSCallMode::CALL_GETTER:
1044 return RTSTUB_ID(CallGetter);
1045 case JSCallMode::CALL_SETTER:
1046 return RTSTUB_ID(CallSetter);
1047 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
1048 return RTSTUB_ID(CallContainersArgs2);
1049 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
1050 return RTSTUB_ID(CallContainersArgs3);
1051 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
1052 return RTSTUB_ID(CallReturnWithArgv);
1053 default:
1054 LOG_ECMA(FATAL) << "this branch is unreachable";
1055 UNREACHABLE();
1056 }
1057 }
1058
PrepareIdxForAsmInterpreterWithBaselineCode()1059 int CallStubBuilder::PrepareIdxForAsmInterpreterWithBaselineCode()
1060 {
1061 switch (callArgs_.mode) {
1062 case JSCallMode::CALL_ARG0:
1063 case JSCallMode::DEPRECATED_CALL_ARG0:
1064 return RTSTUB_ID(CallArg0AndCheckToBaseline);
1065 case JSCallMode::CALL_ARG1:
1066 case JSCallMode::DEPRECATED_CALL_ARG1:
1067 return RTSTUB_ID(CallArg1AndCheckToBaseline);
1068 case JSCallMode::CALL_ARG2:
1069 case JSCallMode::DEPRECATED_CALL_ARG2:
1070 return RTSTUB_ID(CallArgs2AndCheckToBaseline);
1071 case JSCallMode::CALL_ARG3:
1072 case JSCallMode::DEPRECATED_CALL_ARG3:
1073 return RTSTUB_ID(CallArgs3AndCheckToBaseline);
1074 case JSCallMode::CALL_THIS_ARG0:
1075 return RTSTUB_ID(CallThisArg0AndCheckToBaseline);
1076 case JSCallMode::CALL_THIS_ARG1:
1077 return RTSTUB_ID(CallThisArg1AndCheckToBaseline);
1078 case JSCallMode::CALL_THIS_ARG2:
1079 return RTSTUB_ID(CallThisArgs2AndCheckToBaseline);
1080 case JSCallMode::CALL_THIS_ARG3:
1081 return RTSTUB_ID(CallThisArgs3AndCheckToBaseline);
1082 case JSCallMode::CALL_WITH_ARGV:
1083 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
1084 return RTSTUB_ID(CallRangeAndCheckToBaseline);
1085 case JSCallMode::CALL_THIS_WITH_ARGV:
1086 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
1087 return RTSTUB_ID(CallThisRangeAndCheckToBaseline);
1088 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
1089 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
1090 return RTSTUB_ID(CallNewAndCheckToBaseline);
1091 case JSCallMode::SUPER_CALL_WITH_ARGV:
1092 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
1093 return RTSTUB_ID(SuperCallAndCheckToBaseline);
1094 case JSCallMode::CALL_GETTER:
1095 return RTSTUB_ID(CallGetter);
1096 case JSCallMode::CALL_SETTER:
1097 return RTSTUB_ID(CallSetter);
1098 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
1099 return RTSTUB_ID(CallContainersArgs2);
1100 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
1101 return RTSTUB_ID(CallContainersArgs3);
1102 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
1103 return RTSTUB_ID(CallReturnWithArgv);
1104 default:
1105 LOG_ECMA(FATAL) << "this branch is unreachable";
1106 UNREACHABLE();
1107 }
1108 }
1109
PrepareIdxForAsmInterpreterWithoutBaselineCode()1110 int CallStubBuilder::PrepareIdxForAsmInterpreterWithoutBaselineCode()
1111 {
1112 switch (callArgs_.mode) {
1113 case JSCallMode::CALL_ARG0:
1114 case JSCallMode::DEPRECATED_CALL_ARG0:
1115 return RTSTUB_ID(PushCallArg0AndDispatch);
1116 case JSCallMode::CALL_ARG1:
1117 case JSCallMode::DEPRECATED_CALL_ARG1:
1118 return RTSTUB_ID(PushCallArg1AndDispatch);
1119 case JSCallMode::CALL_ARG2:
1120 case JSCallMode::DEPRECATED_CALL_ARG2:
1121 return RTSTUB_ID(PushCallArgs2AndDispatch);
1122 case JSCallMode::CALL_ARG3:
1123 case JSCallMode::DEPRECATED_CALL_ARG3:
1124 return RTSTUB_ID(PushCallArgs3AndDispatch);
1125 case JSCallMode::CALL_THIS_ARG0:
1126 return RTSTUB_ID(PushCallThisArg0AndDispatch);
1127 case JSCallMode::CALL_THIS_ARG1:
1128 return RTSTUB_ID(PushCallThisArg1AndDispatch);
1129 case JSCallMode::CALL_THIS_ARG2:
1130 return RTSTUB_ID(PushCallThisArgs2AndDispatch);
1131 case JSCallMode::CALL_THIS_ARG3:
1132 return RTSTUB_ID(PushCallThisArgs3AndDispatch);
1133 case JSCallMode::CALL_WITH_ARGV:
1134 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
1135 return RTSTUB_ID(PushCallRangeAndDispatch);
1136 case JSCallMode::CALL_THIS_WITH_ARGV:
1137 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
1138 return RTSTUB_ID(PushCallThisRangeAndDispatch);
1139 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
1140 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
1141 return RTSTUB_ID(PushCallNewAndDispatch);
1142 case JSCallMode::SUPER_CALL_WITH_ARGV:
1143 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
1144 return RTSTUB_ID(PushSuperCallAndDispatch);
1145 case JSCallMode::CALL_GETTER:
1146 return RTSTUB_ID(CallGetter);
1147 case JSCallMode::CALL_SETTER:
1148 return RTSTUB_ID(CallSetter);
1149 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
1150 return RTSTUB_ID(CallContainersArgs2);
1151 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
1152 return RTSTUB_ID(CallContainersArgs3);
1153 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
1154 return RTSTUB_ID(CallReturnWithArgv);
1155 default:
1156 LOG_ECMA(FATAL) << "this branch is unreachable";
1157 UNREACHABLE();
1158 }
1159 }
1160
PrepareArgsForAsmInterpreter()1161 std::vector<GateRef> CallStubBuilder::PrepareArgsForAsmInterpreter()
1162 {
1163 std::vector<GateRef> basicArgs = PrepareBasicArgsForAsmInterpreter();
1164 std::vector<GateRef> appendArgs = PrepareAppendArgsForAsmInterpreter();
1165
1166 basicArgs.insert(basicArgs.end(), appendArgs.begin(), appendArgs.end());
1167 return basicArgs;
1168 }
1169
PrepareBasicArgsForAsmInterpreter()1170 std::vector<GateRef> CallStubBuilder::PrepareBasicArgsForAsmInterpreter()
1171 {
1172 switch (callArgs_.mode) {
1173 case JSCallMode::CALL_ARG0:
1174 case JSCallMode::CALL_ARG1:
1175 case JSCallMode::CALL_ARG2:
1176 case JSCallMode::CALL_ARG3:
1177 case JSCallMode::CALL_WITH_ARGV:
1178 case JSCallMode::CALL_THIS_ARG0:
1179 case JSCallMode::CALL_THIS_ARG1:
1180 case JSCallMode::CALL_THIS_ARG2:
1181 case JSCallMode::CALL_THIS_ARG3:
1182 case JSCallMode::CALL_THIS_WITH_ARGV:
1183 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
1184 case JSCallMode::DEPRECATED_CALL_ARG0:
1185 case JSCallMode::DEPRECATED_CALL_ARG1:
1186 case JSCallMode::DEPRECATED_CALL_ARG2:
1187 case JSCallMode::DEPRECATED_CALL_ARG3:
1188 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
1189 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
1190 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
1191 case JSCallMode::SUPER_CALL_WITH_ARGV:
1192 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
1193 if (isForBaseline_) {
1194 return { glue_, baselineBuiltinFp_, func_, method_, callField_ };
1195 } else {
1196 return { glue_, sp_, func_, method_, callField_ };
1197 }
1198 case JSCallMode::CALL_GETTER:
1199 case JSCallMode::CALL_SETTER:
1200 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
1201 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
1202 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
1203 return { glue_, func_, method_, callField_ };
1204 default:
1205 LOG_ECMA(FATAL) << "this branch is unreachable";
1206 UNREACHABLE();
1207 }
1208 }
1209
PrepareAppendArgsForAsmInterpreter()1210 std::vector<GateRef> CallStubBuilder::PrepareAppendArgsForAsmInterpreter()
1211 {
1212 switch (callArgs_.mode) {
1213 case JSCallMode::CALL_ARG0:
1214 case JSCallMode::DEPRECATED_CALL_ARG0:
1215 return {};
1216 case JSCallMode::CALL_ARG1:
1217 case JSCallMode::DEPRECATED_CALL_ARG1:
1218 return { callArgs_.callArgs.arg0 };
1219 case JSCallMode::CALL_ARG2:
1220 case JSCallMode::DEPRECATED_CALL_ARG2:
1221 return {
1222 callArgs_.callArgs.arg0,
1223 callArgs_.callArgs.arg1
1224 };
1225 case JSCallMode::CALL_ARG3:
1226 case JSCallMode::DEPRECATED_CALL_ARG3:
1227 return {
1228 callArgs_.callArgs.arg0,
1229 callArgs_.callArgs.arg1,
1230 callArgs_.callArgs.arg2
1231 };
1232 case JSCallMode::CALL_THIS_ARG0:
1233 return { callArgs_.callArgsWithThis.thisValue };
1234 case JSCallMode::CALL_THIS_ARG1:
1235 return {
1236 callArgs_.callArgsWithThis.arg0,
1237 callArgs_.callArgsWithThis.thisValue
1238 };
1239 case JSCallMode::CALL_THIS_ARG2:
1240 return {
1241 callArgs_.callArgsWithThis.arg0,
1242 callArgs_.callArgsWithThis.arg1,
1243 callArgs_.callArgsWithThis.thisValue
1244 };
1245 case JSCallMode::CALL_THIS_ARG3:
1246 return {
1247 callArgs_.callArgsWithThis.arg0,
1248 callArgs_.callArgsWithThis.arg1,
1249 callArgs_.callArgsWithThis.arg2,
1250 callArgs_.callArgsWithThis.thisValue
1251 };
1252 case JSCallMode::CALL_WITH_ARGV:
1253 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
1254 return {
1255 callArgs_.callArgv.argc,
1256 callArgs_.callArgv.argv
1257 };
1258 case JSCallMode::CALL_THIS_WITH_ARGV:
1259 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
1260 return {
1261 callArgs_.callArgvWithThis.argc,
1262 callArgs_.callArgvWithThis.argv,
1263 callArgs_.callArgvWithThis.thisValue
1264 };
1265 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
1266 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
1267 return {
1268 callArgs_.callConstructorArgs.argc,
1269 callArgs_.callConstructorArgs.argv,
1270 callArgs_.callConstructorArgs.thisObj
1271 };
1272 case JSCallMode::CALL_GETTER:
1273 return { callArgs_.callGetterArgs.receiver };
1274 case JSCallMode::CALL_SETTER:
1275 return {
1276 callArgs_.callSetterArgs.value,
1277 callArgs_.callSetterArgs.receiver
1278 };
1279 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
1280 return {
1281 callArgs_.callThisArg2WithReturnArgs.arg0,
1282 callArgs_.callThisArg2WithReturnArgs.arg1,
1283 callArgs_.callThisArg2WithReturnArgs.thisValue
1284 };
1285 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
1286 return {
1287 callArgs_.callThisArg3WithReturnArgs.value,
1288 callArgs_.callThisArg3WithReturnArgs.key,
1289 callArgs_.callThisArg3WithReturnArgs.thisValue,
1290 callArgs_.callThisArg3WithReturnArgs.argHandle
1291 };
1292 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
1293 return {
1294 callArgs_.callThisArgvWithReturnArgs.argc,
1295 callArgs_.callThisArgvWithReturnArgs.argv,
1296 callArgs_.callThisArgvWithReturnArgs.thisValue
1297 };
1298 case JSCallMode::SUPER_CALL_WITH_ARGV:
1299 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
1300 return {
1301 callArgs_.superCallArgs.argc,
1302 callArgs_.superCallArgs.argv,
1303 callArgs_.superCallArgs.thisObj,
1304 callArgs_.superCallArgs.newTarget
1305 };
1306 default:
1307 LOG_ECMA(FATAL) << "this branch is unreachable";
1308 UNREACHABLE();
1309 }
1310 }
1311
CallFastBuiltin(Label* notFastBuiltins, Label *exit)1312 void CallStubBuilder::CallFastBuiltin(Label* notFastBuiltins, Label *exit)
1313 {
1314 auto env = GetEnvironment();
1315 Label isFastBuiltins(env);
1316 Label supportCall(env);
1317 numArgs_ = ZExtInt32ToPtr(actualNumArgs_);
1318 GateRef isFastBuiltinsMask = Int64(static_cast<uint64_t>(1) << MethodLiteral::IsFastBuiltinBit::START_BIT);
1319 BRANCH(Int64NotEqual(Int64And(callField_, isFastBuiltinsMask), Int64(0)), &isFastBuiltins, notFastBuiltins);
1320 Bind(&isFastBuiltins);
1321 GateRef builtinId = GetBuiltinId(method_);
1322 if (IsCallModeSupportCallBuiltin()) {
1323 BRANCH(Int32GreaterThanOrEqual(builtinId, Int32(kungfu::BuiltinsStubCSigns::BUILTINS_CONSTRUCTOR_STUB_FIRST)),
1324 notFastBuiltins, &supportCall);
1325 Bind(&supportCall);
1326 }
1327 {
1328 GateRef ret;
1329 switch (callArgs_.mode) {
1330 case JSCallMode::CALL_THIS_ARG0:
1331 case JSCallMode::CALL_THIS_ARG1:
1332 case JSCallMode::CALL_THIS_ARG2:
1333 case JSCallMode::CALL_THIS_ARG3:
1334 ret = DispatchBuiltins(glue_, builtinId, PrepareArgsForFastBuiltin());
1335 break;
1336 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
1337 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
1338 ret = DispatchBuiltinsWithArgv(glue_, builtinId, PrepareArgsForFastBuiltin());
1339 break;
1340 default:
1341 LOG_ECMA(FATAL) << "this branch is unreachable";
1342 UNREACHABLE();
1343 }
1344 result_->WriteVariable(ret);
1345 Jump(exit);
1346 }
1347 }
1348
PrepareBasicArgsForFastBuiltin()1349 std::vector<GateRef> CallStubBuilder::PrepareBasicArgsForFastBuiltin()
1350 {
1351 return { glue_, nativeCode_, func_ };
1352 }
1353
PrepareAppendArgsForFastBuiltin()1354 std::vector<GateRef> CallStubBuilder::PrepareAppendArgsForFastBuiltin()
1355 {
1356 switch (callArgs_.mode) {
1357 case JSCallMode::CALL_THIS_ARG0:
1358 return { Undefined(),
1359 callArgs_.callArgsWithThis.thisValue, numArgs_, Undefined(), Undefined(), Undefined()
1360 };
1361 case JSCallMode::CALL_THIS_ARG1:
1362 return { Undefined(),
1363 callArgs_.callArgsWithThis.thisValue, numArgs_,
1364 callArgs_.callArgsWithThis.arg0, Undefined(), Undefined()
1365 };
1366 case JSCallMode::CALL_THIS_ARG2:
1367 return { Undefined(),
1368 callArgs_.callArgsWithThis.thisValue, numArgs_,
1369 callArgs_.callArgsWithThis.arg0,
1370 callArgs_.callArgsWithThis.arg1, Undefined()
1371 };
1372 case JSCallMode::CALL_THIS_ARG3:
1373 return { Undefined(),
1374 callArgs_.callArgsWithThis.thisValue, numArgs_,
1375 callArgs_.callArgsWithThis.arg0,
1376 callArgs_.callArgsWithThis.arg1,
1377 callArgs_.callArgsWithThis.arg2
1378 };
1379 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
1380 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
1381 return { func_, thisValue_, numArgs_,
1382 callArgs_.callConstructorArgs.argv
1383 };
1384 default:
1385 LOG_ECMA(FATAL) << "this branch is unreachable";
1386 UNREACHABLE();
1387 }
1388 }
1389
PrepareArgsForFastBuiltin()1390 std::vector<GateRef> CallStubBuilder::PrepareArgsForFastBuiltin()
1391 {
1392 std::vector<GateRef> basicArgs = PrepareBasicArgsForFastBuiltin();
1393 std::vector<GateRef> appendArgs = PrepareAppendArgsForFastBuiltin();
1394
1395 basicArgs.insert(basicArgs.end(), appendArgs.begin(), appendArgs.end());
1396 return basicArgs;
1397 }
1398
IsCallModeSupportPGO() const1399 bool CallStubBuilder::IsCallModeSupportPGO() const
1400 {
1401 switch (callArgs_.mode) {
1402 case JSCallMode::CALL_ARG0:
1403 case JSCallMode::CALL_ARG1:
1404 case JSCallMode::CALL_ARG2:
1405 case JSCallMode::CALL_ARG3:
1406 case JSCallMode::CALL_WITH_ARGV:
1407 case JSCallMode::CALL_THIS_ARG0:
1408 case JSCallMode::CALL_THIS_ARG1:
1409 case JSCallMode::CALL_THIS_ARG2:
1410 case JSCallMode::CALL_THIS_ARG3:
1411 case JSCallMode::CALL_THIS_WITH_ARGV:
1412 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
1413 case JSCallMode::SUPER_CALL_WITH_ARGV:
1414 case JSCallMode::SUPER_CALL_SPREAD_WITH_ARGV:
1415 case JSCallMode::CALL_GETTER:
1416 case JSCallMode::CALL_SETTER:
1417 return true;
1418 case JSCallMode::DEPRECATED_CALL_ARG0:
1419 case JSCallMode::DEPRECATED_CALL_ARG1:
1420 case JSCallMode::DEPRECATED_CALL_ARG2:
1421 case JSCallMode::DEPRECATED_CALL_ARG3:
1422 case JSCallMode::DEPRECATED_CALL_WITH_ARGV:
1423 case JSCallMode::DEPRECATED_CALL_THIS_WITH_ARGV:
1424 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
1425 case JSCallMode::CALL_ENTRY:
1426 case JSCallMode::CALL_FROM_AOT:
1427 case JSCallMode::CALL_GENERATOR:
1428 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
1429 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
1430 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
1431 return false;
1432 default:
1433 LOG_ECMA(FATAL) << "this branch is unreachable";
1434 UNREACHABLE();
1435 }
1436 }
1437
IsCallModeSupportCallBuiltin() const1438 bool CallStubBuilder::IsCallModeSupportCallBuiltin() const
1439 {
1440 switch (callArgs_.mode) {
1441 case JSCallMode::CALL_THIS_ARG0:
1442 case JSCallMode::CALL_THIS_ARG1:
1443 case JSCallMode::CALL_THIS_ARG2:
1444 case JSCallMode::CALL_THIS_ARG3:
1445 return true;
1446 case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
1447 case JSCallMode::DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV:
1448 return false;
1449 default:
1450 LOG_ECMA(FATAL) << "this branch is unreachable";
1451 UNREACHABLE();
1452 }
1453 }
1454
CheckResultValueChangedWithReturn(GateRef prevResRef) const1455 bool CallStubBuilder::CheckResultValueChangedWithReturn(GateRef prevResRef) const
1456 {
1457 switch (callArgs_.mode) {
1458 case JSCallMode::CALL_GETTER:
1459 case JSCallMode::CALL_SETTER:
1460 case JSCallMode::CALL_THIS_ARG2_WITH_RETURN:
1461 case JSCallMode::CALL_THIS_ARG3_WITH_RETURN:
1462 case JSCallMode::CALL_THIS_ARGV_WITH_RETURN:
1463 return result_->Value() == prevResRef;
1464 default:
1465 return result_->Value() != prevResRef;
1466 }
1467 }
1468
IsSlowAotCall() const1469 bool CallStubBuilder::IsSlowAotCall() const
1470 { return !isFast_ && !isBridge_; }
1471
IsFastAotCall() const1472 bool CallStubBuilder::IsFastAotCall() const
1473 { return isFast_ && !isBridge_; }
1474
IsSlowAotCallWithBridge() const1475 bool CallStubBuilder::IsSlowAotCallWithBridge() const
1476 { return !isFast_ && isBridge_; }
1477
IsFastAotCallWithBridge() const1478 bool CallStubBuilder::IsFastAotCallWithBridge() const
1479 { return isFast_ && isBridge_; }
1480
HandleProfileCall()1481 void CallStubBuilder::HandleProfileCall()
1482 {
1483 if (!callback_.IsEmpty()) {
1484 if (!IsCallModeSupportPGO()) {
1485 return;
1486 }
1487 if (IsCallModeGetterSetter()) {
1488 callback_.ProfileGetterSetterCall(func_);
1489 return;
1490 }
1491 callback_.ProfileCall(func_);
1492 }
1493 }
1494
HandleProfileNativeCall()1495 void CallStubBuilder::HandleProfileNativeCall()
1496 {
1497 if (!callback_.IsEmpty()) {
1498 if (!IsCallModeSupportPGO()) {
1499 return;
1500 }
1501 if (!IsCallModeGetterSetter()) {
1502 callback_.ProfileNativeCall(func_);
1503 }
1504 }
1505 }
1506
IsCallModeGetterSetter()1507 bool CallStubBuilder::IsCallModeGetterSetter()
1508 {
1509 switch (callArgs_.mode) {
1510 case JSCallMode::CALL_GETTER:
1511 case JSCallMode::CALL_SETTER:
1512 return true;
1513 default:
1514 return false;
1515 }
1516 }
1517
1518 } // panda::ecmascript::kungfu
1519