Commit 29359382 authored by John Zhang's avatar John Zhang

refactor, allowing getting function pointer from python script via rffi

parent 546ea4b1
from util import fncptr_from_py_script
from util import fncptr_from_py_script, may_spawn_proc
from rpython.rlib import rmu_fast as rmu # NOTE: depends on RPython
@may_spawn_proc
def test_load_int_from_gcell():
def build_test_bundle(bldr, rmu):
"""
......@@ -53,12 +54,13 @@ def test_load_int_from_gcell():
hdl_num = ctx.handle_from_sint64(42, 64)
ctx.store(rmu.MuMemOrd.NOT_ATOMIC, gcl_hdl, hdl_num)
fnp, (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, init_heap, 'test_fnc')
(fnp, _), (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, init_heap, 'test_fnc')
mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
assert fnp() == 42
@may_spawn_proc
def test_load_ref_from_global():
def build_test_bundle(bldr, rmu):
"""
......@@ -120,12 +122,13 @@ def test_load_ref_from_global():
gcl_hdl = ctx.handle_from_global(id_dic['@gcl'])
ctx.store(rmu.MuMemOrd.NOT_ATOMIC, gcl_hdl, ref_hdl)
fnp, (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, init_heap, 'test_fnc')
(fnp, _), (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, init_heap, 'test_fnc')
mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
assert fnp() == 42
@may_spawn_proc
def test_preserve_ref_field():
def build_test_bundle(bldr, rmu):
"""
......@@ -239,7 +242,7 @@ def test_preserve_ref_field():
gcl_hdl = ctx.handle_from_global(id_dic['@gcl'])
ctx.store(rmu.MuMemOrd.NOT_ATOMIC, gcl_hdl, ref_hd)
fnp, (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, init_heap, 'test_fnc')
(fnp, _), (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, init_heap, 'test_fnc')
mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
assert fnp() == 298
......@@ -575,7 +575,7 @@ def test_threadtran_fib():
"result_type": i64
}
fnp, (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, None, 'fib', [ctypes.c_longlong])
(fnp, _), (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, None, 'fib', [ctypes.c_longlong])
mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
......@@ -646,7 +646,7 @@ def test_new():
"@i64": i64
}
fnp, (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, None, 'test_fnc')
(fnp, _), (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, None, 'test_fnc')
mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
assert fnp() == 1
......@@ -712,7 +712,7 @@ def test_new_cmpeq():
"@i64": i64
}
fnp, (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, None, 'test_fnc')
(fnp, _), (mu, ctx, bldr) = fncptr_from_py_script(build_test_bundle, None, 'test_fnc')
mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
assert fnp() == 0
......
......@@ -53,17 +53,30 @@ def compile_c_script(c_src_name):
return py.path.local('emit').join('%(testname)s.dylib' % locals())
def fncptr_from_lib(lib, fnc_name, argtypes=[], restype=ctypes.c_longlong):
def ctypes_fncptr_from_lib(libpath, fnc_name, argtypes=[], restype=ctypes.c_longlong):
lib = ctypes.CDLL(libpath.strpath)
fnp = getattr(lib, fnc_name)
fnp.argtypes = argtypes
fnp.restype = restype
return fnp
return fnp, lib
def rffi_fncptr_from_lib(libpath, fnc_name, llargtypes, restype):
from rpython.rtyper.lltypesystem import rffi
return rffi.llexternal(fnc_name, llargtypes, restype,
compilation_info=rffi.ExternalCompilationInfo(
libraries=[libpath.strpath],
),
_nowrapper=True)
def fncptr_from_c_script(c_src_name, name, argtypes=[], restype=ctypes.c_ulonglong):
libpath = compile_c_script(c_src_name)
lib = ctypes.CDLL(libpath.strpath)
return fncptr_from_lib(lib, name, argtypes, restype), lib
return ctypes_fncptr_from_lib(libpath, name, argtypes, restype)
def is_ctypes(t):
return isinstance(t, type(ctypes.c_longlong))
def fncptr_from_py_script(py_fnc, heapinit_fnc, name, argtypes=[], restype=ctypes.c_longlong):
......@@ -87,8 +100,10 @@ def fncptr_from_py_script(py_fnc, heapinit_fnc, name, argtypes=[], restype=ctype
libpath = py.path.local('lib%(name)s.dylib' % locals())
mu.compile_to_sharedlib(libpath.strpath, [])
lib = ctypes.CDLL(libpath.strpath)
return fncptr_from_lib(lib, name, argtypes, restype), (mu, ctx, bldr)
if (len(argtypes) > 0 and is_ctypes(argtypes[0])) or is_ctypes(restype):
return ctypes_fncptr_from_lib(libpath, name, argtypes, restype), (mu, ctx, bldr)
else:
return rffi_fncptr_from_lib(libpath, name, argtypes, restype), (mu, ctx, bldr)
def preload_libmu():
......@@ -128,12 +143,9 @@ def fncptr_from_rpy_func(rpy_fnc, llargtypes, llrestype, **kwargs):
db, bdlgen, fnc_name = t.compile_mu()
libpath = py.path.local('lib%(fnc_name)s.dylib' % locals())
bdlgen.mu.compile_to_sharedlib(libpath.strpath, [])
eci = rffi.ExternalCompilationInfo(libraries=[libpath.strpath])
extras = (db, bdlgen)
else:
libpath = t.compile_c()
fnc_name = 'pypy_g_' + rpy_fnc.__name__
eci = rffi.ExternalCompilationInfo(libraries=[libpath.strpath])
extras = None
return rffi.llexternal(fnc_name, llargtypes, llrestype, compilation_info=eci, _nowrapper=True), extras
return rffi_fncptr_from_lib(libpath, fnc_name, llargtypes, llrestype), extras
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment