Author: Antonio Cuni <[email protected]>
Branch: faster-rstruct
Changeset: r80814:8f216a415954
Date: 2015-11-21 11:34 +0100
http://bitbucket.org/pypy/pypy/changeset/8f216a415954/
Log: there is no distinction between native and standard float/double
formats: the Python struct module requires that the format is
ieee754 in both cases. However, in case our platform DOES support
ieee754, we can directly convert the value from the memory. The very
slow path defined in ieee.py is used only for obscure platforms
which do not use native ieee754 floats, or in case we require a
differend endianess
diff --git a/rpython/rlib/rstruct/nativefmttable.py
b/rpython/rlib/rstruct/nativefmttable.py
--- a/rpython/rlib/rstruct/nativefmttable.py
+++ b/rpython/rlib/rstruct/nativefmttable.py
@@ -8,8 +8,7 @@
from rpython.rlib.objectmodel import specialize
from rpython.rlib.rarithmetic import r_singlefloat, widen
from rpython.rlib.rstruct import standardfmttable as std
-from rpython.rlib.rstruct.standardfmttable import (native_is_bigendian,
unpack_fastpath,
- CannotUnpack)
+from rpython.rlib.rstruct.standardfmttable import native_is_bigendian
from rpython.rlib.rstruct.error import StructError
from rpython.rlib.unroll import unrolling_iterable
from rpython.rlib.strstorage import str_storage_getitem
@@ -43,16 +42,6 @@
fmtiter.result.append(chr(value & 0xff))
value >>= 8
[email protected](0)
-def unpack_double(fmtiter):
- try:
- doubleval = unpack_fastpath(rffi.DOUBLE)(fmtiter)
- except CannotUnpack:
- # slow path, take the slice
- input = fmtiter.read(sizeof_double)
- doubleval = str_storage_getitem(rffi.DOUBLE, input, 0)
- #
- fmtiter.appendobj(doubleval)
def pack_float(fmtiter):
doubleval = fmtiter.accept_float_arg()
@@ -68,16 +57,6 @@
fmtiter.result.append(chr(value & 0xff))
value >>= 8
[email protected](0)
-def unpack_float(fmtiter):
- try:
- floatval = unpack_fastpath(rffi.FLOAT)(fmtiter)
- except CannotUnpack:
- input = fmtiter.read(sizeof_float)
- floatval = str_storage_getitem(rffi.FLOAT, input, 0)
- doubleval = float(floatval) # convert from r_singlefloat to rpython's float
- fmtiter.appendobj(doubleval)
-
# ____________________________________________________________
#
# Use rffi_platform to get the native sizes and alignments from the C compiler
@@ -134,10 +113,10 @@
if fmtchar == 'f':
pack = pack_float
- unpack = unpack_float
+ unpack = std.unpack_float
elif fmtchar == 'd':
pack = pack_double
- unpack = unpack_double
+ unpack = std.unpack_double
elif fmtchar == '?':
pack = std.pack_bool
unpack = std.unpack_bool
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
@@ -17,6 +17,7 @@
from rpython.rtyper.lltypesystem import rffi
native_is_bigendian = struct.pack("=i", 1) == struct.pack(">i", 1)
+native_is_ieee754 = float.__getformat__('double').startswith('IEEE')
def pack_pad(fmtiter, count):
fmtiter.result.append_multiple_char('\x00', count)
@@ -175,12 +176,27 @@
end = count
fmtiter.appendobj(data[1:end])
-def make_float_unpacker(size):
+def make_ieee_unpacker(TYPE):
@specialize.argtype(0)
- def unpacker(fmtiter):
- data = fmtiter.read(size)
- fmtiter.appendobj(ieee.unpack_float(data, fmtiter.bigendian))
- return unpacker
+ def unpack_ieee(fmtiter):
+ size = rffi.sizeof(TYPE)
+ if fmtiter.bigendian != native_is_bigendian or not native_is_ieee754:
+ # fallback to the very slow unpacking code in ieee.py
+ data = fmtiter.read(size)
+ fmtiter.appendobj(ieee.unpack_float(data, fmtiter.bigendian))
+ return
+ try:
+ # fast path
+ val = unpack_fastpath(TYPE)(fmtiter)
+ except CannotUnpack:
+ # slow path, take the slice
+ input = fmtiter.read(size)
+ val = str_storage_getitem(TYPE, input, 0)
+ fmtiter.appendobj(float(val))
+ return unpack_ieee
+
+unpack_double = make_ieee_unpacker(rffi.DOUBLE)
+unpack_float = make_ieee_unpacker(rffi.FLOAT)
# ____________________________________________________________
@@ -267,9 +283,9 @@
'p':{ 'size' : 1, 'pack' : pack_pascal, 'unpack' : unpack_pascal,
'needcount' : True },
'f':{ 'size' : 4, 'pack' : make_float_packer(4),
- 'unpack' : make_float_unpacker(4)},
+ 'unpack' : unpack_float},
'd':{ 'size' : 8, 'pack' : make_float_packer(8),
- 'unpack' : make_float_unpacker(8)},
+ 'unpack' : unpack_double},
'?':{ 'size' : 1, 'pack' : pack_bool, 'unpack' : unpack_bool},
}
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit