[pypy-svn] r79563 - pypy/branch/fast-forward/lib_pypy/_ctypes
afa at codespeak.net
afa at codespeak.net
Fri Nov 26 16:31:07 CET 2010
Author: afa
Date: Fri Nov 26 16:31:05 2010
New Revision: 79563
Modified:
pypy/branch/fast-forward/lib_pypy/_ctypes/basics.py
pypy/branch/fast-forward/lib_pypy/_ctypes/builtin.py
pypy/branch/fast-forward/lib_pypy/_ctypes/pointer.py
Log:
Another common potential crasher:
cast() should keep the original object alive, and make a copy of its keepalives.
Remove _CData_value() this is a dangerous function when the value is a string:
the buffer may be freed as soon as the function returns!
Modified: pypy/branch/fast-forward/lib_pypy/_ctypes/basics.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/_ctypes/basics.py (original)
+++ pypy/branch/fast-forward/lib_pypy/_ctypes/basics.py Fri Nov 26 16:31:05 2010
@@ -46,12 +46,6 @@
else:
return self.from_param(as_parameter)
- def _CData_value(self, value):
- cobj = self.from_param(value)
- # we don't care here if this stuff will live afterwards, as we're
- # interested only in value anyway
- return cobj._get_buffer_value()
-
def _CData_output(self, resbuffer, base=None, index=-1):
#assert isinstance(resbuffer, _rawffi.ArrayInstance)
"""Used when data exits ctypes and goes into user code.
Modified: pypy/branch/fast-forward/lib_pypy/_ctypes/builtin.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/_ctypes/builtin.py (original)
+++ pypy/branch/fast-forward/lib_pypy/_ctypes/builtin.py Fri Nov 26 16:31:05 2010
@@ -11,7 +11,8 @@
def _string_at_addr(addr, lgt):
# address here can be almost anything
import ctypes
- arg = ctypes.c_void_p._CData_value(addr)
+ cobj = ctypes.c_void_p.from_param(addr)
+ arg = cobj._get_buffer_value()
return _rawffi.charp2rawstring(arg, lgt)
def set_conversion_mode(encoding, errors):
@@ -22,5 +23,6 @@
def _wstring_at_addr(addr, lgt):
import ctypes
- arg = ctypes.c_void_p._CData_value(addr)
+ cobj = ctypes.c_void_p.from_param(addr)
+ arg = cobj._get_buffer_value()
return _rawffi.wcharp2rawunicode(arg, lgt)
Modified: pypy/branch/fast-forward/lib_pypy/_ctypes/pointer.py
==============================================================================
--- pypy/branch/fast-forward/lib_pypy/_ctypes/pointer.py (original)
+++ pypy/branch/fast-forward/lib_pypy/_ctypes/pointer.py Fri Nov 26 16:31:05 2010
@@ -1,7 +1,8 @@
import _rawffi
from _ctypes.basics import _CData, _CDataMeta, cdata_from_address
-from _ctypes.basics import sizeof, byref, keepalive_key
+from _ctypes.basics import keepalive_key, store_reference, ensure_objects
+from _ctypes.basics import sizeof, byref
from _ctypes.array import Array, array_get_slice_params, array_slice_getitem,\
array_slice_setitem
@@ -102,7 +103,10 @@
return self._type_._CData_output(self._subarray(index), self, index)
def __setitem__(self, index, value):
- self._subarray(index)[0] = self._type_._CData_value(value)
+ cobj = self._type_.from_param(value)
+ if ensure_objects(cobj) is not None:
+ store_reference(self, index, cobj._objects)
+ self._subarray(index)[0] = cobj._get_buffer_value()
def __nonzero__(self):
return self._buffer[0] != 0
@@ -113,31 +117,34 @@
if not (isinstance(tp, _CDataMeta) and tp._is_pointer_like()):
raise TypeError("cast() argument 2 must be a pointer type, not %s"
% (tp,))
- if isinstance(obj, Array):
- ptr = tp.__new__(tp)
- ptr._buffer = tp._ffiarray(1, autofree=True)
- ptr._buffer[0] = obj._buffer
- return ptr
if isinstance(obj, (int, long)):
result = tp()
result._buffer[0] = obj
return result
- if obj is None:
+ elif obj is None:
result = tp()
return result
- if not (isinstance(obj, _CData) and type(obj)._is_pointer_like()):
+ elif isinstance(obj, Array):
+ ptr = tp.__new__(tp)
+ ptr._buffer = tp._ffiarray(1, autofree=True)
+ ptr._buffer[0] = obj._buffer
+ result = ptr
+ elif not (isinstance(obj, _CData) and type(obj)._is_pointer_like()):
raise TypeError("cast() argument 1 must be a pointer, not %s"
% (type(obj),))
- result = tp()
+ else:
+ result = tp()
+ result._buffer[0] = obj._buffer[0]
# The casted objects '_objects' member:
- # It must certainly contain the source objects one.
+ # From now on, both objects will use the same dictionary
+ # It must certainly contain the source objects
# It must contain the source object itself.
if obj._ensure_objects() is not None:
- result._objects = {keepalive_key(0): obj._objects,
- keepalive_key(1): obj}
+ result._objects = obj._objects
+ if isinstance(obj._objects, dict):
+ result._objects[id(obj)] = obj
- result._buffer[0] = obj._buffer[0]
return result
def POINTER(cls):
More information about the Pypy-commit
mailing list