Ejemplo n.º 1
0
    def test__ffi_call_frame_does_not_escape(self):
        from rpython.rlib.test.test_clibffi import get_libm_name

        def main(libm_name):
            try:
                from _rawffi.alt import CDLL, types
            except ImportError:
                sys.stderr.write('SKIP: cannot import _rawffi.alt\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
Ejemplo n.º 2
0
    def test_ctypes_call(self):
        from rpython.rlib.test.test_clibffi 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
        py.test.skip("XXX re-optimize _ffi for the JIT?")
        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)
Ejemplo n.º 3
0
    def test__cffi_bug1(self):
        from rpython.rlib.test.test_clibffi import get_libm_name

        def main(libm_name):
            try:
                import _cffi_backend
            except ImportError:
                sys.stderr.write('SKIP: cannot import _cffi_backend\n')
                return 0

            libm = _cffi_backend.load_library(libm_name)
            BDouble = _cffi_backend.new_primitive_type("double")
            BSin = _cffi_backend.new_function_type([BDouble], BDouble)
            sin = libm.load_function(BSin, 'sin')

            def f(*args):
                for i in range(300):
                    sin(*args)

            f(1.0)
            f(1)

        #
        libm_name = get_libm_name(sys.platform)
        self.run(main, [libm_name])
Ejemplo n.º 4
0
    def test_ctypes_call(self):
        from rpython.rlib.test.test_clibffi 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
        py.test.skip("XXX re-optimize _ffi for the JIT?")
        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)
Ejemplo n.º 5
0
    def test__ffi_call_frame_does_not_escape(self):
        from rpython.rlib.test.test_clibffi import get_libm_name
        def main(libm_name):
            try:
                from _rawffi.alt import CDLL, types
            except ImportError:
                sys.stderr.write('SKIP: cannot import _rawffi.alt\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
Ejemplo n.º 6
0
    def test__cffi_bug1(self):
        from rpython.rlib.test.test_clibffi import get_libm_name

        def main(libm_name):
            try:
                import _cffi_backend
            except ImportError:
                sys.stderr.write("SKIP: cannot import _cffi_backend\n")
                return 0

            libm = _cffi_backend.load_library(libm_name)
            BDouble = _cffi_backend.new_primitive_type("double")
            BSin = _cffi_backend.new_function_type([BDouble], BDouble)
            sin = libm.load_function(BSin, "sin")

            def f(*args):
                for i in range(300):
                    sin(*args)

            f(1.0)
            f(1)

        #
        libm_name = get_libm_name(sys.platform)
        self.run(main, [libm_name])
Ejemplo n.º 7
0
 def setup_class(cls):
     space = cls.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._libm = libm  # otherwise it gets unloaded - argh!
     cls.w_pow_addr = space.wrap(pow_addr)
Ejemplo n.º 8
0
 def setup_class(cls):
     space = cls.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._libm = libm     # otherwise it gets unloaded - argh!
     cls.w_pow_addr = space.wrap(pow_addr)
Ejemplo n.º 9
0
    def test__cffi_call(self):
        from rpython.rlib.test.test_clibffi import get_libm_name

        def main(libm_name):
            try:
                import _cffi_backend
            except ImportError:
                sys.stderr.write("SKIP: cannot import _cffi_backend\n")
                return 0

            libm = _cffi_backend.load_library(libm_name)
            BDouble = _cffi_backend.new_primitive_type("double")
            BInt = _cffi_backend.new_primitive_type("int")
            BPow = _cffi_backend.new_function_type([BDouble, BInt], BDouble)
            ldexp = libm.load_function(BPow, "ldexp")
            i = 0
            res = 0
            while i < 300:
                tmp = ldexp(1, 3)  # ID: cfficall
                res += tmp
                i += 1
            BLong = _cffi_backend.new_primitive_type("long")
            ldexp_addr = int(_cffi_backend.cast(BLong, ldexp))
            return ldexp_addr, res

        #
        libm_name = get_libm_name(sys.platform)
        log = self.run(main, [libm_name])
        ldexp_addr, res = log.result
        assert res == 8.0 * 300
        loop, = log.loops_by_filename(self.filepath)
        assert loop.match_by_id(
            "cfficall",
            """
            p96 = force_token()
            setfield_gc(p0, p96, descr=<FieldP pypy.interpreter.pyframe.PyFrame.vable_token .>)
            f97 = call_release_gil(91, i59, 1.0, 3, descr=<Callf 8 fi EF=7 OS=62>)
            guard_not_forced(descr=...)
            guard_no_exception(descr=...)
        """,
            ignore_ops=["guard_not_invalidated"],
        )
Ejemplo n.º 10
0
    def test__ffi_call(self):
        from rpython.rlib.test.test_clibffi import get_libm_name

        def main(libm_name):
            try:
                from _rawffi.alt import CDLL, types
            except ImportError:
                sys.stderr.write("SKIP: cannot import _rawffi.alt\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
        py.test.skip("XXX re-optimize _ffi for the JIT?")
        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=7>)
            guard_not_forced(descr=...)
            guard_no_exception(descr=...)
        """
            % pow_addr,
        )
Ejemplo n.º 11
0
    def test__cffi_call(self):
        from rpython.rlib.test.test_clibffi import get_libm_name
        def main(libm_name):
            try:
                import _cffi_backend
            except ImportError:
                sys.stderr.write('SKIP: cannot import _cffi_backend\n')
                return 0

            libm = _cffi_backend.load_library(libm_name)
            BDouble = _cffi_backend.new_primitive_type("double")
            BInt = _cffi_backend.new_primitive_type("int")
            BPow = _cffi_backend.new_function_type([BDouble, BInt], BDouble)
            ldexp = libm.load_function(BPow, 'ldexp')
            i = 0
            res = 0
            while i < 300:
                tmp = ldexp(1, 3)   # ID: cfficall
                res += tmp
                i += 1
            BLong = _cffi_backend.new_primitive_type("long")
            ldexp_addr = int(_cffi_backend.cast(BLong, ldexp))
            return ldexp_addr, res
        #
        libm_name = get_libm_name(sys.platform)
        log = self.run(main, [libm_name])
        ldexp_addr, res = log.result
        assert res == 8.0 * 300
        loop, = log.loops_by_filename(self.filepath)
        if 'ConstClass(ldexp)' in repr(loop):   # e.g. OS/X
            ldexp_addr = 'ConstClass(ldexp)'
        assert loop.match_by_id('cfficall', """
            ...
            f1 = call_release_gil(..., descr=<Callf 8 fi EF=6 OS=62>)
            ...
        """)
        ops = loop.ops_by_id('cfficall')
        for name in ['raw_malloc', 'raw_free']:
            assert name not in str(ops)
        for name in ['raw_load', 'raw_store', 'getarrayitem_raw', 'setarrayitem_raw']:
            assert name not in log.opnames(ops)
Ejemplo n.º 12
0
    def test__cffi_call(self):
        from rpython.rlib.test.test_clibffi import get_libm_name

        def main(libm_name):
            try:
                import _cffi_backend
            except ImportError:
                sys.stderr.write('SKIP: cannot import _cffi_backend\n')
                return 0

            libm = _cffi_backend.load_library(libm_name)
            BDouble = _cffi_backend.new_primitive_type("double")
            BInt = _cffi_backend.new_primitive_type("int")
            BPow = _cffi_backend.new_function_type([BDouble, BInt], BDouble)
            ldexp = libm.load_function(BPow, 'ldexp')
            i = 0
            res = 0
            while i < 300:
                tmp = ldexp(1, 3)  # ID: cfficall
                res += tmp
                i += 1
            BLong = _cffi_backend.new_primitive_type("long")
            ldexp_addr = int(_cffi_backend.cast(BLong, ldexp))
            return ldexp_addr, res

        #
        libm_name = get_libm_name(sys.platform)
        log = self.run(main, [libm_name])
        ldexp_addr, res = log.result
        assert res == 8.0 * 300
        loop, = log.loops_by_filename(self.filepath)
        assert loop.match_by_id('cfficall',
                                """
            p96 = force_token()
            setfield_gc(p0, p96, descr=<FieldP pypy.interpreter.pyframe.PyFrame.vable_token .>)
            f97 = call_release_gil_f(91, i59, 1.0, 3, descr=<Callf 8 fi EF=7 OS=62>)
            guard_not_forced(descr=...)
            guard_no_exception(descr=...)
        """,
                                ignore_ops=['guard_not_invalidated'])
Ejemplo n.º 13
0
    def test__ffi_call(self):
        from rpython.rlib.test.test_clibffi import get_libm_name

        def main(libm_name):
            try:
                from _rawffi.alt import CDLL, types
            except ImportError:
                sys.stderr.write('SKIP: cannot import _rawffi.alt\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
        py.test.skip("XXX re-optimize _ffi for the JIT?")
        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=7>)
            guard_not_forced(descr=...)
            guard_no_exception(descr=...)
        """ % pow_addr)
Ejemplo n.º 14
0
    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):
            _virtualizable_ = ["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 rpython.rtyper.lltypesystem import lltype, rffi
        from rpython.rlib.libffi import types, CDLL, ArgChain
        from rpython.rlib.test.test_clibffi 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
Ejemplo n.º 15
0
    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
        # - two virtualizable types
        # - set_param interface
        # - profiler
        # - full optimizer
        # - floats neg and abs
        # - cast_int_to_float
        # - llexternal with macro=True

        class BasicFrame(object):
            _virtualizable_ = ['i']

            def __init__(self, i):
                self.i = i

        class Frame(BasicFrame):
            pass

        eci = ExternalCompilationInfo(
            post_include_bits=['''
#define pypy_my_fabs(x)  fabs(x)
'''])
        myabs1 = rffi.llexternal('pypy_my_fabs', [lltype.Float],
                                 lltype.Float,
                                 macro=True,
                                 releasegil=False,
                                 compilation_info=eci)
        myabs2 = rffi.llexternal('pypy_my_fabs', [lltype.Float],
                                 lltype.Float,
                                 macro=True,
                                 releasegil=True,
                                 compilation_info=eci)

        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)
                _get_virtualizable_token(frame)
                total += frame.i
                if frame.i >= 20:
                    frame.i -= 2
                frame.i -= 1
                j *= -0.712
                if j + (-j): raise ValueError
                j += frame.i
                k = myabs1(myabs2(j))
                if k - abs(j): raise ValueError
                if k - abs(-j): raise ValueError
            return chr(total % 253)

        #
        class Virt2(object):
            _virtualizable_ = ['i']

            def __init__(self, i):
                self.i = i

        from rpython.rlib.libffi import types, CDLL, ArgChain
        from rpython.rlib.test.test_clibffi import get_libm_name
        libm_name = get_libm_name(sys.platform)
        jitdriver2 = JitDriver(greens=[],
                               reds=['v2', 'func', 'res', 'x'],
                               virtualizables=['v2'])

        def libffi_stuff(i, j):
            lib = CDLL(libm_name)
            func = lib.getpointer('fabs', [types.double], types.double)
            res = 0.0
            x = float(j)
            v2 = Virt2(i)
            while v2.i > 0:
                jitdriver2.jit_merge_point(v2=v2, res=res, func=func, x=x)
                promote(func)
                argchain = ArgChain()
                argchain.arg(x)
                res = func.call(argchain, rffi.DOUBLE)
                v2.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
Ejemplo n.º 16
0
    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
        # - two virtualizable types
        # - set_param interface
        # - profiler
        # - full optimizer
        # - floats neg and abs
        # - llexternal with macro=True

        class Frame(object):
            _virtualizable_ = ['i']

            def __init__(self, i):
                self.i = i

        eci = ExternalCompilationInfo(post_include_bits=['''
#define pypy_my_fabs(x)  fabs(x)
'''])
        myabs1 = rffi.llexternal('pypy_my_fabs', [lltype.Float],
                                 lltype.Float, macro=True, releasegil=False,
                                 compilation_info=eci)
        myabs2 = rffi.llexternal('pypy_my_fabs', [lltype.Float],
                                 lltype.Float, macro=True, releasegil=True,
                                 compilation_info=eci)

        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 = myabs1(myabs2(j))
                if k - abs(j):  raise ValueError
                if k - abs(-j): raise ValueError
            return chr(total % 253)
        #
        class Virt2(object):
            _virtualizable_ = ['i']
            def __init__(self, i):
                self.i = i
        from rpython.rlib.libffi import types, CDLL, ArgChain
        from rpython.rlib.test.test_clibffi import get_libm_name
        libm_name = get_libm_name(sys.platform)
        jitdriver2 = JitDriver(greens=[], reds = ['v2', 'func', 'res', 'x'],
                               virtualizables = ['v2'])
        def libffi_stuff(i, j):
            lib = CDLL(libm_name)
            func = lib.getpointer('fabs', [types.double], types.double)
            res = 0.0
            x = float(j)
            v2 = Virt2(i)
            while v2.i > 0:
                jitdriver2.jit_merge_point(v2=v2, res=res, func=func, x=x)
                promote(func)
                argchain = ArgChain()
                argchain.arg(x)
                res = func.call(argchain, rffi.DOUBLE)
                v2.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