[pypy-svn] r72976 - pypy/branch/cpython-extension/pypy/module/cpyext
xoraxax at codespeak.net
xoraxax at codespeak.net
Sat Mar 27 21:40:14 CET 2010
Author: xoraxax
Date: Sat Mar 27 21:40:12 2010
New Revision: 72976
Modified:
pypy/branch/cpython-extension/pypy/module/cpyext/api.py
pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py
pypy/branch/cpython-extension/pypy/module/cpyext/state.py
Log:
Introduce correct refcount handling for (borrowed) exceptions.
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/api.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py Sat Mar 27 21:40:12 2010
@@ -136,10 +136,12 @@
raise
state = space.fromcache(State)
e.normalize_exception(space)
- state.exc_type = e.w_type
- state.exc_value = e.get_w_value(space)
+ state.set_exception(e.w_type, e.get_w_value(space))
return api_function.error_value
finally:
+ if api_function.borrowed:
+ state = space.fromcache(State)
+ state.last_container = 0
from pypy.module.cpyext.macros import Py_DECREF
for arg in to_decref:
Py_DECREF(space, arg)
@@ -322,7 +324,10 @@
@cpython_api([PyObject], lltype.Void, external=False)
def register_container(space, container):
state = space.fromcache(State)
- container_ptr = rffi.cast(ADDR, container)
+ if not container: # self-managed
+ container_ptr = -1
+ else:
+ container_ptr = rffi.cast(ADDR, container)
assert not state.last_container, "Last container was not fetched"
state.last_container = container_ptr
@@ -332,6 +337,8 @@
state.last_container = 0
if not container_ptr:
raise NullPointerException
+ if container_ptr == -1:
+ return
borrowees = state.borrow_mapping.get(container_ptr)
if borrowees is None:
state.borrow_mapping[container_ptr] = borrowees = {}
@@ -371,12 +378,10 @@
except OperationError, e:
failed = True
e.normalize_exception(space)
- state.exc_type = e.w_type
- state.exc_value = e.get_w_value(space)
+ state.set_exception(e.w_type, e.get_w_value(space))
except BaseException, e:
failed = True
- state.exc_type = space.w_SystemError
- state.exc_value = space.wrap(str(e))
+ state.set_exception(space.w_SystemError, space.wrap(str(e)))
import traceback
traceback.print_exc()
else:
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/pyerrors.py Sat Mar 27 21:40:12 2010
@@ -1,25 +1,25 @@
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.interpreter.error import OperationError
-from pypy.module.cpyext.api import cpython_api, PyObject, make_ref
+from pypy.module.cpyext.api import cpython_api, PyObject, make_ref,\
+ register_container
from pypy.module.cpyext.state import State
@cpython_api([PyObject, rffi.CCHARP], lltype.Void)
def PyErr_SetString(space, w_type, message_ptr):
message = rffi.charp2str(message_ptr)
state = space.fromcache(State)
- state.exc_type = w_type
- state.exc_value = space.call_function(w_type, space.wrap(message))
+ state.set_exception(w_type, space.wrap(message))
- at cpython_api([], PyObject)
+ at cpython_api([], PyObject, borrowed=True)
def PyErr_Occurred(space):
state = space.fromcache(State)
+ register_container(space, None)
return state.exc_value
@cpython_api([], lltype.Void)
def PyErr_Clear(space):
state = space.fromcache(State)
- state.exc_type = None
- state.exc_value = None
+ state.clear_exception()
@cpython_api([], lltype.Void)
def PyErr_BadInternalCall(space):
Modified: pypy/branch/cpython-extension/pypy/module/cpyext/state.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/state.py (original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/state.py Sat Mar 27 21:40:12 2010
@@ -1,4 +1,5 @@
from pypy.rlib.objectmodel import we_are_translated
+from pypy.rpython.lltypesystem import rffi, lltype
from pypy.lib.identity_dict import identity_dict
from pypy.interpreter.error import OperationError
from pypy.rpython.lltypesystem import lltype
@@ -19,12 +20,29 @@
self.exc_type = None
self.exc_value = None
+ def set_exception(self, w_type, w_value):
+ self.clear_exception()
+ self.exc_type = w_type
+ self.exc_value = w_value
+
+ def clear_exception(self):
+ from pypy.module.cpyext.macros import Py_DECREF
+ from pypy.module.cpyext.api import make_ref, ADDR
+ # handling of borrowed objects, remove when we have
+ # a weakkeydict
+ exc_value = make_ref(self.space, self.exc_value, borrowed=True)
+ if exc_value:
+ Py_DECREF(self.space, exc_value)
+ containee_ptr = rffi.cast(ADDR, exc_value)
+ del self.borrowed_objects[containee_ptr]
+ self.exc_type = None
+ self.exc_value = None
+
def check_and_raise_exception(self):
exc_value = self.exc_value
exc_type = self.exc_type
if exc_type is not None or exc_value is not None:
- self.exc_value = None
- self.exc_type = None
+ self.clear_exception()
op_err = OperationError(exc_type, exc_value)
raise op_err
More information about the Pypy-commit
mailing list