Author: Antonio Cuni <[email protected]>
Branch: jitypes2
Changeset: r44727:e57e796fb21a
Date: 2011-06-03 11:10 +0200
http://bitbucket.org/pypy/pypy/changeset/e57e796fb21a/

Log:    make errcheck compatible with the fast path

diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -340,16 +340,7 @@
 
         funcptr = self._getfuncptr(argtypes, self._restype_, thisarg)
         result = self._call_funcptr(funcptr, *newargs)
-        # The 'errcheck' protocol
-        if self._errcheck_:
-            v = self._errcheck_(result, self, args)
-            # If the errcheck funtion failed, let it throw
-            # If the errcheck function returned newargs unchanged,
-            # continue normal processing.
-            # If the errcheck function returned something else,
-            # use that as result.
-            if v is not args:
-                result = v
+        result = self._do_errcheck(result, args)
 
         #return result
         if not outargs:
@@ -358,7 +349,6 @@
             return outargs[0]
         return tuple(outargs)
 
-
     def _call_funcptr(self, funcptr, *newargs):
 
         if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
@@ -377,6 +367,19 @@
         #
         return self._build_result(self._restype_, result, newargs)
 
+    def _do_errcheck(self, result, args):
+        # The 'errcheck' protocol
+        if self._errcheck_:
+            v = self._errcheck_(result, self, args)
+            # If the errcheck funtion failed, let it throw
+            # If the errcheck function returned newargs unchanged,
+            # continue normal processing.
+            # If the errcheck function returned something else,
+            # use that as result.
+            if v is not args:
+                return v
+        return result
+
     def _getfuncptr_fromaddress(self, argtypes, restype):
         address = self._get_address()
         ffiargs = [argtype.get_ffi_argtype() for argtype in argtypes]
@@ -644,8 +647,7 @@
         @classmethod
         def enable_fastpath_maybe(cls, obj):
             if (obj.callable is None and
-                obj._com_index is None and
-                obj._errcheck_ is None):
+                obj._com_index is None):
                 obj.__class__ = cls
 
         def __rollback(self):
@@ -668,11 +670,6 @@
             self._com_index = idx
         _com_index = property(lambda x: None, _setcom_index)
 
-        def _seterrcheck(self, func):
-            self.__rollback()
-            self.errcheck = func
-        errcheck = property(lambda x: None, _seterrcheck)
-
         def __call__(self, *args):
             thisarg = None
             argtypes = self._argtypes_
@@ -680,6 +677,7 @@
             funcptr = self._getfuncptr(argtypes, restype, thisarg)
             try:
                 result = self._call_funcptr(funcptr, *args)
+                result = self._do_errcheck(result, args)
             except (TypeError, ArgumentError): # XXX, should be FFITypeError
                 assert self._slowpath_allowed
                 return CFuncPtr.__call__(self, *args)
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_fastpath.py 
b/pypy/module/test_lib_pypy/ctypes_tests/test_fastpath.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_fastpath.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_fastpath.py
@@ -19,26 +19,25 @@
 class TestFastpath(BaseCTypesTestChecker):
 
     def test_fastpath_forbidden(self):
-        def errcheck(result, func, args):
-            return result
+        def myfunc():
+            pass
         #
         tf_b = dll.tf_b
         tf_b.restype = c_byte
         #
         # so far, it's still using the slowpath
         assert not tf_b._is_fastpath
-        tf_b.errcheck = errcheck
+        tf_b.callable = myfunc
         tf_b.argtypes = (c_byte,)
         # errcheck prevented the fastpath to kick in
         assert not tf_b._is_fastpath
         #
-        del tf_b.errcheck
+        del tf_b.callable
         tf_b.argtypes = (c_byte,) # try to re-enable the fastpath
         assert tf_b._is_fastpath
         #
         assert not tf_b._slowpath_allowed
-        # errcheck disables the fastpath
-        py.test.raises(AssertionError, "tf_b.errcheck = errcheck")
+        py.test.raises(AssertionError, "tf_b.callable = myfunc")
         py.test.raises(AssertionError, "tf_b('aaa')") # force a TypeError
 
     def test_simple_args(self):
@@ -74,6 +73,15 @@
         result = f("abcd", ord("b"))
         assert result == "bcd"
 
+    def test_errcheck(self):
+        def errcheck(result, func, args):
+            return 'hello'
+        tf_b = dll.tf_b
+        tf_b.restype = c_byte
+        tf_b.argtypes = (c_byte,)
+        tf_b.errcheck = errcheck
+        assert tf_b(-126) == 'hello'
+
 
 class TestFallbackToSlowpath(BaseCTypesTestChecker):
 
@@ -93,15 +101,3 @@
         assert not tf_b._is_fastpath
         assert tf_b(-126) == -125
         tf_b.callable = None
-
-    def test_errcheck_is_None(self):
-        def errcheck(result, func, args):
-            return result * 2
-        #
-        tf_b = dll2.tf_b
-        tf_b.restype = c_byte
-        tf_b.argtypes = (c_byte,)
-        tf_b.errcheck = errcheck
-        assert not tf_b._is_fastpath
-        assert tf_b(-126) == -84
-        del tf_b.errcheck
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to