procedure InvokeMethod(
const Method: TMethod; Parameters: PParameters; StackSize: Integer);
const
PointerSize = SizeOf(Pointer);
type
TParameters =
packed record
{$IFDEF CPUX86}
Registers:
array[paEDX..paECX]
of Cardinal;
EAXRegister: Cardinal;
ReturnAddress: Pointer;
{$ENDIF CPUX86}
Stack:
array[0..1023]
of Byte;
end;
{$IF Defined(CPUX86)}
asm
push ebp
mov ebp,esp
push eax
// ebp-4 = Method
push ebx
mov ebx, edx
// ebx = Parameters
// if StackSize > 0
test ecx,ecx
jz @@no_stack
// stack address alignment
add ecx,PointerSize-1
and ecx,
not(PointerSize-1)
and ecx,$ffff
sub esp,ecx
// put stack address as second parameter
mov edx,esp
// put params on stack as first parameter
lea eax,[ebx].TParameters.Stack
call Move
@@no_stack:
mov edx,[ebx].TParameters.Registers.dword[0]
mov ecx,[ebx].TParameters.Registers.dword[4]
mov ebx,[ebp-$04]
mov eax,[ebx].TMethod.Data
call [ebx].TMethod.Code
pop ebx
pop eax
mov esp,ebp
pop ebp
end;
{$ELSEIF Defined(CPUX64)}
asm
.params 60
mov [rbp+$200],Method
mov [rbp+$208],Parameters
test r8,r8
jz @@no_stack
// put params on stack as first parameter
lea rcx,[Parameters].TParameters.Stack
// put stack address as second parameter
mov rdx,rsp
call Move
mov rdx,[rbp+$208]
@@no_stack:
mov rcx,[rdx].TParameters.Stack.qword[0]
mov r8,[rdx].TParameters.Stack.qword[16]
mov r9,[rdx].TParameters.Stack.qword[24]
movsd xmm0,[rdx].TParameters.Stack.qword[0]
movsd xmm1,[rdx].TParameters.Stack.qword[8]
movsd xmm2,[rdx].TParameters.Stack.qword[16]
movsd xmm3,[rdx].TParameters.Stack.qword[24]
mov rdx,[rdx].TParameters.Stack.qword[8]
mov rax,[rbp+$200]
lea rax,[rax]
mov rcx,[rax].TMethod.Data
call [rax].TMethod.Code
end;
{$IFEND}