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(&notFastBuiltins, exit);
146             Bind(&notFastBuiltins);
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