mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 08:03:29 +00:00
commit
6561159387
@ -97,10 +97,10 @@ void ExtendedAssembler::RestoreLrAndFp()
|
||||
Ldp(Register(X30), Register(X29), MemoryOperand(sp, 16, POSTINDEX)); // 16: 2 registers
|
||||
}
|
||||
|
||||
void ExtendedAssembler::PushArgsWithArgv(Register argc, Register argv, Register op, panda::ecmascript::Label *next)
|
||||
void ExtendedAssembler::PushArgsWithArgv(Register argc, Register argv, Register op,
|
||||
Register fp, panda::ecmascript::Label *next)
|
||||
{
|
||||
Label loopBeginning;
|
||||
Register sp(SP);
|
||||
if (next != nullptr) {
|
||||
Cmp(argc.W(), Immediate(0));
|
||||
B(Condition::LS, next);
|
||||
@ -108,20 +108,30 @@ void ExtendedAssembler::PushArgsWithArgv(Register argc, Register argv, Register
|
||||
Add(argv, argv, Operand(argc.W(), UXTW, 3)); // 3: argc * 8
|
||||
Bind(&loopBeginning);
|
||||
Ldr(op, MemoryOperand(argv, -8, PREINDEX)); // -8: 8 bytes
|
||||
Str(op, MemoryOperand(sp, -8, PREINDEX)); // -8: 8 bytes
|
||||
Str(op, MemoryOperand(fp, -8, PREINDEX)); // -8: 8 bytes
|
||||
Sub(argc.W(), argc.W(), Immediate(1));
|
||||
Cbnz(argc.W(), &loopBeginning);
|
||||
}
|
||||
|
||||
void ExtendedAssembler::PushArgc(int32_t argc, Register op)
|
||||
void ExtendedAssembler::PushArgc(int32_t argc, Register op, Register fp)
|
||||
{
|
||||
Mov(op, Immediate(JSTaggedValue(argc).GetRawData()));
|
||||
Str(op, MemoryOperand(Register(SP), -8, PREINDEX)); // -8: 8 bytes
|
||||
Str(op, MemoryOperand(fp, -8, PREINDEX)); // -8: 8 bytes
|
||||
}
|
||||
|
||||
void ExtendedAssembler::PushArgc(Register argc, Register op)
|
||||
void ExtendedAssembler::PushArgc(Register argc, Register op, Register fp)
|
||||
{
|
||||
Orr(op, argc, LogicalImmediate::Create(JSTaggedValue::TAG_INT, RegXSize));
|
||||
Str(op, MemoryOperand(Register(SP), -8, PREINDEX)); // -8: 8 bytes
|
||||
Str(op, MemoryOperand(fp, -8, PREINDEX)); // -8: 8 bytes
|
||||
}
|
||||
|
||||
void ExtendedAssembler::Align16(Register fp)
|
||||
{
|
||||
Label aligned;
|
||||
Tst(fp, LogicalImmediate::Create(0xf, RegXSize)); // 0xf: 0x1111
|
||||
B(Condition::EQ, &aligned);
|
||||
// 8: frame slot size
|
||||
Sub(fp, fp, Immediate(8));
|
||||
Bind(&aligned);
|
||||
}
|
||||
} // namespace panda::ecmascript::aarch64
|
@ -37,9 +37,11 @@ public:
|
||||
void RestoreFpAndLr();
|
||||
void SaveLrAndFp();
|
||||
void RestoreLrAndFp();
|
||||
void PushArgsWithArgv(Register argc, Register argv, Register op, panda::ecmascript::Label *next);
|
||||
void PushArgc(int32_t argc, Register op);
|
||||
void PushArgc(Register argc, Register op);
|
||||
void PushArgsWithArgv(Register argc, Register argv, Register op,
|
||||
Register fp, panda::ecmascript::Label *next);
|
||||
void PushArgc(int32_t argc, Register op, Register fp);
|
||||
void PushArgc(Register argc, Register op, Register fp);
|
||||
void Align16(Register fp);
|
||||
|
||||
Register TempRegister1()
|
||||
{
|
||||
|
@ -686,9 +686,12 @@ void AssemblerStubs::CallRuntimeWithArgv(ExtendedAssembler *assembler)
|
||||
|
||||
// Generate code for entering asm interpreter
|
||||
// c++ calling convention
|
||||
// Input: %X0 - glue
|
||||
// %X1 - argc
|
||||
// %X2 - argv(<callTarget, newTarget, this> are at the beginning of argv)
|
||||
// Input: glue - %X0
|
||||
// callTarget - %X1
|
||||
// method - %X2
|
||||
// callField - %X3
|
||||
// argc - %X4
|
||||
// argv - %X5(<callTarget, newTarget, this> are at the beginning of argv)
|
||||
void AssemblerStubs::AsmInterpreterEntry(ExtendedAssembler *assembler)
|
||||
{
|
||||
__ BindAssemblerStub(RTSTUB_ID(AsmInterpreterEntry));
|
||||
@ -704,29 +707,26 @@ void AssemblerStubs::AsmInterpreterEntry(ExtendedAssembler *assembler)
|
||||
}
|
||||
}
|
||||
|
||||
// Input: glueRegister - %X0
|
||||
// argcRegister - %X1
|
||||
// argvRegister - %X2(<callTarget, newTarget, this> are at the beginning of argv)
|
||||
// prevSpRegister - %X29
|
||||
// Input: glue - %X0
|
||||
// callTarget - %X1
|
||||
// method - %X2
|
||||
// callField - %X3
|
||||
// argc - %X4
|
||||
// argv - %X5(<callTarget, newTarget, this> are at the beginning of argv)
|
||||
void AssemblerStubs::JSCallDispatch(ExtendedAssembler *assembler)
|
||||
{
|
||||
Label notJSFunction;
|
||||
Label callNativeEntry;
|
||||
Label callJSFunctionEntry;
|
||||
Label pushArgsSlowPath;
|
||||
Label callJSProxyEntry;
|
||||
Label notCallable;
|
||||
Register glueRegister(X0);
|
||||
Register argcRegister(X1, W);
|
||||
Register argvRegister(X2);
|
||||
Register prevSpRegister(X29);
|
||||
|
||||
Register callTargetRegister(X3);
|
||||
Register methodRegister(X4);
|
||||
Register bitFieldRegister(X5);
|
||||
Register tempRegister(X6); // can not be used to store any variable
|
||||
Register functionTypeRegister(X7, W);
|
||||
__ Ldr(callTargetRegister, MemoryOperand(argvRegister, 0));
|
||||
Register argcRegister(X4, W);
|
||||
Register argvRegister(X5);
|
||||
Register callTargetRegister(X1);
|
||||
Register callFieldRegister(X3);
|
||||
Register bitFieldRegister(X16);
|
||||
Register tempRegister(X17); // can not be used to store any variable
|
||||
Register functionTypeRegister(X18, W);
|
||||
__ Ldr(tempRegister, MemoryOperand(callTargetRegister, 0)); // hclass
|
||||
__ Ldr(bitFieldRegister, MemoryOperand(tempRegister, JSHClass::BIT_FIELD_OFFSET));
|
||||
__ And(functionTypeRegister, bitFieldRegister.W(), LogicalImmediate::Create(0xFF, RegWSize));
|
||||
@ -741,39 +741,17 @@ void AssemblerStubs::JSCallDispatch(ExtendedAssembler *assembler)
|
||||
__ Tst(bitFieldRegister,
|
||||
LogicalImmediate::Create(static_cast<int64_t>(1ULL << JSHClass::CallableBit::START_BIT), RegXSize));
|
||||
__ B(Condition::EQ, ¬Callable);
|
||||
__ Mov(tempRegister.W(), Immediate(static_cast<int64_t>(JSType::JS_PROXY)));
|
||||
__ Cmp(functionTypeRegister, tempRegister.W());
|
||||
__ B(Condition::EQ, &callJSProxyEntry);
|
||||
// bound function branch, default native
|
||||
__ Ldr(methodRegister, MemoryOperand(callTargetRegister, JSFunctionBase::METHOD_OFFSET));
|
||||
// fall through
|
||||
}
|
||||
__ Bind(&callNativeEntry);
|
||||
CallNativeEntry(assembler);
|
||||
__ Bind(&callJSProxyEntry);
|
||||
{
|
||||
__ Ldr(methodRegister, MemoryOperand(callTargetRegister, JSProxy::METHOD_OFFSET));
|
||||
__ B(&callNativeEntry);
|
||||
}
|
||||
__ Bind(&callJSFunctionEntry);
|
||||
{
|
||||
__ Ldr(methodRegister, MemoryOperand(callTargetRegister, JSFunctionBase::METHOD_OFFSET));
|
||||
Register callFieldRegister(X7);
|
||||
__ Ldr(callFieldRegister, MemoryOperand(methodRegister, JSMethod::GetCallFieldOffset(false)));
|
||||
__ Tbnz(callFieldRegister, JSMethod::IsNativeBit::START_BIT, &callNativeEntry);
|
||||
Register declaredNumArgsRegister(X9);
|
||||
GetDeclaredNumArgsFromCallField(assembler, callFieldRegister, declaredNumArgsRegister);
|
||||
__ Cmp(declaredNumArgsRegister.W(), argcRegister);
|
||||
__ B(Condition::NE, &pushArgsSlowPath);
|
||||
// fast path
|
||||
__ PushFpAndLr();
|
||||
Register fpRegister(X10);
|
||||
__ Mov(fpRegister, Register(SP));
|
||||
PushArgsFastPath(assembler, glueRegister, argcRegister, argvRegister, callTargetRegister, methodRegister,
|
||||
prevSpRegister, fpRegister, callFieldRegister);
|
||||
__ Bind(&pushArgsSlowPath);
|
||||
PushArgsSlowPath(assembler, glueRegister, declaredNumArgsRegister, argcRegister, argvRegister,
|
||||
callTargetRegister, methodRegister, prevSpRegister, callFieldRegister);
|
||||
__ Add(argvRegister, argvRegister, Immediate(BuiltinFrame::RESERVED_CALL_ARGCOUNT * JSTaggedValue::TaggedTypeSize()));
|
||||
JSCallCommonEntry(assembler, JSCallMode::CALL_ENTRY);
|
||||
}
|
||||
__ Bind(¬Callable);
|
||||
{
|
||||
@ -801,8 +779,8 @@ void AssemblerStubs::JSCallCommonEntry(ExtendedAssembler *assembler, JSCallMode
|
||||
Register thisRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG2);
|
||||
[[maybe_unused]] TempRegister1Scope scope(assembler);
|
||||
Register tempArgcRegister = __ TempRegister1();
|
||||
__ PushArgc(argcRegister, tempArgcRegister);
|
||||
__ Str(thisRegister, MemoryOperand(Register(SP), -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ PushArgc(argcRegister, tempArgcRegister, fpRegister);
|
||||
__ Str(thisRegister, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
jumpSize = 0;
|
||||
}
|
||||
|
||||
@ -840,6 +818,7 @@ void AssemblerStubs::JSCallCommonEntry(ExtendedAssembler *assembler, JSCallMode
|
||||
void AssemblerStubs::JSCallCommonFastPath(ExtendedAssembler *assembler, JSCallMode mode, Label *pushCallThis)
|
||||
{
|
||||
auto argc = kungfu::AssemblerModule::GetArgcFromJSCallMode(mode);
|
||||
Register fpRegister = __ AvailableRegister1();
|
||||
// call range
|
||||
if (argc < 0) {
|
||||
Register numRegister = __ AvailableRegister2();
|
||||
@ -848,19 +827,19 @@ void AssemblerStubs::JSCallCommonFastPath(ExtendedAssembler *assembler, JSCallMo
|
||||
__ Mov(numRegister, argcRegister);
|
||||
[[maybe_unused]] TempRegister1Scope scope(assembler);
|
||||
Register opRegister = __ TempRegister1();
|
||||
__ PushArgsWithArgv(numRegister, argvRegister, opRegister, pushCallThis);
|
||||
__ PushArgsWithArgv(numRegister, argvRegister, opRegister, fpRegister, pushCallThis);
|
||||
} else if (argc > 0) {
|
||||
Register arg0 = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG0);
|
||||
Register arg1 = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG1);
|
||||
Register arg2 = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG2);
|
||||
if (argc > 2) { // 2: call arg2
|
||||
__ Str(arg2, MemoryOperand(Register(SP), -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(arg2, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
}
|
||||
if (argc > 1) {
|
||||
__ Str(arg1, MemoryOperand(Register(SP), -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(arg1, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
}
|
||||
if (argc > 0) {
|
||||
__ Str(arg0, MemoryOperand(Register(SP), -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(arg0, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -871,7 +850,7 @@ void AssemblerStubs::JSCallCommonSlowPath(ExtendedAssembler *assembler, JSCallMo
|
||||
Register callFieldRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::CALL_FIELD);
|
||||
Register argcRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARGC);
|
||||
Register argvRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARGV);
|
||||
|
||||
Register fpRegister = __ AvailableRegister1();
|
||||
Register arg0 = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG0);
|
||||
Register arg1 = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG1);
|
||||
Label noExtraEntry;
|
||||
@ -885,9 +864,9 @@ void AssemblerStubs::JSCallCommonSlowPath(ExtendedAssembler *assembler, JSCallMo
|
||||
[[maybe_unused]] TempRegister1Scope scope1(assembler);
|
||||
Register tempArgcRegister = __ TempRegister1();
|
||||
if (argc >= 0) {
|
||||
__ PushArgc(argc, tempArgcRegister);
|
||||
__ PushArgc(argc, tempArgcRegister, fpRegister);
|
||||
} else {
|
||||
__ PushArgc(argcRegister, tempArgcRegister);
|
||||
__ PushArgc(argcRegister, tempArgcRegister, fpRegister);
|
||||
}
|
||||
// fall through
|
||||
}
|
||||
@ -897,7 +876,8 @@ void AssemblerStubs::JSCallCommonSlowPath(ExtendedAssembler *assembler, JSCallMo
|
||||
{
|
||||
[[maybe_unused]] TempRegister1Scope scope(assembler);
|
||||
Register tempRegister = __ TempRegister1();
|
||||
PushUndefinedWithArgc(assembler, declaredNumArgsRegister, tempRegister, nullptr);
|
||||
PushUndefinedWithArgc(assembler,
|
||||
declaredNumArgsRegister, tempRegister, fpRegister, nullptr);
|
||||
}
|
||||
__ B(fastPathEntry);
|
||||
return;
|
||||
@ -911,7 +891,7 @@ void AssemblerStubs::JSCallCommonSlowPath(ExtendedAssembler *assembler, JSCallMo
|
||||
}
|
||||
[[maybe_unused]] TempRegister2Scope scope2(assembler);
|
||||
Register tempRegister = __ TempRegister2();
|
||||
PushUndefinedWithArgc(assembler, diffRegister, tempRegister, &pushArgsEntry);
|
||||
PushUndefinedWithArgc(assembler, diffRegister, tempRegister, fpRegister, &pushArgsEntry);
|
||||
__ B(fastPathEntry);
|
||||
}
|
||||
// declare < actual
|
||||
@ -930,19 +910,19 @@ void AssemblerStubs::JSCallCommonSlowPath(ExtendedAssembler *assembler, JSCallMo
|
||||
if (argc < 0) {
|
||||
[[maybe_unused]] TempRegister1Scope scope(assembler);
|
||||
Register opRegister = __ TempRegister1();
|
||||
__ PushArgsWithArgv(declaredNumArgsRegister, argvRegister, opRegister, nullptr);
|
||||
__ PushArgsWithArgv(declaredNumArgsRegister, argvRegister, opRegister, fpRegister, nullptr);
|
||||
} else if (argc > 0) {
|
||||
Label pushArgs0;
|
||||
if (argc > 2) { // 2: call arg2
|
||||
// decalare is 2 or 1 now
|
||||
__ Cmp(declaredNumArgsRegister, Immediate(1));
|
||||
__ B(Condition::EQ, &pushArgs0);
|
||||
__ Str(arg1, MemoryOperand(Register(SP), -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(arg1, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
}
|
||||
if (argc > 1) {
|
||||
__ Bind(&pushArgs0);
|
||||
// decalare is is 1 now
|
||||
__ Str(arg0, MemoryOperand(Register(SP), -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(arg0, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
}
|
||||
}
|
||||
__ B(pushCallThis);
|
||||
@ -958,8 +938,34 @@ Register AssemblerStubs::GetThisRegsiter(ExtendedAssembler *assembler, JSCallMod
|
||||
return __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG1);
|
||||
case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
|
||||
case JSCallMode::CALL_THIS_WITH_ARGV:
|
||||
case JSCallMode::CALL_FROM_AOT:
|
||||
return __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG2);
|
||||
case JSCallMode::CALL_FROM_AOT:
|
||||
case JSCallMode::CALL_ENTRY: {
|
||||
Register argvRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG1);
|
||||
Register thisRegister = __ AvailableRegister2();
|
||||
__ Ldur(thisRegister, MemoryOperand(argvRegister, -FRAME_SLOT_SIZE));
|
||||
return thisRegister;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
return INVALID_REG;
|
||||
}
|
||||
|
||||
Register AssemblerStubs::GetNewTargetRegsiter(ExtendedAssembler *assembler, JSCallMode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
|
||||
case JSCallMode::CALL_THIS_WITH_ARGV:
|
||||
return __ CallDispatcherArgument(kungfu::CallDispatchInputs::CALL_TARGET);
|
||||
case JSCallMode::CALL_FROM_AOT:
|
||||
case JSCallMode::CALL_ENTRY: {
|
||||
Register argvRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG1);
|
||||
Register newTargetRegister = __ AvailableRegister2();
|
||||
// 2: new Target index
|
||||
__ Ldur(newTargetRegister, MemoryOperand(argvRegister, -2 * FRAME_SLOT_SIZE));
|
||||
return newTargetRegister;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
@ -1051,33 +1057,45 @@ void AssemblerStubs::CallNativeWithArgv(ExtendedAssembler *assembler, bool callN
|
||||
Register opArgc(X8);
|
||||
Register opArgv(X9);
|
||||
Register temp(X10);
|
||||
Register stackArgs(X11);
|
||||
Register sp(SP);
|
||||
Register fpRegister(X11);
|
||||
Register spRegister(SP);
|
||||
|
||||
Label pushThis;
|
||||
|
||||
PushBuiltinFrame(assembler, glue, FrameType::BUILTIN_FRAME_WITH_ARGV, temp);
|
||||
|
||||
PushBuiltinFrame(assembler, glue, FrameType::BUILTIN_FRAME_WITH_ARGV, temp, argc);
|
||||
StackOverflowCheck(assembler);
|
||||
|
||||
__ Str(argc, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Mov(fpRegister, spRegister);
|
||||
__ Mov(opArgc, argc);
|
||||
__ Mov(opArgv, argv);
|
||||
__ PushArgsWithArgv(opArgc, opArgv, temp, &pushThis);
|
||||
__ PushArgsWithArgv(opArgc, opArgv, temp, fpRegister, &pushThis);
|
||||
|
||||
__ Bind(&pushThis);
|
||||
__ Str(thisObj, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX)); // this
|
||||
// newTarget
|
||||
if (callNew) {
|
||||
__ Str(callTarget, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
// 16: this & newTarget
|
||||
__ Stp(callTarget, thisObj, MemoryOperand(fpRegister, -16, AddrMode::PREINDEX));
|
||||
} else {
|
||||
__ Mov(temp, Immediate(JSTaggedValue::VALUE_UNDEFINED));
|
||||
__ Str(temp, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
// 16: this & newTarget
|
||||
__ Stp(temp, thisObj, MemoryOperand(fpRegister, -16, AddrMode::PREINDEX));
|
||||
}
|
||||
__ Str(callTarget, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX)); // callTarget
|
||||
__ Mov(stackArgs, sp);
|
||||
// callTarget
|
||||
__ Str(callTarget, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Mov(spRegister, fpRegister);
|
||||
|
||||
CallNativeInternal(assembler, glue, argc, stackArgs, nativeCode);
|
||||
Label call;
|
||||
Label notAligned;
|
||||
__ Tst(fpRegister, LogicalImmediate::Create(0xf, RegXSize)); // 0xf: 0x1111
|
||||
__ B(Condition::NE, ¬Aligned);
|
||||
// 16: xzr & stackArgs
|
||||
__ Stp(fpRegister, Register(Zero), MemoryOperand(spRegister, -16, AddrMode::PREINDEX));
|
||||
__ B(&call);
|
||||
__ Bind(¬Aligned);
|
||||
// push stackArgs
|
||||
__ Stur(fpRegister, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE));
|
||||
__ Sub(Register(SP), Register(SP), Immediate(FRAME_SLOT_SIZE));
|
||||
__ Bind(&call);
|
||||
CallNativeInternal(assembler, glue, argc, nativeCode);
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
@ -1115,30 +1133,39 @@ void AssemblerStubs::PushCallArgsAndDispatchNative(ExtendedAssembler *assembler)
|
||||
Register temp(X6);
|
||||
Register fp(FP);
|
||||
|
||||
PushBuiltinFrame(assembler, glue, FrameType::BUILTIN_FRAME, temp);
|
||||
PushBuiltinFrame(assembler, glue, FrameType::BUILTIN_FRAME, temp, argv);
|
||||
|
||||
__ Ldr(nativeCode, MemoryOperand(fp, BuiltinFrame::GetNativeCodeToFpDelta(false)));
|
||||
__ Ldr(argc, MemoryOperand(fp, BuiltinFrame::GetNumArgsToFpDelta(false)));
|
||||
__ Add(argv, fp, Immediate(BuiltinFrame::GetStackArgsToFpDelta(false)));
|
||||
|
||||
CallNativeInternal(assembler, glue, argc, argv, nativeCode);
|
||||
CallNativeInternal(assembler, glue, argc, nativeCode);
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
void AssemblerStubs::PushBuiltinFrame(ExtendedAssembler *assembler, Register glue, FrameType type, Register op)
|
||||
void AssemblerStubs::PushBuiltinFrame(ExtendedAssembler *assembler, Register glue,
|
||||
FrameType type, Register op, Register next)
|
||||
{
|
||||
__ SaveFpAndLr();
|
||||
__ Str(Register(FP), MemoryOperand(glue, JSThread::GlueData::GetLeaveFrameOffset(false)));
|
||||
__ Mov(op, Immediate(static_cast<int32_t>(type)));
|
||||
__ Str(op, MemoryOperand(Register(SP), -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
if (type == FrameType::BUILTIN_FRAME) {
|
||||
// push stack args
|
||||
__ Add(next, Register(FP), Immediate(BuiltinFrame::GetStackArgsToFpDelta(false)));
|
||||
// 16: type & next
|
||||
__ Stp(next, op, MemoryOperand(Register(SP), -16, AddrMode::PREINDEX));
|
||||
} else {
|
||||
// 16: type & next
|
||||
__ Stp(next, op, MemoryOperand(Register(SP), -16, AddrMode::PREINDEX));
|
||||
}
|
||||
}
|
||||
|
||||
void AssemblerStubs::CallNativeInternal(ExtendedAssembler *assembler, Register glue, Register numArgs,
|
||||
Register stackArgs, Register nativeCode)
|
||||
void AssemblerStubs::CallNativeInternal(ExtendedAssembler *assembler, Register glue,
|
||||
Register numArgs, Register nativeCode)
|
||||
{
|
||||
GlueToThread(assembler, glue, glue);
|
||||
ConstructEcmaRuntimeCallInfo(assembler, glue, numArgs, stackArgs);
|
||||
|
||||
__ And(numArgs, numArgs, LogicalImmediate::Create(0x00000000FFFFFFFF, RegXSize));
|
||||
// 16: numArgs & glue
|
||||
__ Stp(glue, numArgs, MemoryOperand(Register(SP), -16, AddrMode::PREINDEX));
|
||||
// rsp is ecma callinfo base
|
||||
__ Mov(Register(X0), Register(SP));
|
||||
__ Blr(nativeCode);
|
||||
@ -1415,13 +1442,14 @@ void AssemblerStubs::GeneratorReEnterAsmInterpDispatch(ExtendedAssembler *assemb
|
||||
__ Ldr(nRegsRegister, MemoryOperand(contextRegister, GeneratorContext::GENERATOR_NREGS_OFFSET));
|
||||
__ Ldr(regsArrayRegister, MemoryOperand(contextRegister, GeneratorContext::GENERATOR_REGS_ARRAY_OFFSET));
|
||||
__ Add(regsArrayRegister, regsArrayRegister, Immediate(TaggedArray::DATA_OFFSET));
|
||||
__ PushArgsWithArgv(nRegsRegister, regsArrayRegister, temp, &pushFrameState);
|
||||
__ PushArgsWithArgv(nRegsRegister, regsArrayRegister, temp, fpRegister, &pushFrameState);
|
||||
|
||||
__ Bind(&pushFrameState);
|
||||
__ Mov(newSp, spRegister);
|
||||
__ Mov(newSp, fpRegister);
|
||||
// push frame state
|
||||
PushGeneratorFrameState(assembler, prevSpRegister, fpRegister, callTarget, method, contextRegister, pc, temp);
|
||||
|
||||
__ Align16(fpRegister);
|
||||
__ Mov(Register(SP), fpRegister);
|
||||
// call bc stub
|
||||
CallBCStub(assembler, newSp, glue, callTarget, method, pc, temp);
|
||||
}
|
||||
@ -1430,7 +1458,7 @@ void AssemblerStubs::PushCallThis(ExtendedAssembler *assembler, JSCallMode mode)
|
||||
{
|
||||
Register callFieldRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::CALL_FIELD);
|
||||
Register callTargetRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::CALL_TARGET);
|
||||
Register sp(SP);
|
||||
Register fpRegister = __ AvailableRegister1();
|
||||
|
||||
Label pushVregs;
|
||||
Label pushNewTarget;
|
||||
@ -1446,10 +1474,10 @@ void AssemblerStubs::PushCallThis(ExtendedAssembler *assembler, JSCallMode mode)
|
||||
[[maybe_unused]] TempRegister1Scope scope1(assembler);
|
||||
Register tempRegister = __ TempRegister1();
|
||||
__ Mov(tempRegister, Immediate(JSTaggedValue::VALUE_UNDEFINED));
|
||||
__ Str(tempRegister, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(tempRegister, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
} else {
|
||||
Register thisRegister = GetThisRegsiter(assembler, mode);
|
||||
__ Str(thisRegister, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(thisRegister, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
}
|
||||
__ Bind(&pushNewTarget);
|
||||
{
|
||||
@ -1458,15 +1486,16 @@ void AssemblerStubs::PushCallThis(ExtendedAssembler *assembler, JSCallMode mode)
|
||||
[[maybe_unused]] TempRegister1Scope scope1(assembler);
|
||||
Register newTarget = __ TempRegister1();
|
||||
__ Mov(newTarget, Immediate(JSTaggedValue::VALUE_UNDEFINED));
|
||||
__ Str(newTarget, MemoryOperand(Register(SP), -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(newTarget, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
} else {
|
||||
__ Str(callTargetRegister, MemoryOperand(Register(SP), -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
Register newTargetRegister = GetNewTargetRegsiter(assembler, mode);
|
||||
__ Str(newTargetRegister, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
}
|
||||
}
|
||||
__ Bind(&pushCallTarget);
|
||||
{
|
||||
__ Tbz(callFieldRegister, JSMethod::HaveFuncBit::START_BIT, &pushVregs);
|
||||
__ Str(callTargetRegister, MemoryOperand(Register(SP), -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(callTargetRegister, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
}
|
||||
__ Bind(&pushVregs);
|
||||
{
|
||||
@ -1488,12 +1517,13 @@ void AssemblerStubs::PushVregs(ExtendedAssembler *assembler)
|
||||
// args register can be reused now.
|
||||
Register numVregsRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG0);
|
||||
GetNumVregsFromCallField(assembler, callFieldRegister, numVregsRegister);
|
||||
PushUndefinedWithArgc(assembler, numVregsRegister, tempRegister, &pushFrameStateAndCall);
|
||||
PushUndefinedWithArgc(assembler, numVregsRegister,
|
||||
tempRegister, fpRegister, &pushFrameStateAndCall);
|
||||
// fall through
|
||||
__ Bind(&pushFrameStateAndCall);
|
||||
{
|
||||
Register newSpRegister = __ AvailableRegister2();
|
||||
__ Mov(newSpRegister, Register(SP));
|
||||
__ Mov(newSpRegister, fpRegister);
|
||||
|
||||
StackOverflowCheck(assembler);
|
||||
|
||||
@ -1502,6 +1532,8 @@ void AssemblerStubs::PushVregs(ExtendedAssembler *assembler)
|
||||
PushFrameState(assembler, prevSpRegister, fpRegister, callTargetRegister, methodRegister, pcRegister,
|
||||
tempRegister);
|
||||
|
||||
__ Align16(fpRegister);
|
||||
__ Mov(Register(SP), fpRegister);
|
||||
DispatchCall(assembler, pcRegister, newSpRegister);
|
||||
}
|
||||
}
|
||||
@ -1537,15 +1569,15 @@ void AssemblerStubs::DispatchCall(ExtendedAssembler *assembler, Register pcRegis
|
||||
void AssemblerStubs::PushFrameState(ExtendedAssembler *assembler, Register prevSp, Register fp,
|
||||
Register callTarget, Register method, Register pc, Register op)
|
||||
{
|
||||
Register sp(SP);
|
||||
__ Mov(op, Immediate(static_cast<int32_t>(FrameType::ASM_INTERPRETER_FRAME)));
|
||||
__ Stp(prevSp, op, MemoryOperand(sp, -16, AddrMode::PREINDEX)); // -16: frame type & prevSp
|
||||
__ Stp(prevSp, op, MemoryOperand(fp, -16, AddrMode::PREINDEX)); // -16: frame type & prevSp
|
||||
__ Ldr(pc, MemoryOperand(method, JSMethod::GetBytecodeArrayOffset(false)));
|
||||
__ Stp(fp, pc, MemoryOperand(sp, -16, AddrMode::PREINDEX)); // -16: pc & fp
|
||||
__ Mov(op, Register(SP));
|
||||
__ Stp(op, pc, MemoryOperand(fp, -16, AddrMode::PREINDEX)); // -16: pc & fp
|
||||
__ Ldr(op, MemoryOperand(callTarget, JSFunction::LEXICAL_ENV_OFFSET));
|
||||
__ Stp(op, Register(Zero), MemoryOperand(sp, -16, AddrMode::PREINDEX)); // -16: jumpSizeAfterCall & env
|
||||
__ Stp(op, Register(Zero), MemoryOperand(fp, -16, AddrMode::PREINDEX)); // -16: jumpSizeAfterCall & env
|
||||
__ Mov(op, Immediate(JSTaggedValue::VALUE_HOLE));
|
||||
__ Stp(callTarget, op, MemoryOperand(sp, -16, AddrMode::PREINDEX)); // -16: acc & callTarget
|
||||
__ Stp(callTarget, op, MemoryOperand(fp, -16, AddrMode::PREINDEX)); // -16: acc & callTarget
|
||||
}
|
||||
|
||||
void AssemblerStubs::GetNumVregsFromCallField(ExtendedAssembler *assembler, Register callField, Register numVregs)
|
||||
@ -1566,7 +1598,7 @@ void AssemblerStubs::GetDeclaredNumArgsFromCallField(ExtendedAssembler *assemble
|
||||
}
|
||||
|
||||
void AssemblerStubs::PushUndefinedWithArgc(ExtendedAssembler *assembler, Register argc, Register temp,
|
||||
panda::ecmascript::Label *next)
|
||||
Register fp, panda::ecmascript::Label *next)
|
||||
{
|
||||
if (next != nullptr) {
|
||||
__ Cmp(argc.W(), Immediate(0));
|
||||
@ -1575,7 +1607,7 @@ void AssemblerStubs::PushUndefinedWithArgc(ExtendedAssembler *assembler, Registe
|
||||
Label loopBeginning;
|
||||
__ Mov(temp, Immediate(JSTaggedValue::VALUE_UNDEFINED));
|
||||
__ Bind(&loopBeginning);
|
||||
__ Str(temp, MemoryOperand(Register(SP), -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(temp, MemoryOperand(fp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Sub(argc.W(), argc.W(), Immediate(1));
|
||||
__ Cbnz(argc.W(), &loopBeginning);
|
||||
}
|
||||
@ -1585,17 +1617,6 @@ void AssemblerStubs::GlueToThread(ExtendedAssembler *assembler, Register glue, R
|
||||
__ Sub(thread, glue, Immediate(JSThread::GetGlueDataOffset()));
|
||||
}
|
||||
|
||||
void AssemblerStubs::ConstructEcmaRuntimeCallInfo(ExtendedAssembler *assembler, Register thread, Register numArgs,
|
||||
Register stackArgs)
|
||||
{
|
||||
Register sp(SP);
|
||||
__ Sub(sp, sp, Immediate(sizeof(EcmaRuntimeCallInfo)));
|
||||
__ Str(thread, MemoryOperand(sp, EcmaRuntimeCallInfo::GetThreadOffset()));
|
||||
__ And(numArgs, numArgs, LogicalImmediate::Create(0x00000000FFFFFFFF, RegXSize));
|
||||
__ Str(numArgs, MemoryOperand(sp, EcmaRuntimeCallInfo::GetNumArgsOffset()));
|
||||
__ Str(stackArgs, MemoryOperand(sp, EcmaRuntimeCallInfo::GetStackArgsOffset()));
|
||||
}
|
||||
|
||||
void AssemblerStubs::StackOverflowCheck([[maybe_unused]] ExtendedAssembler *assembler)
|
||||
{
|
||||
}
|
||||
@ -1615,7 +1636,6 @@ void AssemblerStubs::PushAsmInterpEntryFrame(ExtendedAssembler *assembler, bool
|
||||
Register frameTypeRegister = __ TempRegister2();
|
||||
|
||||
if (saveLeave) {
|
||||
__ Str(glue, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
// prev managed fp is leave frame or nullptr(the first frame)
|
||||
__ Ldr(prevFrameRegister, MemoryOperand(glue, JSThread::GlueData::GetLeaveFrameOffset(false)));
|
||||
__ Mov(frameTypeRegister, Immediate(static_cast<int64_t>(FrameType::ASM_INTERPRETER_ENTRY_FRAME)));
|
||||
@ -1628,7 +1648,8 @@ void AssemblerStubs::PushAsmInterpEntryFrame(ExtendedAssembler *assembler, bool
|
||||
|
||||
// 2 : 2 means pair
|
||||
__ Stp(prevFrameRegister, frameTypeRegister, MemoryOperand(sp, -2 * FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(Register(Zero), MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX)); // pc
|
||||
// 2 : pc & glue
|
||||
__ Stp(glue, Register(Zero), MemoryOperand(sp, -2 * FRAME_SLOT_SIZE, AddrMode::PREINDEX)); // pc
|
||||
}
|
||||
|
||||
void AssemblerStubs::PopAsmInterpEntryFrame(ExtendedAssembler *assembler, bool saveLeave)
|
||||
@ -1639,15 +1660,17 @@ void AssemblerStubs::PopAsmInterpEntryFrame(ExtendedAssembler *assembler, bool s
|
||||
Register prevFrameRegister = __ TempRegister1();
|
||||
[[maybe_unused]] TempRegister2Scope scope2(assembler);
|
||||
Register glue = __ TempRegister2();
|
||||
// skip pc
|
||||
__ Add(sp, sp, Immediate(FRAME_SLOT_SIZE));
|
||||
__ Ldr(prevFrameRegister, MemoryOperand(sp, FRAME_SLOT_SIZE, AddrMode::POSTINDEX));
|
||||
// skip frame type
|
||||
__ Add(sp, sp, Immediate(FRAME_SLOT_SIZE));
|
||||
|
||||
if (saveLeave) {
|
||||
// 2: glue & pc
|
||||
__ Ldp(glue, Register(Zero), MemoryOperand(sp, 2 * FRAME_SLOT_SIZE, AddrMode::POSTINDEX));
|
||||
} else {
|
||||
// 2: glue & pc
|
||||
__ Add(sp, sp, Immediate(2 * FRAME_SLOT_SIZE));
|
||||
}
|
||||
// 2: skip frame type & prev
|
||||
__ Ldp(prevFrameRegister, Register(Zero), MemoryOperand(sp, 2 * FRAME_SLOT_SIZE, AddrMode::POSTINDEX));
|
||||
if (saveLeave) {
|
||||
__ RestoreFpAndLr();
|
||||
__ Ldr(glue, MemoryOperand(sp, FRAME_SLOT_SIZE, AddrMode::POSTINDEX));
|
||||
__ Str(prevFrameRegister, MemoryOperand(glue, JSThread::GlueData::GetLeaveFrameOffset(false)));
|
||||
} else {
|
||||
__ RestoreLrAndFp();
|
||||
@ -1661,10 +1684,9 @@ void AssemblerStubs::PushGeneratorFrameState(ExtendedAssembler *assembler, Regis
|
||||
Register &fpRegister, Register &callTargetRegister, Register &methodRegister,
|
||||
Register &contextRegister, Register &pcRegister, Register &operatorRegister)
|
||||
{
|
||||
Register sp(SP);
|
||||
__ Mov(operatorRegister, Immediate(static_cast<int64_t>(FrameType::ASM_INTERPRETER_FRAME)));
|
||||
// 2 : frameType and prevSp
|
||||
__ Stp(prevSpRegister, operatorRegister, MemoryOperand(sp, -2 * FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Stp(prevSpRegister, operatorRegister, MemoryOperand(fpRegister, -2 * FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Ldr(pcRegister, MemoryOperand(methodRegister, JSMethod::GetBytecodeArrayOffset(false)));
|
||||
// offset need 8 align, GENERATOR_NREGS_OFFSET instead of GENERATOR_BC_OFFSET_OFFSET
|
||||
__ Ldr(operatorRegister, MemoryOperand(contextRegister, GeneratorContext::GENERATOR_NREGS_OFFSET));
|
||||
@ -1673,23 +1695,21 @@ void AssemblerStubs::PushGeneratorFrameState(ExtendedAssembler *assembler, Regis
|
||||
__ Add(pcRegister, operatorRegister, pcRegister);
|
||||
__ Add(pcRegister, pcRegister, Immediate(BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8_V8)));
|
||||
// pc and fp
|
||||
__ Stp(fpRegister, pcRegister, MemoryOperand(sp, -2 * FRAME_SLOT_SIZE, AddrMode::PREINDEX)); // 2 : 2 means pair
|
||||
__ Mov(operatorRegister, Register(SP));
|
||||
__ Stp(operatorRegister, pcRegister, MemoryOperand(fpRegister, -2 * FRAME_SLOT_SIZE, AddrMode::PREINDEX)); // 2 : 2 means pair
|
||||
// jumpSizeAfterCall
|
||||
__ Str(Register(Zero), MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(Register(Zero), MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Ldr(operatorRegister, MemoryOperand(contextRegister, GeneratorContext::GENERATOR_LEXICALENV_OFFSET));
|
||||
// env
|
||||
__ Str(operatorRegister, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Str(operatorRegister, MemoryOperand(fpRegister, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Ldr(operatorRegister, MemoryOperand(contextRegister, GeneratorContext::GENERATOR_ACC_OFFSET));
|
||||
// 2 : acc and callTarget
|
||||
__ Stp(callTargetRegister, operatorRegister, MemoryOperand(sp, -2 * FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
__ Stp(callTargetRegister, operatorRegister, MemoryOperand(fpRegister, -2 * FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
}
|
||||
|
||||
void AssemblerStubs::CallBCStub(ExtendedAssembler *assembler, Register &newSp, Register &glue,
|
||||
Register &callTarget, Register &method, Register &pc, Register &temp)
|
||||
{
|
||||
Register sp(SP);
|
||||
// caller save newSp register to restore rsp after call
|
||||
__ Str(newSp, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
// prepare call entry
|
||||
__ Mov(Register(X19), glue); // X19 - glue
|
||||
__ Mov(Register(FP), newSp); // FP - sp
|
||||
@ -1710,137 +1730,28 @@ void AssemblerStubs::CallBCStub(ExtendedAssembler *assembler, Register &newSp, R
|
||||
void AssemblerStubs::CallNativeEntry(ExtendedAssembler *assembler)
|
||||
{
|
||||
Register glue(X0);
|
||||
Register argc(X1);
|
||||
Register argv(X2);
|
||||
Register method(X4);
|
||||
Register function(X3);
|
||||
Register argc(X4);
|
||||
Register argv(X5);
|
||||
Register method(X2);
|
||||
Register function(X1);
|
||||
Register nativeCode(X7);
|
||||
Register temp(X9);
|
||||
|
||||
Register sp(SP);
|
||||
__ Str(function, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
// 16: function & align
|
||||
__ Stp(function, Register(Zero), MemoryOperand(sp, -16, AddrMode::PREINDEX));
|
||||
// 16: skip nativeCode & argc
|
||||
__ Sub(sp, sp, Immediate(16));
|
||||
PushBuiltinFrame(assembler, glue, FrameType::BUILTIN_ENTRY_FRAME, temp);
|
||||
PushBuiltinFrame(assembler, glue, FrameType::BUILTIN_ENTRY_FRAME, temp, argv);
|
||||
// get native pointer
|
||||
__ Ldr(nativeCode, MemoryOperand(method, JSMethod::GetBytecodeArrayOffset(false)));
|
||||
CallNativeInternal(assembler, glue, argc, argv, nativeCode);
|
||||
CallNativeInternal(assembler, glue, argc, nativeCode);
|
||||
|
||||
// 24: skip function
|
||||
__ Add(sp, sp, Immediate(24));
|
||||
// 32: skip function
|
||||
__ Add(sp, sp, Immediate(32));
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
// Input: glue - %X0
|
||||
// argc - %X1
|
||||
// argv - %X2(<callTarget, newTarget, this> are at the beginning of argv)
|
||||
// callTarget - %X3
|
||||
// method - %X4
|
||||
// prevSp - %X29
|
||||
// fp - %10
|
||||
// callField - %X7
|
||||
void AssemblerStubs::PushArgsFastPath(ExtendedAssembler *assembler,
|
||||
Register &glue, Register &argc, Register &argv, Register &callTarget,
|
||||
Register &method, Register &prevSp, Register &fp, Register &callField)
|
||||
{
|
||||
Label pushCallThis;
|
||||
Label pushNewTarget;
|
||||
Label pushCallTarget;
|
||||
Label pushVregs;
|
||||
Label pushFrameState;
|
||||
Register sp(SP);
|
||||
|
||||
Register argvOnlyHaveArgs(X11);
|
||||
__ Add(argvOnlyHaveArgs, argv, Immediate(BuiltinFrame::RESERVED_CALL_ARGCOUNT * JSTaggedValue::TaggedTypeSize()));
|
||||
Register tempRegister(X12);
|
||||
__ PushArgsWithArgv(argc, argvOnlyHaveArgs, tempRegister, &pushCallThis);
|
||||
|
||||
__ Bind(&pushCallThis);
|
||||
__ Tst(callField, LogicalImmediate::Create(CALL_TYPE_MASK, RegXSize));
|
||||
__ B(Condition::EQ, &pushVregs);
|
||||
__ Tst(callField, LogicalImmediate::Create(JSMethod::HaveThisBit::Mask(), RegXSize));
|
||||
__ B(Condition::EQ, &pushNewTarget);
|
||||
__ Ldr(tempRegister, MemoryOperand(argv, 16)); // 16: skip callTarget, newTarget
|
||||
__ Str(tempRegister, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
|
||||
__ Bind(&pushNewTarget);
|
||||
__ Tst(callField, LogicalImmediate::Create(JSMethod::HaveNewTargetBit::Mask(), RegXSize));
|
||||
__ B(Condition::EQ, &pushCallTarget);
|
||||
__ Ldr(tempRegister, MemoryOperand(argv, 8)); // 8: skip callTarget
|
||||
__ Str(tempRegister, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
|
||||
__ Bind(&pushCallTarget);
|
||||
__ Tst(callField, LogicalImmediate::Create(JSMethod::HaveFuncBit::Mask(), RegXSize));
|
||||
__ B(Condition::EQ, &pushVregs);
|
||||
__ Str(callTarget, MemoryOperand(sp, -FRAME_SLOT_SIZE, AddrMode::PREINDEX));
|
||||
|
||||
__ Bind(&pushVregs);
|
||||
{
|
||||
Register numVregsRegister(X13);
|
||||
GetNumVregsFromCallField(assembler, callField, numVregsRegister);
|
||||
__ Cbz(numVregsRegister.W(), &pushFrameState);
|
||||
PushUndefinedWithArgc(assembler, numVregsRegister, tempRegister, &pushFrameState);
|
||||
}
|
||||
|
||||
__ Bind(&pushFrameState);
|
||||
Register newSpRegister(X14);
|
||||
__ Mov(newSpRegister, sp);
|
||||
|
||||
StackOverflowCheck(assembler);
|
||||
|
||||
Register pcRegister(X11);
|
||||
PushFrameState(assembler, prevSp, fp, callTarget, method, pcRegister, tempRegister);
|
||||
CallBCStub(assembler, newSpRegister, glue, callTarget, method, pcRegister, tempRegister);
|
||||
}
|
||||
|
||||
// Input: glueRegister - %X0
|
||||
// declaredNumArgsRegister - %X9
|
||||
// argcRegister - %X1
|
||||
// argvRegister - %X2(<callTarget, newTarget, this> are at the beginning of argv)
|
||||
// callTargetRegister - %X3
|
||||
// methodRegister - %X4
|
||||
// prevSpRegister - %X29
|
||||
// callFieldRegister - %X7
|
||||
void AssemblerStubs::PushArgsSlowPath(ExtendedAssembler *assembler, Register &glueRegister,
|
||||
Register &declaredNumArgsRegister, Register &argcRegister, Register &argvRegister, Register &callTargetRegister,
|
||||
Register &methodRegister, Register &prevSpRegister, Register &callFieldRegister)
|
||||
{
|
||||
Label jumpToFastPath;
|
||||
Label haveExtra;
|
||||
Label pushUndefined;
|
||||
Register fpRegister(X10);
|
||||
Register tempRegister(X12);
|
||||
|
||||
__ PushFpAndLr();
|
||||
__ Mov(fpRegister, Register(SP));
|
||||
__ Tst(callFieldRegister, LogicalImmediate::Create(JSMethod::HaveExtraBit::Mask(), RegXSize));
|
||||
__ B(Condition::NE, &haveExtra);
|
||||
__ Mov(tempRegister.W(), declaredNumArgsRegister.W());
|
||||
__ Sub(declaredNumArgsRegister.W(), declaredNumArgsRegister.W(), argcRegister.W());
|
||||
__ Cmp(declaredNumArgsRegister.W(), Immediate(0));
|
||||
__ B(Condition::GT, &pushUndefined);
|
||||
__ Mov(argcRegister.W(), tempRegister.W()); // actual = std::min(declare, actual)
|
||||
__ B(&jumpToFastPath);
|
||||
// fall through
|
||||
__ Bind(&haveExtra);
|
||||
{
|
||||
Register tempArgcRegister(X13);
|
||||
__ PushArgc(argcRegister, tempArgcRegister);
|
||||
__ Sub(declaredNumArgsRegister.W(), declaredNumArgsRegister.W(), argcRegister.W());
|
||||
__ Cmp(declaredNumArgsRegister.W(), Immediate(0));
|
||||
__ B(Condition::LE, &jumpToFastPath);
|
||||
// fall through
|
||||
}
|
||||
__ Bind(&pushUndefined);
|
||||
{
|
||||
PushUndefinedWithArgc(assembler, declaredNumArgsRegister, tempRegister, &jumpToFastPath);
|
||||
// fall through
|
||||
}
|
||||
__ Bind(&jumpToFastPath);
|
||||
PushArgsFastPath(assembler, glueRegister, argcRegister, argvRegister, callTargetRegister, methodRegister,
|
||||
prevSpRegister, fpRegister, callFieldRegister);
|
||||
}
|
||||
|
||||
void AssemblerStubs::PushArgsWithArgV(ExtendedAssembler *assembler, Register jsfunc,
|
||||
Register actualNumArgs, Register argV, Label *pushCallThis)
|
||||
{
|
||||
@ -1861,7 +1772,7 @@ void AssemblerStubs::PushArgsWithArgV(ExtendedAssembler *assembler, Register jsf
|
||||
{
|
||||
[[maybe_unused]] TempRegister2Scope scope2(assembler);
|
||||
Register undefinedValue = __ TempRegister2();
|
||||
PushUndefinedWithArgc(assembler, tmp, undefinedValue, nullptr);
|
||||
PushUndefinedWithArgc(assembler, tmp, undefinedValue, Register(SP), nullptr);
|
||||
}
|
||||
|
||||
__ Bind(©Arguments);
|
||||
|
@ -110,15 +110,17 @@ private:
|
||||
static void PushCallThis(ExtendedAssembler *assembler, JSCallMode mode);
|
||||
|
||||
static Register GetThisRegsiter(ExtendedAssembler *assembler, JSCallMode mode);
|
||||
static Register GetNewTargetRegsiter(ExtendedAssembler *assembler, JSCallMode mode);
|
||||
|
||||
static void PushVregs(ExtendedAssembler *assembler);
|
||||
|
||||
static void DispatchCall(ExtendedAssembler *assembler, Register pc, Register newSp);
|
||||
|
||||
static void CallNativeInternal(ExtendedAssembler *assembler, Register glue, Register numArgs, Register stackArgs,
|
||||
static void CallNativeInternal(ExtendedAssembler *assembler, Register glue, Register numArgs,
|
||||
Register nativeCode);
|
||||
|
||||
static void PushBuiltinFrame(ExtendedAssembler *assembler, Register glue, FrameType type, Register op);
|
||||
static void PushBuiltinFrame(ExtendedAssembler *assembler, Register glue,
|
||||
FrameType type, Register op, Register next);
|
||||
|
||||
static void PushFrameState(ExtendedAssembler *assembler, Register prevSp, Register fp, Register callTarget,
|
||||
Register method, Register pc, Register op);
|
||||
@ -134,15 +136,12 @@ private:
|
||||
Register declaredNumArgs);
|
||||
|
||||
static void PushUndefinedWithArgc(ExtendedAssembler *assembler, Register argc, Register temp,
|
||||
panda::ecmascript::Label *next);
|
||||
Register fp, panda::ecmascript::Label *next);
|
||||
|
||||
static void SaveFpAndJumpSize(ExtendedAssembler *assembler, Immediate jumpSize);
|
||||
|
||||
static void GlueToThread(ExtendedAssembler *assembler, Register glue, Register thread);
|
||||
|
||||
static void ConstructEcmaRuntimeCallInfo(ExtendedAssembler *assembler, Register thread, Register numArgs,
|
||||
Register stackArgs);
|
||||
|
||||
static void StackOverflowCheck([[maybe_unused]] ExtendedAssembler *assembler);
|
||||
|
||||
static void PushAsmInterpEntryFrame(ExtendedAssembler *assembler, bool saveLeave);
|
||||
@ -159,14 +158,6 @@ private:
|
||||
static void CallNativeEntry(ExtendedAssembler *assembler);
|
||||
|
||||
static void CallNativeWithArgv(ExtendedAssembler *assembler, bool callNew);
|
||||
|
||||
static void PushArgsFastPath(ExtendedAssembler *assembler,
|
||||
Register &glue, Register &argc, Register &argv, Register &callTarget,
|
||||
Register &method, Register &prevSp, Register &fp, Register &callField);
|
||||
|
||||
static void PushArgsSlowPath(ExtendedAssembler *assembler, Register &glueRegister,
|
||||
Register &declaredNumArgsRegister, Register &argcRegister, Register &argvRegister, Register &callTargetRegister,
|
||||
Register &methodRegister, Register &prevSpRegister, Register &callFieldRegister);
|
||||
static void OptimizedCallAsmInterpreter(ExtendedAssembler *assembler);
|
||||
static void PushArgsWithArgV(ExtendedAssembler *assembler, Register jsfunc,
|
||||
Register actualNumArgs, Register argV, Label *pushCallThis);
|
||||
|
@ -892,10 +892,12 @@ void AssemblerStubsX64::CallRuntimeWithArgv(ExtendedAssembler *assembler)
|
||||
}
|
||||
|
||||
// Generate code for Entering asm interpreter
|
||||
// c++ calling convention
|
||||
// Input: %rdi - glue
|
||||
// %rsi - argc
|
||||
// %rdx - argv(<callTarget, newTarget, this> are at the beginning of argv)
|
||||
// Input: glue - %rdi
|
||||
// callTarget - %rsi
|
||||
// method - %rdx
|
||||
// callField - %rcx
|
||||
// argc - %r8
|
||||
// argv - %r9(<callTarget, newTarget, this> are at the beginning of argv)
|
||||
void AssemblerStubsX64::AsmInterpreterEntry(ExtendedAssembler *assembler)
|
||||
{
|
||||
__ BindAssemblerStub(RTSTUB_ID(AsmInterpreterEntry));
|
||||
@ -962,28 +964,24 @@ void AssemblerStubsX64::GeneratorReEnterAsmInterpDispatch(ExtendedAssembler *ass
|
||||
CallBCStub(assembler, newSpRegister, glueRegister, callTargetRegister, methodRegister, pcRegister);
|
||||
}
|
||||
|
||||
// Input: glueRegister - %rdi
|
||||
// argcRegister - %rsi
|
||||
// argvRegister - %rdx(<callTarget, newTarget, this> are at the beginning of argv)
|
||||
// prevSpRegister - %rbp
|
||||
// Input: glue - %rdi
|
||||
// callTarget - %rsi
|
||||
// method - %rdx
|
||||
// callField - %rcx
|
||||
// argc - %r8
|
||||
// argv - %r9(<callTarget, newTarget, this> are at the beginning of argv)
|
||||
// prevSp - %rbp
|
||||
void AssemblerStubsX64::JSCallDispatch(ExtendedAssembler *assembler)
|
||||
{
|
||||
Label notJSFunction;
|
||||
Label callNativeEntry;
|
||||
Label callJSFunctionEntry;
|
||||
Label pushArgsSlowPath;
|
||||
Label callJSProxyEntry;
|
||||
Label notCallable;
|
||||
Register glueRegister = rdi;
|
||||
Register argcRegister = rsi;
|
||||
Register argvRegister = rdx;
|
||||
Register prevSpRegister = rbp;
|
||||
|
||||
Register callTargetRegister = r9;
|
||||
Register methodRegister = rcx;
|
||||
Register callTargetRegister = rsi;
|
||||
Register argvRegister = r9;
|
||||
Register bitFieldRegister = r12;
|
||||
Register tempRegister = r11; // can not be used to store any variable
|
||||
__ Movq(Operand(rdx, 0), callTargetRegister);
|
||||
__ Movq(Operand(callTargetRegister, 0), tempRegister); // hclass
|
||||
__ Movq(Operand(tempRegister, JSHClass::BIT_FIELD_OFFSET), bitFieldRegister);
|
||||
__ Cmpb(static_cast<int32_t>(JSType::JS_FUNCTION_BEGIN), bitFieldRegister);
|
||||
@ -994,38 +992,19 @@ void AssemblerStubsX64::JSCallDispatch(ExtendedAssembler *assembler)
|
||||
{
|
||||
__ Testq(static_cast<int64_t>(1ULL << JSHClass::CallableBit::START_BIT), bitFieldRegister);
|
||||
__ Jz(¬Callable);
|
||||
__ Cmpb(static_cast<int32_t>(JSType::JS_PROXY), bitFieldRegister);
|
||||
__ Je(&callJSProxyEntry);
|
||||
// bound function branch, default native
|
||||
__ Movq(Operand(callTargetRegister, JSFunctionBase::METHOD_OFFSET), methodRegister);
|
||||
// fall through
|
||||
}
|
||||
__ Bind(&callNativeEntry);
|
||||
CallNativeEntry(assembler);
|
||||
__ Bind(&callJSProxyEntry);
|
||||
{
|
||||
__ Movq(Operand(callTargetRegister, JSProxy::METHOD_OFFSET), methodRegister);
|
||||
__ Jmp(&callNativeEntry);
|
||||
}
|
||||
__ Bind(&callJSFunctionEntry);
|
||||
{
|
||||
__ Movq(Operand(callTargetRegister, JSFunctionBase::METHOD_OFFSET), methodRegister);
|
||||
Register callFieldRegister = r14;
|
||||
__ Movq(Operand(methodRegister, JSMethod::GetCallFieldOffset(false)), callFieldRegister);
|
||||
Register callFieldRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::CALL_FIELD);
|
||||
__ Btq(JSMethod::IsNativeBit::START_BIT, callFieldRegister);
|
||||
__ Jb(&callNativeEntry);
|
||||
Register declaredNumArgsRegister = r11;
|
||||
GetDeclaredNumArgsFromCallField(assembler, callFieldRegister, declaredNumArgsRegister);
|
||||
__ Cmpq(declaredNumArgsRegister, argcRegister);
|
||||
__ Jne(&pushArgsSlowPath);
|
||||
// fast path
|
||||
Register fpRegister = r10;
|
||||
__ Movq(rsp, fpRegister);
|
||||
PushArgsFastPath(assembler, glueRegister, argcRegister, argvRegister, callTargetRegister, methodRegister,
|
||||
prevSpRegister, fpRegister, callFieldRegister);
|
||||
__ Bind(&pushArgsSlowPath);
|
||||
PushArgsSlowPath(assembler, glueRegister, declaredNumArgsRegister, argcRegister, argvRegister,
|
||||
callTargetRegister, methodRegister, prevSpRegister, callFieldRegister);
|
||||
|
||||
__ Leaq(Operand(argvRegister, BuiltinFrame::RESERVED_CALL_ARGCOUNT * JSTaggedValue::TaggedTypeSize()),
|
||||
argvRegister);
|
||||
JSCallCommonEntry(assembler, JSCallMode::CALL_ENTRY);
|
||||
}
|
||||
__ Bind(¬Callable);
|
||||
{
|
||||
@ -1045,117 +1024,6 @@ void AssemblerStubsX64::JSCallDispatch(ExtendedAssembler *assembler)
|
||||
}
|
||||
}
|
||||
|
||||
// Input: glueRegister - %rdi
|
||||
// argcRegister - %rsi
|
||||
// argvRegister - %rdx(<callTarget, newTarget, this> are at the beginning of argv)
|
||||
// callTargetRegister - %r9
|
||||
// methodRegister - %rcx
|
||||
// prevSpRegister - %rbp
|
||||
// fpRegister - %r10
|
||||
// callFieldRegister - %r14
|
||||
void AssemblerStubsX64::PushArgsFastPath(ExtendedAssembler *assembler, Register glueRegister,
|
||||
Register argcRegister, Register argvRegister, Register callTargetRegister, Register methodRegister,
|
||||
Register prevSpRegister, Register fpRegister, Register callFieldRegister)
|
||||
{
|
||||
Label pushCallThis;
|
||||
Label pushNewTarget;
|
||||
Label pushCallTarget;
|
||||
Label pushVregs;
|
||||
Label pushFrameState;
|
||||
|
||||
__ Cmpq(0, argcRegister);
|
||||
__ Jbe(&pushCallThis); // skip push args
|
||||
Register argvOnlyHaveArgsRegister = r12;
|
||||
__ Leaq(Operand(argvRegister, BuiltinFrame::RESERVED_CALL_ARGCOUNT * JSTaggedValue::TaggedTypeSize()),
|
||||
argvOnlyHaveArgsRegister);
|
||||
Register tempRegister = r11;
|
||||
__ PushArgsWithArgv(argcRegister, argvOnlyHaveArgsRegister, tempRegister); // args
|
||||
|
||||
__ Bind(&pushCallThis);
|
||||
__ Testb(CALL_TYPE_MASK, callFieldRegister);
|
||||
__ Jz(&pushVregs);
|
||||
__ Testq(JSMethod::HaveThisBit::Mask(), callFieldRegister);
|
||||
__ Jz(&pushNewTarget);
|
||||
__ Movq(Operand(argvRegister, 16), tempRegister); // 16: skip callTarget, newTarget
|
||||
__ Pushq(tempRegister); // this
|
||||
|
||||
__ Bind(&pushNewTarget);
|
||||
__ Testq(JSMethod::HaveNewTargetBit::Mask(), callFieldRegister);
|
||||
__ Jz(&pushCallTarget);
|
||||
__ Movq(Operand(argvRegister, 8), tempRegister); // 8: skip callTarget
|
||||
__ Pushq(tempRegister); // newTarget
|
||||
|
||||
__ Bind(&pushCallTarget);
|
||||
__ Testq(JSMethod::HaveFuncBit::Mask(), callFieldRegister);
|
||||
__ Jz(&pushVregs);
|
||||
__ Pushq(callTargetRegister); // callTarget
|
||||
|
||||
__ Bind(&pushVregs);
|
||||
{
|
||||
Register numVregsRegister = r11;
|
||||
GetNumVregsFromCallField(assembler, callFieldRegister, numVregsRegister);
|
||||
__ Cmpq(0, numVregsRegister);
|
||||
__ Jz(&pushFrameState);
|
||||
PushUndefinedWithArgc(assembler, numVregsRegister);
|
||||
}
|
||||
|
||||
__ Bind(&pushFrameState);
|
||||
Register newSpRegister = r8;
|
||||
__ Movq(rsp, newSpRegister);
|
||||
|
||||
StackOverflowCheck(assembler);
|
||||
|
||||
Register pcRegister = r12; // reuse r12
|
||||
PushFrameState(assembler, prevSpRegister, fpRegister, callTargetRegister, methodRegister, pcRegister, tempRegister);
|
||||
CallBCStub(assembler, newSpRegister, glueRegister, callTargetRegister, methodRegister, pcRegister);
|
||||
}
|
||||
|
||||
// Input: glueRegister - %rdi
|
||||
// declaredNumArgsRegister - %r11
|
||||
// argcRegister - %rsi
|
||||
// argvRegister - %rdx(<callTarget, newTarget, this> are at the beginning of argv)
|
||||
// callTargetRegister - %r9
|
||||
// methodRegister - %rcx
|
||||
// prevSpRegister - %rbp
|
||||
// callFieldRegister - %r14
|
||||
void AssemblerStubsX64::PushArgsSlowPath(ExtendedAssembler *assembler, Register glueRegister,
|
||||
Register declaredNumArgsRegister, Register argcRegister, Register argvRegister, Register callTargetRegister,
|
||||
Register methodRegister, Register prevSpRegister, Register callFieldRegister)
|
||||
{
|
||||
Label jumpToFastPath;
|
||||
Label haveExtra;
|
||||
Label pushUndefined;
|
||||
Register fpRegister = r10;
|
||||
Register tempRegister = r12;
|
||||
__ Movq(rsp, fpRegister);
|
||||
__ Testq(JSMethod::HaveExtraBit::Mask(), callFieldRegister);
|
||||
__ Jnz(&haveExtra);
|
||||
__ Movq(declaredNumArgsRegister, tempRegister);
|
||||
__ Subq(argcRegister, declaredNumArgsRegister);
|
||||
__ Cmpq(0, declaredNumArgsRegister);
|
||||
__ Jg(&pushUndefined);
|
||||
__ Movq(tempRegister, argcRegister); // std::min(declare, actual)
|
||||
__ Jmp(&jumpToFastPath);
|
||||
// fall through
|
||||
__ Bind(&haveExtra);
|
||||
{
|
||||
Register tempArgcRegister = r15;
|
||||
__ PushArgc(argcRegister, tempArgcRegister);
|
||||
__ Subq(argcRegister, declaredNumArgsRegister);
|
||||
__ Cmpq(0, declaredNumArgsRegister);
|
||||
__ Jle(&jumpToFastPath);
|
||||
// fall through
|
||||
}
|
||||
__ Bind(&pushUndefined);
|
||||
{
|
||||
PushUndefinedWithArgc(assembler, declaredNumArgsRegister);
|
||||
// fall through
|
||||
}
|
||||
__ Bind(&jumpToFastPath);
|
||||
PushArgsFastPath(assembler, glueRegister, argcRegister, argvRegister, callTargetRegister, methodRegister,
|
||||
prevSpRegister, fpRegister, callFieldRegister);
|
||||
}
|
||||
|
||||
void AssemblerStubsX64::PushFrameState(ExtendedAssembler *assembler, Register prevSpRegister, Register fpRegister,
|
||||
Register callTargetRegister, Register methodRegister, Register pcRegister, Register operatorRegister)
|
||||
{
|
||||
@ -1527,6 +1395,7 @@ Register AssemblerStubsX64::GetThisRegsiter(ExtendedAssembler *assembler, JSCall
|
||||
case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
|
||||
case JSCallMode::CALL_THIS_WITH_ARGV:
|
||||
return __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG2);
|
||||
case JSCallMode::CALL_ENTRY:
|
||||
case JSCallMode::CALL_FROM_AOT: {
|
||||
Register argvRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG1);
|
||||
Register thisRegister = __ AvailableRegister2();
|
||||
@ -1539,6 +1408,26 @@ Register AssemblerStubsX64::GetThisRegsiter(ExtendedAssembler *assembler, JSCall
|
||||
return rInvalid;
|
||||
}
|
||||
|
||||
Register AssemblerStubsX64::GetNewTargetRegsiter(ExtendedAssembler *assembler, JSCallMode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case JSCallMode::CALL_CONSTRUCTOR_WITH_ARGV:
|
||||
case JSCallMode::CALL_THIS_WITH_ARGV:
|
||||
return __ CallDispatcherArgument(kungfu::CallDispatchInputs::CALL_TARGET);
|
||||
case JSCallMode::CALL_FROM_AOT:
|
||||
case JSCallMode::CALL_ENTRY: {
|
||||
Register argvRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::ARG1);
|
||||
Register newTargetRegister = __ AvailableRegister2();
|
||||
// 16: new Target offset
|
||||
__ Movq(Operand(argvRegister, -16), newTargetRegister);
|
||||
return newTargetRegister;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
return rInvalid;
|
||||
}
|
||||
|
||||
// Input: %r14 - callField
|
||||
// %rdi - argv
|
||||
void AssemblerStubsX64::PushCallThis(ExtendedAssembler *assembler,
|
||||
@ -1574,7 +1463,8 @@ void AssemblerStubsX64::PushCallThis(ExtendedAssembler *assembler,
|
||||
if (!haveNewTarget) {
|
||||
__ Pushq(JSTaggedValue::Undefined().GetRawData());
|
||||
} else {
|
||||
__ Pushq(callTargetRegister);
|
||||
Register newTargetRegister = GetNewTargetRegsiter(assembler, mode);
|
||||
__ Pushq(newTargetRegister);
|
||||
}
|
||||
}
|
||||
// fall through
|
||||
@ -1736,10 +1626,10 @@ void AssemblerStubsX64::CallNativeWithArgv(ExtendedAssembler *assembler, bool ca
|
||||
void AssemblerStubsX64::CallNativeEntry(ExtendedAssembler *assembler)
|
||||
{
|
||||
Register glue = rdi;
|
||||
Register argc = rsi;
|
||||
Register argv = rdx;
|
||||
Register method = rcx;
|
||||
Register function = r9;
|
||||
Register argc = r8;
|
||||
Register argv = r9;
|
||||
Register method = rdx;
|
||||
Register function = rsi;
|
||||
Register nativeCode = r10;
|
||||
|
||||
__ Push(function);
|
||||
|
@ -82,12 +82,6 @@ public:
|
||||
static void JSCallWithArgV(ExtendedAssembler *assembler);
|
||||
|
||||
private:
|
||||
static void PushArgsFastPath(ExtendedAssembler *assembler, Register glueRegister, Register argcRegister,
|
||||
Register argvRegister, Register callTargetRegister, Register methodRegister, Register prevSpRegister,
|
||||
Register fpRegister, Register callFieldRegister);
|
||||
static void PushArgsSlowPath(ExtendedAssembler *assembler, Register glueRegister,
|
||||
Register declaredNumArgsRegister, Register argcRegister, Register argvRegister, Register callTargetRegister,
|
||||
Register methodRegister, Register prevSpRegister, Register callFieldRegister);
|
||||
static void PushFrameState(ExtendedAssembler *assembler, Register prevSpRegister, Register fpRegister,
|
||||
Register callTargetRegister, Register methodRegister, Register pcRegister, Register operatorRegister);
|
||||
static void PushGeneratorFrameState(ExtendedAssembler *assembler, Register prevSpRegister,
|
||||
@ -111,6 +105,7 @@ private:
|
||||
static void StackOverflowCheck(ExtendedAssembler *assembler);
|
||||
static void PushCallThis(ExtendedAssembler *assembler, JSCallMode mode);
|
||||
static Register GetThisRegsiter(ExtendedAssembler *assembler, JSCallMode mode);
|
||||
static Register GetNewTargetRegsiter(ExtendedAssembler *assembler, JSCallMode mode);
|
||||
static void PushVregs(ExtendedAssembler *assembler);
|
||||
static void DispatchCall(ExtendedAssembler *assembler, Register pcRegister, Register newSpRegister);
|
||||
static void CallNativeEntry(ExtendedAssembler *assemblSer);
|
||||
|
@ -187,7 +187,8 @@ using panda::ecmascript::kungfu::CommonStubCSigns;
|
||||
#define GET_ACC() (acc) // NOLINT(cppcoreguidelines-macro-usage)
|
||||
#define SET_ACC(val) (acc = val); // NOLINT(cppcoreguidelines-macro-usage)
|
||||
|
||||
using InterpreterEntry = JSTaggedType (*)(uintptr_t glue, uint32_t argc, uintptr_t argv);
|
||||
using InterpreterEntry = JSTaggedType (*)(uintptr_t glue, ECMAObject *callTarget,
|
||||
JSMethod *method, uint64_t callField, uint32_t argc, uintptr_t argv);
|
||||
using GeneratorReEnterInterpEntry = JSTaggedType (*)(uintptr_t glue, JSTaggedType context);
|
||||
|
||||
void InterpreterAssembly::InitStackFrame(JSThread *thread)
|
||||
@ -217,7 +218,11 @@ JSTaggedValue InterpreterAssembly::Execute(EcmaRuntimeCallInfo *info)
|
||||
size_t argc = info->GetArgsNumber();
|
||||
uintptr_t argv = reinterpret_cast<uintptr_t>(info->GetArgs());
|
||||
auto entry = thread->GetRTInterface(kungfu::RuntimeStubCSigns::ID_AsmInterpreterEntry);
|
||||
auto acc = reinterpret_cast<InterpreterEntry>(entry)(thread->GetGlueAddr(), argc, argv);
|
||||
|
||||
ECMAObject *callTarget = reinterpret_cast<ECMAObject*>(info->GetFunctionValue().GetTaggedObject());
|
||||
JSMethod *method = callTarget->GetCallTarget();
|
||||
auto acc = reinterpret_cast<InterpreterEntry>(entry)(thread->GetGlueAddr(),
|
||||
callTarget, method, method->GetCallField(), argc, argv);
|
||||
auto sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
ASSERT(FrameHandler::GetFrameType(sp) == FrameType::INTERPRETER_ENTRY_FRAME);
|
||||
auto prevEntry = InterpretedEntryFrame::GetFrameFromSp(sp)->GetPrevFrameFp();
|
||||
|
Loading…
Reference in New Issue
Block a user