[pypy-commit] pypy struct-double: all the tests pass now

alex_gaynor noreply at buildbot.pypy.org
Sun Mar 4 01:21:28 CET 2012


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: struct-double
Changeset: r53156:65705b303582
Date: 2012-03-03 19:21 -0500
http://bitbucket.org/pypy/pypy/changeset/65705b303582/

Log:	all the tests pass now

diff --git a/pypy/rlib/rstring.py b/pypy/rlib/rstring.py
--- a/pypy/rlib/rstring.py
+++ b/pypy/rlib/rstring.py
@@ -3,7 +3,7 @@
 
 from pypy.annotation.model import (SomeObject, SomeString, s_None, SomeChar,
     SomeInteger, SomeUnicodeCodePoint, SomeUnicodeString, SomePtr, SomePBC,
-    SomeFloat)
+    SomeFloat, SomeSingleFloat)
 from pypy.rlib.rarithmetic import ovfcheck
 from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.rpython.lltypesystem import lltype
@@ -146,7 +146,7 @@
         return s_None
 
     def method_append_float(self, f):
-        assert isinstance(f, SomeFloat)
+        assert isinstance(f, SomeFloat) or isinstance(f, SomeSingleFloat)
         return s_None
 
     def method_getlength(self):
diff --git a/pypy/rpython/lltypesystem/rbuilder.py b/pypy/rpython/lltypesystem/rbuilder.py
--- a/pypy/rpython/lltypesystem/rbuilder.py
+++ b/pypy/rpython/lltypesystem/rbuilder.py
@@ -1,6 +1,6 @@
 from pypy.rlib import rgc, jit
-from pypy.rlib.objectmodel import enforceargs, keepalive_until_here
 from pypy.rlib.rarithmetic import ovfcheck
+from pypy.rlib.objectmodel import enforceargs, keepalive_until_here, specialize
 from pypy.rpython.annlowlevel import llstr
 from pypy.rpython.rptr import PtrRepr
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rstr
@@ -9,6 +9,7 @@
     string_repr, unichar_repr, unicode_repr)
 from pypy.rpython.rbuilder import AbstractStringBuilderRepr
 from pypy.tool.sourcetools import func_with_new_name
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
 
 # Think about heuristics below, maybe we can come up with something
 # better or at least compare it with list heuristics
@@ -117,6 +118,15 @@
 
     @staticmethod
     def ll_append_float(ll_builder, f):
+        StringBuilderRepr._append_float(ll_builder, f, float2memory)
+
+    @staticmethod
+    def ll_append_single_float(ll_builder, f):
+        StringBuilderRepr._append_float(ll_builder, f, singlefloat2memory)
+
+    @staticmethod
+    @specialize.argtype(1)
+    def _append_float(ll_builder, f, memory_func):
         T = lltype.typeOf(f)
         BUF_T = lltype.typeOf(ll_builder.buf).TO
 
@@ -127,7 +137,7 @@
 
         chars_offset = llmemory.offsetof(BUF_T, 'chars') + llmemory.itemoffsetof(BUF_T.chars, 0)
         array = llmemory.cast_ptr_to_adr(ll_builder.buf) + chars_offset + llmemory.sizeof(BUF_T.chars.OF) * used
-        rffi.cast(rffi.CArrayPtr(T), array)[0]
+        memory_func(f, rffi.cast(rffi.CCHARP, array))
         keepalive_until_here(ll_builder.buf)
         ll_builder.used += size
 
@@ -170,3 +180,39 @@
 
 unicodebuilder_repr = UnicodeBuilderRepr()
 stringbuilder_repr = StringBuilderRepr()
+
+
+eci = ExternalCompilationInfo(includes=['string.h'],
+                              post_include_bits=["""
+void pypy__float2memory(double x, char *p) {
+    memcpy(p, (char *)&x, sizeof(double));
+}
+void pypy__singlefloat2memory(float x, char *p) {
+    memcpy(p, (char *)&x, sizeof(float));
+}
+"""])
+
+def float2memory_emulator(f, c_ptr):
+    with lltype.scoped_alloc(rffi.CArray(lltype.Float), 1) as f_array:
+        f_array[0] = f
+        c_array = rffi.cast(rffi.CCHARP, f_array)
+        for i in range(rffi.sizeof(lltype.Float)):
+            c_ptr[i] = c_array[i]
+
+def singlefloat2memory_emulator(f, c_ptr):
+    with lltype.scoped_alloc(rffi.CArray(lltype.SingleFloat), 1) as f_array:
+        f_array[0] = f
+        c_array = rffi.cast(rffi.CCHARP, f_array)
+        for i in range(rffi.sizeof(lltype.SingleFloat)):
+            c_ptr[i] = c_array[i]
+
+float2memory = rffi.llexternal(
+    "pypy__float2memory", [lltype.Float, rffi.CCHARP], lltype.Void,
+    compilation_info=eci, _nowrapper=True, sandboxsafe=True,
+    _callable=float2memory_emulator
+)
+singlefloat2memory = rffi.llexternal(
+    "pypy__singlefloat2memory", [lltype.SingleFloat, rffi.CCHARP], lltype.Void,
+    compilation_info=eci, _nowrapper=True, sandboxsafe=True,
+    _callable=singlefloat2memory_emulator,
+)
\ No newline at end of file
diff --git a/pypy/rpython/ootypesystem/ootype.py b/pypy/rpython/ootypesystem/ootype.py
--- a/pypy/rpython/ootypesystem/ootype.py
+++ b/pypy/rpython/ootypesystem/ootype.py
@@ -1,10 +1,9 @@
 import py
 from py.builtin import set
-from pypy.rpython.lltypesystem.lltype import LowLevelType, Signed, Unsigned, Float, Char
-from pypy.rpython.lltypesystem.lltype import Bool, Void, UniChar, typeOf, \
-        Primitive, isCompatibleType, enforce, saferecursive, SignedLongLong, UnsignedLongLong
-from pypy.rpython.lltypesystem.lltype import frozendict
-from pypy.rpython.lltypesystem.lltype import identityhash
+from pypy.rpython.lltypesystem.lltype import (LowLevelType, Signed, Unsigned,
+    Float, SingleFloat, Char, Bool, Void, UniChar, typeOf, Primitive,
+    isCompatibleType, enforce, saferecursive, SignedLongLong, UnsignedLongLong,
+    frozendict, identityhash)
 from pypy.rlib.rarithmetic import intmask
 from pypy.rlib import objectmodel
 from pypy.tool.uid import uid
@@ -75,7 +74,7 @@
 
     def _example(self):
         return _class(ROOT)
-    
+
 Class = Class()
 
 class Instance(OOType):
@@ -111,7 +110,7 @@
 
     def __hash__(self):
         return object.__hash__(self)
-        
+
     def _defl(self):
         return self._null
 
@@ -153,7 +152,7 @@
             _, meth = self._lookup(name)
             if meth is not None:
                 raise TypeError("Cannot add field %r: method already exists" % name)
-        
+
             if self._superclass is not None:
                 if self._superclass._has_field(name):
                     raise TypeError("Field %r exists in superclass" % name)
@@ -161,7 +160,7 @@
             if type(defn) is not tuple:
                 if isinstance(defn, Meth):
                     raise TypeError("Attempting to store method in field")
-                
+
                 fields[name] = (defn, defn._defl())
             else:
                 ootype, default = defn
@@ -198,7 +197,7 @@
     def _init_instance(self, instance):
         if self._superclass is not None:
             self._superclass._init_instance(instance)
-        
+
         for name, (ootype, default) in self._fields.iteritems():
             instance.__dict__[name] = enforce(ootype, default)
 
@@ -512,6 +511,8 @@
             "ll_append_char": Meth([CHARTP], Void),
             "ll_append": Meth([STRINGTP], Void),
             "ll_build": Meth([], STRINGTP),
+            "ll_append_float": Meth([Float], Void),
+            "ll_append_single_float": Meth([SingleFloat], Void),
             "ll_getlength": Meth([], Signed),
             })
         self._setup_methods({})
@@ -612,7 +613,7 @@
     def __hash__(self):
         if self.ITEM is None:
             raise TypeError("Can't hash uninitialized List type.")
-        return BuiltinADTType.__hash__(self)    
+        return BuiltinADTType.__hash__(self)
 
     def __str__(self):
         return '%s(%s)' % (self.__class__.__name__,
@@ -624,7 +625,7 @@
     def _specialize(self, generic_types):
         ITEMTYPE = self._specialize_type(self.ITEM, generic_types)
         return self.__class__(ITEMTYPE)
-    
+
     def _defl(self):
         return self._null
 
@@ -643,7 +644,7 @@
     # placeholders for types
     # make sure that each derived class has his own SELFTYPE_T
     # placeholder, because we want backends to distinguish that.
-    
+
     SELFTYPE_T = object()
     ITEMTYPE_T = object()
     oopspec_name = 'list'
@@ -693,7 +694,7 @@
     def __hash__(self):
         if self.ITEM is None:
             raise TypeError("Can't hash uninitialized List type.")
-        return BuiltinADTType.__hash__(self)    
+        return BuiltinADTType.__hash__(self)
 
     def __str__(self):
         return '%s(%s)' % (self.__class__.__name__,
@@ -789,7 +790,7 @@
             return False
         if not self._is_initialized() or not other._is_initialized():
             return False # behave like a ForwardReference, i.e. compare by identity
-        return BuiltinADTType.__eq__(self, other) 
+        return BuiltinADTType.__eq__(self, other)
 
     def __ne__(self, other):
         return not (self == other)
@@ -811,7 +812,7 @@
         self._KEYTYPE = KEYTYPE
         self._VALUETYPE = VALUETYPE
         self._init_methods()
-                                           
+
 
 class CustomDict(Dict):
     def __init__(self, KEYTYPE=None, VALUETYPE=None):
@@ -870,7 +871,7 @@
         KEYTYPE = self._specialize_type(self._KEYTYPE, generic_types)
         VALUETYPE = self._specialize_type(self._VALUETYPE, generic_types)
         return self.__class__(KEYTYPE, VALUETYPE)
-    
+
 # ____________________________________________________________
 
 class _object(object):
@@ -942,7 +943,7 @@
 Class._null = nullruntimeclass
 
 class _instance(object):
-    
+
     def __init__(self, INSTANCE):
         self.__dict__["_TYPE"] = INSTANCE
         INSTANCE._init_instance(self)
@@ -957,7 +958,7 @@
         DEFINST, meth = self._TYPE._lookup(name)
         if meth is not None:
             return meth._bound(DEFINST, self)
-        
+
         self._TYPE._check_field(name)
 
         return self.__dict__[name]
@@ -997,7 +998,7 @@
         return self
 
     _enforce = _upcast
-    
+
     def _downcast(self, INSTANCE):
         assert instanceof(self, INSTANCE)
         return self
@@ -1022,7 +1023,7 @@
         def __getattribute__(self, name):
             if name.startswith("_"):
                 return object.__getattribute__(self, name)
-        
+
             raise RuntimeError("Access to field in null object")
 
         def __setattr__(self, name, value):
@@ -1188,7 +1189,7 @@
 
    def __ne__(self, other):
        return not (self == other)
-   
+
    def __hash__(self):
        return hash(frozendict(self.__dict__))
 
@@ -1226,7 +1227,7 @@
 
    def __eq__(self, other):
        return self is other
-   
+
    def __hash__(self):
        return id(self)
 
@@ -1250,7 +1251,7 @@
 
 class _meth(_callable):
     _bound_class = _bound_meth
-    
+
     def __init__(self, METHOD, **attrs):
         assert isinstance(METHOD, Meth)
         _callable.__init__(self, METHOD, **attrs)
@@ -1336,7 +1337,7 @@
             return True
         else:
             return False
-    
+
     def annotation_to_lltype(cls, ann):
         from pypy.annotation import model as annmodel
         return annmodel.annotation_to_lltype(ann)
@@ -1541,6 +1542,14 @@
         assert isinstance(s, _string)
         self._buf.append(s._str)
 
+    def ll_append_float(self, f):
+        import struct
+        self._buf.append(struct.pack("d", f))
+
+    def ll_append_single_float(self, f):
+        import struct
+        self._buf.append(struct.pack("f", f))
+
     def ll_build(self):
         if self._TYPE is StringBuilder:
             return make_string(''.join(self._buf))
@@ -1602,7 +1611,7 @@
         return len(self._list)
 
     def _ll_resize_ge(self, length):
-        # NOT_RPYTHON        
+        # NOT_RPYTHON
         if len(self._list) < length:
             diff = length - len(self._list)
             self._list += [self._TYPE.ITEM._defl()] * diff
@@ -1638,7 +1647,7 @@
 class _null_list(_null_mixin(_list), _list):
 
     def __init__(self, LIST):
-        self.__dict__["_TYPE"] = LIST 
+        self.__dict__["_TYPE"] = LIST
 
 class _array(_builtin_type):
     def __init__(self, ARRAY, length):
@@ -1671,7 +1680,7 @@
 class _null_array(_null_mixin(_array), _array):
 
     def __init__(self, ARRAY):
-        self.__dict__["_TYPE"] = ARRAY 
+        self.__dict__["_TYPE"] = ARRAY
 
 class _dict(_builtin_type):
     def __init__(self, DICT):
@@ -1769,7 +1778,7 @@
     def ll_go_next(self):
         # NOT_RPYTHON
         self._check_stamp()
-        self._index += 1        
+        self._index += 1
         if self._index >= len(self._items):
             return False
         else:
@@ -1780,7 +1789,7 @@
         self._check_stamp()
         assert 0 <= self._index < len(self._items)
         return self._items[self._index][0]
-    
+
     def ll_current_value(self):
         # NOT_RPYTHON
         self._check_stamp()
@@ -1840,7 +1849,7 @@
 class _null_record(_null_mixin(_record), _record):
 
     def __init__(self, RECORD):
-        self.__dict__["_TYPE"] = RECORD 
+        self.__dict__["_TYPE"] = RECORD
 
 
 def new(TYPE):
@@ -1932,7 +1941,7 @@
 
 def ooupcast(INSTANCE, instance):
     return instance._upcast(INSTANCE)
-    
+
 def oodowncast(INSTANCE, instance):
     return instance._downcast(INSTANCE)
 
@@ -1959,7 +1968,7 @@
 def oostring(obj, base):
     """
     Convert char, int, float, instances and str to str.
-    
+
     Base is used only for formatting int: for other types is ignored
     and should be set to -1. For int only base 8, 10 and 16 are
     supported.
diff --git a/pypy/rpython/ootypesystem/rbuilder.py b/pypy/rpython/ootypesystem/rbuilder.py
--- a/pypy/rpython/ootypesystem/rbuilder.py
+++ b/pypy/rpython/ootypesystem/rbuilder.py
@@ -9,7 +9,7 @@
 class BaseBuilderRepr(AbstractStringBuilderRepr):
     def empty(self):
         return ootype.null(self.lowleveltype)
-    
+
     @classmethod
     def ll_new(cls, init_size):
         if init_size < 0 or init_size > MAX:
@@ -40,6 +40,14 @@
             builder.ll_append_char(char)
 
     @staticmethod
+    def ll_append_float(builder, f):
+        builder.ll_append_float(f)
+
+    @staticmethod
+    def ll_append_single_float(builder, f):
+        builder.ll_append_single_float(f)
+
+    @staticmethod
     def ll_build(builder):
         return builder.ll_build()
 
diff --git a/pypy/rpython/rbuilder.py b/pypy/rpython/rbuilder.py
--- a/pypy/rpython/rbuilder.py
+++ b/pypy/rpython/rbuilder.py
@@ -1,5 +1,6 @@
 from pypy.annotation.model import SomeChar, SomeUnicodeCodePoint
 from pypy.rlib.rstring import INIT_SIZE
+from pypy.rpython.error import TyperError
 from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.rmodel import Repr
 
@@ -40,9 +41,14 @@
         return hop.gendirectcall(self.ll_append_charpsize, *vlist)
 
     def rtype_method_append_float(self, hop):
-        vlist = hop.inputargs(self, lltype.Float)
+        try:
+            vlist = hop.inputargs(self, lltype.Float)
+            target = self.ll_append_float
+        except TyperError:
+            vlist = hop.inputargs(self, lltype.SingleFloat)
+            target = self.ll_append_single_float
         hop.exception_cannot_occur()
-        return hop.gendirectcall(self.ll_append_float, *vlist)
+        return hop.gendirectcall(target, *vlist)
 
     def rtype_method_getlength(self, hop):
         vlist = hop.inputargs(self)
diff --git a/pypy/rpython/test/test_rbuilder.py b/pypy/rpython/test/test_rbuilder.py
--- a/pypy/rpython/test/test_rbuilder.py
+++ b/pypy/rpython/test/test_rbuilder.py
@@ -1,6 +1,7 @@
 from __future__ import with_statement
 import py
 
+from pypy.rlib.rarithmetic import r_singlefloat
 from pypy.rlib.rstring import StringBuilder, UnicodeBuilder
 from pypy.rpython.annlowlevel import llstr, hlstr
 from pypy.rpython.lltypesystem import rffi


More information about the pypy-commit mailing list