1 /* 2 * Copyright (c) 2022 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 #ifndef ECMASCRIPT_COMPILER_ASSEMBLER_MODULE_X64_H 17 #define ECMASCRIPT_COMPILER_ASSEMBLER_MODULE_X64_H 18 19 #include "ecmascript/compiler/assembler/x64/assembler_x64.h" 20 #include "ecmascript/compiler/assembler/x64/extended_assembler_x64.h" 21 #include "ecmascript/frames.h" 22 23 namespace panda::ecmascript::x64 { 24 class CommonCall { 25 public: 26 static constexpr int FRAME_SLOT_SIZE = 8; 27 static constexpr int DOUBLE_SLOT_SIZE = 16; 28 static constexpr int TRIPLE_SLOT_SIZE = 24; 29 static constexpr int QUADRUPLE_SLOT_SIZE = 32; 30 static constexpr int QUINTUPLE_SLOT_SIZE = 40; 31 static constexpr int SEXTUPLE_SLOT_SIZE = 48; 32 static void CopyArgumentWithArgV(ExtendedAssembler *assembler, Register argc, Register argV); 33 static void PushAsmInterpBridgeFrame(ExtendedAssembler *assembler); 34 static void PopAsmInterpBridgeFrame(ExtendedAssembler *assembler); 35 static void PushUndefinedWithArgc(ExtendedAssembler *assembler, Register argc); 36 static void GetArgvAtStack(ExtendedAssembler *assembler); 37 static void PushArgsWithArgvAndCheckStack(ExtendedAssembler *assembler, Register glue, Register argc, Register argv, 38 Register op1, Register op2, Label *stackOverflow); 39 static void StackOverflowCheck(ExtendedAssembler *assembler, Register glue, Register numArgs, Register op1, 40 Register op2, Label *stackOverflow); 41 }; 42 43 class OptimizedCall : public CommonCall { 44 public: 45 static void CallRuntime(ExtendedAssembler *assembler); 46 47 static void JSFunctionEntry(ExtendedAssembler *assembler); 48 49 static void OptimizedCallOptimized(ExtendedAssembler *assembler); 50 51 static void CallBuiltinTrampoline(ExtendedAssembler *assembler); 52 53 static void JSProxyCallInternalWithArgV(ExtendedAssembler *assembler); 54 55 static void JSCall(ExtendedAssembler *assembler); 56 57 static void ConstructorJSCall(ExtendedAssembler *assembler); 58 59 static void CallRuntimeWithArgv(ExtendedAssembler *assembler); 60 61 static void JSCallWithArgV(ExtendedAssembler *assembler); 62 63 static void ConstructorJSCallWithArgV(ExtendedAssembler *assembler); 64 65 static void DeoptHandlerAsm(ExtendedAssembler *assembler); 66 67 static void JSCallNew(ExtendedAssembler *assembler); 68 69 static void JSCallNewWithArgV(ExtendedAssembler *assembler); 70 71 static void GenJSCall(ExtendedAssembler *assembler, bool isNew); 72 73 static void GenJSCallWithArgV(ExtendedAssembler *assembler, bool isNew); 74 private: 75 static void DeoptEnterAsmInterp(ExtendedAssembler *assembler); 76 static void JSCallCheck(ExtendedAssembler *assembler, Register jsFuncReg, 77 Label *lNonCallable, Label *lNotJSFunction, Label *lJSFunctionCall); 78 static void ThrowNonCallableInternal(ExtendedAssembler *assembler, Register glueReg); 79 static void CallOptimziedMethodInternal(ExtendedAssembler *assembler, Register glueReg, Register jsFuncReg, 80 Register methodCallField, Register argc, Register codeAddrReg, 81 Register expectedNumArgsReg); 82 static void JSBoundFunctionCallInternal(ExtendedAssembler *assembler, Register jsFuncReg, Label *jsCall); 83 static void JSProxyCallInternal(ExtendedAssembler *assembler, Register jsFuncReg); 84 static void OptimizedCallAsmInterpreter(ExtendedAssembler *assembler); 85 static void PushArgsWithArgV(ExtendedAssembler *assembler, Register jsfunc, 86 Register actualNumArgs, Register argV, Label *pushCallThis); 87 static void PushMandatoryJSArgs(ExtendedAssembler *assembler, Register jsfunc, 88 Register thisObj, Register newTarget); 89 static void PopJSFunctionArgs(ExtendedAssembler *assembler, Register expectedNumArgs); 90 static void PushJSFunctionEntryFrame (ExtendedAssembler *assembler, Register prevFp); 91 static void PopJSFunctionEntryFrame(ExtendedAssembler *assembler, Register glue); 92 static void PushOptimizedUnfoldArgVFrame(ExtendedAssembler *assembler, Register callSiteSp); 93 static void PopOptimizedUnfoldArgVFrame(ExtendedAssembler *assembler); 94 }; 95 96 class AsmInterpreterCall : public CommonCall { 97 public: 98 static void GeneratorReEnterAsmInterp(ExtendedAssembler *assembler); 99 100 static void GeneratorReEnterAsmInterpDispatch(ExtendedAssembler *assembler); 101 102 static void AsmInterpEntryDispatch(ExtendedAssembler *assembler); 103 104 static void AsmInterpreterEntry(ExtendedAssembler *assembler); 105 106 static void PushCallThisRangeAndDispatch(ExtendedAssembler *assembler); 107 108 static void PushCallRangeAndDispatch(ExtendedAssembler *assembler); 109 110 static void PushCallArgs3AndDispatch(ExtendedAssembler *assembler); 111 112 static void PushCallArgs2AndDispatch(ExtendedAssembler *assembler); 113 114 static void PushCallArg1AndDispatch(ExtendedAssembler *assembler); 115 116 static void PushCallArg0AndDispatch(ExtendedAssembler *assembler); 117 118 static void PushCallThisArg0AndDispatch(ExtendedAssembler *assembler); 119 120 static void PushCallThisArg1AndDispatch(ExtendedAssembler *assembler); 121 122 static void PushCallThisArgs2AndDispatch(ExtendedAssembler *assembler); 123 124 static void PushCallThisArgs3AndDispatch(ExtendedAssembler *assembler); 125 126 static void PushCallNewAndDispatch(ExtendedAssembler *assembler); 127 128 static void PushCallNewAndDispatchNative(ExtendedAssembler *assembler); 129 130 static void PushCallRangeAndDispatchNative(ExtendedAssembler *assembler); 131 132 static void PushCallArgsAndDispatchNative(ExtendedAssembler *assembler); 133 134 static void ResumeRspAndDispatch(ExtendedAssembler *assembler); 135 136 static void ResumeRspAndReturn([[maybe_unused]] ExtendedAssembler *assembler); 137 138 static void CallGetter(ExtendedAssembler *assembler); 139 140 static void CallSetter(ExtendedAssembler *assembler); 141 142 static void CallContainersArgs3(ExtendedAssembler *assembler); 143 144 static void ResumeCaughtFrameAndDispatch(ExtendedAssembler *assembler); 145 146 static void ResumeUncaughtFrameAndReturn(ExtendedAssembler *assembler); 147 148 private: 149 static void PushFrameState(ExtendedAssembler *assembler, Register prevSpRegister, Register fpRegister, 150 Register callTargetRegister, Register thisRegister, Register methodRegister, Register pcRegister, 151 Register operatorRegister); 152 static void PushGeneratorFrameState(ExtendedAssembler *assembler, Register prevSpRegister, 153 Register fpRegister, Register callTargetRegister, Register thisRegister, Register methodRegister, 154 Register contextRegister, Register pcRegister, Register operatorRegister); 155 static void PushAsmInterpEntryFrame(ExtendedAssembler *assembler); 156 static void PopAsmInterpEntryFrame(ExtendedAssembler *assembler); 157 static void GetDeclaredNumArgsFromCallField(ExtendedAssembler *assembler, Register callFieldRegister, 158 Register declaredNumArgsRegister); 159 static void GetNumVregsFromCallField(ExtendedAssembler *assembler, Register callFieldRegister, 160 Register numVregsRegister); 161 static void PushUndefinedWithArgcAndCheckStack(ExtendedAssembler *assembler, Register glue, Register argc, 162 Register op1, Register op2, Label *stackOverflow); 163 static void ThrowStackOverflowExceptionAndReturn(ExtendedAssembler *assembler, Register glue, Register fp, 164 Register op); 165 static void HasPendingException(ExtendedAssembler *assembler, Register threadRegister); 166 static void PushCallThis(ExtendedAssembler *assembler, JSCallMode mode, Label *stackOverflow); 167 static Register GetThisRegsiter(ExtendedAssembler *assembler, JSCallMode mode, Register defaultRegister); 168 static Register GetNewTargetRegsiter(ExtendedAssembler *assembler, JSCallMode mode, Register defaultRegister); 169 static void PushVregs(ExtendedAssembler *assembler, Label *stackOverflow); 170 static void DispatchCall(ExtendedAssembler *assembler, Register pcRegister, Register newSpRegister, 171 Register methodRegister, Register accRegister = rInvalid); 172 static void CallNativeEntry(ExtendedAssembler *assemblSer); 173 static void CallNativeWithArgv(ExtendedAssembler *assembler, bool callNew); 174 static void CallNativeInternal(ExtendedAssembler *assembler, Register nativeCode); 175 static void PushBuiltinFrame(ExtendedAssembler *assembler, Register glue, FrameType type); 176 static void JSCallCommonEntry(ExtendedAssembler *assembler, JSCallMode mode); 177 static void JSCallCommonFastPath(ExtendedAssembler *assembler, JSCallMode mode, Label *stackOverflow); 178 static void JSCallCommonSlowPath(ExtendedAssembler *assembler, JSCallMode mode, 179 Label *fastPathEntry, Label *pushCallThis, Label *stackOverflow); 180 friend class OptimizedCall; 181 }; 182 } // namespace panda::ecmascript::x64 183 #endif // ECMASCRIPT_COMPILER_ASSEMBLER_MODULE_X64_H 184