[pypy-svn] r64101 - in pypy/trunk/pypy: rlib rpython/lltypesystem translator/stackless

arigo at codespeak.net arigo at codespeak.net
Wed Apr 15 17:33:29 CEST 2009


Author: arigo
Date: Wed Apr 15 17:33:27 2009
New Revision: 64101

Modified:
   pypy/trunk/pypy/rlib/objectmodel.py
   pypy/trunk/pypy/rpython/lltypesystem/rffi.py
   pypy/trunk/pypy/translator/stackless/code.py
Log:
(niko, arigo)
Be a bit safer against C callbacks with stackless: instead of crashing,
raises a RuntimeError.


Modified: pypy/trunk/pypy/rlib/objectmodel.py
==============================================================================
--- pypy/trunk/pypy/rlib/objectmodel.py	(original)
+++ pypy/trunk/pypy/rlib/objectmodel.py	Wed Apr 15 17:33:27 2009
@@ -219,6 +219,10 @@
     llhelper(rffi.AroundFnPtr, before)
     llhelper(rffi.AroundFnPtr, after)
 
+def is_in_callback():
+    from pypy.rpython.lltypesystem import rffi
+    return rffi.aroundstate.callback_counter > 0
+
 
 class UnboxedValue(object):
     """A mixin class to use for classes that have exactly one field which

Modified: pypy/trunk/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/trunk/pypy/rpython/lltypesystem/rffi.py	(original)
+++ pypy/trunk/pypy/rpython/lltypesystem/rffi.py	Wed Apr 15 17:33:27 2009
@@ -215,6 +215,8 @@
             if after:
                 after()
             # from now on we hold the GIL
+            if aroundstate is not None:
+                aroundstate.callback_counter += 1
             try:
                 result = callable(%s)
             except Exception, e:
@@ -225,6 +227,8 @@
                     import traceback
                     traceback.print_exc()
                 result = errorcode
+            if aroundstate is not None:
+                aroundstate.callback_counter -= 1
             if before:
                 before()
             # here we don't hold the GIL any more. As in the wrapper() produced
@@ -245,6 +249,7 @@
     def _freeze_(self):
         self.before = None    # or a regular RPython function
         self.after = None     # or a regular RPython function
+        self.callback_counter = 0
         return False
 aroundstate = AroundState()
 aroundstate._freeze_()

Modified: pypy/trunk/pypy/translator/stackless/code.py
==============================================================================
--- pypy/trunk/pypy/translator/stackless/code.py	(original)
+++ pypy/trunk/pypy/translator/stackless/code.py	Wed Apr 15 17:33:27 2009
@@ -1,12 +1,16 @@
 import sys
 from pypy.rpython.lltypesystem import lltype, llmemory, lloperation
 from pypy.tool.sourcetools import func_with_new_name
-from pypy.rlib import rarithmetic
+from pypy.rlib import rarithmetic, objectmodel
 from pypy.translator.stackless import frame
 from pypy.translator.stackless.frame import STATE_HEADER, SAVED_REFERENCE, STORAGE_TYPES_AND_FIELDS
 
 EMPTY_STATE = frame.make_state_header_type('empty_state')
 
+def check_can_raise_unwind():
+    if objectmodel.is_in_callback():
+        raise RuntimeError
+
 # ____________________________________________________________
 
 SWITCH_STATE = frame.make_state_header_type('switch_state',
@@ -359,6 +363,7 @@
         # To switch manually to a different frame, code issues a regular
         # UnwindException first, to empty the C stack, and then issues a
         # (XXX complete this comment)
+        check_can_raise_unwind()
         self.frame_bottom = frame.null_state
         self.depth = 0
     __init__.stackless_explicit = True



More information about the Pypy-commit mailing list