Created
October 28, 2014 14:39
-
-
Save cheery/99ca4f159b774e2741c4 to your computer and use it in GitHub Desktop.
Samples of LIBFFI usage in pypy/rpython
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Simple sample of LIBFFI usage in pypy/rpython | |
import sys | |
from rpython.rtyper.lltypesystem import rffi, lltype | |
from rpython.rlib import jit_libffi, rdynload, clibffi | |
def entry_point(argv): | |
lib = rdynload.dlopen('libSDL.so') | |
SDL_Init = rdynload.dlsym(lib, "SDL_Init") | |
argc = 1 | |
# The cif is initialized with the stuff needed to call the function | |
# In pixie the cif was built during the first call to the function. | |
exchange_size = 0 | |
exchange_arg0 = argc * rffi.sizeof(rffi.CCHARP) | |
exchange_result = exchange_arg0 | |
# ARG[0] | |
exchange_result = exchange_size | |
exchange_size += rffi.sizeof(rffi.LONG) | |
# RETVAL | |
exchange_result = exchange_size | |
exchange_size += rffi.sizeof(rffi.LONG) | |
cif = lltype.malloc(jit_libffi.CIF_DESCRIPTION, 1, flavor='raw') | |
cif.abi = clibffi.FFI_DEFAULT_ABI | |
cif.nargs = argc | |
cif.rtype = clibffi.cast_type_to_ffitype(rffi.LONG) | |
atypes = lltype.malloc(clibffi.FFI_TYPE_PP.TO, argc, flavor='raw') | |
atypes[0] = clibffi.cast_type_to_ffitype(rffi.LONG) | |
cif.atypes = atypes | |
cif.exchange_size = exchange_size | |
cif.exchange_result = exchange_result | |
cif.exchange_result_libffi = exchange_result | |
cif.exchange_args[0] = exchange_arg0 | |
jit_libffi.jit_ffi_prep_cif(cif) | |
# Exchange buffer is built for every call. Filled with arguments that are passed to the function. | |
exc = lltype.malloc(rffi.CCHARP.TO, cif.exchange_size, flavor='raw') | |
offset_p = rffi.ptradd(exc, cif.exchange_args[0]) | |
pnt = rffi.cast(rffi.LONGP, offset_p) | |
pnt[0] = rffi.cast(rffi.LONG, 0x00000020) # SDL_INIT_VIDEO | |
offset_p = rffi.cast(rffi.CCHARP, rffi.ptradd(pnt, rffi.sizeof(rffi.LONG))) | |
jit_libffi.jit_ffi_call(cif, SDL_Init, exc) | |
offset_p = rffi.ptradd(exc, cif.exchange_result) | |
retval = rffi.cast(rffi.LONGP, offset_p)[0] | |
print "SDL_Init returned", retval | |
lltype.free(exc, flavor='raw') | |
return 0 | |
def target(*args): | |
return entry_point, None | |
if __name__=='__main__': | |
sys.exit(entry_point(sys.argv)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment