[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