Author: Maciej Fijalkowski <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit