[pypy-svn] r45316 - in pypy/dist/pypy: rpython/lltypesystem rpython/lltypesystem/test translator/c
fijal at codespeak.net
fijal at codespeak.net
Wed Jul 25 11:40:06 CEST 2007
Author: fijal
Date: Wed Jul 25 11:40:06 2007
New Revision: 45316
Modified:
pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py
pypy/dist/pypy/rpython/lltypesystem/lltype.py
pypy/dist/pypy/rpython/lltypesystem/rffi.py
pypy/dist/pypy/rpython/lltypesystem/rfficache.py
pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py
pypy/dist/pypy/rpython/lltypesystem/test/test_rfficache.py
pypy/dist/pypy/translator/c/database.py
Log:
Implement opaque_type on top of ll2ctypes, so we are able to create
pointers to opaque structures and test it on top of cpython.
Few minor code changes (like more meta-programming)
Modified: pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py Wed Jul 25 11:40:06 2007
@@ -137,6 +137,10 @@
cls = build_ctypes_struct(T)
elif isinstance(T, lltype.Array):
cls = build_ctypes_array(T)
+ elif isinstance(T, lltype.OpaqueType):
+ if T.hints.get('external', None) != 'C':
+ raise TypeError("%s is not external" % T)
+ cls = ctypes.c_char * T.hints['size']
else:
_setup_ctypes_cache()
if T in _ctypes_cache:
@@ -311,6 +315,9 @@
convert_struct(container)
elif isinstance(T.TO, lltype.Array):
convert_array(container)
+ elif isinstance(T.TO, lltype.OpaqueType):
+ container._storage = ctypes.create_string_buffer(
+ T.TO.hints['size'])
else:
raise NotImplementedError(T)
storage = container._storage
@@ -352,6 +359,8 @@
funcptr = lltype.functionptr(T.TO, getattr(cobj, '__name__', '?'))
make_callable_via_ctypes(funcptr, cfunc=cobj)
return funcptr
+ elif isinstance(T.TO, lltype.OpaqueType):
+ container = lltype._opaque(T.TO)
else:
raise NotImplementedError(T)
llobj = lltype._ptr(T, container, solid=True)
Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Wed Jul 25 11:40:06 2007
@@ -1655,6 +1655,8 @@
o = _struct(T, n, initialization=initialization)
elif isinstance(T, Array):
o = _array(T, n, initialization=initialization)
+ elif isinstance(T, OpaqueType):
+ o = _opaque(T, n, initialization=initialization)
else:
raise TypeError, "malloc for Structs and Arrays only"
if T._gckind != 'gc' and not immortal and flavor.startswith('gc'):
Modified: pypy/dist/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rffi.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rffi.py Wed Jul 25 11:40:06 2007
@@ -93,11 +93,14 @@
c_fields = [('c_' + key, value) for key, value in fields]
return lltype.Ptr(lltype.Struct(name, *c_fields, **kwds))
-def COpaque(name, hints=None):
+def COpaque(name, hints=None, **kwds):
if hints is None:
hints = {}
+ else:
+ hints = hints.copy()
hints['external'] = 'C'
hints['c_name'] = name
+ hints['size'] = platform.sizeof(name, **kwds)
return lltype.Ptr(lltype.OpaqueType(name, hints))
c_errno = CConstant('errno', lltype.Signed)
Modified: pypy/dist/pypy/rpython/lltypesystem/rfficache.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rfficache.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rfficache.py Wed Jul 25 11:40:06 2007
@@ -10,7 +10,8 @@
from pypy.rlib import rarithmetic
from pypy.rpython.lltypesystem import lltype
-def ask_gcc(question, includes={}, add_source="", compiler_exe=None):
+def ask_gcc(question, includes={}, add_source="", include_dirs=[],
+ compiler_exe=None):
if isinstance(includes, list):
includes = dict.fromkeys(includes)
from py.compat.subprocess import PIPE, Popen
@@ -33,14 +34,15 @@
c_file = udir.join("gcctest.c")
c_file.write(c_source)
- c_exec = build_executable([str(c_file)], compiler_exe=compiler_exe)
+ c_exec = build_executable([str(c_file)], include_dirs=include_dirs,
+ compiler_exe=compiler_exe)
pipe = Popen(c_exec, stdout=PIPE)
pipe.wait()
return pipe.stdout.read()
def sizeof_c_type(c_typename, **kwds):
question = 'printf("%%d", sizeof(%s));' % (c_typename,);
- return int(ask_gcc(question, **kwds)) * 8
+ return int(ask_gcc(question, **kwds))
def c_ifdefined(c_def, **kwds):
question = py.code.Source("""
@@ -54,6 +56,18 @@
question = 'printf("%%d", %s);' % (c_def,)
return int(ask_gcc(question, **kwds))
+def create_cache_access_method(acc_func, meth_name):
+ def method(self, name, **kwds):
+ try:
+ return self.cache[name]
+ except KeyError:
+ res = acc_func(name, **kwds)
+ self.cache[name] = res
+ self._store_cache()
+ return res
+ method.func_name = meth_name
+ return method
+
class RffiCache(object):
""" Class holding all of the c-level caches, eventually loaded from
the file, like #ifdefs, typesizes, int-level #defines
@@ -85,7 +99,7 @@
try:
return self.types[name]
except KeyError:
- bits = sizeof_c_type(c_name, **kwds)
+ bits = sizeof_c_type(c_name, **kwds) * 8
inttype = rarithmetic.build_int('r_' + name, signed, bits)
self.cache[c_name] = bits
self.type_names[name] = (c_name, signed)
@@ -95,23 +109,9 @@
self._store_cache()
return tp
- def defined(self, name, **kwds):
- try:
- return self.cache[name]
- except KeyError:
- res = c_ifdefined(name, **kwds)
- self.cache[name] = res
- self._store_cache()
- return res
-
- def intdefined(self, name, **kwds):
- try:
- return self.cache[name]
- except KeyError:
- res = c_defined_int(name, **kwds)
- self.cache[name] = res
- self._store_cache()
- return res
+ defined = create_cache_access_method(c_ifdefined, 'defined')
+ intdefined = create_cache_access_method(c_defined_int, 'intdefined')
+ sizeof = create_cache_access_method(sizeof_c_type, 'sizeof')
# optimal way of caching it, would be to store file on __del__,
# but since we cannot rely on __del__ having all modules, let's
Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py Wed Jul 25 11:40:06 2007
@@ -226,6 +226,17 @@
assert res2 == res2b
assert res3 == res3b
+ def test_opaque_obj(self):
+ includes = ['sys/time.h', 'time.h']
+ TIMEVALP = rffi.COpaque('struct timeval', includes=includes)
+ TIMEZONEP = rffi.COpaque('struct timezone', includes=includes)
+ gettimeofday = rffi.llexternal('gettimeofday', [TIMEVALP, TIMEZONEP],
+ rffi.INT, includes=includes)
+ ll_timevalp = lltype.malloc(TIMEVALP.TO, flavor='raw')
+ ll_timezonep = lltype.malloc(TIMEZONEP.TO, flavor='raw')
+ res = gettimeofday(ll_timevalp, ll_timezonep)
+ assert res != -1
+
def test_simple_cast(self):
assert rffi.cast(rffi.SIGNEDCHAR, 0x123456) == 0x56
assert rffi.cast(rffi.SIGNEDCHAR, 0x123481) == -127
Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py Wed Jul 25 11:40:06 2007
@@ -227,7 +227,8 @@
h_file = udir.join("opaque.h")
h_file.write(h_source)
- STUFFP = COpaque('stuff')
+ STUFFP = COpaque('struct stuff', includes=['opaque.h'],
+ include_dirs=[str(udir)])
ll_get = llexternal('get', [STUFFP], lltype.Char, includes=['opaque.h'],
include_dirs=[str(udir)])
Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_rfficache.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_rfficache.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_rfficache.py Wed Jul 25 11:40:06 2007
@@ -5,7 +5,7 @@
def test_sizeof_c_type():
sizeofchar = sizeof_c_type('char')
- assert sizeofchar == 8
+ assert sizeofchar == 1
def test_c_ifdefined():
assert c_ifdefined('X', add_source='#define X')
@@ -22,10 +22,12 @@
assert cache.defined('STUFF')
assert cache.intdefined('STUFFI', add_source='#define STUFFI 3') == 3
assert cache.intdefined('STUFFI') == 3
+ assert cache.sizeof('short') == 2
cache = RffiCache(udir.join('cache.py'))
assert cache.intdefined('STUFFI') == 3
assert cache.defined('STUFF')
assert cache.inttype('uchar', 'unsigned char', False, compiler_exe='xxx')._type.BITS == 8
+ assert cache.sizeof('short', compiler_exe='xxx') == 2
def test_types_present():
for name in rffi.TYPES:
Modified: pypy/dist/pypy/translator/c/database.py
==============================================================================
--- pypy/dist/pypy/translator/c/database.py (original)
+++ pypy/dist/pypy/translator/c/database.py Wed Jul 25 11:40:06 2007
@@ -130,7 +130,7 @@
who_asks.dependencies[node] = True
return 'struct %s @' % node.name
elif T.hints.get('external', None) == 'C':
- return 'struct %s @' % T.hints['c_name']
+ return '%s @' % T.hints['c_name']
else:
#raise Exception("don't know about opaque type %r" % (T,))
return 'struct %s @' % (
More information about the Pypy-commit
mailing list