[pypy-commit] pypy null_byte_after_str: Cancel a fragile dependency with details of space.str_w(), and instead
arigo
pypy.commits at gmail.com
Tue Aug 2 09:26:07 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: null_byte_after_str
Changeset: r85987:2977ce236abb
Date: 2016-08-02 15:27 +0200
http://bitbucket.org/pypy/pypy/changeset/2977ce236abb/
Log: Cancel a fragile dependency with details of space.str_w(), and
instead do it all inside W_CTypeFunc._call
diff --git a/pypy/module/_cffi_backend/ctypefunc.py b/pypy/module/_cffi_backend/ctypefunc.py
--- a/pypy/module/_cffi_backend/ctypefunc.py
+++ b/pypy/module/_cffi_backend/ctypefunc.py
@@ -157,11 +157,13 @@
mustfree_max_plus_1 = 0
buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
try:
+ keepalives = [None] * len(args_w) # None or strings
for i in range(len(args_w)):
data = rffi.ptradd(buffer, cif_descr.exchange_args[i])
w_obj = args_w[i]
argtype = self.fargs[i]
- if argtype.convert_argument_from_object(data, w_obj):
+ if argtype.convert_argument_from_object(data, w_obj,
+ keepalives, i):
# argtype is a pointer type, and w_obj a list/tuple/str
mustfree_max_plus_1 = i + 1
@@ -181,7 +183,8 @@
if flag == 1:
lltype.free(raw_cdata, flavor='raw')
elif flag >= 4:
- value = args_w[i].str_w(space)
+ value = keepalives[i]
+ assert value is not None
rffi.free_nonmovingbuffer(value, raw_cdata, chr(flag))
lltype.free(buffer, flavor='raw')
keepalive_until_here(args_w)
diff --git a/pypy/module/_cffi_backend/ctypeobj.py b/pypy/module/_cffi_backend/ctypeobj.py
--- a/pypy/module/_cffi_backend/ctypeobj.py
+++ b/pypy/module/_cffi_backend/ctypeobj.py
@@ -83,7 +83,7 @@
raise oefmt(space.w_TypeError, "cannot initialize cdata '%s'",
self.name)
- def convert_argument_from_object(self, cdata, w_ob):
+ def convert_argument_from_object(self, cdata, w_ob, keepalives, i):
self.convert_from_object(cdata, w_ob)
return False
diff --git a/pypy/module/_cffi_backend/ctypeptr.py b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -261,13 +261,12 @@
else:
return lltype.nullptr(rffi.CCHARP.TO)
- def _prepare_pointer_call_argument(self, w_init, cdata):
+ def _prepare_pointer_call_argument(self, w_init, cdata, keepalives, i):
space = self.space
if self.accept_str and space.isinstance_w(w_init, space.w_str):
# special case to optimize strings passed to a "char *" argument
- # WARNING: this relies on the fact that w_init.str_w() returns
- # always the same object for the same w_init!
value = w_init.str_w(space)
+ keepalives[i] = value
buf, buf_flag = rffi.get_nonmovingbuffer_final_null(value)
rffi.cast(rffi.CCHARPP, cdata)[0] = buf
return ord(buf_flag) # 4, 5 or 6
@@ -307,10 +306,11 @@
rffi.cast(rffi.CCHARPP, cdata)[0] = result
return 1
- def convert_argument_from_object(self, cdata, w_ob):
+ def convert_argument_from_object(self, cdata, w_ob, keepalives, i):
from pypy.module._cffi_backend.ctypefunc import set_mustfree_flag
result = (not isinstance(w_ob, cdataobj.W_CData) and
- self._prepare_pointer_call_argument(w_ob, cdata))
+ self._prepare_pointer_call_argument(w_ob, cdata,
+ keepalives, i))
if result == 0:
self.convert_from_object(cdata, w_ob)
set_mustfree_flag(cdata, result)
diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -451,9 +451,6 @@
return self._value
def str_w(self, space):
- # WARNING: _cffi_backend/ctypeptr.py depends on the fact that
- # w_obj.str_w() called twice on the same object returns the
- # exact same string object!
return self._value
def buffer_w(self, space, flags):
More information about the pypy-commit
mailing list