def test__ffi_call(self): from pypy.rlib.test.test_libffi import get_libm_name def main(libm_name): try: from _ffi import CDLL, types except ImportError: sys.stderr.write('SKIP: cannot import _ffi\n') return 0 libm = CDLL(libm_name) pow = libm.getfunc('pow', [types.double, types.double], types.double) i = 0 res = 0 while i < 300: tmp = pow(2, 3) # ID: fficall res += tmp i += 1 return pow.getaddr(), res # libm_name = get_libm_name(sys.platform) log = self.run(main, [libm_name]) pow_addr, res = log.result assert res == 8.0 * 300 loop, = log.loops_by_filename(self.filepath) if 'ConstClass(pow)' in repr(loop): # e.g. OS/X pow_addr = 'ConstClass(pow)' assert loop.match_by_id('fficall', """ guard_not_invalidated(descr=...) i17 = force_token() setfield_gc(p0, i17, descr=<.* .*PyFrame.vable_token .*>) f21 = call_release_gil(%s, 2.000000, 3.000000, descr=<Callf 8 ff EF=6>) guard_not_forced(descr=...) guard_no_exception(descr=...) """ % pow_addr)
def test_ctypes_call(self): from pypy.rlib.test.test_libffi import get_libm_name def main(libm_name): import ctypes libm = ctypes.CDLL(libm_name) fabs = libm.fabs fabs.argtypes = [ctypes.c_double] fabs.restype = ctypes.c_double x = -4 i = 0 while i < 300: x = fabs(x) x = x - 100 i += 1 return fabs._ptr.getaddr(), x libm_name = get_libm_name(sys.platform) log = self.run(main, [libm_name], import_site=True) fabs_addr, res = log.result assert res == -4.0 loop, = log.loops_by_filename(self.filepath) ops = loop.allops() opnames = log.opnames(ops) assert opnames.count('new_with_vtable') == 1 # only the virtualref assert opnames.count('call_release_gil') == 1 idx = opnames.index('call_release_gil') call = ops[idx] assert (call.args[0] == 'ConstClass(fabs)' or # e.g. OS/X int(call.args[0]) == fabs_addr)
def test__ffi_call_frame_does_not_escape(self): from pypy.rlib.test.test_libffi import get_libm_name def main(libm_name): try: from _ffi import CDLL, types except ImportError: sys.stderr.write('SKIP: cannot import _ffi\n') return 0 libm = CDLL(libm_name) pow = libm.getfunc('pow', [types.double, types.double], types.double) def mypow(a, b): return pow(a, b) i = 0 res = 0 while i < 300: tmp = mypow(2, 3) res += tmp i += 1 return pow.getaddr(), res # libm_name = get_libm_name(sys.platform) log = self.run(main, [libm_name]) pow_addr, res = log.result assert res == 8.0 * 300 loop, = log.loops_by_filename(self.filepath) opnames = log.opnames(loop.allops()) # we only force the virtualref, not its content assert opnames.count('new_with_vtable') == 1
def setup_class(cls): from pypy.rpython.lltypesystem import rffi from pypy.rlib.libffi import get_libc_name, CDLL, types from pypy.rlib.test.test_libffi import get_libm_name space = gettestobjspace(usemodules=('_ffi', '_rawffi')) cls.space = space cls.w_iswin32 = space.wrap(sys.platform == 'win32') cls.w_libfoo_name = space.wrap(cls.prepare_c_example()) cls.w_libc_name = space.wrap(get_libc_name()) libm_name = get_libm_name(sys.platform) cls.w_libm_name = space.wrap(libm_name) libm = CDLL(libm_name) pow = libm.getpointer('pow', [], types.void) pow_addr = rffi.cast(rffi.LONG, pow.funcsym) cls.w_pow_addr = space.wrap(pow_addr)
def setup_class(cls): from pypy.rpython.lltypesystem import rffi from pypy.rlib.libffi import get_libc_name, CDLL, types from pypy.rlib.test.test_libffi import get_libm_name space = gettestobjspace(usemodules=('_ffi', '_rawffi')) cls.space = space cls.w_iswin32 = space.wrap(sys.platform == 'win32') cls.w_libfoo_name = space.wrap(cls.prepare_c_example()) cls.w_libc_name = space.wrap(get_libc_name()) libm_name = get_libm_name(sys.platform) cls.w_libm_name = space.wrap(libm_name) libm = CDLL(libm_name) pow = libm.getpointer('pow', [], types.void) pow_addr = rffi.cast(rffi.LONG, pow.funcsym) cls.w_pow_addr = space.wrap(pow_addr) # # these are needed for test_single_float_args from ctypes import c_float f_12_34 = c_float(12.34).value f_56_78 = c_float(56.78).value f_result = c_float(f_12_34 + f_56_78).value cls.w_f_12_34_plus_56_78 = space.wrap(f_result)
def test_stuff_translates(self): # this is a basic test that tries to hit a number of features and their # translation: # - jitting of loops and bridges # - virtualizables # - set_param interface # - profiler # - full optimizer # - floats neg and abs class Frame(object): _virtualizable2_ = ['i'] def __init__(self, i): self.i = i @dont_look_inside def myabs(x): return abs(x) jitdriver = JitDriver(greens=[], reds=['total', 'frame', 'j'], virtualizables=['frame']) def f(i, j): for param, _ in unroll_parameters: defl = PARAMETERS[param] set_param(jitdriver, param, defl) set_param(jitdriver, "threshold", 3) set_param(jitdriver, "trace_eagerness", 2) total = 0 frame = Frame(i) j = float(j) while frame.i > 3: jitdriver.can_enter_jit(frame=frame, total=total, j=j) jitdriver.jit_merge_point(frame=frame, total=total, j=j) total += frame.i if frame.i >= 20: frame.i -= 2 frame.i -= 1 j *= -0.712 if j + (-j): raise ValueError k = myabs(j) if k - abs(j): raise ValueError if k - abs(-j): raise ValueError return chr(total % 253) # from pypy.rpython.lltypesystem import lltype, rffi from pypy.rlib.libffi import types, CDLL, ArgChain from pypy.rlib.test.test_libffi import get_libm_name libm_name = get_libm_name(sys.platform) jitdriver2 = JitDriver(greens=[], reds=['i', 'func', 'res', 'x']) def libffi_stuff(i, j): lib = CDLL(libm_name) func = lib.getpointer('fabs', [types.double], types.double) res = 0.0 x = float(j) while i > 0: jitdriver2.jit_merge_point(i=i, res=res, func=func, x=x) promote(func) argchain = ArgChain() argchain.arg(x) res = func.call(argchain, rffi.DOUBLE) i -= 1 return res # def main(i, j): a_char = f(i, j) a_float = libffi_stuff(i, j) return ord(a_char) * 10 + int(a_float) expected = main(40, -49) res = self.meta_interp(main, [40, -49]) assert res == expected
def test_stuff_translates(self): # this is a basic test that tries to hit a number of features and their # translation: # - jitting of loops and bridges # - virtualizables # - set_param interface # - profiler # - full optimizer # - floats neg and abs class Frame(object): _virtualizable2_ = ["i"] def __init__(self, i): self.i = i @dont_look_inside def myabs(x): return abs(x) jitdriver = JitDriver(greens=[], reds=["total", "frame", "j"], virtualizables=["frame"]) def f(i, j): for param, _ in unroll_parameters: defl = PARAMETERS[param] jitdriver.set_param(param, defl) jitdriver.set_param("threshold", 3) jitdriver.set_param("trace_eagerness", 2) total = 0 frame = Frame(i) while frame.i > 3: jitdriver.can_enter_jit(frame=frame, total=total, j=j) jitdriver.jit_merge_point(frame=frame, total=total, j=j) total += frame.i if frame.i >= 20: frame.i -= 2 frame.i -= 1 j *= -0.712 if j + (-j): raise ValueError k = myabs(j) if k - abs(j): raise ValueError if k - abs(-j): raise ValueError return chr(total % 253) # from pypy.rpython.lltypesystem import lltype, rffi from pypy.rlib.libffi import types, CDLL, ArgChain from pypy.rlib.test.test_libffi import get_libm_name libm_name = get_libm_name(sys.platform) jitdriver2 = JitDriver(greens=[], reds=["i", "func", "res", "x"]) def libffi_stuff(i, j): lib = CDLL(libm_name) func = lib.getpointer("fabs", [types.double], types.double) res = 0.0 x = float(j) while i > 0: jitdriver2.jit_merge_point(i=i, res=res, func=func, x=x) promote(func) argchain = ArgChain() argchain.arg(x) res = func.call(argchain, rffi.DOUBLE) i -= 1 return res # def main(i, j): a_char = f(i, j) a_float = libffi_stuff(i, j) return ord(a_char) * 10 + int(a_float) expected = main(40, -49) res = self.meta_interp(main, [40, -49]) assert res == expected