Author: Antonio Cuni <[email protected]>
Branch: faster-rstruct-2
Changeset: r91233:6d4406afffe5
Date: 2017-05-10 19:04 +0200
http://bitbucket.org/pypy/pypy/changeset/6d4406afffe5/
Log: test&fix native's pack_{float,double}. In the meantime, reduce some
code duplication between nativefmttable.py and ieee.py
diff --git a/rpython/rlib/rstruct/ieee.py b/rpython/rlib/rstruct/ieee.py
--- a/rpython/rlib/rstruct/ieee.py
+++ b/rpython/rlib/rstruct/ieee.py
@@ -264,9 +264,13 @@
sign = r_ulonglong(sign)
return (mant, (sign << BITS - MANT_DIG - 1) | exp)
[email protected]_safe
+
def pack_float(result, pos, x, size, be):
unsigned = float_pack(x, size)
+ pack_float_to_buffer(result, pos, unsigned, size, be)
+
[email protected]_safe
+def pack_float_to_buffer(result, pos, unsigned, size, be):
if be:
# write in reversed order
for i in range(size):
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
@@ -10,6 +10,7 @@
from rpython.rlib.rstruct import standardfmttable as std
from rpython.rlib.rstruct.standardfmttable import native_is_bigendian
from rpython.rlib.rstruct.error import StructError
+from rpython.rlib.rstruct.ieee import pack_float_to_buffer
from rpython.rlib.unroll import unrolling_iterable
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rtyper.tool import rffi_platform
@@ -26,35 +27,19 @@
# ____________________________________________________________
-range_8_unroll = unrolling_iterable(list(reversed(range(8))))
-range_4_unroll = unrolling_iterable(list(reversed(range(4))))
-
def pack_double(fmtiter):
doubleval = fmtiter.accept_float_arg()
value = longlong2float.float2longlong(doubleval)
- if fmtiter.bigendian:
- for i in range_8_unroll:
- x = (value >> (8*i)) & 0xff
- fmtiter.result.append(chr(x))
- else:
- for i in range_8_unroll:
- fmtiter.result.append(chr(value & 0xff))
- value >>= 8
-
+ pack_float_to_buffer(fmtiter.result, fmtiter.pos, value, 8,
fmtiter.bigendian)
+ fmtiter.advance(8)
def pack_float(fmtiter):
doubleval = fmtiter.accept_float_arg()
floatval = r_singlefloat(doubleval)
value = longlong2float.singlefloat2uint(floatval)
value = widen(value)
- if fmtiter.bigendian:
- for i in range_4_unroll:
- x = (value >> (8*i)) & 0xff
- fmtiter.result.append(chr(x))
- else:
- for i in range_4_unroll:
- fmtiter.result.append(chr(value & 0xff))
- value >>= 8
+ pack_float_to_buffer(fmtiter.result, fmtiter.pos, value, 4,
fmtiter.bigendian)
+ fmtiter.advance(4)
# ____________________________________________________________
#
diff --git a/rpython/rlib/rstruct/test/test_pack.py
b/rpython/rlib/rstruct/test/test_pack.py
--- a/rpython/rlib/rstruct/test/test_pack.py
+++ b/rpython/rlib/rstruct/test/test_pack.py
@@ -1,5 +1,5 @@
import pytest
-from rpython.rlib.rstruct import standardfmttable
+from rpython.rlib.rstruct import standardfmttable, nativefmttable
from rpython.rlib.mutbuffer import MutableStringBuffer
import struct
@@ -40,26 +40,25 @@
implement struct.pack in pypy/module/struct
"""
- endianess = None
- fmttable = standardfmttable.standard_fmttable
+ bigendian = None
+ fmt_prefix = None
+ fmttable = None
def mypack(self, fmt, value):
- bigendian = self.endianess == '>'
size = struct.calcsize(fmt)
- fake_fmtiter = FakeFormatIter(bigendian, size, value)
+ fake_fmtiter = FakeFormatIter(self.bigendian, size, value)
attrs = self.fmttable[fmt]
pack = attrs['pack']
pack(fake_fmtiter)
return fake_fmtiter.finish()
def mypack_fn(self, func, size, arg, value):
- bigendian = self.endianess == '>'
- fmtiter = FakeFormatIter(bigendian, size, value)
+ fmtiter = FakeFormatIter(self.bigendian, size, value)
func(fmtiter, arg)
return fmtiter.finish()
def check(self, fmt, value):
- expected = struct.pack(self.endianess+fmt, value)
+ expected = struct.pack(self.fmt_prefix+fmt, value)
got = self.mypack(fmt, value)
assert got == expected
@@ -108,8 +107,16 @@
class TestPackLittleEndian(BaseTestPack):
- endianess = '<'
-
+ bigendian = False
+ fmt_prefix = '<'
+ fmttable = standardfmttable.standard_fmttable
class TestPackBigEndian(BaseTestPack):
- endianess = '>'
+ bigendian = True
+ fmt_prefix = '>'
+ fmttable = standardfmttable.standard_fmttable
+
+class TestNative(BaseTestPack):
+ bigendian = nativefmttable.native_is_bigendian
+ fmt_prefix = '@'
+ fmttable = nativefmttable.native_fmttable
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit