[pypy-svn] r45877 - pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem
fijal at codespeak.net
fijal at codespeak.net
Mon Aug 20 15:55:59 CEST 2007
Author: fijal
Date: Mon Aug 20 15:55:57 2007
New Revision: 45877
Modified:
pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/ll2ctypes.py
pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py
Log:
A proper support for CConstant (right now only ints).
Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/ll2ctypes.py (original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/ll2ctypes.py Mon Aug 20 15:55:57 2007
@@ -2,6 +2,7 @@
import ctypes
import ctypes.util
import os
+import py
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.extfunc import ExtRegistryEntry
from pypy.rlib.objectmodel import Symbolic
@@ -425,14 +426,20 @@
# ____________________________________________
def get_ctypes_callable(funcptr):
- if getattr(funcptr._obj, 'source', None) is not None:
- # give up - for tests with an inlined bit of C code
- raise NotImplementedError("cannot call a C function defined in "
- "a custom C source snippet")
FUNCTYPE = lltype.typeOf(funcptr).TO
funcname = funcptr._obj._name
libraries = getattr(funcptr._obj, 'libraries', None)
- if not libraries:
+ if getattr(funcptr._obj, 'sources', None):
+ # compile the library
+ from pypy.translator.tool.cbuild import compile_c_module
+ obj = funcptr._obj
+ name = 'ctypes_' + obj._name
+ d = py.path.local(obj.sources[0]).dirpath()
+ compile_c_module(obj.sources, name, obj.include_dirs, obj.libraries)
+ # ARGH! win issues here
+ clib = ctypes.cdll.LoadLibrary(str(d.join(name)) + '.so')
+ cfunc = getattr(clib, funcname, None)
+ elif not libraries:
cfunc = getattr(standard_c_lib, funcname, None)
else:
cfunc = None
Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py (original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/lltypesystem/rffi.py Mon Aug 20 15:55:57 2007
@@ -6,20 +6,8 @@
from pypy.tool.sourcetools import func_with_new_name
from pypy.rlib.objectmodel import Symbolic, CDefinedIntSymbolic
from pypy.rlib import rarithmetic
-import os
-
-class CConstant(Symbolic):
- """ A C-level constant, maybe #define, rendered directly.
- """
- def __init__(self, c_name, TP):
- self.c_name = c_name
- self.TP = TP
-
- def annotation(self):
- return lltype_to_annotation(self.TP)
-
- def lltype(self):
- return self.TP
+import os, py
+from pypy.tool.udir import udir
def llexternal(name, args, result, _callable=None, sources=[], includes=[],
libraries=[], include_dirs=[], sandboxsafe=False):
@@ -99,12 +87,6 @@
def CStructPtr(*args, **kwds):
return lltype.Ptr(CStruct(*args, **kwds))
-#def CArray(field):
-# return lltype.Array(field, hints={'nolength':True})
-
-#def CArrayPtr(field):
-# return lltype.Ptr(CArray(fld))
-
def COpaque(name, hints=None, **kwds):
if hints is None:
hints = {}
@@ -123,23 +105,30 @@
def COpaquePtr(*args, **kwds):
return lltype.Ptr(COpaque(*args, **kwds))
-def CExternVariable(TYPE, name):
+def CExternVariable(TYPE, name, **kwds):
"""Return a pair of functions - a getter and a setter - to access
the given global C variable.
"""
- # XXX THIS IS ONLY A QUICK HACK TO MAKE IT WORK
- # In general, we need to re-think a few things to be more consistent,
- # e.g. what if a CStruct, COpaque or CExternVariable requires
- # some #include...
- assert not isinstance(TYPE, lltype.ContainerType)
- CTYPE = lltype.FixedSizeArray(TYPE, 1)
- c_variable_ref = CConstant('(&%s)' % (name,), lltype.Ptr(CTYPE))
- def getter():
- return c_variable_ref[0]
- def setter(newvalue):
- c_variable_ref[0] = newvalue
- return (func_with_new_name(getter, '%s_getter' % (name,)),
- func_with_new_name(setter, '%s_setter' % (name,)))
+ assert TYPE is lltype.Signed # we need to-c-mapping for that
+ src = py.code.Source("""
+ #include <errno.h>
+ int _rffi_get_%(name)s()
+ {
+ return %(name)s;
+ }
+ void _rffi_set_%(name)s(int arg)
+ {
+ %(name)s = arg;
+ }
+ """ % {'name':name})
+ csrc = udir.join(name + "_getset.c")
+ csrc.write(str(src))
+ getter = llexternal('_rffi_get_' + name, [], TYPE, sources=[str(csrc)],
+ **kwds)
+ setter = llexternal('_rffi_set_' + name, [TYPE], lltype.Void,
+ sources=[str(csrc)], **kwds)
+
+ return getter, setter
get_errno, set_errno = CExternVariable(lltype.Signed, 'errno')
@@ -210,19 +199,19 @@
cast = ll2ctypes.force_cast # a forced, no-checking cast
def size_and_sign(tp):
- if tp is lltype.Char:
- return 1, False
- if tp is lltype.Float:
- return 8, False
- assert isinstance(tp, lltype.Number)
- if tp is lltype.Signed:
- unsigned = False
- else:
+ size = sizeof(tp)
+ try:
unsigned = not tp._type.SIGNED
- return sizeof(tp), unsigned
+ except AttributeError:
+ if tp in [lltype.Char, lltype.Float, lltype.Signed]:
+ unsigned = False
+ else:
+ unsigned = True
+ return size, unsigned
def sizeof(tp):
- # works only for int types!
+ if isinstance(tp, lltype.FixedSizeArray):
+ return sizeof(tp.OF) * tp.length
if tp is lltype.Char:
return 1
if tp is lltype.Float:
More information about the Pypy-commit
mailing list