Author: Antonio Cuni <anto.c...@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 +@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 +@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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit