[pypy-svn] r76599 - in pypy/branch/fast-ctypes: . lib-python lib_pypy pypy/jit/backend/x86 pypy/jit/backend/x86/test pypy/jit/metainterp pypy/jit/metainterp/doc pypy/module/__builtin__/test pypy/module/_codecs/test pypy/module/_file/test pypy/module/_socket/test pypy/module/_sre/test pypy/module/array pypy/module/array/benchmark pypy/module/array/test pypy/module/cpyext pypy/module/fcntl/test pypy/module/marshal/test pypy/module/thread/test pypy/objspace/std pypy/rpython/lltypesystem

getxsick at codespeak.net getxsick at codespeak.net
Thu Aug 12 00:21:23 CEST 2010


Author: getxsick
Date: Thu Aug 12 00:21:21 2010
New Revision: 76599

Removed:
   pypy/branch/fast-ctypes/pypy/jit/metainterp/doc/
Modified:
   pypy/branch/fast-ctypes/   (props changed)
   pypy/branch/fast-ctypes/lib-python/conftest.py
   pypy/branch/fast-ctypes/lib_pypy/array.py
   pypy/branch/fast-ctypes/pypy/jit/backend/x86/assembler.py
   pypy/branch/fast-ctypes/pypy/jit/backend/x86/regalloc.py
   pypy/branch/fast-ctypes/pypy/jit/backend/x86/rx86.py
   pypy/branch/fast-ctypes/pypy/jit/backend/x86/test/test_regloc.py
   pypy/branch/fast-ctypes/pypy/jit/backend/x86/test/test_rx86.py
   pypy/branch/fast-ctypes/pypy/jit/metainterp/optimizeopt.py
   pypy/branch/fast-ctypes/pypy/module/__builtin__/test/test_buffer.py
   pypy/branch/fast-ctypes/pypy/module/_codecs/test/test_codecs.py
   pypy/branch/fast-ctypes/pypy/module/_file/test/test_file_extra.py
   pypy/branch/fast-ctypes/pypy/module/_socket/test/test_sock_app.py
   pypy/branch/fast-ctypes/pypy/module/_sre/test/test_app_sre.py
   pypy/branch/fast-ctypes/pypy/module/array/benchmark/Makefile   (props changed)
   pypy/branch/fast-ctypes/pypy/module/array/benchmark/intimg.c   (props changed)
   pypy/branch/fast-ctypes/pypy/module/array/benchmark/intimgtst.c   (props changed)
   pypy/branch/fast-ctypes/pypy/module/array/benchmark/intimgtst.py   (props changed)
   pypy/branch/fast-ctypes/pypy/module/array/benchmark/loop.c   (props changed)
   pypy/branch/fast-ctypes/pypy/module/array/benchmark/sum.c   (props changed)
   pypy/branch/fast-ctypes/pypy/module/array/benchmark/sumtst.c   (props changed)
   pypy/branch/fast-ctypes/pypy/module/array/benchmark/sumtst.py   (props changed)
   pypy/branch/fast-ctypes/pypy/module/array/interp_array.py
   pypy/branch/fast-ctypes/pypy/module/array/test/test_array.py
   pypy/branch/fast-ctypes/pypy/module/array/test/test_array_old.py   (props changed)
   pypy/branch/fast-ctypes/pypy/module/cpyext/api.py
   pypy/branch/fast-ctypes/pypy/module/fcntl/test/test_fcntl.py
   pypy/branch/fast-ctypes/pypy/module/marshal/test/test_marshalimpl.py
   pypy/branch/fast-ctypes/pypy/module/thread/test/test_gil.py
   pypy/branch/fast-ctypes/pypy/objspace/std/itertype.py
   pypy/branch/fast-ctypes/pypy/rpython/lltypesystem/ll2ctypes.py
Log:
merge from trunk


Modified: pypy/branch/fast-ctypes/lib-python/conftest.py
==============================================================================
--- pypy/branch/fast-ctypes/lib-python/conftest.py	(original)
+++ pypy/branch/fast-ctypes/lib-python/conftest.py	Thu Aug 12 00:21:21 2010
@@ -132,7 +132,7 @@
     RegrTest('test_ast.py', core=True),
     RegrTest('test_anydbm.py'),
     RegrTest('test_applesingle.py', skip=True),
-    RegrTest('test_array.py', core=True, usemodules='struct'),
+    RegrTest('test_array.py', core=True, usemodules='struct array'),
     RegrTest('test_asynchat.py', usemodules='thread'),
     RegrTest('test_atexit.py', core=True),
     RegrTest('test_audioop.py', skip=True),

Modified: pypy/branch/fast-ctypes/lib_pypy/array.py
==============================================================================
--- pypy/branch/fast-ctypes/lib_pypy/array.py	(original)
+++ pypy/branch/fast-ctypes/lib_pypy/array.py	Thu Aug 12 00:21:21 2010
@@ -1,24 +1,531 @@
-from array import array as _array
+"""This module defines an object type which can efficiently represent
+an array of basic values: characters, integers, floating point
+numbers.  Arrays are sequence types and behave very much like lists,
+except that the type of objects stored in them is constrained.  The
+type is specified at object creation time by using a type code, which
+is a single character.  The following type codes are defined:
+
+    Type code   C Type             Minimum size in bytes 
+    'c'         character          1 
+    'b'         signed integer     1 
+    'B'         unsigned integer   1 
+    'u'         Unicode character  2 
+    'h'         signed integer     2 
+    'H'         unsigned integer   2 
+    'i'         signed integer     2 
+    'I'         unsigned integer   2 
+    'l'         signed integer     4 
+    'L'         unsigned integer   4 
+    'f'         floating point     4 
+    'd'         floating point     8 
+
+The constructor is:
+
+array(typecode [, initializer]) -- create a new array
+"""
+
+from struct import calcsize, pack, pack_into, unpack_from
+import operator
+
+# the buffer-like object to use internally: trying from
+# various places in order...
+try:
+    import _rawffi                    # a reasonable implementation based
+    _RAWARRAY = _rawffi.Array('c')    # on raw_malloc, and providing a
+    def bytebuffer(size):             # real address
+        return _RAWARRAY(size, autofree=True)
+    def getbufaddress(buf):
+        return buf.buffer
+except ImportError:
+    try:
+        from __pypy__ import bytebuffer     # a reasonable implementation
+        def getbufaddress(buf):             # compatible with oo backends,
+            return 0                        # but no address
+    except ImportError:
+        # not running on PyPy.  Fall back to ctypes...
+        import ctypes
+        bytebuffer = ctypes.create_string_buffer
+        def getbufaddress(buf):
+            voidp = ctypes.cast(ctypes.pointer(buf), ctypes.c_void_p)
+            return voidp.value
+
+# ____________________________________________________________
+
+TYPECODES = "cbBuhHiIlLfd"
 
 class array(object):
-    def __init__(self, typecode, initializer=None):
-        self._array = _array(typecode)
-        if initializer is not None:
+    """array(typecode [, initializer]) -> array
+    
+    Return a new array whose items are restricted by typecode, and
+    initialized from the optional initializer value, which must be a list,
+    string. or iterable over elements of the appropriate type.
+    
+    Arrays represent basic values and behave very much like lists, except
+    the type of objects stored in them is constrained.
+    
+    Methods:
+    
+    append() -- append a new item to the end of the array
+    buffer_info() -- return information giving the current memory info
+    byteswap() -- byteswap all the items of the array
+    count() -- return number of occurences of an object
+    extend() -- extend array by appending multiple elements from an iterable
+    fromfile() -- read items from a file object
+    fromlist() -- append items from the list
+    fromstring() -- append items from the string
+    index() -- return index of first occurence of an object
+    insert() -- insert a new item into the array at a provided position
+    pop() -- remove and return item (default last)
+    read() -- DEPRECATED, use fromfile()
+    remove() -- remove first occurence of an object
+    reverse() -- reverse the order of the items in the array
+    tofile() -- write all items to a file object
+    tolist() -- return the array converted to an ordinary list
+    tostring() -- return the array converted to a string
+    write() -- DEPRECATED, use tofile()
+    
+    Attributes:
+    
+    typecode -- the typecode character used to create the array
+    itemsize -- the length in bytes of one array item
+    """
+    __slots__ = ["typecode", "itemsize", "_data", "_descriptor", "__weakref__"]
+
+    def __new__(cls, typecode, initializer=[], **extrakwds):
+        self = object.__new__(cls)
+        if cls is array and extrakwds:
+            raise TypeError("array() does not take keyword arguments")
+        if not isinstance(typecode, str) or len(typecode) != 1:
+            raise TypeError(
+                     "array() argument 1 must be char, not %s" % type(typecode))
+        if typecode not in TYPECODES:
+            raise ValueError(
+                  "bad typecode (must be one of %s)" % ', '.join(TYPECODES))
+        self._data = bytebuffer(0)
+        self.typecode = typecode
+        self.itemsize = calcsize(typecode)
+        if isinstance(initializer, list):
+            self.fromlist(initializer)
+        elif isinstance(initializer, str):
+            self.fromstring(initializer)
+        elif isinstance(initializer, unicode) and self.typecode == "u":
+            self.fromunicode(initializer)
+        else:
             self.extend(initializer)
+        return self
 
+    def _clear(self):
+        self._data = bytebuffer(0)
 
-    def append(self ,x):
-        self._array.append(x)
-    def __getitem__(self, idx):
-        return self._array[idx]
-    def __setitem__(self, idx, val):
-        self._array[idx]=val
-    def __len__(self):
-        return len(self._array)
+    ##### array-specific operations
 
+    def fromfile(self, f, n):
+        """Read n objects from the file object f and append them to the end of
+        the array. Also called as read."""
+        if not isinstance(f, file):
+            raise TypeError("arg1 must be open file")
+        size = self.itemsize * n
+        item = f.read(size)
+        if len(item) < size:
+            raise EOFError("not enough items in file")
+        self.fromstring(item)
+
+    def fromlist(self, l):
+        """Append items to array from list."""
+        if not isinstance(l, list):
+            raise TypeError("arg must be list")
+        self._fromiterable(l)
+        
+    def fromstring(self, s):
+        """Appends items from the string, interpreting it as an array of machine
+        values, as if it had been read from a file using the fromfile()
+        method."""
+        if isinstance(s, unicode):
+            s = str(s)
+        self._frombuffer(s)
+
+    def _frombuffer(self, s):
+        length = len(s)
+        if length % self.itemsize != 0:
+            raise ValueError("string length not a multiple of item size")
+        boundary = len(self._data)
+        newdata = bytebuffer(boundary + length)
+        newdata[:boundary] = self._data
+        newdata[boundary:] = s
+        self._data = newdata
+
+    def fromunicode(self, ustr):
+        """Extends this array with data from the unicode string ustr. The array
+        must be a type 'u' array; otherwise a ValueError is raised. Use
+        array.fromstring(ustr.encode(...)) to append Unicode data to an array of
+        some other type."""
+        if not self.typecode == "u":
+            raise ValueError(
+                          "fromunicode() may only be called on type 'u' arrays")
+        # XXX the following probable bug is not emulated:
+        # CPython accepts a non-unicode string or a buffer, and then
+        # behaves just like fromstring(), except that it strangely truncates
+        # string arguments at multiples of the unicode byte size.
+        # Let's only accept unicode arguments for now.
+        if not isinstance(ustr, unicode):
+            raise TypeError("fromunicode() argument should probably be "
+                            "a unicode string")
+        # _frombuffer() does the currect thing using
+        # the buffer behavior of unicode objects
+        self._frombuffer(buffer(ustr))
+
+    def tofile(self, f):
+        """Write all items (as machine values) to the file object f.  Also
+        called as write."""
+        if not isinstance(f, file):
+            raise TypeError("arg must be open file")
+        f.write(self.tostring())
+        
+    def tolist(self):
+        """Convert array to an ordinary list with the same items."""
+        count = len(self._data) // self.itemsize
+        return list(unpack_from('%d%s' % (count, self.typecode), self._data))
+
+    def tostring(self):
+        return self._data[:]
+
+    def __buffer__(self):
+        return buffer(self._data)
+
+    def tounicode(self):
+        """Convert the array to a unicode string. The array must be a type 'u'
+        array; otherwise a ValueError is raised. Use array.tostring().decode()
+        to obtain a unicode string from an array of some other type."""
+        if self.typecode != "u":
+            raise ValueError("tounicode() may only be called on type 'u' arrays")
+        # XXX performance is not too good
+        return u"".join(self.tolist())
+
+    def byteswap(self):
+        """Byteswap all items of the array.  If the items in the array are not
+        1, 2, 4, or 8 bytes in size, RuntimeError is raised."""
+        if self.itemsize not in [1, 2, 4, 8]:
+            raise RuntimeError("byteswap not supported for this array")
+        # XXX slowish
+        itemsize = self.itemsize
+        bytes = self._data
+        for start in range(0, len(bytes), itemsize):
+            stop = start + itemsize
+            bytes[start:stop] = bytes[start:stop][::-1]
+
+    def buffer_info(self):
+        """Return a tuple (address, length) giving the current memory address
+        and the length in items of the buffer used to hold array's contents. The
+        length should be multiplied by the itemsize attribute to calculate the
+        buffer length in bytes. On PyPy the address might be meaningless
+        (returned as 0), depending on the available modules."""
+        return (getbufaddress(self._data), len(self))
     
+    read = fromfile
+
+    write = tofile
+
+    ##### general object protocol
+    
+    def __repr__(self):
+        if len(self._data) == 0:
+            return "array('%s')" % self.typecode
+        elif self.typecode == "c":
+            return "array('%s', %s)" % (self.typecode, repr(self.tostring()))
+        elif self.typecode == "u":
+            return "array('%s', %s)" % (self.typecode, repr(self.tounicode()))
+        else:
+            return "array('%s', %s)" % (self.typecode, repr(self.tolist()))
+
+    def __copy__(self):
+        a = array(self.typecode)
+        a._data = bytebuffer(len(self._data))
+        a._data[:] = self._data
+        return a
+
+    def __eq__(self, other):
+        if not isinstance(other, array):
+            return NotImplemented
+        if self.typecode == 'c':
+            return buffer(self._data) == buffer(other._data)
+        else:
+            return self.tolist() == other.tolist()
+
+    def __ne__(self, other):
+        if not isinstance(other, array):
+            return NotImplemented
+        if self.typecode == 'c':
+            return buffer(self._data) != buffer(other._data)
+        else:
+            return self.tolist() != other.tolist()
+
+    def __lt__(self, other):
+        if not isinstance(other, array):
+            return NotImplemented
+        if self.typecode == 'c':
+            return buffer(self._data) < buffer(other._data)
+        else:
+            return self.tolist() < other.tolist()
+
+    def __gt__(self, other):
+        if not isinstance(other, array):
+            return NotImplemented
+        if self.typecode == 'c':
+            return buffer(self._data) > buffer(other._data)
+        else:
+            return self.tolist() > other.tolist()
+
+    def __le__(self, other):
+        if not isinstance(other, array):
+            return NotImplemented
+        if self.typecode == 'c':
+            return buffer(self._data) <= buffer(other._data)
+        else:
+            return self.tolist() <= other.tolist()
+
+    def __ge__(self, other):
+        if not isinstance(other, array):
+            return NotImplemented
+        if self.typecode == 'c':
+            return buffer(self._data) >= buffer(other._data)
+        else:
+            return self.tolist() >= other.tolist()
+
+    def __reduce__(self):
+        dict = getattr(self, '__dict__', None)
+        data = self.tostring()
+        if data:
+            initargs = (self.typecode, data)
+        else:
+            initargs = (self.typecode,)
+        return (type(self), initargs, dict)
+
+    ##### list methods
+    
+    def append(self, x):
+        """Append new value x to the end of the array."""
+        self._frombuffer(pack(self.typecode, x))
+
+    def count(self, x):
+        """Return number of occurences of x in the array."""
+        return operator.countOf(self, x)
+
     def extend(self, iterable):
-        for i in iterable: self.append(i)
+        """Append items to the end of the array."""
+        if isinstance(iterable, array) \
+                                    and not self.typecode == iterable.typecode:
+            raise TypeError("can only extend with array of same kind")
+        self._fromiterable(iterable)
+
+    def index(self, x):
+        """Return index of first occurence of x in the array."""
+        return operator.indexOf(self, x)
     
+    def insert(self, i, x):
+        """Insert a new item x into the array before position i."""
+        seqlength = len(self)
+        if i < 0:
+            i += seqlength
+            if i < 0:
+                i = 0
+        elif i > seqlength:
+            i = seqlength
+        boundary = i * self.itemsize
+        data = pack(self.typecode, x)
+        newdata = bytebuffer(len(self._data) + len(data))
+        newdata[:boundary] = self._data[:boundary]
+        newdata[boundary:boundary+self.itemsize] = data
+        newdata[boundary+self.itemsize:] = self._data[boundary:]
+        self._data = newdata
+        
+    def pop(self, i=-1):
+        """Return the i-th element and delete it from the array. i defaults to
+        -1."""
+        seqlength = len(self)
+        if i < 0:
+            i += seqlength
+        if not (0 <= i < seqlength):
+            raise IndexError(i)
+        boundary = i * self.itemsize
+        result = unpack_from(self.typecode, self._data, boundary)[0]
+        newdata = bytebuffer(len(self._data) - self.itemsize)
+        newdata[:boundary] = self._data[:boundary]
+        newdata[boundary:] = self._data[boundary+self.itemsize:]
+        self._data = newdata
+        return result
+        
+    def remove(self, x):
+        """Remove the first occurence of x in the array."""
+        self.pop(self.index(x))
+        
+    def reverse(self):
+        """Reverse the order of the items in the array."""
+        lst = self.tolist()
+        lst.reverse()
+        self._clear()
+        self.fromlist(lst)
 
+    ##### list protocol
     
+    def __len__(self):
+        return len(self._data) // self.itemsize
+    
+    def __add__(self, other):
+        if not isinstance(other, array):
+            raise TypeError("can only append array to array")
+        if self.typecode != other.typecode:
+            raise TypeError("bad argument type for built-in operation")
+        return array(self.typecode, buffer(self._data) + buffer(other._data))
+
+    def __mul__(self, repeat):
+        return array(self.typecode, buffer(self._data) * repeat)
+
+    __rmul__ = __mul__
+
+    def __getitem__(self, i):
+        seqlength = len(self)
+        if isinstance(i, slice):
+            start, stop, step = i.indices(seqlength)
+            if step != 1:
+                sublist = self.tolist()[i]    # fall-back
+                return array(self.typecode, sublist)
+            if start < 0:
+                start = 0
+            if stop < start:
+                stop = start
+            assert stop <= seqlength
+            return array(self.typecode, self._data[start * self.itemsize :
+                                                   stop * self.itemsize])
+        else:
+            if i < 0:
+                i += seqlength
+            if self.typecode == 'c':  # speed trick
+                return self._data[i]
+            if not (0 <= i < seqlength):
+                raise IndexError(i)
+            boundary = i * self.itemsize
+            return unpack_from(self.typecode, self._data, boundary)[0]
+
+    def __getslice__(self, i, j):
+        return self.__getitem__(slice(i, j))
+
+    def __setitem__(self, i, x):
+        if isinstance(i, slice):
+            if (not isinstance(x, array)
+                or self.typecode != x.typecode):
+                raise TypeError("can only assign array of same kind"
+                                " to array slice")
+            seqlength = len(self)
+            start, stop, step = i.indices(seqlength)
+            if step != 1:
+                sublist = self.tolist()    # fall-back
+                sublist[i] = x.tolist()
+                self._clear()
+                self.fromlist(sublist)
+                return
+            if start < 0:
+                start = 0
+            if stop < start:
+                stop = start
+            assert stop <= seqlength
+            boundary1 = start * self.itemsize
+            boundary2 = stop * self.itemsize
+            boundary2new = boundary1 + len(x._data)
+            if boundary2 == boundary2new:
+                self._data[boundary1:boundary2] = x._data
+            else:
+                newdata = bytebuffer(len(self._data) + boundary2new-boundary2)
+                newdata[:boundary1] = self._data[:boundary1]
+                newdata[boundary1:boundary2new] = x._data
+                newdata[boundary2new:] = self._data[boundary2:]
+                self._data = newdata
+        else:
+            seqlength = len(self)
+            if i < 0:
+                i += seqlength
+            if self.typecode == 'c':  # speed trick
+                self._data[i] = x
+                return
+            if not (0 <= i < seqlength):
+                raise IndexError(i)
+            boundary = i * self.itemsize
+            pack_into(self.typecode, self._data, boundary, x)
+
+    def __setslice__(self, i, j, x):
+        self.__setitem__(slice(i, j), x)
+
+    def __delitem__(self, i):
+        if isinstance(i, slice):
+            seqlength = len(self)
+            start, stop, step = i.indices(seqlength)
+            if start < 0:
+                start = 0
+            if stop < start:
+                stop = start
+            assert stop <= seqlength
+            if step != 1:
+                sublist = self.tolist()    # fall-back
+                del sublist[i]
+                self._clear()
+                self.fromlist(sublist)
+                return
+            dellength = stop - start
+            boundary1 = start * self.itemsize
+            boundary2 = stop * self.itemsize
+            newdata = bytebuffer(len(self._data) - (boundary2-boundary1))
+            newdata[:boundary1] = self._data[:boundary1]
+            newdata[boundary1:] = self._data[boundary2:]
+            self._data = newdata
+        else:            
+            seqlength = len(self)
+            if i < 0:
+                i += seqlength
+            if not (0 <= i < seqlength):
+                raise IndexError(i)
+            boundary = i * self.itemsize
+            newdata = bytebuffer(len(self._data) - self.itemsize)
+            newdata[:boundary] = self._data[:boundary]
+            newdata[boundary:] = self._data[boundary+self.itemsize:]
+            self._data = newdata
+
+    def __delslice__(self, i, j):
+        self.__delitem__(slice(i, j))
+
+    def __contains__(self, item):
+        for x in self:
+            if x == item:
+                return True
+        return False
+
+    def __iadd__(self, other):
+        if not isinstance(other, array):
+            raise TypeError("can only extend array with array")
+        self.extend(other)
+        return self
+
+    def __imul__(self, repeat):
+        newdata = buffer(self._data) * repeat
+        self._data = bytebuffer(len(newdata))
+        self._data[:] = newdata
+        return self
+
+    def __iter__(self):
+        p = 0
+        typecode = self.typecode
+        itemsize = self.itemsize
+        while p < len(self._data):
+            yield unpack_from(typecode, self._data, p)[0]
+            p += itemsize
+
+    ##### internal methods
+
+    def _fromiterable(self, iterable):
+        iterable = tuple(iterable)
+        n = len(iterable)
+        boundary = len(self._data)
+        newdata = bytebuffer(boundary + n * self.itemsize)
+        newdata[:boundary] = self._data
+        pack_into('%d%s' % (n, self.typecode), newdata, boundary, *iterable)
+        self._data = newdata
+
+ArrayType = array

Modified: pypy/branch/fast-ctypes/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/fast-ctypes/pypy/jit/backend/x86/assembler.py	Thu Aug 12 00:21:21 2010
@@ -1741,7 +1741,15 @@
         # the following is supposed to be the slow path, so whenever possible
         # we choose the most compact encoding over the most efficient one.
         for i in range(len(arglocs)-1, -1, -1):
-            self.mc.PUSH(arglocs[i])
+            loc = arglocs[i]
+            if isinstance(loc, RegLoc):
+                self.mc.PUSH_r(loc.value)
+            else:
+                if IS_X86_64:
+                    self.mc.MOV_ri(X86_64_SCRATCH_REG.value, loc.getint())
+                    self.mc.PUSH_r(X86_64_SCRATCH_REG.value)
+                else:
+                    self.mc.PUSH_i32(loc.getint())
         
         if IS_X86_64:
             # We clobber these registers to pass the arguments, but that's
@@ -1757,8 +1765,10 @@
         self.mc.CALL(imm(descr.get_write_barrier_fn(self.cpu)))
         for i in range(len(arglocs)):
             loc = arglocs[i]
-            assert isinstance(loc, RegLoc)
-            self.mc.POP(loc)
+            if isinstance(loc, RegLoc):
+                self.mc.POP_r(loc.value)
+            else:
+                self.mc.ADD_ri(esp.value, WORD)   # ignore the pushed constant
         # patch the JZ above
         offset = self.mc.get_relative_pos() - jz_location
         assert 0 < offset <= 127

Modified: pypy/branch/fast-ctypes/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/jit/backend/x86/regalloc.py	(original)
+++ pypy/branch/fast-ctypes/pypy/jit/backend/x86/regalloc.py	Thu Aug 12 00:21:21 2010
@@ -672,13 +672,12 @@
         
     def consider_cond_call_gc_wb(self, op):
         assert op.result is None
+        loc_newvalue = self.rm.make_sure_var_in_reg(op.args[1], op.args)
+        # ^^^ we force loc_newvalue in a reg (unless it's a Const),
+        # because it will be needed anyway by the following setfield_gc.
+        # It avoids loading it twice from the memory.
         loc_base = self.rm.make_sure_var_in_reg(op.args[0], op.args,
                                                 imm_fine=False)
-        loc_newvalue = self.rm.make_sure_var_in_reg(op.args[1], op.args,
-                                                    imm_fine=False)
-        # ^^^ we also force loc_newvalue in a reg, because it will be needed
-        # anyway by the following setfield_gc.  It avoids loading it twice
-        # from the memory.
         arglocs = [loc_base, loc_newvalue]
         # add eax, ecx and edx as extra "arguments" to ensure they are
         # saved and restored.  Fish in self.rm to know which of these

Modified: pypy/branch/fast-ctypes/pypy/jit/backend/x86/rx86.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/jit/backend/x86/rx86.py	(original)
+++ pypy/branch/fast-ctypes/pypy/jit/backend/x86/rx86.py	Thu Aug 12 00:21:21 2010
@@ -290,6 +290,9 @@
 def encode_rex(mc, rexbyte, basevalue, orbyte):
     if mc.WORD == 8:
         assert 0 <= rexbyte < 8
+        # XXX: Hack. Ignore REX.W if we are using 16-bit operands
+        if mc._use_16_bit_immediate:
+            basevalue &= ~REX_W
         if basevalue != 0x40 or rexbyte != 0:
             mc.writechar(chr(basevalue | rexbyte))
     else:
@@ -492,6 +495,7 @@
 
     PUSH_r = insn(rex_nw, register(1), '\x50')
     PUSH_b = insn(rex_nw, '\xFF', orbyte(6<<3), stack_bp(1))
+    PUSH_i32 = insn('\x68', immediate(1, 'i'))
 
     POP_r = insn(rex_nw, register(1), '\x58')
     POP_b = insn(rex_nw, '\x8F', orbyte(0<<3), stack_bp(1))

Modified: pypy/branch/fast-ctypes/pypy/jit/backend/x86/test/test_regloc.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/jit/backend/x86/test/test_regloc.py	(original)
+++ pypy/branch/fast-ctypes/pypy/jit/backend/x86/test/test_regloc.py	Thu Aug 12 00:21:21 2010
@@ -16,13 +16,27 @@
 cb64 = LocationCodeBuilder64
 
 def test_mov_16():
+    # 32-bit
     assert_encodes_as(cb32, "MOV16", (ecx, ebx), '\x66\x89\xD9')
     assert_encodes_as(cb32, "MOV16", (ecx, ImmedLoc(12345)), '\x66\xB9\x39\x30')
 
+    # 64-bit
+    assert_encodes_as(cb64, "MOV16", (ecx, ebx), '\x66\x89\xD9')
+    # XXX: What we are testing for here is actually not the most compact
+    # encoding.
+    assert_encodes_as(cb64, "MOV16", (ecx, ImmedLoc(12345)), '\x66\xC7\xC1\x39\x30')
+    assert_encodes_as(cb64, "MOV16", (AddressLoc(r13, ImmedLoc(0), 0, 0), ImmedLoc(12345)), '\x66\x41\xC7\x45\x00\x39\x30')
+
 def test_cmp_16():
+    # 32-bit
     assert_encodes_as(cb32, "CMP16", (ecx, ebx), '\x66\x39\xD9')
     assert_encodes_as(cb32, "CMP16", (ecx, ImmedLoc(12345)), '\x66\x81\xF9\x39\x30')
 
+    # 64-bit
+    assert_encodes_as(cb64, "CMP16", (ecx, ebx), '\x66\x39\xD9')
+    assert_encodes_as(cb64, "CMP16", (ecx, ImmedLoc(12345)), '\x66\x81\xF9\x39\x30')
+    assert_encodes_as(cb64, "CMP16", (AddressLoc(r13, ImmedLoc(0), 0, 0), ImmedLoc(12345)), '\x66\x41\x81\x7D\x00\x39\x30')
+
 def test_jmp_wraparound():
     if not IS_X86_32:
         py.test.skip()

Modified: pypy/branch/fast-ctypes/pypy/jit/backend/x86/test/test_rx86.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/jit/backend/x86/test/test_rx86.py	(original)
+++ pypy/branch/fast-ctypes/pypy/jit/backend/x86/test/test_rx86.py	Thu Aug 12 00:21:21 2010
@@ -188,6 +188,10 @@
     assert_encodes_as(cb, 'MOV8_mi', ((edx, 16), 99), '\xC6\x42\x10\x63')
     assert_encodes_as(cb, 'MOV8_ai', ((ebx, ecx, 2, 16), 99), '\xC6\x44\x8B\x10\x63')
 
+def test_push32():
+    cb = CodeBuilder32
+    assert_encodes_as(cb, 'PUSH_i32', (9,), '\x68\x09\x00\x00\x00')
+
 class CodeBuilder64(CodeBuilderMixin, X86_64_CodeBuilder):
     pass
 

Modified: pypy/branch/fast-ctypes/pypy/jit/metainterp/optimizeopt.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/jit/metainterp/optimizeopt.py	(original)
+++ pypy/branch/fast-ctypes/pypy/jit/metainterp/optimizeopt.py	Thu Aug 12 00:21:21 2010
@@ -612,7 +612,7 @@
                 assert oldop.opnum == op.opnum
                 self.make_equal_to(op.result, self.getvalue(oldop.result))
                 return
-            elif self.find_rewriteable_bool(op, args):
+            elif self.find_rewritable_bool(op, args):
                 return
             else:
                 self.pure_operations[args] = op
@@ -635,7 +635,7 @@
         return False
 
     
-    def find_rewriteable_bool(self, op, args):
+    def find_rewritable_bool(self, op, args):
         try:
             oldopnum = opboolinvers[op.opnum]
             targs = [args[0], args[1], ConstInt(oldopnum)]

Modified: pypy/branch/fast-ctypes/pypy/module/__builtin__/test/test_buffer.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/module/__builtin__/test/test_buffer.py	(original)
+++ pypy/branch/fast-ctypes/pypy/module/__builtin__/test/test_buffer.py	Thu Aug 12 00:21:21 2010
@@ -1,8 +1,11 @@
 """Tests some behaviour of the buffer type that is not tested in
 lib-python/2.5.2/test/test_types.py where the stdlib buffer tests live."""
 import autopath
+from pypy.conftest import gettestobjspace
 
 class AppTestBuffer:
+    def setup_class(cls):
+        cls.space = gettestobjspace(usemodules=('array',))
 
     def test_unicode_buffer(self):
         import sys

Modified: pypy/branch/fast-ctypes/pypy/module/_codecs/test/test_codecs.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/module/_codecs/test/test_codecs.py	(original)
+++ pypy/branch/fast-ctypes/pypy/module/_codecs/test/test_codecs.py	Thu Aug 12 00:21:21 2010
@@ -123,6 +123,10 @@
 
 class AppTestPartialEvaluation:
 
+    def setup_class(cls):
+        space = gettestobjspace(usemodules=('array',))
+        cls.space = space
+
     def test_partial_utf8(self):
         import _codecs
         encoding = 'utf-8'

Modified: pypy/branch/fast-ctypes/pypy/module/_file/test/test_file_extra.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/module/_file/test/test_file_extra.py	(original)
+++ pypy/branch/fast-ctypes/pypy/module/_file/test/test_file_extra.py	Thu Aug 12 00:21:21 2010
@@ -353,6 +353,10 @@
 
 class AppTestAFewExtra:
 
+    def setup_class(cls):
+        space = gettestobjspace(usemodules=('array',))
+        cls.space = space
+
     def setup_method(self, method):
         fn = str(udir.join('temptestfile'))
         self.w_temptestfile = self.space.wrap(fn)

Modified: pypy/branch/fast-ctypes/pypy/module/_socket/test/test_sock_app.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/module/_socket/test/test_sock_app.py	(original)
+++ pypy/branch/fast-ctypes/pypy/module/_socket/test/test_sock_app.py	Thu Aug 12 00:21:21 2010
@@ -4,7 +4,7 @@
 from pypy.tool.udir import udir
 
 def setup_module(mod):
-    mod.space = gettestobjspace(usemodules=['_socket'])
+    mod.space = gettestobjspace(usemodules=['_socket', 'array'])
     global socket
     import socket
     mod.w_socket = space.appexec([], "(): import _socket as m; return m")

Modified: pypy/branch/fast-ctypes/pypy/module/_sre/test/test_app_sre.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/module/_sre/test/test_app_sre.py	(original)
+++ pypy/branch/fast-ctypes/pypy/module/_sre/test/test_app_sre.py	Thu Aug 12 00:21:21 2010
@@ -87,7 +87,9 @@
 
 
 class AppTestSreMatch:
-
+    def setup_class(cls):
+        cls.space = gettestobjspace(usemodules=('array', ))
+        
     def test_copy(self):
         import re
         # copy support is disabled by default in _sre.c

Modified: pypy/branch/fast-ctypes/pypy/module/array/interp_array.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/module/array/interp_array.py	(original)
+++ pypy/branch/fast-ctypes/pypy/module/array/interp_array.py	Thu Aug 12 00:21:21 2010
@@ -14,9 +14,10 @@
 from pypy.objspace.std.model import W_Object
 from pypy.interpreter.argument import Arguments, Signature
 from pypy.module._file.interp_file import W_File
+from pypy.interpreter.buffer import RWBuffer
 
-def w_array(space, w_cls, typecode, w_initializer=None, w_args=None):
-    if len(w_args.arguments_w) > 0:
+def w_array(space, w_cls, typecode, w_args=None):
+    if len(w_args.arguments_w) > 1:
         msg = 'array() takes at most 2 arguments'
         raise OperationError(space.w_TypeError, space.wrap(msg))
     if len(typecode) != 1:
@@ -29,23 +30,23 @@
             a = space.allocate_instance(types[tc].w_class, w_cls)
             a.__init__(space)
 
-            if w_initializer is not None:
-                if not space.is_w(w_initializer, space.w_None):
-                    if space.type(w_initializer) is space.w_str:
-                        a.fromstring(w_initializer)
-                    elif space.type(w_initializer) is space.w_unicode:
-                        a.fromsequence(w_initializer)
-                    elif space.type(w_initializer) is space.w_list:
-                        a.fromlist(w_initializer)
-                    else:
-                        a.extend(w_initializer)
+            if len(w_args.arguments_w) > 0:
+                w_initializer = w_args.arguments_w[0]
+                if space.type(w_initializer) is space.w_str:
+                    a.fromstring(w_initializer)
+                elif space.type(w_initializer) is space.w_unicode:
+                    a.fromsequence(w_initializer)
+                elif space.type(w_initializer) is space.w_list:
+                    a.fromlist(w_initializer)
+                else:
+                    a.extend(w_initializer)
             break
     else:
         msg = 'bad typecode (must be c, b, B, u, h, H, i, I, l, L, f or d)'
         raise OperationError(space.w_ValueError, space.wrap(msg))
 
     return a
-w_array.unwrap_spec = (ObjSpace, W_Root, str, W_Root, Arguments)
+w_array.unwrap_spec = (ObjSpace, W_Root, str, Arguments)
 
 
 array_append = SMM('append', 2)
@@ -142,6 +143,22 @@
     v.typecode = k
 unroll_typecodes = unrolling_iterable(types.keys())
 
+class ArrayBuffer(RWBuffer):
+    def __init__(self, data, bytes):
+        self.data = data
+        self.len = bytes
+
+    def getlength(self):
+        return self.len
+
+    def getitem(self, index):
+        return self.data[index]
+
+    def setitem(self, index, char):
+        self.data[index] = char
+
+
+
 
 def make_array(mytype):
     class W_Array(W_ArrayBase):
@@ -460,6 +477,7 @@
     def mul__Array_ANY(space, self, w_repeat):
         repeat = space.int_w(w_repeat)
         a = mytype.w_class(space)
+        repeat = max(repeat, 0)
         a.setlen(self.len * repeat)
         for r in range(repeat):
             for i in range(self.len):
@@ -472,6 +490,7 @@
     def inplace_mul__Array_ANY(space, self, w_repeat):
         repeat = space.int_w(w_repeat)
         oldlen = self.len
+        repeat = max(repeat, 0)
         self.setlen(self.len * repeat)
         for r in range(1, repeat):
             for i in range(oldlen):
@@ -560,14 +579,13 @@
             w_lst2 = space.call_method(other, 'tolist')
             return space.cmp(w_lst1, w_lst2)
         else:
-            raise OperationError(space.w_NotImplementedError, space.wrap(''))
+            return space.w_NotImplemented
 
     # Misc methods
 
     def buffer__Array(space, self):
-        from pypy.interpreter.buffer import StringLikeBuffer
-        w_s = array_tostring__Array(space, self)
-        return space.wrap(StringLikeBuffer(space, w_s))
+        b = ArrayBuffer(self.charbuf(), self.len * mytype.bytes)
+        return space.wrap(b)
 
     def array_buffer_info__Array(space, self):
         w_ptr = space.wrap(rffi.cast(lltype.Unsigned, self.buffer))
@@ -580,7 +598,11 @@
             args = [space.wrap(mytype.typecode), w_s]
         else:
             args = [space.wrap(mytype.typecode)]
-        return space.newtuple([space.type(self), space.newtuple(args)])
+        try:
+            dct = space.getattr(self, space.wrap('__dict__'))
+        except OperationError:
+            dct = space.w_None
+        return space.newtuple([space.type(self), space.newtuple(args), dct])
 
     def array_byteswap__Array(space, self):
         if mytype.bytes not in [1, 2, 4, 8]:
@@ -638,3 +660,5 @@
 
 for mytype in types.values():
     make_array(mytype)
+
+register_all(locals(), globals())

Modified: pypy/branch/fast-ctypes/pypy/module/array/test/test_array.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/module/array/test/test_array.py	(original)
+++ pypy/branch/fast-ctypes/pypy/module/array/test/test_array.py	Thu Aug 12 00:21:21 2010
@@ -61,6 +61,7 @@
 
         for tc in 'bhilBHILfd':
             assert self.array(tc).typecode == tc
+            raises(TypeError, self.array, tc, None)
 
     def test_value_range(self):
         values = (-129, 128, -128, 127, 0, 255, -1, 256,
@@ -421,7 +422,7 @@
         a = self.array('h', 'Hi')
         buf = buffer(a)
         assert buf[1] == 'i'
-        raises(TypeError, buf.__setitem__, 1, 'o')
+        #raises(TypeError, buf.__setitem__, 1, 'o')
 
     def test_list_methods(self):
         assert repr(self.array('i')) == "array('i')"
@@ -468,6 +469,12 @@
         assert repr(a) == "array('i', [20, 8, 2, 9, 7, 10])"
 
     def test_compare(self):
+        class comparable(object):
+            def __cmp__(self, other):
+                return 0
+        class incomparable(object):
+            pass
+        
         for v1, v2, tt in (([1, 2, 3], [1, 3, 2], 'bhilBHIL'),
                          ('abc', 'acb', 'c'),
                          (unicode('abc'), unicode('acb'), 'u')):
@@ -476,6 +483,13 @@
                 b = self.array(t, v1)
                 c = self.array(t, v2)
 
+                print (a==7)
+                assert (a == 7) is False
+                assert (comparable() == a) is True
+                assert (a == comparable()) is True
+                assert (a == incomparable()) is False
+                assert (incomparable() == a) is False
+
                 assert (a == a) is True
                 assert (a == b) is True
                 assert (b == a) is True
@@ -531,10 +545,8 @@
         assert len(b) == 0 and b.typecode == 'l'
 
         a = self.array('i', [1, 2, 4])
-        print "itter"
         i = iter(a)
-        print "ok"
-        raises(TypeError, pickle.dumps, i, 1)
+        #raises(TypeError, pickle.dumps, i, 1)
 
     def test_copy_swap(self):
         a = self.array('i', [1, 2, 3])
@@ -599,6 +611,13 @@
         assert addable() + self.array('i') == 'add'
         assert self.array('i') + addable() == 'radd'
 
+        a = self.array('i', [1, 2])
+        assert a * -1 == self.array('i')
+        b = a
+        a *= -1
+        assert a == self.array('i')
+        assert b == self.array('i')
+
     def test_delitem(self):
         a = self.array('i', [1, 2, 3])
         del a[1]
@@ -726,6 +745,12 @@
         assert repr(mya('i', [1, 2, 3])) == "array('i', [1, 2, 3])"
         assert repr(mya('i', (1, 2, 3))) == "array('i', [1, 2, 3])"
 
+    def test_unicode_outofrange(self):
+        a = self.array('u', unicode(r'\x01\u263a\x00\ufeff', 'unicode-escape'))
+        b = self.array('u', unicode(r'\x01\u263a\x00\ufeff', 'unicode-escape'))
+        b.byteswap()
+        assert a != b
+
 
 class TestCPythonsOwnArray(BaseArrayTests):
 

Modified: pypy/branch/fast-ctypes/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/module/cpyext/api.py	(original)
+++ pypy/branch/fast-ctypes/pypy/module/cpyext/api.py	Thu Aug 12 00:21:21 2010
@@ -1,5 +1,5 @@
 import ctypes
-import sys
+import sys, os
 import atexit
 
 import py
@@ -896,6 +896,8 @@
 initfunctype = lltype.Ptr(lltype.FuncType([], lltype.Void))
 @unwrap_spec(ObjSpace, str, str)
 def load_extension_module(space, path, name):
+    if os.sep not in path:
+        path = os.curdir + os.sep + path      # force a '/' in the path
     state = space.fromcache(State)
     state.package_context = name
     try:

Modified: pypy/branch/fast-ctypes/pypy/module/fcntl/test/test_fcntl.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/module/fcntl/test/test_fcntl.py	(original)
+++ pypy/branch/fast-ctypes/pypy/module/fcntl/test/test_fcntl.py	Thu Aug 12 00:21:21 2010
@@ -13,7 +13,7 @@
 
 class AppTestFcntl:
     def setup_class(cls):
-        space = gettestobjspace(usemodules=('fcntl',))
+        space = gettestobjspace(usemodules=('fcntl', 'array'))
         cls.space = space
         tmpprefix = str(udir.ensure('test_fcntl', dir=1).join('tmp_'))
         cls.w_tmp = space.wrap(tmpprefix)

Modified: pypy/branch/fast-ctypes/pypy/module/marshal/test/test_marshalimpl.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/module/marshal/test/test_marshalimpl.py	(original)
+++ pypy/branch/fast-ctypes/pypy/module/marshal/test/test_marshalimpl.py	Thu Aug 12 00:21:21 2010
@@ -1,9 +1,13 @@
 from pypy.module.marshal import interp_marshal
 from pypy.interpreter.error import OperationError
+from pypy.conftest import gettestobjspace
 import sys
 
 
 class AppTestMarshalMore:
+    def setup_class(cls):
+        space = gettestobjspace(usemodules=('array',))
+        cls.space = space
 
     def test_long_0(self):
         import marshal

Modified: pypy/branch/fast-ctypes/pypy/module/thread/test/test_gil.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/module/thread/test/test_gil.py	(original)
+++ pypy/branch/fast-ctypes/pypy/module/thread/test/test_gil.py	Thu Aug 12 00:21:21 2010
@@ -1,7 +1,6 @@
 import time
 from pypy.module.thread import gil
 from pypy.module.thread.test import test_ll_thread
-from pypy.rpython.lltypesystem import rffi
 from pypy.module.thread import ll_thread as thread
 from pypy.rlib.objectmodel import we_are_translated
 

Modified: pypy/branch/fast-ctypes/pypy/objspace/std/itertype.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/objspace/std/itertype.py	(original)
+++ pypy/branch/fast-ctypes/pypy/objspace/std/itertype.py	Thu Aug 12 00:21:21 2010
@@ -10,9 +10,9 @@
     a registration with copy_reg, instead.
     """
 
-    # cpython does not support pickling iterators
-    msg = 'Pickling for iterators dissabled as cpython does not support it'
-    raise OperationError(space.w_TypeError, space.wrap(msg))
+    # cpython does not support pickling iterators but stackless python do
+    #msg = 'Pickling for iterators dissabled as cpython does not support it'
+    #raise OperationError(space.w_TypeError, space.wrap(msg))
 
     from pypy.objspace.std.iterobject import W_AbstractSeqIterObject
     assert isinstance(w_self, W_AbstractSeqIterObject)

Modified: pypy/branch/fast-ctypes/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/branch/fast-ctypes/pypy/rpython/lltypesystem/ll2ctypes.py	(original)
+++ pypy/branch/fast-ctypes/pypy/rpython/lltypesystem/ll2ctypes.py	Thu Aug 12 00:21:21 2010
@@ -24,6 +24,7 @@
 from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
 from pypy.rpython import raddress
 from pypy.translator.platform import platform
+from array import array
 
 def uaddressof(obj):
     return fixid(ctypes.addressof(obj))
@@ -756,7 +757,15 @@
     elif T is lltype.Char:
         llobj = chr(cobj)
     elif T is lltype.UniChar:
-        llobj = unichr(cobj)
+        try:
+            llobj = unichr(cobj)
+        except (ValueError, OverflowError):
+            for tc in 'HIL':
+                if array(tc).itemsize == array('u').itemsize:
+                    llobj = array('u', array(tc, (cobj,)).tostring())[0]
+                    break
+            else:
+                raise
     elif T is lltype.Signed:
         llobj = cobj
     elif T is lltype.Bool:



More information about the Pypy-commit mailing list