Author: Maciej Fijalkowski <fij...@gmail.com>
Branch: 
Changeset: r67352:6f41123c181b
Date: 2013-10-14 12:56 +0200
http://bitbucket.org/pypy/pypy/changeset/6f41123c181b/

Log:    merge

diff --git a/pypy/module/cpyext/include/numpy/arrayobject.h 
b/pypy/module/cpyext/include/numpy/arrayobject.h
--- a/pypy/module/cpyext/include/numpy/arrayobject.h
+++ b/pypy/module/cpyext/include/numpy/arrayobject.h
@@ -1,5 +1,8 @@
 
-/* NDArray object interface - S. H. Muller, 2013/07/26 */
+/* NDArray object interface - S. H. Muller, 2013/07/26 
+ * It will be copied by numpy/core/setup.py by install_data to
+ * site-packages/numpy/core/includes/numpy  
+*/
 
 #ifndef Py_NDARRAYOBJECT_H
 #define Py_NDARRAYOBJECT_H
@@ -9,7 +12,6 @@
 
 #include "old_defines.h"
 
-#define NPY_INLINE
 #define NPY_UNUSED(x) x
 #define PyArray_MAX(a,b) (((a)>(b))?(a):(b))
 #define PyArray_MIN(a,b) (((a)<(b))?(a):(b))
@@ -22,11 +24,12 @@
 
 typedef unsigned char npy_bool;
 typedef unsigned char npy_uint8;
+typedef unsigned short npy_uint16;
+typedef signed short npy_int16;
+typedef signed char npy_int8;
 typedef int npy_int;
 
-#ifndef npy_intp
-#define npy_intp long
-#endif
+typedef long npy_intp;
 #ifndef NPY_INTP_FMT
 #define NPY_INTP_FMT "ld"
 #endif
diff --git a/pypy/module/cpyext/include/numpy/npy_3kcompat.h 
b/pypy/module/cpyext/include/numpy/npy_3kcompat.h
--- a/pypy/module/cpyext/include/numpy/npy_3kcompat.h
+++ b/pypy/module/cpyext/include/numpy/npy_3kcompat.h
@@ -0,0 +1,41 @@
+/*
+ * In numpy this is a convenience header file providing compatibility utilities
+ * for supporting Python 2 and Python 3 in the same code base.
+ *
+ * PyPy uses it as a convenient place to add compatability declarations
+ * It will be copied by numpy/core/setup.py by install_data to
+ * site-packages/numpy/core/includes/numpy  
+*/
+
+#ifndef _NPY_3KCOMPAT_H_
+#define _NPY_3KCOMPAT_H_
+
+#include <numpy/npy_common.h>
+
+#define npy_PyFile_Dup(file, mode) (NULL)
+#define npy_PyFile_DupClose(file, handle) (0)
+
+static NPY_INLINE PyObject*
+npy_PyFile_OpenFile(PyObject *filename, const char *mode)
+{
+    PyObject *open;
+    open = PyDict_GetItemString(PyEval_GetBuiltins(), "open");
+    if (open == NULL) {
+        return NULL;
+    }
+    return PyObject_CallFunction(open, "Os", filename, mode);
+}
+
+static NPY_INLINE int
+npy_PyFile_CloseFile(PyObject *file)
+{
+    PyObject *ret;
+
+    ret = PyObject_CallMethod(file, "close", NULL);
+    if (ret == NULL) {
+        return -1;
+    }
+    Py_DECREF(ret);
+    return 0;
+}
+#endif
diff --git a/pypy/module/cpyext/ndarrayobject.py 
b/pypy/module/cpyext/ndarrayobject.py
--- a/pypy/module/cpyext/ndarrayobject.py
+++ b/pypy/module/cpyext/ndarrayobject.py
@@ -171,6 +171,15 @@
         w_array.implementation.shape = []
     return w_array
 
+@cpython_api([Py_ssize_t], PyObject)
+def _PyArray_DescrFromType(space, typenum):
+    try:
+        dtype = get_dtype_cache(space).dtypes_by_num[typenum]
+        return dtype
+    except KeyError:
+        raise OperationError(space.w_ValueError, space.wrap(
+            '_PyArray_DescrFromType called with invalid dtype %d' % typenum))
+
 @cpython_api([PyObject, Py_ssize_t, Py_ssize_t, Py_ssize_t], PyObject)
 def _PyArray_FromObject(space, w_obj, typenum, min_depth, max_depth):
     try:
diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py 
b/pypy/module/cpyext/test/test_ndarrayobject.py
--- a/pypy/module/cpyext/test/test_ndarrayobject.py
+++ b/pypy/module/cpyext/test/test_ndarrayobject.py
@@ -265,6 +265,12 @@
                 return obj2;
                 '''
                 ),
+                ("test_DescrFromType", "METH_O",
+                """
+                    Signed typenum = PyInt_AsLong(args);
+                    return _PyArray_DescrFromType(typenum);
+                """
+                ),
                 ], prologue='#include <numpy/arrayobject.h>')
         arr = mod.test_simplenew()
         assert arr.shape == (2, 3)
@@ -278,3 +284,5 @@
         #Make sure these work without errors
         arr = mod.test_FromAny()
         arr = mod.test_FromObject()
+        dt = mod.test_DescrFromType(11)
+        assert dt.num == 11
diff --git a/pypy/module/micronumpy/interp_numarray.py 
b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -954,6 +954,13 @@
     def descr___array_finalize__(self, space, w_obj):
         pass
 
+    def descr___array_wrap__(self, space, w_obj, w_context=None):
+        return w_obj
+
+    def descr___array_prepare__(self, space, w_obj, w_context=None):
+        return w_obj
+        pass
+
 @unwrap_spec(offset=int, order=str)
 def descr_new_array(space, w_subtype, w_shape, w_dtype=None, w_buffer=None,
                     offset=0, w_strides=None, order='C'):
@@ -1144,7 +1151,8 @@
     __reduce__ = interp2app(W_NDimArray.descr_reduce),
     __setstate__ = interp2app(W_NDimArray.descr_setstate),
     __array_finalize__ = interp2app(W_NDimArray.descr___array_finalize__),
-
+    __array_prepare__ = interp2app(W_NDimArray.descr___array_prepare__),
+    __array_wrap__ = interp2app(W_NDimArray.descr___array_wrap__),
     __array__         = interp2app(W_NDimArray.descr___array__),
 )
 
diff --git a/pypy/module/micronumpy/interp_ufuncs.py 
b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -342,6 +342,9 @@
         if w_ldtype.is_str_type() and w_rdtype.is_str_type() and \
            self.comparison_func:
             pass
+        elif (w_ldtype.is_str_type() or w_rdtype.is_str_type()) and \
+            self.comparison_func and w_out is None:
+            return space.wrap(False)
         elif (w_ldtype.is_flexible_type() or \
                 w_rdtype.is_flexible_type()):
             raise OperationError(space.w_TypeError, space.wrap(
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py 
b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -712,7 +712,8 @@
 
     def test_comparisons(self):
         import operator
-        from numpypy import equal, not_equal, less, less_equal, greater, 
greater_equal
+        from numpypy import (equal, not_equal, less, less_equal, greater,
+                            greater_equal, arange)
 
         for ufunc, func in [
             (equal, operator.eq),
@@ -735,7 +736,9 @@
                 (3, 3.5),
             ]:
                 assert ufunc(a, b) == func(a, b)
-
+        c = arange(10)
+        val = c == 'abcdefg'
+        assert val == False
 
     def test_count_nonzero(self):
         from numpypy import count_nonzero
diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py
--- a/pypy/module/mmap/interp_mmap.py
+++ b/pypy/module/mmap/interp_mmap.py
@@ -290,9 +290,6 @@
         self.space = space
         self.mmap = mmap
 
-    def get_raw_address(self):
-        return self.mmap.data
-
     def getlength(self):
         return self.mmap.size
 
diff --git a/rpython/jit/metainterp/heapcache.py 
b/rpython/jit/metainterp/heapcache.py
--- a/rpython/jit/metainterp/heapcache.py
+++ b/rpython/jit/metainterp/heapcache.py
@@ -51,10 +51,10 @@
         return self.output_indirections.get(box, box)
 
     def invalidate_caches(self, opnum, descr, argboxes):
-        self.mark_escaped(opnum, argboxes)
+        self.mark_escaped(opnum, descr, argboxes)
         self.clear_caches(opnum, descr, argboxes)
 
-    def mark_escaped(self, opnum, argboxes):
+    def mark_escaped(self, opnum, descr, argboxes):
         if opnum == rop.SETFIELD_GC:
             assert len(argboxes) == 2
             box, valuebox = argboxes
@@ -69,6 +69,15 @@
                 self.dependencies.setdefault(box, []).append(valuebox)
             else:
                 self._escape(valuebox)
+        elif (opnum == rop.CALL and
+              descr.get_extra_info().oopspecindex == 
descr.get_extra_info().OS_ARRAYCOPY and
+              isinstance(argboxes[3], ConstInt) and
+              isinstance(argboxes[4], ConstInt) and
+              isinstance(argboxes[5], ConstInt) and
+              len(descr.get_extra_info().write_descrs_arrays) == 1):
+            # ARRAYCOPY with constant starts and constant length doesn't escape
+            # its argument
+            pass
         # GETFIELD_GC, MARK_OPAQUE_PTR, PTR_EQ, and PTR_NE don't escape their
         # arguments
         elif (opnum != rop.GETFIELD_GC and
@@ -118,16 +127,50 @@
             # A special case for ll_arraycopy, because it is so common, and its
             # effects are so well defined.
             elif effectinfo.oopspecindex == effectinfo.OS_ARRAYCOPY:
-                # The destination box
                 if (
+                    isinstance(argboxes[3], ConstInt) and
+                    isinstance(argboxes[4], ConstInt) and
+                    isinstance(argboxes[5], ConstInt) and
+                    len(effectinfo.write_descrs_arrays) == 1
+                ):
+                    descr = effectinfo.write_descrs_arrays[0]
+                    cache = self.heap_array_cache.get(descr, None)
+                    srcstart = argboxes[3].getint()
+                    dststart = argboxes[4].getint()
+                    length = argboxes[5].getint()
+                    for i in xrange(length):
+                        value = self.getarrayitem(
+                            argboxes[1],
+                            ConstInt(srcstart + i),
+                            descr,
+                        )
+                        if value is not None:
+                            self.setarrayitem(
+                                argboxes[2],
+                                ConstInt(dststart + i),
+                                value,
+                                descr,
+                            )
+                        elif cache is not None:
+                            if argboxes[2] in self.new_boxes:
+                                try:
+                                    idx_cache = cache[dststart + i]
+                                except KeyError:
+                                    pass
+                                else:
+                                    for frombox in idx_cache.keys():
+                                        if not self.is_unescaped(frombox):
+                                            del idx_cache[frombox]
+                            else:
+                                cache[dststart + i].clear()
+                    return
+                elif (
                     argboxes[2] in self.new_boxes and
                     len(effectinfo.write_descrs_arrays) == 1
                 ):
                     # Fish the descr out of the effectinfo
                     cache = 
self.heap_array_cache.get(effectinfo.write_descrs_arrays[0], None)
                     if cache is not None:
-                        # XXX: in theory the indices of the copy could be
-                        # looked at
                         for idx, cache in cache.iteritems():
                             for frombox in cache.keys():
                                 if not self.is_unescaped(frombox):
@@ -210,9 +253,9 @@
         return new_d
 
     def getarrayitem(self, box, indexbox, descr):
-        box = self._input_indirection(box)
         if not isinstance(indexbox, ConstInt):
             return
+        box = self._input_indirection(box)
         index = indexbox.getint()
         cache = self.heap_array_cache.get(descr, None)
         if cache:
@@ -221,10 +264,10 @@
                 return self._output_indirection(indexcache.get(box, None))
 
     def getarrayitem_now_known(self, box, indexbox, valuebox, descr):
+        if not isinstance(indexbox, ConstInt):
+            return
         box = self._input_indirection(box)
         valuebox = self._input_indirection(valuebox)
-        if not isinstance(indexbox, ConstInt):
-            return
         index = indexbox.getint()
         cache = self.heap_array_cache.setdefault(descr, {})
         indexcache = cache.get(index, None)
diff --git a/rpython/jit/metainterp/test/test_heapcache.py 
b/rpython/jit/metainterp/test/test_heapcache.py
--- a/rpython/jit/metainterp/test/test_heapcache.py
+++ b/rpython/jit/metainterp/test/test_heapcache.py
@@ -1,6 +1,6 @@
 from rpython.jit.metainterp.heapcache import HeapCache
 from rpython.jit.metainterp.resoperation import rop
-from rpython.jit.metainterp.history import ConstInt
+from rpython.jit.metainterp.history import ConstInt, BoxInt
 
 box1 = "box1"
 box2 = "box2"
@@ -73,7 +73,6 @@
         assert not h.is_nonstandard_virtualizable(1)
         assert not h.is_nonstandard_virtualizable(2)
 
-
     def test_heapcache_fields(self):
         h = HeapCache()
         assert h.getfield(box1, descr1) is None
@@ -278,7 +277,6 @@
         assert h.getarrayitem(box1, index1, descr1) is None
         assert h.getarrayitem(box1, index2, descr1) is None
 
-
     def test_replace_box(self):
         h = HeapCache()
         h.setfield(box1, box2, descr1)
@@ -372,22 +370,22 @@
         h.invalidate_caches(
             rop.CALL,
             FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, 
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
-            [None, None, box2, None, None]
+            [None, box5, box2, index1, index1, index1]
         )
         assert h.getarrayitem(box1, index1, descr1) is box2
         h.invalidate_caches(
             rop.CALL,
             FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, 
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
-            [None, None, box3, None, None]
+            [None, box5, box3, index1, index1, index1]
         )
-        assert h.getarrayitem(box1, index1, descr1) is None
+        assert h.getarrayitem(box1, index1, descr1) is box2
 
         h.setarrayitem(box4, index1, box2, descr1)
         assert h.getarrayitem(box4, index1, descr1) is box2
         h.invalidate_caches(
             rop.CALL,
             FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, 
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
-            [None, None, box2, None, None]
+            [None, box3, box5, index1, index1, index2]
         )
         assert h.getarrayitem(box4, index1, descr1) is None
 
@@ -399,10 +397,48 @@
         h.invalidate_caches(
             rop.CALL,
             FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, 
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr2]),
-            [None, None, box2, None, None]
+            [None, box3, box2, index1, index1, index2]
         )
         assert h.getarrayitem(box1, index1, descr1) is box2
 
+    def test_ll_arraycopy_result_propogated(self):
+        h = HeapCache()
+        h.setarrayitem(box1, index1, box2, descr1)
+        h.invalidate_caches(
+            rop.CALL,
+            FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, 
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
+            [None, box1, box3, index1, index1, index2]
+        )
+        assert h.getarrayitem(box3, index1, descr1) is box2
+
+    def test_ll_arraycopy_dest_new(self):
+        h = HeapCache()
+        h.new_array(box1, lengthbox1)
+        h.setarrayitem(box3, index1, box4, descr1)
+        h.invalidate_caches(
+            rop.CALL,
+            FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, 
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
+            [None, box2, box1, index1, index1, index2]
+        )
+
+    def test_ll_arraycopy_doesnt_escape_arrays(self):
+        h = HeapCache()
+        h.new_array(box1, lengthbox1)
+        h.new_array(box2, lengthbox2)
+        h.invalidate_caches(
+            rop.CALL,
+            FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, 
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
+            [None, box2, box1, index1, index1, index2]
+        )
+        assert h.is_unescaped(box1)
+        assert h.is_unescaped(box2)
+        h.invalidate_caches(
+            rop.CALL,
+            FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE, 
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
+            [None, box2, box1, index1, index1, BoxInt()]
+        )
+        assert not h.is_unescaped(box1)
+        assert not h.is_unescaped(box2)
 
     def test_unescaped(self):
         h = HeapCache()
diff --git a/rpython/rtyper/lltypesystem/rdict.py 
b/rpython/rtyper/lltypesystem/rdict.py
--- a/rpython/rtyper/lltypesystem/rdict.py
+++ b/rpython/rtyper/lltypesystem/rdict.py
@@ -162,6 +162,9 @@
                 fasthashfn = None
             else:
                 fasthashfn = self.key_repr.get_ll_fasthash_function()
+                if getattr(self.key_repr.get_ll_eq_function(),
+                           'no_direct_compare', False):
+                    entrymeths['no_direct_compare'] = True
             if fasthashfn is None:
                 entryfields.append(("f_hash", lltype.Signed))
                 entrymeths['hash'] = ll_hash_from_cache
diff --git a/rpython/rtyper/lltypesystem/rstr.py 
b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -577,9 +577,7 @@
             return -1
 
         m = len(s2.chars)
-        if m == 0:
-            return start
-        elif m == 1:
+        if m == 1:
             return cls.ll_find_char(s1, s2.chars[0], start, end)
 
         return cls.ll_search(s1, s2, start, end, FAST_FIND)
@@ -594,9 +592,7 @@
             return -1
 
         m = len(s2.chars)
-        if m == 0:
-            return end
-        elif m == 1:
+        if m == 1:
             return cls.ll_rfind_char(s1, s2.chars[0], start, end)
 
         return cls.ll_search(s1, s2, start, end, FAST_RFIND)
@@ -611,9 +607,7 @@
             return 0
 
         m = len(s2.chars)
-        if m == 0:
-            return end - start + 1
-        elif m == 1:
+        if m == 1:
             return cls.ll_count_char(s1, s2.chars[0], start, end)
 
         res = cls.ll_search(s1, s2, start, end, FAST_COUNT)
@@ -629,6 +623,14 @@
         n = end - start
         m = len(s2.chars)
 
+        if m == 0:
+            if mode == FAST_COUNT:
+                return end - start + 1
+            elif mode == FAST_RFIND:
+                return end
+            else:
+                return start
+
         w = n - m
 
         if w < 0:
diff --git a/rpython/rtyper/rint.py b/rpython/rtyper/rint.py
--- a/rpython/rtyper/rint.py
+++ b/rpython/rtyper/rint.py
@@ -251,14 +251,15 @@
         raise TyperError("not an integer: %r" % (value,))
 
     def get_ll_eq_function(self):
+        if getattr(self, '_opprefix', '?') is None:
+            return ll_eq_shortint
         return None
-    get_ll_gt_function = get_ll_eq_function
-    get_ll_lt_function = get_ll_eq_function
-    get_ll_ge_function = get_ll_eq_function
-    get_ll_le_function = get_ll_eq_function
 
     def get_ll_ge_function(self):
         return None
+    get_ll_gt_function = get_ll_ge_function
+    get_ll_lt_function = get_ll_ge_function
+    get_ll_le_function = get_ll_ge_function
 
     def get_ll_hash_function(self):
         if (sys.maxint == 2147483647 and
@@ -390,6 +391,10 @@
 def ll_hash_long_long(n):
     return intmask(intmask(n) + 9 * intmask(n >> 32))
 
+def ll_eq_shortint(n, m):
+    return intmask(n) == intmask(m)
+ll_eq_shortint.no_direct_compare = True
+
 def ll_check_chr(n):
     if 0 <= n <= 255:
         return
diff --git a/rpython/rtyper/test/test_rdict.py 
b/rpython/rtyper/test/test_rdict.py
--- a/rpython/rtyper/test/test_rdict.py
+++ b/rpython/rtyper/test/test_rdict.py
@@ -999,6 +999,26 @@
         res = f()
         assert res == 1
 
+    def test_dict_with_SHORT_keys(self):
+        def func(x):
+            d = {}
+            d[rffi.cast(rffi.SHORT, 42)] = 123
+            d[rffi.cast(rffi.SHORT, -43)] = 321
+            return d[rffi.cast(rffi.SHORT, x)]
+
+        assert self.interpret(func, [42]) == 123
+        assert self.interpret(func, [2**16 - 43]) == 321
+
+    def test_dict_with_bool_keys(self):
+        def func(x):
+            d = {}
+            d[False] = 123
+            d[True] = 321
+            return d[x == 42]
+
+        assert self.interpret(func, [5]) == 123
+        assert self.interpret(func, [42]) == 321
+
     def test_nonnull_hint(self):
         def eq(a, b):
             return a == b
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to