Back to index

python3.2  3.2.2
Functions
win32.c File Reference
#include <ffi.h>
#include <ffi_common.h>

Go to the source code of this file.

Functions

 __declspec (naked)

Function Documentation

__declspec ( naked  )

Definition at line 40 of file win32.c.

{
       _asm {
              push ebp
              mov ebp, esp

              push esi // NEW: this register must be preserved across function calls
// XXX SAVE ESP NOW!
              mov esi, esp         // save stack pointer before the call

// Make room for all of the new args.
              mov ecx, [ebp+16]
              sub esp, ecx         // sub esp, bytes
              
              mov eax, esp

// Place all of the ffi_prep_args in position
              push [ebp + 12] // ecif
              push eax
              call [ebp + 8] // prepfunc

// Return stack to previous state and call the function
              add esp, 8
// FIXME: Align the stack to a 128-bit boundary to avoid
// potential performance hits.
              call [ebp + 28]

// Load ecif->cif->abi
              mov ecx, [ebp + 12]
              mov ecx, [ecx]ecif.cif
              mov ecx, [ecx]ecif.cif.abi
              
              cmp ecx, FFI_STDCALL
              je noclean
// STDCALL: Remove the space we pushed for the args
              mov ecx, [ebp + 16]
              add esp, ecx
// CDECL: Caller has already cleaned the stack
noclean:
// Check that esp has the same value as before!
              sub esi, esp

// Load %ecx with the return type code
              mov ecx, [ebp + 20]

// If the return value pointer is NULL, assume no return value.
/*
  Intel asm is weird. We have to explicitely specify 'DWORD PTR' in the nexr instruction,
  otherwise only one BYTE will be compared (instead of a DWORD)!
 */
              cmp DWORD PTR [ebp + 24], 0
              jne sc_retint

// Even if there is no space for the return value, we are
// obliged to handle floating-point values.
              cmp ecx, FFI_TYPE_FLOAT
              jne sc_noretval
//        fstp  %st(0)
              fstp st(0)

              jmp sc_epilogue

sc_retint:
              cmp ecx, FFI_TYPE_INT
              jne sc_retfloat
//        # Load %ecx with the pointer to storage for the return value
              mov ecx, [ebp + 24]
              mov [ecx + 0], eax
              jmp sc_epilogue

sc_retfloat:
              cmp ecx, FFI_TYPE_FLOAT
              jne sc_retdouble
// Load %ecx with the pointer to storage for the return value
              mov ecx, [ebp+24]
//        fstps (%ecx)
              fstp DWORD PTR [ecx]
              jmp sc_epilogue

sc_retdouble:
              cmp ecx, FFI_TYPE_DOUBLE
              jne sc_retlongdouble
//        movl  24(%ebp),%ecx
              mov ecx, [ebp+24]
              fstp QWORD PTR [ecx]
              jmp sc_epilogue

              jmp sc_retlongdouble // avoid warning about unused label
sc_retlongdouble:
              cmp ecx, FFI_TYPE_LONGDOUBLE
              jne sc_retint64
// Load %ecx with the pointer to storage for the return value
              mov ecx, [ebp+24]
//        fstpt (%ecx)
              fstp QWORD PTR [ecx] /* XXX ??? */
              jmp sc_epilogue

sc_retint64:
              cmp ecx, FFI_TYPE_SINT64
              jne sc_retstruct
// Load %ecx with the pointer to storage for the return value
              mov ecx, [ebp+24]
              mov [ecx+0], eax
              mov [ecx+4], edx

sc_retstruct:
// Nothing to do!

sc_noretval:
sc_epilogue:
              mov eax, esi
              pop esi // NEW restore: must be preserved across function calls
              mov esp, ebp
              pop ebp
              ret
       }
}

Here is the call graph for this function: