[pypy-svn] r36349 - in pypy/dist/pypy: rlib/rctypes rlib/rctypes/test rpython

arigo at codespeak.net arigo at codespeak.net
Tue Jan 9 13:58:04 CET 2007


Author: arigo
Date: Tue Jan  9 13:58:01 2007
New Revision: 36349

Added:
   pypy/dist/pypy/rlib/rctypes/rfunc.py   (contents, props changed)
   pypy/dist/pypy/rlib/rctypes/test/test_rfunc.py
      - copied, changed from r36147, pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py
Modified:
   pypy/dist/pypy/rlib/rctypes/implementation.py
   pypy/dist/pypy/rlib/rctypes/rstruct.py
   pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py
   pypy/dist/pypy/rpython/controllerentry.py
Log:
Fix constructor args for ctypes.Structures.
Started working on ctypes functions, not really working so far.


Modified: pypy/dist/pypy/rlib/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/implementation.py	(original)
+++ pypy/dist/pypy/rlib/rctypes/implementation.py	Tue Jan  9 13:58:01 2007
@@ -46,8 +46,11 @@
             _controller_ = cls
     register_for_metatype = classmethod(register_for_metatype)
 
+    def ctypecheck(self, x):
+        return isinstance(x, self.ctype)
+
     def convert(self, x):
-        if isinstance(x, self.ctype):
+        if self.ctypecheck(x):
             key = "by_id", id(x)
         else:
             key = "by_value", x
@@ -120,7 +123,10 @@
 
 class CTypesObjEntry(ControllerEntryForPrebuilt):
     def getcontroller(self):
-        ctype = self.type
+        if hasattr(self._controller_, 'real_ctype_of'):
+            ctype = self._controller_.real_ctype_of(self.instance)
+        else:
+            ctype = self.type
         return _build_controller(self._controller_, ctype)
 
 TLS = tlsobject()
@@ -202,3 +208,4 @@
 import pypy.rlib.rctypes.rstruct
 import pypy.rlib.rctypes.rbuiltin
 import pypy.rlib.rctypes.rchar_p
+import pypy.rlib.rctypes.rfunc

Added: pypy/dist/pypy/rlib/rctypes/rfunc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rlib/rctypes/rfunc.py	Tue Jan  9 13:58:01 2007
@@ -0,0 +1,71 @@
+from pypy.annotation import model as annmodel
+from pypy.rlib.rctypes.implementation import CTypeController, getcontroller
+from pypy.rlib.rctypes import rctypesobject
+from pypy.rpython.lltypesystem import lltype
+
+import ctypes
+
+CFuncPtrType = type(ctypes.CFUNCTYPE(None))
+
+
+class FuncPtrCTypeController(CTypeController):
+    ready = 0
+
+    def __init__(self, ctype):
+        CTypeController.__init__(self, ctype)
+        sample_instance = self.ctype()
+        self.argtypes = sample_instance.argtypes
+        self.restype  = sample_instance.restype
+        self.knowntype = rctypesobject.RPointer(None)
+
+    def setup(self):
+        if self.ready == 0:
+            self.ready = 1
+            self.argscontrollers = [getcontroller(a) for a in self.argtypes]
+            self.rescontroller = getcontroller(self.restype)
+            argscls = [c.knowntype for c in self.argscontrollers]
+            rescls = self.rescontroller.knowntype
+            self.rfunctype = rctypesobject.RFuncType(argscls, rescls)
+            self.knowntype.setpointertype(self.rfunctype, force=True)
+            self.make_helpers()
+            self.ready = 2
+
+    def make_helpers(self):
+        # XXX need stuff to unwrap pointer boxes to lltype pointers
+        pass
+
+    def real_ctype_of(fnptr):
+        # in ctypes, most function pointers have argtypes and restype set
+        # on the function pointer object itself, not on its class
+        return ctypes.CFUNCTYPE(fnptr.restype, *fnptr.argtypes)
+    real_ctype_of = staticmethod(real_ctype_of)
+
+    def ctypecheck(self, x):
+        return (isinstance(type(x), CFuncPtrType) and
+                tuple(x.argtypes) == tuple(self.argtypes) and
+                x.restype == self.restype)
+
+    def new(self):
+        obj = self.knowntype.allocate()
+        return obj
+
+    def initialize_prebuilt(self, ptrobj, cfuncptr):
+        if not cfuncptr:   # passed as arg to functions expecting func pointers
+            return
+        # XXX this assumes it is an external function, correctly initialized
+        # with includes and libraries attributes
+        name = cfuncptr.__name__
+        includes = getattr(cfuncptr, 'includes', ())
+        libraries = getattr(cfuncptr, 'libraries', ())
+        rlib = rctypesobject.RLibrary(libraries, includes)
+        llinterp_friendly_version = getattr(cfuncptr,
+                                            'llinterp_friendly_version',
+                                            None)
+        funcobj = self.rfunctype.fromlib(rlib, name, llinterp_friendly_version)
+        ptrobj.set_contents(funcobj)
+
+    def call(self, fnptrobj, *args):
+        return fnptrobj.get_contents().call(*args)
+
+
+FuncPtrCTypeController.register_for_metatype(CFuncPtrType)

Modified: pypy/dist/pypy/rlib/rctypes/rstruct.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rstruct.py	(original)
+++ pypy/dist/pypy/rlib/rctypes/rstruct.py	Tue Jan  9 13:58:01 2007
@@ -1,3 +1,4 @@
+from pypy.annotation import model as annmodel
 from pypy.rlib.rctypes.implementation import CTypeController, getcontroller
 from pypy.rlib.rctypes import rctypesobject
 from pypy.rpython.extregistry import ExtRegistryEntry
@@ -84,10 +85,12 @@
                 while len(lst) <= index:
                     lst.append(None)
                 if lst[index] is not None:
-                    raise TypeError("duplicate value for argument %r" % name)
+                    from pypy.rpython.error import TyperError
+                    raise TyperError("duplicate value for argument %r" % name)
                 lst[index] = value
         if kwds:
-            raise TypeError("unknown keyword(s): %r" % (kwds.keys(),))
+            from pypy.rpython.error import TyperError
+            raise TyperError("unknown keyword(s): %r" % (kwds.keys(),))
         return lst
 
     def ctrl_new_ex(self, bookkeeper, *args_s, **kwds_s):
@@ -148,7 +151,7 @@
         assert s_fieldname.is_constant()
         ofs = offsetof(s_Struct.const, s_fieldname.const)
         assert ofs >= 0
-        s_result = SomeInteger(nonneg=True)
+        s_result = annmodel.SomeInteger(nonneg=True)
         s_result.const = ofs
         return s_result
 

Modified: pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py	(original)
+++ pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py	Tue Jan  9 13:58:01 2007
@@ -5,6 +5,7 @@
 import py.test
 import pypy.rlib.rctypes.implementation
 from pypy.rlib.rctypes.test.test_rprimitive import BaseTestAnnotation
+from pypy.rpython.error import TyperError
 from pypy.rpython.test.test_llinterp import interpret
 from pypy.translator.c.test.test_genc import compile
 from pypy.rlib.rctypes.rstruct import offsetof
@@ -179,7 +180,6 @@
         assert res == 289
 
     def test_specialize_constructor_args(self):
-        #py.test.skip("in-progress")
         class S(Structure):
             _fields_ = [('x', c_int),
                         ('y', c_char)]
@@ -201,7 +201,6 @@
         assert res == 463
 
     def test_specialize_bad_constructor_args(self):
-        py.test.skip("in-progress")
         class S(Structure):
             _fields_ = [('x', c_int),
                         ('y', c_char)]
@@ -214,7 +213,6 @@
         py.test.raises(TyperError, "interpret(f2, [4])")
 
     def test_specialize_offsetof(self):
-        py.test.skip("in-progress")
         def f1():
             return offsetof(tagpoint, 'y')
         res = interpret(f1, [])

Modified: pypy/dist/pypy/rpython/controllerentry.py
==============================================================================
--- pypy/dist/pypy/rpython/controllerentry.py	(original)
+++ pypy/dist/pypy/rpython/controllerentry.py	Tue Jan  9 13:58:01 2007
@@ -124,6 +124,13 @@
         from pypy.rpython.rcontrollerentry import rtypedelegate
         return rtypedelegate(self.is_true, hop)
 
+    def ctrl_call(self, s_obj, *args_s):
+        return delegate(self.call, s_obj, *args_s)
+
+    def rtype_call(self, hop):
+        from pypy.rpython.rcontrollerentry import rtypedelegate
+        return rtypedelegate(self.call, hop)
+
 
 def delegate(boundmethod, *args_s):
     bk = getbookkeeper()
@@ -218,6 +225,9 @@
     def is_true(s_cin):
         return s_cin.controller.ctrl_is_true(s_cin.s_real_obj)
 
+    def simple_call(s_cin, *args_s):
+        return s_cin.controller.ctrl_call(s_cin.s_real_obj, *args_s)
+
 
 class __extend__(pairtype(SomeControlledInstance, annmodel.SomeObject)):
 



More information about the Pypy-commit mailing list