Here's a safe approach that can call both Procedure and ProcedureC style procedures.
Code: Select all
; ** CallFnSafe code **
Procedure CallFnSafe_addr_()
!mov eax, CallFnFast_start
ProcedureReturn
!CallFnFast_start:
!push ebp
!mov ebp, esp
!and esp, 0xfffffff0
!sub esp, 32
!mov ecx, 28
!CallFnFast_loop:
!mov eax, [ebp + ecx + 12]
!mov [esp + ecx], eax
!sub ecx, 4
!jnc CallFnFast_loop
!call dword [ebp + 8]
!mov esp, ebp
!pop ebp
!ret
EndProcedure
PrototypeC CallFnSafe_proto(*Function, Arg1 = 0, Arg2 = 0, Arg3 = 0, Arg4 = 0, Arg5 = 0, Arg6 = 0, Arg7 = 0, Arg8 = 0)
Global CallFnSafe.CallFnSafe_proto = CallFnSafe_addr_()
; ** end of CallFnSafe code **
; test the code
Procedure MyProcedure(n)
Debug n
EndProcedure
ProcedureC MyCProcedure(n)
Debug n
EndProcedure
CallFnSafe(@MyProcedure(), 1)
CallFnSafe(@MyCProcedure(), 2)