Author: Alex Gaynor <alex.gay...@gmail.com> Branch: numpy-full-fromstring Changeset: r50507:2fbc0588123e Date: 2011-12-14 11:26 -0500 http://bitbucket.org/pypy/pypy/changeset/2fbc0588123e/
Log: merged default in diff --git a/lib-python/modified-2.7/ctypes/test/test_callbacks.py b/lib-python/modified-2.7/ctypes/test/test_callbacks.py --- a/lib-python/modified-2.7/ctypes/test/test_callbacks.py +++ b/lib-python/modified-2.7/ctypes/test/test_callbacks.py @@ -1,5 +1,6 @@ import unittest from ctypes import * +from ctypes.test import xfail import _ctypes_test class Callbacks(unittest.TestCase): @@ -98,6 +99,7 @@ ## self.check_type(c_char_p, "abc") ## self.check_type(c_char_p, "def") + @xfail def test_pyobject(self): o = () from sys import getrefcount as grc diff --git a/lib-python/modified-2.7/ctypes/test/test_libc.py b/lib-python/modified-2.7/ctypes/test/test_libc.py --- a/lib-python/modified-2.7/ctypes/test/test_libc.py +++ b/lib-python/modified-2.7/ctypes/test/test_libc.py @@ -25,7 +25,10 @@ lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort)) self.assertEqual(chars.raw, " ,,aaaadmmmnpppsss\x00") - def test_no_more_xfail(self): + def SKIPPED_test_no_more_xfail(self): + # We decided to not explicitly support the whole ctypes-2.7 + # and instead go for a case-by-case, demand-driven approach. + # So this test is skipped instead of failing. import socket import ctypes.test self.assertTrue(not hasattr(ctypes.test, 'xfail'), diff --git a/pypy/doc/config/objspace.std.withspecialisedtuple.txt b/pypy/doc/config/objspace.std.withspecialisedtuple.txt new file mode 100644 --- /dev/null +++ b/pypy/doc/config/objspace.std.withspecialisedtuple.txt @@ -0,0 +1,3 @@ +Use "specialized tuples", a custom implementation for some common kinds +of tuples. Currently limited to tuples of length 2, in three variants: +(int, int), (float, float), and a generic (object, object). diff --git a/pypy/jit/backend/llsupport/regalloc.py b/pypy/jit/backend/llsupport/regalloc.py --- a/pypy/jit/backend/llsupport/regalloc.py +++ b/pypy/jit/backend/llsupport/regalloc.py @@ -163,7 +163,7 @@ if not we_are_translated() and self.box_types is not None: assert isinstance(v, TempBox) or v.type in self.box_types - def possibly_free_var(self, v, _hint_dont_reuse_quickly=False): + def possibly_free_var(self, v): """ If v is stored in a register and v is not used beyond the current position, then free it. Must be called at some point for all variables that might be in registers. @@ -173,10 +173,7 @@ return if v not in self.longevity or self.longevity[v][1] <= self.position: if v in self.reg_bindings: - if _hint_dont_reuse_quickly: - self.free_regs.insert(0, self.reg_bindings[v]) - else: - self.free_regs.append(self.reg_bindings[v]) + self.free_regs.append(self.reg_bindings[v]) del self.reg_bindings[v] if self.frame_manager is not None: self.frame_manager.mark_as_free(v) diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py --- a/pypy/jit/backend/x86/assembler.py +++ b/pypy/jit/backend/x86/assembler.py @@ -38,6 +38,7 @@ from pypy.jit.backend.x86.jump import remap_frame_layout from pypy.jit.codewriter.effectinfo import EffectInfo from pypy.jit.codewriter import longlong +from pypy.rlib.rarithmetic import intmask # darwin requires the stack to be 16 bytes aligned on calls. Same for gcc 4.5.0, # better safe than sorry @@ -837,7 +838,7 @@ if isinstance(loc, RegLoc) and loc.is_xmm: self.mc.SUB_ri(esp.value, 8) # = size of doubles self.mc.MOVSD_sx(0, loc.value) - elif WORD == 4 and isinstance(loc, StackLoc) and loc.width == 8: + elif WORD == 4 and isinstance(loc, StackLoc) and loc.get_width() == 8: # XXX evil trick self.mc.PUSH_b(get_ebp_ofs(loc.position)) self.mc.PUSH_b(get_ebp_ofs(loc.position + 1)) @@ -848,13 +849,25 @@ if isinstance(loc, RegLoc) and loc.is_xmm: self.mc.MOVSD_xs(loc.value, 0) self.mc.ADD_ri(esp.value, 8) # = size of doubles - elif WORD == 4 and isinstance(loc, StackLoc) and loc.width == 8: + elif WORD == 4 and isinstance(loc, StackLoc) and loc.get_width() == 8: # XXX evil trick self.mc.POP_b(get_ebp_ofs(loc.position + 1)) self.mc.POP_b(get_ebp_ofs(loc.position)) else: self.mc.POP(loc) + def regalloc_immedmem2mem(self, from_loc, to_loc): + # move a ConstFloatLoc directly to a StackLoc, as two MOVs + # (even on x86-64, because the immediates are encoded as 32 bits) + assert isinstance(from_loc, ConstFloatLoc) + assert isinstance(to_loc, StackLoc) + low_part = rffi.cast(rffi.CArrayPtr(rffi.INT), from_loc.value)[0] + high_part = rffi.cast(rffi.CArrayPtr(rffi.INT), from_loc.value)[1] + low_part = intmask(low_part) + high_part = intmask(high_part) + self.mc.MOV_bi(to_loc.value, low_part) + self.mc.MOV_bi(to_loc.value + 4, high_part) + def regalloc_perform(self, op, arglocs, resloc): genop_list[op.getopnum()](self, op, arglocs, resloc) @@ -1006,18 +1019,18 @@ self.mc.MOVSD_sx(p, loc.value) else: self.mc.MOV_sr(p, loc.value) - p += round_up_to_4(loc.width) + p += loc.get_width() p = 0 for i in range(start, n): loc = arglocs[i] if not isinstance(loc, RegLoc): - if loc.width == 8: + if loc.get_width() == 8: self.mc.MOVSD(xmm0, loc) self.mc.MOVSD_sx(p, xmm0.value) else: self.mc.MOV(tmp, loc) self.mc.MOV_sr(p, tmp.value) - p += round_up_to_4(loc.width) + p += loc.get_width() self._regalloc.reserve_param(p//WORD) # x is a location self.mc.CALL(x) @@ -2070,7 +2083,7 @@ argtypes=op.getdescr().get_arg_types(), callconv=op.getdescr().get_call_conv()) - if IS_X86_32 and isinstance(resloc, StackLoc) and resloc.width == 8: + if IS_X86_32 and isinstance(resloc, StackLoc) and resloc.type == FLOAT: # a float or a long long return if op.getdescr().get_return_type() == 'L': self.mc.MOV_br(resloc.value, eax.value) # long long @@ -2555,11 +2568,6 @@ num = getattr(rop, opname.upper()) genop_list[num] = value -def round_up_to_4(size): - if size < 4: - return 4 - return size - # XXX: ri386 migration shims: def addr_add(reg_or_imm1, reg_or_imm2, offset=0, scale=0): return AddressLoc(reg_or_imm1, reg_or_imm2, scale, offset) diff --git a/pypy/jit/backend/x86/jump.py b/pypy/jit/backend/x86/jump.py --- a/pypy/jit/backend/x86/jump.py +++ b/pypy/jit/backend/x86/jump.py @@ -1,6 +1,6 @@ import sys from pypy.tool.pairtype import extendabletype -from pypy.jit.backend.x86.regloc import ImmedLoc, StackLoc +from pypy.jit.backend.x86.regloc import ImmediateAssemblerLocation, StackLoc def remap_frame_layout(assembler, src_locations, dst_locations, tmpreg): pending_dests = len(dst_locations) @@ -12,7 +12,7 @@ srccount[key] = 0 for i in range(len(dst_locations)): src = src_locations[i] - if isinstance(src, ImmedLoc): + if isinstance(src, ImmediateAssemblerLocation): continue key = src._getregkey() if key in srccount: @@ -31,7 +31,7 @@ srccount[key] = -1 # means "it's done" pending_dests -= 1 src = src_locations[i] - if not isinstance(src, ImmedLoc): + if not isinstance(src, ImmediateAssemblerLocation): key = src._getregkey() if key in srccount: srccount[key] -= 1 @@ -66,6 +66,13 @@ def _move(assembler, src, dst, tmpreg): if dst.is_memory_reference() and src.is_memory_reference(): + if isinstance(src, ImmediateAssemblerLocation): + assembler.regalloc_immedmem2mem(src, dst) + return + if tmpreg is None: + assembler.regalloc_push(src) + assembler.regalloc_pop(dst) + return assembler.regalloc_mov(src, tmpreg) src = tmpreg assembler.regalloc_mov(src, dst) @@ -87,7 +94,7 @@ dstloc = dst_locations2[i] if isinstance(loc, StackLoc): key = loc._getregkey() - if (key in dst_keys or (loc.width > WORD and + if (key in dst_keys or (loc.get_width() > WORD and (key + WORD) in dst_keys)): assembler.regalloc_push(loc) extrapushes.append(dstloc) diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py --- a/pypy/jit/backend/x86/regalloc.py +++ b/pypy/jit/backend/x86/regalloc.py @@ -130,9 +130,9 @@ @staticmethod def frame_pos(i, box_type): if IS_X86_32 and box_type == FLOAT: - return StackLoc(i, get_ebp_ofs(i+1), 2, box_type) + return StackLoc(i, get_ebp_ofs(i+1), box_type) else: - return StackLoc(i, get_ebp_ofs(i), 1, box_type) + return StackLoc(i, get_ebp_ofs(i), box_type) @staticmethod def frame_size(box_type): if IS_X86_32 and box_type == FLOAT: @@ -174,12 +174,11 @@ operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations, allgcrefs) # compute longevity of variables - longevity = self._compute_vars_longevity(inputargs, operations) - self.longevity = longevity - self.rm = gpr_reg_mgr_cls(longevity, + self._compute_vars_longevity(inputargs, operations) + self.rm = gpr_reg_mgr_cls(self.longevity, frame_manager = self.fm, assembler = self.assembler) - self.xrm = xmm_reg_mgr_cls(longevity, frame_manager = self.fm, + self.xrm = xmm_reg_mgr_cls(self.longevity, frame_manager = self.fm, assembler = self.assembler) return operations @@ -481,7 +480,7 @@ # only to guard operations or to jump or to finish produced = {} last_used = {} - #useful = {} + last_real_usage = {} for i in range(len(operations)-1, -1, -1): op = operations[i] if op.result: @@ -492,10 +491,13 @@ opnum = op.getopnum() for j in range(op.numargs()): arg = op.getarg(j) - #if opnum != rop.JUMP and opnum != rop.FINISH: - # useful[arg] = None - if isinstance(arg, Box) and arg not in last_used: + if not isinstance(arg, Box): + continue + if arg not in last_used: last_used[arg] = i + if opnum != rop.JUMP and opnum != rop.LABEL: + if arg not in last_real_usage: + last_real_usage[arg] = i if op.is_guard(): for arg in op.getfailargs(): if arg is None: # hole @@ -503,7 +505,8 @@ assert isinstance(arg, Box) if arg not in last_used: last_used[arg] = i - + self.last_real_usage = last_real_usage + # longevity = {} for arg in produced: if arg in last_used: @@ -519,7 +522,7 @@ longevity[arg] = (0, last_used[arg]) del last_used[arg] assert len(last_used) == 0 - return longevity#, useful + self.longevity = longevity def loc(self, v): if v is None: # xxx kludgy @@ -1384,13 +1387,6 @@ assert isinstance(descr, TargetToken) arglocs = descr._x86_arglocs self.jump_target_descr = descr - # compute 'tmploc' to be all_regs[0] by spilling what is there - tmpbox1 = TempBox() - tmpbox2 = TempBox() - tmpreg = X86RegisterManager.all_regs[0] - self.rm.force_allocate_reg(tmpbox1, selected_reg=tmpreg) - xmmtmp = X86XMMRegisterManager.all_regs[0] - self.xrm.force_allocate_reg(tmpbox2, selected_reg=xmmtmp) # Part about non-floats src_locations1 = [] dst_locations1 = [] @@ -1402,19 +1398,23 @@ box = op.getarg(i) src_loc = self.loc(box) dst_loc = arglocs[i] - assert dst_loc != tmpreg and dst_loc != xmmtmp if box.type != FLOAT: src_locations1.append(src_loc) dst_locations1.append(dst_loc) else: src_locations2.append(src_loc) dst_locations2.append(dst_loc) + # Do we have a temp var? + if IS_X86_64: + tmpreg = X86_64_SCRATCH_REG + xmmtmp = X86_64_XMM_SCRATCH_REG + else: + tmpreg = None + xmmtmp = None # Do the remapping remap_frame_layout_mixed(assembler, src_locations1, dst_locations1, tmpreg, src_locations2, dst_locations2, xmmtmp) - self.rm.possibly_free_var(tmpbox1) - self.xrm.possibly_free_var(tmpbox2) self.possibly_free_vars_for_op(op) assembler.closing_jump(self.jump_target_descr) @@ -1471,16 +1471,15 @@ inputargs = op.getarglist() arglocs = [None] * len(inputargs) # - # we need to make sure that the tmpreg and xmmtmp are free - tmpreg = X86RegisterManager.all_regs[0] - tmpvar = TempBox() - self.rm.force_allocate_reg(tmpvar, selected_reg=tmpreg) - self.rm.possibly_free_var(tmpvar, _hint_dont_reuse_quickly=True) - # - xmmtmp = X86XMMRegisterManager.all_regs[0] - tmpvar = TempBox() - self.xrm.force_allocate_reg(tmpvar, selected_reg=xmmtmp) - self.xrm.possibly_free_var(tmpvar, _hint_dont_reuse_quickly=True) + # we use force_spill() on the boxes that are not going to be really + # used any more in the loop, but that are kept alive anyway + # by being in a next LABEL's or a JUMP's argument or fail_args + # of some guard + position = self.rm.position + for arg in inputargs: + assert isinstance(arg, Box) + if self.last_real_usage.get(arg, -1) <= position: + self.force_spill_var(arg) # # we need to make sure that no variable is stored in ebp for arg in inputargs: @@ -1491,9 +1490,9 @@ # for i in range(len(inputargs)): arg = inputargs[i] - assert not isinstance(arg, Const) + assert isinstance(arg, Box) loc = self.loc(arg) - assert not (loc is tmpreg or loc is xmmtmp or loc is ebp) + assert loc is not ebp arglocs[i] = loc if isinstance(loc, RegLoc): self.fm.mark_as_free(arg) diff --git a/pypy/jit/backend/x86/regloc.py b/pypy/jit/backend/x86/regloc.py --- a/pypy/jit/backend/x86/regloc.py +++ b/pypy/jit/backend/x86/regloc.py @@ -16,8 +16,7 @@ # class AssemblerLocation(object): - # XXX: Is adding "width" here correct? - _attrs_ = ('value', 'width', '_location_code') + _attrs_ = ('value', '_location_code') _immutable_ = True def _getregkey(self): return self.value @@ -28,6 +27,9 @@ def location_code(self): return self._location_code + def get_width(self): + raise NotImplementedError + def value_r(self): return self.value def value_b(self): return self.value def value_s(self): return self.value @@ -43,13 +45,21 @@ _immutable_ = True _location_code = 'b' - def __init__(self, position, ebp_offset, num_words, type): + def __init__(self, position, ebp_offset, type): + # _getregkey() returns self.value; the value returned must not + # conflict with RegLoc._getregkey(). It doesn't a bit by chance, + # so let it fail the following assert if it no longer does. + assert not (0 <= ebp_offset < 8 + 8 * IS_X86_64) self.position = position self.value = ebp_offset - self.width = num_words * WORD # One of INT, REF, FLOAT self.type = type + def get_width(self): + if self.type == FLOAT: + return 8 + return WORD + def __repr__(self): return '%d(%%ebp)' % (self.value,) @@ -63,10 +73,8 @@ self.value = regnum self.is_xmm = is_xmm if self.is_xmm: - self.width = 8 self._location_code = 'x' else: - self.width = WORD self._location_code = 'r' def __repr__(self): if self.is_xmm: @@ -74,6 +82,11 @@ else: return rx86.R.names[self.value] + def get_width(self): + if self.is_xmm: + return 8 + return WORD + def lowest8bits(self): assert not self.is_xmm return RegLoc(rx86.low_byte(self.value), False) @@ -91,9 +104,11 @@ else: return eax -class ImmedLoc(AssemblerLocation): +class ImmediateAssemblerLocation(AssemblerLocation): _immutable_ = True - width = WORD + +class ImmedLoc(ImmediateAssemblerLocation): + _immutable_ = True _location_code = 'i' def __init__(self, value): @@ -104,6 +119,9 @@ def getint(self): return self.value + def get_width(self): + return WORD + def __repr__(self): return "ImmedLoc(%d)" % (self.value) @@ -116,7 +134,6 @@ class AddressLoc(AssemblerLocation): _immutable_ = True - width = WORD # The address is base_loc + (scaled_loc << scale) + static_offset def __init__(self, base_loc, scaled_loc, scale=0, static_offset=0): assert 0 <= scale < 4 @@ -145,6 +162,9 @@ info = getattr(self, attr, '?') return '<AddressLoc %r: %s>' % (self._location_code, info) + def get_width(self): + return WORD + def value_a(self): return self.loc_a @@ -179,32 +199,34 @@ raise AssertionError(self._location_code) return result -class ConstFloatLoc(AssemblerLocation): - # XXX: We have to use this class instead of just AddressLoc because - # we want a width of 8 (... I think. Check this!) +class ConstFloatLoc(ImmediateAssemblerLocation): _immutable_ = True - width = 8 _location_code = 'j' def __init__(self, address): self.value = address + def get_width(self): + return 8 + def __repr__(self): return '<ConstFloatLoc @%s>' % (self.value,) if IS_X86_32: - class FloatImmedLoc(AssemblerLocation): + class FloatImmedLoc(ImmediateAssemblerLocation): # This stands for an immediate float. It cannot be directly used in # any assembler instruction. Instead, it is meant to be decomposed # in two 32-bit halves. On 64-bit, FloatImmedLoc() is a function # instead; see below. _immutable_ = True - width = 8 _location_code = '#' # don't use me def __init__(self, floatstorage): self.aslonglong = floatstorage + def get_width(self): + return 8 + def low_part(self): return intmask(self.aslonglong) diff --git a/pypy/jit/backend/x86/test/test_jump.py b/pypy/jit/backend/x86/test/test_jump.py --- a/pypy/jit/backend/x86/test/test_jump.py +++ b/pypy/jit/backend/x86/test/test_jump.py @@ -71,6 +71,18 @@ ('mov', eax, s24), ('mov', s12, edi)] +def test_no_tmp_reg(): + assembler = MockAssembler() + s8 = frame_pos(0, INT) + s12 = frame_pos(13, INT) + s20 = frame_pos(20, INT) + s24 = frame_pos(221, INT) + remap_frame_layout(assembler, [s8, eax, s12], [s20, s24, edi], None) + assert assembler.ops == [('push', s8), + ('pop', s20), + ('mov', eax, s24), + ('mov', s12, edi)] + def test_reordering(): assembler = MockAssembler() s8 = frame_pos(8, INT) diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -381,11 +381,11 @@ 'GUARD_ISNULL/1d', 'GUARD_NONNULL_CLASS/2d', '_GUARD_FOLDABLE_LAST', - 'GUARD_NO_EXCEPTION/0d', - 'GUARD_EXCEPTION/1d', + 'GUARD_NO_EXCEPTION/0d', # may be called with an exception currently set + 'GUARD_EXCEPTION/1d', # may be called with an exception currently set 'GUARD_NO_OVERFLOW/0d', 'GUARD_OVERFLOW/0d', - 'GUARD_NOT_FORCED/0d', + 'GUARD_NOT_FORCED/0d', # may be called with an exception currently set 'GUARD_NOT_INVALIDATED/0d', '_GUARD_LAST', # ----- end of guard operations ----- diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py --- a/pypy/module/micronumpy/__init__.py +++ b/pypy/module/micronumpy/__init__.py @@ -1,9 +1,19 @@ from pypy.interpreter.mixedmodule import MixedModule +class PyPyModule(MixedModule): + interpleveldefs = { + 'debug_repr': 'interp_extras.debug_repr', + } + appleveldefs = {} + class Module(MixedModule): applevel_name = 'numpypy' + submodules = { + 'pypy': PyPyModule + } + interpleveldefs = { 'ndarray': 'interp_numarray.W_NDimArray', 'dtype': 'interp_dtype.W_Dtype', @@ -81,6 +91,7 @@ 'mean': 'app_numpy.mean', 'sum': 'app_numpy.sum', 'min': 'app_numpy.min', + 'identity': 'app_numpy.identity', 'max': 'app_numpy.max', 'inf': 'app_numpy.inf', 'e': 'app_numpy.e', diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py --- a/pypy/module/micronumpy/app_numpy.py +++ b/pypy/module/micronumpy/app_numpy.py @@ -13,6 +13,11 @@ # weighting, just the average part! return mean(a) +def identity(n, dtype=None): + a = numpypy.zeros((n,n), dtype=dtype) + for i in range(n): + a[i][i] = 1 + return a def mean(a): if not hasattr(a, "mean"): diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -86,6 +86,7 @@ descr_ge = _binop_impl("greater_equal") descr_radd = _binop_right_impl("add") + descr_rsub = _binop_right_impl("subtract") descr_rmul = _binop_right_impl("multiply") descr_neg = _unaryop_impl("negative") @@ -170,7 +171,8 @@ __mul__ = interp2app(W_GenericBox.descr_mul), __div__ = interp2app(W_GenericBox.descr_div), - __radd__ = interp2app(W_GenericBox.descr_add), + __radd__ = interp2app(W_GenericBox.descr_radd), + __rsub__ = interp2app(W_GenericBox.descr_rsub), __rmul__ = interp2app(W_GenericBox.descr_rmul), __eq__ = interp2app(W_GenericBox.descr_eq), diff --git a/pypy/module/micronumpy/interp_extras.py b/pypy/module/micronumpy/interp_extras.py new file mode 100644 --- /dev/null +++ b/pypy/module/micronumpy/interp_extras.py @@ -0,0 +1,7 @@ +from pypy.interpreter.gateway import unwrap_spec +from pypy.module.micronumpy.interp_numarray import BaseArray + + +@unwrap_spec(array=BaseArray) +def debug_repr(space, array): + return space.wrap(array.debug_repr()) 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 @@ -791,7 +791,8 @@ raise OperationError(space.w_IndexError, space.wrap( "0-d arrays can't be indexed")) item = concrete._index_of_single_item(space, w_idx) - concrete.setitem_w(space, item, w_value) + dtype = concrete.find_dtype() + concrete.setitem(item, dtype.coerce(space, w_value)) return if not isinstance(w_value, BaseArray): w_value = convert_to_array(space, w_value) @@ -924,9 +925,6 @@ def start_iter(self, res_shape=None): raise NotImplementedError - def descr_debug_repr(self, space): - return space.wrap(self.debug_repr()) - def descr_array_iface(self, space): concrete = self.get_concrete() storage = concrete.get_storage(space) @@ -1178,10 +1176,6 @@ def eval(self, iter): return self.parent.getitem(iter.get_offset()) - @unwrap_spec(item=int) - def setitem_w(self, space, item, w_value): - return self.parent.setitem_w(space, item, w_value) - def setitem(self, item, value): # This is currently not possible to be called from anywhere. raise NotImplementedError @@ -1330,9 +1324,6 @@ raise OperationError(space.w_TypeError, space.wrap( "len() of unsized object")) - def setitem_w(self, space, item, w_value): - return self.setitem(item, self.dtype.coerce(space, w_value)) - def setitem(self, item, value): self.invalidated() self.dtype.setitem(self.storage, item, value) @@ -1472,7 +1463,6 @@ __repr__ = interp2app(BaseArray.descr_repr), __str__ = interp2app(BaseArray.descr_str), - __debug_repr__ = interp2app(BaseArray.descr_debug_repr), __array_interface__ = GetSetProperty(BaseArray.descr_array_iface), dtype = GetSetProperty(BaseArray.descr_get_dtype), diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -259,22 +259,31 @@ assert numpy.uint16('65536') == 0 def test_int32(self): + import sys import numpypy as numpy x = numpy.int32(23) assert x == 23 assert numpy.int32(2147483647) == 2147483647 - assert numpy.int32(2147483648) == -2147483648 assert numpy.int32('2147483647') == 2147483647 - assert numpy.int32('2147483648') == -2147483648 + if sys.maxint > 2 ** 31 - 1: + assert numpy.int32(2147483648) == -2147483648 + assert numpy.int32('2147483648') == -2147483648 + else: + raises(OverflowError, numpy.int32, 2147483648) + raises(OverflowError, numpy.int32, '2147483648') def test_uint32(self): + import sys import numpypy as numpy - assert numpy.uint32(4294967295) == 4294967295 - assert numpy.uint32(4294967296) == 0 - assert numpy.uint32('4294967295') == 4294967295 - assert numpy.uint32('4294967296') == 0 + assert numpy.uint32(10) == 10 + + if sys.maxint > 2 ** 31 - 1: + assert numpy.uint32(4294967295) == 4294967295 + assert numpy.uint32(4294967296) == 0 + assert numpy.uint32('4294967295') == 4294967295 + assert numpy.uint32('4294967296') == 0 def test_int_(self): import numpypy as numpy @@ -294,10 +303,14 @@ assert numpy.dtype(numpy.int64).type is numpy.int64 assert numpy.int64(3) == 3 - assert numpy.int64(9223372036854775807) == 9223372036854775807 + if sys.maxint >= 2 ** 63 - 1: + assert numpy.int64(9223372036854775807) == 9223372036854775807 + assert numpy.int64('9223372036854775807') == 9223372036854775807 + else: + raises(OverflowError, numpy.int64, 9223372036854775807) + raises(OverflowError, numpy.int64, '9223372036854775807') + raises(OverflowError, numpy.int64, 9223372036854775808) - - assert numpy.int64('9223372036854775807') == 9223372036854775807 raises(OverflowError, numpy.int64, '9223372036854775808') def test_uint64(self): diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -491,6 +491,11 @@ for i in range(5): assert b[i] == i - 5 + def test_scalar_subtract(self): + from numpypy import int32 + assert int32(2) - 1 == 1 + assert 1 - int32(2) == -1 + def test_mul(self): import numpypy @@ -722,6 +727,26 @@ a = array([True] * 5, bool) assert a.sum() == 5 + def test_identity(self): + from numpypy import identity, array + from numpypy import int32, float64, dtype + a = identity(0) + assert len(a) == 0 + assert a.dtype == dtype('float64') + assert a.shape == (0,0) + b = identity(1, dtype=int32) + assert len(b) == 1 + assert b[0][0] == 1 + assert b.shape == (1,1) + assert b.dtype == dtype('int32') + c = identity(2) + assert c.shape == (2,2) + assert (c == [[1,0],[0,1]]).all() + d = identity(3, dtype='int32') + assert d.shape == (3,3) + assert d.dtype == dtype('int32') + assert (d == [[1,0,0],[0,1,0],[0,0,1]]).all() + def test_prod(self): from numpypy import array a = array(range(1, 6)) @@ -868,16 +893,17 @@ def test_debug_repr(self): from numpypy import zeros, sin + from numpypy.pypy import debug_repr a = zeros(1) - assert a.__debug_repr__() == 'Array' - assert (a + a).__debug_repr__() == 'Call2(add, Array, Array)' - assert (a[::2]).__debug_repr__() == 'Slice(Array)' - assert (a + 2).__debug_repr__() == 'Call2(add, Array, Scalar)' - assert (a + a.flat).__debug_repr__() == 'Call2(add, Array, FlatIter(Array))' - assert sin(a).__debug_repr__() == 'Call1(sin, Array)' + assert debug_repr(a) == 'Array' + assert debug_repr(a + a) == 'Call2(add, Array, Array)' + assert debug_repr(a[::2]) == 'Slice(Array)' + assert debug_repr(a + 2) == 'Call2(add, Array, Scalar)' + assert debug_repr(a + a.flat) == 'Call2(add, Array, FlatIter(Array))' + assert debug_repr(sin(a)) == 'Call1(sin, Array)' b = a + a b[0] = 3 - assert b.__debug_repr__() == 'Call2(add, forced=Array)' + assert debug_repr(b) == 'Call2(add, forced=Array)' def test_tolist_scalar(self): from numpypy import int32, bool_ diff --git a/pypy/module/pypyjit/test_pypy_c/model.py b/pypy/module/pypyjit/test_pypy_c/model.py --- a/pypy/module/pypyjit/test_pypy_c/model.py +++ b/pypy/module/pypyjit/test_pypy_c/model.py @@ -210,9 +210,9 @@ def entry_bridge_ops(self, *args, **kwds): ops = list(self._allops(*args, **kwds)) labels = [op for op in ops if op.name == 'label'] - assert ops.index(labels[0]) == 0 - i = ops.index(labels[1]) - return ops[1:i] + i0 = ops.index(labels[0]) + i1 = ops.index(labels[1]) + return ops[i0+1:i1] @property def chunks(self): @@ -409,7 +409,7 @@ """ iter_exp_ops = iter(expected_ops) iter_ops = RevertableIterator(self.ops) - for opindex, exp_op in enumerate(iter_exp_ops): + for exp_op in iter_exp_ops: try: if exp_op == '...': # loop until we find an operation which matches @@ -430,7 +430,7 @@ if exp_op[4] is False: # optional operation iter_ops.revert_one() continue # try to match with the next exp_op - e.opindex = opindex + e.opindex = iter_ops.index - 1 raise # # make sure we exhausted iter_ops diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py b/pypy/module/pypyjit/test_pypy_c/test_00_model.py --- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py +++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py @@ -45,8 +45,10 @@ cmdline = [sys.executable] if not import_site: cmdline.append('-S') - for key, value in jitopts.iteritems(): - cmdline += ['--jit', '%s=%s' % (key, value)] + if jitopts: + jitcmdline = ['%s=%s' % (key, value) + for key, value in jitopts.items()] + cmdline += ['--jit', ','.join(jitcmdline)] cmdline.append(str(self.filepath)) # print cmdline, logfile diff --git a/pypy/module/pypyjit/test_pypy_c/test_generators.py b/pypy/module/pypyjit/test_pypy_c/test_generators.py --- a/pypy/module/pypyjit/test_pypy_c/test_generators.py +++ b/pypy/module/pypyjit/test_pypy_c/test_generators.py @@ -6,6 +6,8 @@ def main(n): def f(): for i in range(10000): + i -= 1 + i -= 42 # ID: subtract yield i def g(): @@ -15,6 +17,13 @@ g() log = self.run(main, [500]) + # XXX XXX this test fails so far because of a detail that + # changed with jit-simplify-backendintf. We should try to + # think of a way to be more resistent against such details. + # The issue is that we now get one Tracing, then go back + # to the interpreter hoping to immediately run the JITted + # code; but instead, we Trace again, just because another + # counter was also about to reach its limit... loop, = log.loops_by_filename(self.filepath, is_entry_bridge='*') assert loop.match_by_id("generator", """ ... @@ -26,3 +35,8 @@ i47 = arraylen_gc(p8, descr=<GcPtrArrayDescr>) # Should be removed by backend jump(..., descr=...) """) + assert loop.match_by_id("subtract", """ + setfield_gc(p7, 35, descr=<.*last_instr .*>) # XXX bad, kill me + i2 = int_sub_ovf(i1, 42) + guard_no_overflow(descr=...) + """) diff --git a/pypy/objspace/std/specialisedtupleobject.py b/pypy/objspace/std/specialisedtupleobject.py --- a/pypy/objspace/std/specialisedtupleobject.py +++ b/pypy/objspace/std/specialisedtupleobject.py @@ -177,52 +177,55 @@ _specialisations = [] Cls_ii = make_specialised_class((int, int)) -Cls_is = make_specialised_class((int, str)) -Cls_io = make_specialised_class((int, object)) -Cls_si = make_specialised_class((str, int)) -Cls_ss = make_specialised_class((str, str)) -Cls_so = make_specialised_class((str, object)) -Cls_oi = make_specialised_class((object, int)) -Cls_os = make_specialised_class((object, str)) +#Cls_is = make_specialised_class((int, str)) +#Cls_io = make_specialised_class((int, object)) +#Cls_si = make_specialised_class((str, int)) +#Cls_ss = make_specialised_class((str, str)) +#Cls_so = make_specialised_class((str, object)) +#Cls_oi = make_specialised_class((object, int)) +#Cls_os = make_specialised_class((object, str)) Cls_oo = make_specialised_class((object, object)) Cls_ff = make_specialised_class((float, float)) -Cls_ooo = make_specialised_class((object, object, object)) +#Cls_ooo = make_specialised_class((object, object, object)) def makespecialisedtuple(space, list_w): if len(list_w) == 2: w_arg1, w_arg2 = list_w w_type1 = space.type(w_arg1) - w_type2 = space.type(w_arg2) + #w_type2 = space.type(w_arg2) # if w_type1 is space.w_int: + w_type2 = space.type(w_arg2) if w_type2 is space.w_int: return Cls_ii(space, w_arg1, w_arg2) - elif w_type2 is space.w_str: - return Cls_is(space, w_arg1, w_arg2) - else: - return Cls_io(space, w_arg1, w_arg2) + #elif w_type2 is space.w_str: + # return Cls_is(space, w_arg1, w_arg2) + #else: + # return Cls_io(space, w_arg1, w_arg2) # - elif w_type1 is space.w_str: - if w_type2 is space.w_int: - return Cls_si(space, w_arg1, w_arg2) - elif w_type2 is space.w_str: - return Cls_ss(space, w_arg1, w_arg2) - else: - return Cls_so(space, w_arg1, w_arg2) + #elif w_type1 is space.w_str: + # if w_type2 is space.w_int: + # return Cls_si(space, w_arg1, w_arg2) + # elif w_type2 is space.w_str: + # return Cls_ss(space, w_arg1, w_arg2) + # else: + # return Cls_so(space, w_arg1, w_arg2) # - elif w_type1 is space.w_float and w_type2 is space.w_float: - return Cls_ff(space, w_arg1, w_arg2) + elif w_type1 is space.w_float: + w_type2 = space.type(w_arg2) + if w_type2 is space.w_float: + return Cls_ff(space, w_arg1, w_arg2) # - else: - if w_type2 is space.w_int: - return Cls_oi(space, w_arg1, w_arg2) - elif w_type2 is space.w_str: - return Cls_os(space, w_arg1, w_arg2) - else: - return Cls_oo(space, w_arg1, w_arg2) + #else: + # if w_type2 is space.w_int: + # return Cls_oi(space, w_arg1, w_arg2) + # elif w_type2 is space.w_str: + # return Cls_os(space, w_arg1, w_arg2) + # else: + return Cls_oo(space, w_arg1, w_arg2) # - elif len(list_w) == 3: - return Cls_ooo(space, list_w[0], list_w[1], list_w[2]) + #elif len(list_w) == 3: + # return Cls_ooo(space, list_w[0], list_w[1], list_w[2]) else: raise NotSpecialised diff --git a/pypy/objspace/std/test/test_specialisedtupleobject.py b/pypy/objspace/std/test/test_specialisedtupleobject.py --- a/pypy/objspace/std/test/test_specialisedtupleobject.py +++ b/pypy/objspace/std/test/test_specialisedtupleobject.py @@ -33,15 +33,15 @@ N_space = gettestobjspace(**{"objspace.std.withspecialisedtuple": False}) S_space = gettestobjspace(**{"objspace.std.withspecialisedtuple": True}) - def hash_test(values): + def hash_test(values, must_be_specialized=True): N_values_w = [N_space.wrap(value) for value in values] S_values_w = [S_space.wrap(value) for value in values] N_w_tuple = N_space.newtuple(N_values_w) S_w_tuple = S_space.newtuple(S_values_w) - - assert isinstance(S_w_tuple, W_SpecialisedTupleObject) + + if must_be_specialized: + assert isinstance(S_w_tuple, W_SpecialisedTupleObject) assert isinstance(N_w_tuple, W_TupleObject) - assert not N_space.is_true(N_space.eq(N_w_tuple, S_w_tuple)) assert S_space.is_true(S_space.eq(N_w_tuple, S_w_tuple)) assert S_space.is_true(S_space.eq(N_space.hash(N_w_tuple), S_space.hash(S_w_tuple))) @@ -53,7 +53,7 @@ hash_test([1,(1,2)]) hash_test([1,('a',2)]) hash_test([1,()]) - hash_test([1,2,3]) + hash_test([1,2,3], must_be_specialized=False) class AppTestW_SpecialisedTupleObject: @@ -83,6 +83,8 @@ return ("SpecialisedTupleObject" + expected) in r def test_createspecialisedtuple(self): + have = ['ii', 'ff', 'oo'] + # spec = {int: 'i', float: 'f', str: 's', @@ -92,14 +94,14 @@ for y in [43, 4.3, "bar", []]: expected1 = spec[type(x)] expected2 = spec[type(y)] - if (expected1 == 'f') ^ (expected2 == 'f'): - if expected1 == 'f': expected1 = 'o' - if expected2 == 'f': expected2 = 'o' + if expected1 + expected2 not in have: + expected1 = expected2 = 'o' obj = (x, y) assert self.isspecialised(obj, '_' + expected1 + expected2) # - obj = (1, 2, 3) - assert self.isspecialised(obj, '_ooo') + if 'ooo' in have: + obj = (1, 2, 3) + assert self.isspecialised(obj, '_ooo') def test_delegation(self): t = self.forbid_delegation((42, 43)) @@ -214,6 +216,8 @@ raises(IndexError, "t[-3]") def test_three_tuples(self): + if not self.isspecialised((1, 2, 3)): + skip("don't have specialization for 3-tuples") b = self.forbid_delegation((1, 2, 3)) c = (1,) d = c + (2, 3) @@ -221,6 +225,16 @@ assert b == d def test_mongrel(self): + a = self.forbid_delegation((2.2, '333')) + assert self.isspecialised(a) + assert len(a) == 2 + assert a[0] == 2.2 and a[1] == '333' + b = ('333',) + assert a == (2.2,) + b + assert not a != (2.2,) + b + # + if not self.isspecialised((1, 2, 3)): + skip("don't have specialization for 3-tuples") a = self.forbid_delegation((1, 2.2, '333')) assert self.isspecialised(a) assert len(a) == 3 diff --git a/pypy/objspace/std/typetype.py b/pypy/objspace/std/typetype.py --- a/pypy/objspace/std/typetype.py +++ b/pypy/objspace/std/typetype.py @@ -10,7 +10,6 @@ w_dict=gateway.NoneNotWrapped): "This is used to create user-defined classes only." - from pypy.objspace.std.typeobject import W_TypeObject # XXX check types w_typetype = _precheck_for_new(space, w_typetype) @@ -19,10 +18,18 @@ if (space.is_w(space.type(w_typetype), space.w_type) and w_bases is None and w_dict is None): return space.type(w_name) - elif w_bases is None or w_dict is None: + else: + return _create_new_type(space, w_typetype, w_name, w_bases, w_dict) + + +def _create_new_type(space, w_typetype, w_name, w_bases, w_dict): + # this is in its own function because we want the special case 'type(x)' + # above to be seen by the jit. + from pypy.objspace.std.typeobject import W_TypeObject + + if w_bases is None or w_dict is None: raise OperationError(space.w_TypeError, space.wrap("type() takes 1 or 3 arguments")) - bases_w = space.fixedview(w_bases) w_winner = w_typetype _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit