[pypy-svn] r48219 - in pypy/dist/pypy/translator/llvm: . test
rxe at codespeak.net
rxe at codespeak.net
Wed Oct 31 00:48:54 CET 2007
Author: rxe
Date: Wed Oct 31 00:48:53 2007
New Revision: 48219
Modified:
pypy/dist/pypy/translator/llvm/buildllvm.py
pypy/dist/pypy/translator/llvm/genllvm.py
pypy/dist/pypy/translator/llvm/modwrapper.py
pypy/dist/pypy/translator/llvm/test/test_runtest.py
Log:
try and make the interface richer
Modified: pypy/dist/pypy/translator/llvm/buildllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/buildllvm.py (original)
+++ pypy/dist/pypy/translator/llvm/buildllvm.py Wed Oct 31 00:48:53 2007
@@ -5,7 +5,7 @@
from pypy.translator.tool import stdoutcapture
from pypy.translator.llvm.log import log
-from pypy.translator.llvm.modwrapper import write_ctypes_module
+from pypy.translator.llvm.modwrapper import CtypesModule
def llvm_is_on_path():
if py.path.local.sysfind("llvm-as") is None or \
@@ -153,7 +153,7 @@
try:
self.execute_cmds()
- modname = write_ctypes_module(self.genllvm, "%s.so" % base)
+ modname = CtypesModule(self.genllvm, "%s.so" % base).create()
finally:
self.lastdir.chdir()
Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py (original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py Wed Oct 31 00:48:53 2007
@@ -250,7 +250,7 @@
from pypy.translator.tool.cbuild import import_module_from_directory
mod = import_module_from_directory(dirpath, modname)
- wrap_fun = getattr(mod, 'pypy_' + self.entry_func_name + "_wrapper")
+ wrap_fun = getattr(mod, 'entrypoint')
return mod, wrap_fun
def compile_standalone(self, exe_name):
Modified: pypy/dist/pypy/translator/llvm/modwrapper.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/modwrapper.py (original)
+++ pypy/dist/pypy/translator/llvm/modwrapper.py Wed Oct 31 00:48:53 2007
@@ -1,3 +1,4 @@
+import py
import ctypes
from pypy.rpython.lltypesystem import lltype
@@ -35,35 +36,50 @@
return code
-TO_CTYPES = {lltype.Bool: "ctypes.c_int",
- lltype.SingleFloat: "ctypes.c_float",
- lltype.Float: "ctypes.c_double",
- lltype.Char: "ctypes.c_char",
- lltype.Signed: "ctypes.c_int",
- lltype.Unsigned: "ctypes.c_uint",
- lltype.SignedLongLong: "ctypes.c_longlong",
- lltype.UnsignedLongLong: "ctypes.c_ulonglong",
- lltype.Void: None
- }
-
-def to_ctype(T):
- if isinstance(T, lltype.Ptr):
- return "ctypes.c_void_p"
- else:
- return TO_CTYPES[T]
-def build_lltype_to_ctypes_to_res(T):
- identity = """
-def tores(res):
+class CtypesModule:
+ """ use ctypes to create a temporary module """
+
+ prolog = """
+import ctypes
+from os.path import join, dirname, realpath
+
+_c = ctypes.CDLL(join(dirname(realpath(__file__)), "%s"))
+
+raised = _c.__entrypoint__raised_LLVMException
+raised.argtypes = []
+raised.restype = ctypes.c_int
+
+GC_get_heap_size_wrapper = _c.GC_get_heap_size
+GC_get_heap_size_wrapper.argtypes = []
+GC_get_heap_size_wrapper.restype = ctypes.c_int
+
+startup_code = _c.ctypes_RPython_StartupCode
+startup_code.argtypes = []
+startup_code.restype = ctypes.c_int
+
+_setup = False
+
+class LLVMException(Exception):
+ pass
+
+def entrypoint(*args):
+ global _setup
+ if not _setup:
+ if not startup_code():
+ raise LLVMException("Failed to startup")
+ _setup = True
+ args = to_llargs(args)
+ result = __entrypoint__(*args)
+ if raised():
+ raise LLVMException("Exception raised")
+ return ll_to_res(result)
+
+def identity(res):
return res
- """
- to_bool = """
-def tores(res):
+def to_bool(res):
return bool(res)
- """
-
- to_str = """
class Chars(ctypes.Structure):
_fields_ = [("size", ctypes.c_int),
@@ -73,115 +89,117 @@
_fields_ = [("hash", ctypes.c_int),
("array", Chars)]
-def tores(res):
+def to_str(res):
if res:
s = ctypes.cast(res, ctypes.POINTER(STR)).contents
return ctypes.string_at(res + (STR.array.offset + Chars.data.offset), s.array.size)
else:
return None
- """
- to_tuple = """
-def tores(res):
+def to_tuple(res, size, C_TYPE, action):
if res:
- t = ctypes.cast(res, ctypes.POINTER(%s * %s)).contents
- return tuple(t)
+ t = ctypes.cast(res, ctypes.POINTER(C_TYPE * size)).contents
+ return tuple([action(ii) for ii in t])
else:
return None
- """
-
- to_list = """
-def tores(res):
+def to_list(res, C_TYPE, action):
if res:
size = ctypes.cast(res, ctypes.POINTER(ctypes.c_int)).contents.value
class Array(ctypes.Structure):
_fields_ = [("size", ctypes.c_int),
- ("data", %s * size)]
+ ("data", C_TYPE * size)]
array = ctypes.cast(res, ctypes.POINTER(Array)).contents
- return list(array.data)
+ return [action(array.data[ii]) for ii in range(size)]
else:
return None
- """
-
- from pypy.rpython.lltypesystem.rstr import STR
-
- if T is lltype.Bool:
- return to_bool
- elif isinstance(T, lltype.Ptr) and T.TO is STR:
- return to_str
- elif isinstance(T, lltype.Ptr) and isinstance(T.TO, lltype.Struct):
- fields = [getattr(T.TO, name) for name in T.TO._names_without_voids()]
- if fields:
- F0 = fields[0]
- for F in fields[1:]:
- if F0 is not F:
- raise Exception("struct must be of same kind")
- if F0 not in TO_CTYPES:
- raise Exception("struct must be of primitve type")
-
- return to_tuple % (len(fields), TO_CTYPES[F0])
-
- elif isinstance(T, lltype.Ptr) and isinstance(T.TO, lltype.Array):
- OF = T.TO.OF
- if OF not in TO_CTYPES:
- raise Exception("struct must be of primitve type")
-
- return to_list % TO_CTYPES[OF]
- else:
- return identity
-
-def write_ctypes_module(genllvm, dllname):
- """ use ctypes to create a temporary module """
-
- template = """
-import ctypes
-from os.path import join, dirname, realpath
-_c = ctypes.CDLL(join(dirname(realpath(__file__)), "%(dllname)s"))
-
-_setup = False
-
-class LLVMException(Exception):
- pass
-
-%(name)s = _c.__entrypoint__%(name)s
-%(name)s.argtypes = %(args)s
-%(name)s.restype = %(returntype)s
-
-%(name)s_raised = _c.__entrypoint__raised_LLVMException
-%(name)s_raised.argtypes = []
-%(name)s_raised.restype = ctypes.c_int
-
-GC_get_heap_size_wrapper = _c.GC_get_heap_size
-GC_get_heap_size_wrapper.argtypes = []
-GC_get_heap_size_wrapper.restype = ctypes.c_int
-
-startup_code = _c.ctypes_RPython_StartupCode
-startup_code.argtypes = []
-startup_code.restype = ctypes.c_int
-
-def %(name)s_wrapper(*args):
- global _setup
- if not _setup:
- if not startup_code():
- raise LLVMException("Failed to startup")
- _setup = True
- result = %(name)s(*args)
- if %(name)s_raised():
- raise LLVMException("Exception raised")
- return tores(result)
"""
- basename = genllvm.filename.purebasename + '_wrapper.py'
- modfilename = genllvm.filename.new(basename = basename)
- name = genllvm.entrynode.ref.strip("%")
-
- g = genllvm.entrynode.graph
- rt = g.returnblock.inputargs[0].concretetype
- returntype = to_ctype(rt)
- inputargtypes = [TO_CTYPES[a.concretetype] for a in g.startblock.inputargs]
- args = '[%s]' % ", ".join(inputargtypes)
+ epilog = """
+to_llargs = %(to_llargs)s
+ll_to_res = %(ll_to_res)s
+__entrypoint__ = _c.__entrypoint__%(name)s
+__entrypoint__.argtypes = %(args)s
+__entrypoint__.restype = %(returntype)s
+ """
+ def __init__(self, genllvm, dllname):
+ self.genllvm = genllvm
+ self.dllname = dllname
+ basename = self.genllvm.filename.purebasename + '_wrapper.py'
+ self.modfilename = genllvm.filename.new(basename=basename)
+ self.count = 0
+
+ def create(self):
+ self.file = open(str(self.modfilename), 'w')
+ self.file.write(self.prolog % self.dllname)
+
+ g = self.genllvm.entrynode.graph
+ name = "pypy_" + g.name
- modfilename.write(template % locals() + build_lltype_to_ctypes_to_res(rt))
+ inputargtypes = [self.to_ctype(a.concretetype) for a in g.startblock.inputargs]
+ to_llargs = 'identity'
+ args = '[%s]' % ', '.join(inputargtypes)
- return modfilename.purebasename
+ RT = g.returnblock.inputargs[0].concretetype
+ returntype, ll_to_res = self.build_lltype_to_ctypes_to_res(RT)
+
+ self.file.write(self.epilog % locals())
+ self.file.close()
+ return self.modfilename.purebasename
+
+ def create_simple_closure(self, args, code):
+ name = 'tmpfunction_%s' % self.count
+ self.count += 1
+ self.file.write('\n')
+ self.file.write('def %s(%s): return %s' % (name, args, code))
+ self.file.write('\n')
+ return name
+
+ def build_lltype_to_ctypes_to_res(self, T):
+ from pypy.rpython.lltypesystem.rstr import STR
+
+ if T is lltype.Bool:
+ action = 'to_bool'
+
+ elif isinstance(T, lltype.Ptr) and T.TO is STR:
+ action = 'to_str'
+
+ elif isinstance(T, lltype.Ptr) and isinstance(T.TO, lltype.Struct):
+ fields = [getattr(T.TO, name) for name in T.TO._names_without_voids()]
+ if fields:
+ F0 = fields[0]
+ _c_type, _action = self.build_lltype_to_ctypes_to_res(F0)
+ action = self.create_simple_closure('res', 'to_tuple(res, %s, %s, %s)' % (len(fields),
+ _c_type,
+ _action))
+
+ elif isinstance(T, lltype.Ptr) and isinstance(T.TO, lltype.Array):
+ OF = T.TO.OF
+ _c_type, _action = self.build_lltype_to_ctypes_to_res(OF)
+ action = self.create_simple_closure('res', 'to_list(res, %s, %s)' % (_c_type, _action))
+
+ else:
+ assert not isinstance(T, lltype.Ptr)
+ action = 'identity'
+
+ c_type = self.to_ctype(T)
+ return c_type, action
+
+ def to_ctype(self, T):
+ TO_CTYPES = {lltype.Bool: "ctypes.c_byte",
+ lltype.SingleFloat: "ctypes.c_float",
+ lltype.Float: "ctypes.c_double",
+ lltype.Char: "ctypes.c_char",
+ lltype.Signed: "ctypes.c_int",
+ lltype.Unsigned: "ctypes.c_uint",
+ lltype.SignedLongLong: "ctypes.c_longlong",
+ lltype.UnsignedLongLong: "ctypes.c_ulonglong",
+ lltype.Void: None,
+ lltype.UniChar: "ctypes.c_uint",
+ }
+
+ if isinstance(T, lltype.Ptr):
+ return 'ctypes.c_void_p'
+ else:
+ return TO_CTYPES[T]
+
Modified: pypy/dist/pypy/translator/llvm/test/test_runtest.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/test_runtest.py (original)
+++ pypy/dist/pypy/translator/llvm/test/test_runtest.py Wed Oct 31 00:48:53 2007
@@ -8,3 +8,18 @@
y = 1 + x
return None
assert self.interpret(fn,[1]) == None
+
+ def test_list_of_strings(self):
+ def fn():
+ return ['abc', 'def']
+ assert self.interpret(fn, []) == ['abc', 'def']
+
+ def test_list_of_bools(self):
+ def fn():
+ return [True, True, False]
+ assert self.interpret(fn, []) == [True, True, False]
+
+ def test_tuple_of_list_of_stringss(self):
+ def fn():
+ return ['abc', 'def'], ['abc', 'def']
+ assert self.interpret(fn, []) == (['abc', 'def'], ['abc', 'def'])
More information about the Pypy-commit
mailing list