[pypy-svn] r50279 - in pypy/dist/pypy/rpython/lltypesystem: . test

fijal at codespeak.net fijal at codespeak.net
Thu Jan 3 10:39:29 CET 2008


Author: fijal
Date: Thu Jan  3 10:39:28 2008
New Revision: 50279

Modified:
   pypy/dist/pypy/rpython/lltypesystem/rffi.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_rffi.py
Log:
Implement errorcode for callbacks and print a warning.


Modified: pypy/dist/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rffi.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rffi.py	Thu Jan  3 10:39:28 2008
@@ -106,7 +106,11 @@
                     freeme = arg
             elif isfunctype(TARGET):
                 # XXX pass additional arguments
-                arg = llhelper(TARGET, _make_wrapper_for(arg))
+                if invoke_around_handlers:
+                    arg = llhelper(TARGET, _make_wrapper_for(TARGET, arg,
+                                                             aroundstate))
+                else:
+                    arg = llhelper(TARGET, _make_wrapper_for(TARGET, arg))
             else:
                 SOURCE = lltype.typeOf(arg)
                 if SOURCE != TARGET:
@@ -139,12 +143,20 @@
 
     return func_with_new_name(wrapper, name)
 
-def _make_wrapper_for(callable, error_code=None):
+def _make_wrapper_for(TP, callable, aroundstate=None):
     """ Function creating wrappers for callbacks. Note that this is
     cheating as we assume constant callbacks and we just memoize wrappers
     """
+    if hasattr(callable, '_errorcode_'):
+        errorcode = callable._errorcode_
+    else:
+        errorcode = TP.TO.RESULT._example()
     def wrapper(*args):
-        return callable(*args)
+        try:
+            return callable(*args)
+        except Exception, e:
+            os.write(2, "Warning: uncatched exception: %s" % str(e))
+            return errorcode
     return wrapper
 _make_wrapper_for._annspecialcase_ = 'specialize:memo'
 

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	Thu Jan  3 10:39:28 2008
@@ -324,7 +324,10 @@
         h_source = py.code.Source("""
         int eating_callback(int arg, int(*call)(int))
         {
-            return call(arg);
+            int res = call(arg);
+            if (res == -1)
+              return -1;
+            return res;
         }
         """)
         
@@ -370,6 +373,22 @@
         assert fn(4) == 4
         assert fn(1) == 3
 
+    def test_exception_callback(self):
+        eating_callback = self.eating_callback()
+
+        def raising(i):
+            if i > 3:
+                raise ValueError
+            else:
+                return 3
+        raising._errorcode_ = -1
+
+        def f(i):
+            return eating_callback(i, raising)
+
+        fn = self.compile(f, [int])
+        assert fn(13) == -1
+
 class TestRffiInternals:
     def test_struct_create(self):
         X = CStruct('xx', ('one', INT))


More information about the pypy-svn mailing list