1. Maciej Fijalkowski
  2. hack2

Source

hack2 / pypyembed / embed.py


from ctypes import py_object, addressof, CDLL, c_long, c_char_p, c_int
import inspect

pypy = CDLL('./libpypy-c.so')
pypy_main_startup = pypy.pypy_main_startup
pypy_main_startup.argtypes = (c_int, c_char_p * 3)
pypy_main_startup.restype = c_int
pypy_prepare_function = pypy.pypy_prepare_function
pypy_prepare_function.argtypes = [c_long, c_char_p]
pypy_prepare_function.restype = None
pypy_call_function = pypy.pypy_call_function
pypy_call_function.argtypes = [c_char_p, c_long, py_object * 2]
pypy_call_function.restype = py_object

pypy_main_startup(3, (c_char_p * 3)("pypy-c", "-c", "pass"))

def addr(obj):
    return addressof(py_object(obj))

pypy_prepare_function(0, open('inner.py').read())

def export_function(func):
    src = ['@cross_call\n'] + inspect.getsource(func).splitlines()[1:]
    pypy_prepare_function(0, "\n".join(src))
    def f(*args):
        lgt = len(args)
        args = (py_object * lgt)(*args)
        return pypy_call_function(func.func_name, lgt, args)
    f.func_name = func.func_name
    return f