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 from rpython.rlib import rmu_fast as rmu # NOTE: depends on RPython
@may_spawn_proc
def test_load_int_from_gcell(): def test_load_int_from_gcell():
def build_test_bundle(bldr, rmu): def build_test_bundle(bldr, rmu):
""" """
...@@ -53,12 +54,13 @@ def test_load_int_from_gcell(): ...@@ -53,12 +54,13 @@ def test_load_int_from_gcell():
hdl_num = ctx.handle_from_sint64(42, 64) hdl_num = ctx.handle_from_sint64(42, 64)
ctx.store(rmu.MuMemOrd.NOT_ATOMIC, gcl_hdl, hdl_num) 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)) mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
assert fnp() == 42 assert fnp() == 42
@may_spawn_proc
def test_load_ref_from_global(): def test_load_ref_from_global():
def build_test_bundle(bldr, rmu): def build_test_bundle(bldr, rmu):
""" """
...@@ -120,12 +122,13 @@ def test_load_ref_from_global(): ...@@ -120,12 +122,13 @@ def test_load_ref_from_global():
gcl_hdl = ctx.handle_from_global(id_dic['@gcl']) gcl_hdl = ctx.handle_from_global(id_dic['@gcl'])
ctx.store(rmu.MuMemOrd.NOT_ATOMIC, gcl_hdl, ref_hdl) 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)) mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
assert fnp() == 42 assert fnp() == 42
@may_spawn_proc
def test_preserve_ref_field(): def test_preserve_ref_field():
def build_test_bundle(bldr, rmu): def build_test_bundle(bldr, rmu):
""" """
...@@ -239,7 +242,7 @@ def test_preserve_ref_field(): ...@@ -239,7 +242,7 @@ def test_preserve_ref_field():
gcl_hdl = ctx.handle_from_global(id_dic['@gcl']) gcl_hdl = ctx.handle_from_global(id_dic['@gcl'])
ctx.store(rmu.MuMemOrd.NOT_ATOMIC, gcl_hdl, ref_hd) 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)) mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
assert fnp() == 298 assert fnp() == 298
...@@ -575,7 +575,7 @@ def test_threadtran_fib(): ...@@ -575,7 +575,7 @@ def test_threadtran_fib():
"result_type": i64 "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)) mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
...@@ -646,7 +646,7 @@ def test_new(): ...@@ -646,7 +646,7 @@ def test_new():
"@i64": i64 "@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)) mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
assert fnp() == 1 assert fnp() == 1
...@@ -712,7 +712,7 @@ def test_new_cmpeq(): ...@@ -712,7 +712,7 @@ def test_new_cmpeq():
"@i64": i64 "@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)) mu.current_thread_as_mu_thread(rmu.null(rmu.MuCPtr))
assert fnp() == 0 assert fnp() == 0
......
...@@ -53,17 +53,30 @@ def compile_c_script(c_src_name): ...@@ -53,17 +53,30 @@ def compile_c_script(c_src_name):
return py.path.local('emit').join('%(testname)s.dylib' % locals()) 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 = getattr(lib, fnc_name)
fnp.argtypes = argtypes fnp.argtypes = argtypes
fnp.restype = restype 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): def fncptr_from_c_script(c_src_name, name, argtypes=[], restype=ctypes.c_ulonglong):
libpath = compile_c_script(c_src_name) libpath = compile_c_script(c_src_name)
lib = ctypes.CDLL(libpath.strpath) return ctypes_fncptr_from_lib(libpath, name, argtypes, restype)
return fncptr_from_lib(lib, name, argtypes, restype), lib
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): 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 ...@@ -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()) libpath = py.path.local('lib%(name)s.dylib' % locals())
mu.compile_to_sharedlib(libpath.strpath, []) mu.compile_to_sharedlib(libpath.strpath, [])
lib = ctypes.CDLL(libpath.strpath) if (len(argtypes) > 0 and is_ctypes(argtypes[0])) or is_ctypes(restype):
return fncptr_from_lib(lib, name, argtypes, restype), (mu, ctx, bldr) 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(): def preload_libmu():
...@@ -128,12 +143,9 @@ def fncptr_from_rpy_func(rpy_fnc, llargtypes, llrestype, **kwargs): ...@@ -128,12 +143,9 @@ def fncptr_from_rpy_func(rpy_fnc, llargtypes, llrestype, **kwargs):
db, bdlgen, fnc_name = t.compile_mu() db, bdlgen, fnc_name = t.compile_mu()
libpath = py.path.local('lib%(fnc_name)s.dylib' % locals()) libpath = py.path.local('lib%(fnc_name)s.dylib' % locals())
bdlgen.mu.compile_to_sharedlib(libpath.strpath, []) bdlgen.mu.compile_to_sharedlib(libpath.strpath, [])
eci = rffi.ExternalCompilationInfo(libraries=[libpath.strpath])
extras = (db, bdlgen) extras = (db, bdlgen)
else: else:
libpath = t.compile_c() libpath = t.compile_c()
fnc_name = 'pypy_g_' + rpy_fnc.__name__ fnc_name = 'pypy_g_' + rpy_fnc.__name__
eci = rffi.ExternalCompilationInfo(libraries=[libpath.strpath])
extras = None extras = None
return rffi_fncptr_from_lib(libpath, fnc_name, llargtypes, llrestype), extras
return rffi.llexternal(fnc_name, llargtypes, llrestype, compilation_info=eci, _nowrapper=True), 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