[pypy-commit] pypy faster-rstruct: merge heads

antocuni noreply at buildbot.pypy.org
Mon Nov 23 18:58:30 EST 2015


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: faster-rstruct
Changeset: r80875:c9ab4be2f15b
Date: 2015-11-24 00:59 +0100
http://bitbucket.org/pypy/pypy/changeset/c9ab4be2f15b/

Log:	merge heads

diff --git a/rpython/rlib/rstruct/standardfmttable.py b/rpython/rlib/rstruct/standardfmttable.py
--- a/rpython/rlib/rstruct/standardfmttable.py
+++ b/rpython/rlib/rstruct/standardfmttable.py
@@ -12,7 +12,7 @@
 from rpython.rlib.rstruct import ieee
 from rpython.rlib.rstruct.error import StructError, StructOverflowError
 from rpython.rlib.unroll import unrolling_iterable
-from rpython.rlib.strstorage import str_storage_getitem
+from rpython.rlib.strstorage import str_storage_getitem, str_storage_supported
 from rpython.rlib import rarithmetic
 from rpython.rtyper.lltypesystem import rffi
 
@@ -185,6 +185,13 @@
             data = fmtiter.read(size)
             fmtiter.appendobj(ieee.unpack_float(data, fmtiter.bigendian))
             return
+        if not str_storage_supported(TYPE):
+            # this happens e.g. on win32 and ARM32: we cannot read the string
+            # content as an array of doubles because it's not properly
+            # aligned. But we can read a longlong and convert to float
+            assert TYPE == rffi.DOUBLE
+            assert rffi.sizeof(TYPE) == 8
+            return unpack_longlong2float(fmtiter)
         try:
             # fast path
             val = unpack_fastpath(TYPE)(fmtiter)
@@ -195,6 +202,16 @@
         fmtiter.appendobj(float(val))
     return unpack_ieee
 
+ at specialize.argtype(0)
+def unpack_longlong2float(fmtiter):
+    from rpython.rlib.rstruct.runpack import runpack
+    from rpython.rlib.longlong2float import longlong2float
+    s = fmtiter.read(8)
+    llval = runpack('q', s) # this is a bit recursive, I know
+    doubleval = longlong2float(llval)
+    fmtiter.appendobj(doubleval)
+
+
 unpack_double = make_ieee_unpacker(rffi.DOUBLE)
 unpack_float = make_ieee_unpacker(rffi.FLOAT)
 
@@ -229,7 +246,7 @@
 
     @specialize.argtype(0)
     def unpack_int_fastpath_maybe(fmtiter):
-        if fmtiter.bigendian != native_is_bigendian:
+        if fmtiter.bigendian != native_is_bigendian or not str_storage_supported(TYPE):
             return False
         try:
             intvalue = unpack_fastpath(TYPE)(fmtiter)
diff --git a/rpython/rlib/strstorage.py b/rpython/rlib/strstorage.py
--- a/rpython/rlib/strstorage.py
+++ b/rpython/rlib/strstorage.py
@@ -32,6 +32,18 @@
 from rpython.rtyper.annlowlevel import llstr
 from rpython.rlib.objectmodel import specialize
 
+def compute_offsetof(TP, field):
+    """
+    NOT_RPYTHON
+    """
+    obj = lltype.malloc(TP, 0)
+    baseadr = llmemory.cast_ptr_to_adr(obj)
+    offset = llmemory.offsetof(TP, field)
+    interioradr = baseadr + offset
+    return (llmemory.cast_adr_to_int(interioradr, 'forced') -
+            llmemory.cast_adr_to_int(baseadr, 'forced'))
+
+
 @specialize.memo()
 def rpy_string_as_type(TP):
     # sanity check that STR is actually what we think it is
@@ -42,8 +54,19 @@
     STR_AS_TP = lltype.GcStruct('rpy_string_as_%s' % TP,
                                 ('hash',  lltype.Signed),
                                 ('chars', lltype.Array(TP, hints={'immutable': True})))
+    # sanity check
+    assert compute_offsetof(STR, 'chars') == compute_offsetof(STR_AS_TP, 'chars')
     return STR_AS_TP
 
+ at specialize.memo()
+def str_storage_supported(TP):
+    try:
+        rpy_string_as_type(TP)
+    except AssertionError:
+        return False
+    else:
+        return True
+
 @specialize.ll()
 def str_storage_getitem(TP, s, index):
     STR_AS_TP = rpy_string_as_type(TP)
diff --git a/rpython/rlib/test/test_strstorage.py b/rpython/rlib/test/test_strstorage.py
--- a/rpython/rlib/test/test_strstorage.py
+++ b/rpython/rlib/test/test_strstorage.py
@@ -1,7 +1,7 @@
 import py
 import struct
 from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.rlib.strstorage import str_storage_getitem
+from rpython.rlib.strstorage import str_storage_getitem, str_storage_supported
 from rpython.rlib.rarithmetic import r_singlefloat
 from rpython.rtyper.test.tool import BaseRtypingTest
 
@@ -22,6 +22,8 @@
         assert int(x) == 43
 
     def test_float(self):
+        if not str_storage_supported(lltype.Float):
+            py.test.skip('str_storage_getitem(lltype.Float) not supported on this machine')
         buf = struct.pack('@dd', 12.3, 45.6)
         size = struct.calcsize('@d')
         assert self.str_storage_getitem(lltype.Float, buf, 0) == 12.3


More information about the pypy-commit mailing list