Author: Richard Plangger <[email protected]>
Branch: strbuf-as-buffer
Changeset: r88982:15b144ea1d4d
Date: 2016-12-09 12:04 +0100
http://bitbucket.org/pypy/pypy/changeset/15b144ea1d4d/
Log: a new approach to get the raw address to a string
diff --git a/rpython/rlib/buffer.py b/rpython/rlib/buffer.py
--- a/rpython/rlib/buffer.py
+++ b/rpython/rlib/buffer.py
@@ -78,15 +78,12 @@
return [1]
class StringBuffer(Buffer):
- __slots__ = ['value', 'charlist']
+ __slots__ = ['value', '__weakref__']
_immutable_ = True
def __init__(self, value):
self.value = value
self.readonly = True
- # the not initialized list of chars, copied from value
- # as soon as get_raw_address is called
- self.charlist = None
def getlength(self):
return len(self.value)
@@ -111,12 +108,8 @@
return Buffer.getslice(self, start, stop, step, size)
def get_raw_address(self):
- if not self.charlist:
- data = [c for c in self.value]
- self.charlist = resizable_list_supporting_raw_ptr(data)
- return nonmoving_raw_ptr_for_resizable_list(self.charlist)
-
-
+ from rpython.rtyper.lltypesystem import rffi
+ return rffi.get_raw_address_of_string(self, self.value)
class SubBuffer(Buffer):
__slots__ = ['buffer', 'offset', 'size']
diff --git a/rpython/rtyper/lltypesystem/rffi.py
b/rpython/rtyper/lltypesystem/rffi.py
--- a/rpython/rtyper/lltypesystem/rffi.py
+++ b/rpython/rtyper/lltypesystem/rffi.py
@@ -754,6 +754,53 @@
SIGNED = lltype.Signed
SIGNEDP = lltype.Ptr(lltype.Array(SIGNED, hints={'nolength': True}))
+
+class RawBytes(object):
+ # literal copy of _cffi_backend/func.py
+ def __init__(self, string):
+ self.ptr = str2charp(string, track_allocation=False)
+ def __del__(self):
+ free_charp(self.ptr, track_allocation=False)
+
+from rpython.rlib import rweakref
+from rpython.rlib.buffer import Buffer
+_STR_WDICT = rweakref.RWeakKeyDictionary(Buffer, RawBytes)
+
[email protected]_look_inside
+def get_raw_address_of_string(key, string):
+ """Returns a 'char *' that is valid as long as the key object is alive.
+ Two calls to to this function are guaranteed to return the same pointer.
+
+ The extra parameter key is necessary to create a weak reference.
+ The buffer of the returned pointer (if object is young) lives as long
+ as key is alive. If key goes out of scope, the buffer will eventually
+ be freed. `string` cannot go out of scope until the RawBytes object
+ referencing it goes out of scope.
+ """
+ from rpython.rtyper.annlowlevel import llstr
+ from rpython.rtyper.lltypesystem.rstr import STR
+ from rpython.rtyper.lltypesystem import llmemory
+ from rpython.rlib import rgc
+
+ global _STR_WDICT
+ rawbytes = _STR_WDICT.get(key)
+ if rawbytes is None:
+ if we_are_translated() and not rgc.can_move(string):
+ lldata = llstr(string)
+ data_start = (llmemory.cast_ptr_to_adr(lldata) +
+ offsetof(STR, 'chars') +
+ llmemory.itemoffsetof(STR.chars, 0))
+ data_start = cast(CCHARP, data_start)
+ data_start[len(string)] = '\x00' # write the final extra null
+ return data_start
+ rawbytes = RawBytes(string)
+ _STR_WDICT.set(key, rawbytes)
+ return rawbytes.ptr
+
+
+
+
+
# various type mapping
# conversions between str and char*
@@ -876,6 +923,7 @@
get_nonmovingbuffer._always_inline_ = 'try' # get rid of the returned tuple
get_nonmovingbuffer._annenforceargs_ = [strtype]
+
@jit.dont_look_inside
def get_nonmovingbuffer_final_null(data):
tup = get_nonmovingbuffer(data)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit