Author: Armin Rigo <ar...@tunes.org> Branch: py3.5 Changeset: r88272:5980a1419dc2 Date: 2016-11-09 15:04 +0100 http://bitbucket.org/pypy/pypy/changeset/5980a1419dc2/
Log: hg merge default diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -34,7 +34,12 @@ if w_dict is not None: # for tests w_entry_point = space.getitem(w_dict, space.wrap('entry_point')) w_run_toplevel = space.getitem(w_dict, space.wrap('run_toplevel')) + w_initstdio = space.getitem(w_dict, space.wrap('initstdio')) withjit = space.config.objspace.usemodules.pypyjit + else: + w_initstdio = space.appexec([], """(): + return lambda unbuffered: None + """) def entry_point(argv): if withjit: @@ -110,18 +115,23 @@ " not found in %s or in any parent directory" % home1) return rffi.cast(rffi.INT, 1) space.startup() - space.appexec([w_path], """(path): - import sys - sys.path[:] = path - """) - # import site + must_leave = space.threadlocals.try_enter_thread(space) try: - space.setattr(space.getbuiltinmodule('sys'), - space.wrap('executable'), - space.wrap(home)) - import_ = space.getattr(space.getbuiltinmodule('builtins'), - space.wrap('__import__')) - space.call_function(import_, space.wrap('site')) + # initialize sys.{path,executable,stdin,stdout,stderr} + # (in unbuffered mode, to avoid troubles) and import site + space.appexec([w_path, space.wrap(home), w_initstdio], + r"""(path, home, initstdio): + import sys + sys.path[:] = path + sys.executable = home + initstdio(unbuffered=True) + try: + import site + except Exception as e: + sys.stderr.write("'import site' failed:\n") + import traceback + traceback.print_exc() + """) return rffi.cast(rffi.INT, 0) except OperationError as e: if verbose: @@ -129,6 +139,9 @@ debug(" operror-type: " + e.w_type.getname(space).encode('utf-8')) debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space)))) return rffi.cast(rffi.INT, -1) + finally: + if must_leave: + space.threadlocals.leave_thread(space) @entrypoint_highlevel('main', [rffi.CCHARP], c_name='pypy_execute_source') def pypy_execute_source(ll_source): diff --git a/pypy/interpreter/test/test_targetpypy.py b/pypy/interpreter/test/test_targetpypy.py --- a/pypy/interpreter/test/test_targetpypy.py +++ b/pypy/interpreter/test/test_targetpypy.py @@ -20,7 +20,7 @@ space.wrap('modules')), space.wrap('xyz'))) assert x == 3 - lls = rffi.str2charp("sys") + lls = rffi.str2charp("sys # should give a NameError") execute_source(lls) lltype.free(lls, flavor='raw') # did not crash - the same globals diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -71,7 +71,6 @@ def startup(self, space): from pypy.module._cffi_backend import embedding embedding.glob.space = space - embedding.glob.patched_sys = False def get_dict_rtld_constants(): diff --git a/pypy/module/_cffi_backend/embedding.py b/pypy/module/_cffi_backend/embedding.py --- a/pypy/module/_cffi_backend/embedding.py +++ b/pypy/module/_cffi_backend/embedding.py @@ -45,25 +45,6 @@ pass glob = Global() -def patch_sys(space): - # Annoying: CPython would just use the C-level std{in,out,err} as - # configured by the main application, for example in binary mode - # on Windows or with buffering turned off. We can't easily do the - # same. Instead, go for the safest bet (but possibly bad for - # performance) and open sys.std{in,out,err} unbuffered. On - # Windows I guess binary mode is a better default choice. - # - # XXX if needed, we could add support for a flag passed to - # pypy_init_embedded_cffi_module(). - if not glob.patched_sys: - space.appexec([], """(): - import os, sys - sys.stdin = sys.__stdin__ = os.fdopen(0, 'rb', 0) - sys.stdout = sys.__stdout__ = os.fdopen(1, 'wb', 0) - sys.stderr = sys.__stderr__ = os.fdopen(2, 'wb', 0) - """) - glob.patched_sys = True - def pypy_init_embedded_cffi_module(version, init_struct): # called from __init__.py @@ -76,7 +57,6 @@ must_leave = False try: must_leave = space.threadlocals.try_enter_thread(space) - patch_sys(space) load_embedded_cffi_module(space, version, init_struct) res = 0 except OperationError as operr: diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py --- a/rpython/jit/backend/llgraph/runner.py +++ b/rpython/jit/backend/llgraph/runner.py @@ -18,7 +18,7 @@ from rpython.rtyper import rclass from rpython.rlib.clibffi import FFI_DEFAULT_ABI -from rpython.rlib.rarithmetic import ovfcheck, r_uint, r_ulonglong +from rpython.rlib.rarithmetic import ovfcheck, r_uint, r_ulonglong, intmask from rpython.rlib.objectmodel import Symbolic class LLAsmInfo(object): @@ -840,6 +840,11 @@ vector_arith_code = """ def bh_vec_{0}_{1}(self, vx, vy, count): assert len(vx) == len(vy) == count + return [intmask(_vx {2} _vy) for _vx,_vy in zip(vx,vy)] + """ + vector_float_arith_code = """ + def bh_vec_{0}_{1}(self, vx, vy, count): + assert len(vx) == len(vy) == count return [_vx {2} _vy for _vx,_vy in zip(vx,vy)] """ exec py.code.Source(vector_arith_code.format('int','add','+')).compile() @@ -847,11 +852,12 @@ exec py.code.Source(vector_arith_code.format('int','mul','*')).compile() exec py.code.Source(vector_arith_code.format('int','and','&')).compile() exec py.code.Source(vector_arith_code.format('int','or','|')).compile() - exec py.code.Source(vector_arith_code.format('float','add','+')).compile() - exec py.code.Source(vector_arith_code.format('float','sub','-')).compile() - exec py.code.Source(vector_arith_code.format('float','mul','*')).compile() - exec py.code.Source(vector_arith_code.format('float','truediv','/')).compile() - exec py.code.Source(vector_arith_code.format('float','eq','==')).compile() + + exec py.code.Source(vector_float_arith_code.format('float','add','+')).compile() + exec py.code.Source(vector_float_arith_code.format('float','sub','-')).compile() + exec py.code.Source(vector_float_arith_code.format('float','mul','*')).compile() + exec py.code.Source(vector_float_arith_code.format('float','truediv','/')).compile() + exec py.code.Source(vector_float_arith_code.format('float','eq','==')).compile() def bh_vec_float_neg(self, vx, count): return [e * -1 for e in vx] @@ -891,9 +897,6 @@ return [longlong.getfloatstorage(float(longlong.int2singlefloat(v))) for v in vx] - a = float(a) - return longlong.getfloatstorage(a) - def bh_vec_cast_float_to_int(self, vx, count): return [int(x) for x in vx] @@ -934,27 +937,26 @@ return [heaptracker.int_signext(_vx, ext) for _vx in vx] def build_load(func): - def method(self, struct, offset, scale, disp, descr, _count): + def load(self, struct, offset, scale, disp, descr, _count): values = [] count = self.vector_ext.vec_size() // descr.get_item_size_in_bytes() assert _count == count assert count > 0 - adr = struct + (offset * scale + disp) + adr = support.addr_add_bytes(struct, (offset * scale + disp)) a = support.cast_arg(lltype.Ptr(descr.A), adr) array = a._obj for i in range(count): val = support.cast_result(descr.A.OF, array.getitem(i)) values.append(val) return values - return method + return load bh_vec_load_i = build_load(bh_getarrayitem_raw) bh_vec_load_f = build_load(bh_getarrayitem_raw) del build_load def bh_vec_store(self, struct, offset, newvalues, scale, disp, descr, count): - stride = descr.get_item_size_in_bytes() - adr = struct + (offset * scale + disp) + adr = support.addr_add_bytes(struct, offset * scale + disp) a = support.cast_arg(lltype.Ptr(descr.A), adr) array = a._obj for i,n in enumerate(newvalues): @@ -1557,7 +1559,7 @@ if opname.startswith('vec_'): # pre vector op count = self.current_op.count - assert count >= 1 + assert count >= 0 new_args = new_args + (count,) result = getattr(self.cpu, 'bh_' + opname)(*new_args) if isinstance(result, list): diff --git a/rpython/jit/backend/llgraph/support.py b/rpython/jit/backend/llgraph/support.py --- a/rpython/jit/backend/llgraph/support.py +++ b/rpython/jit/backend/llgraph/support.py @@ -156,3 +156,11 @@ call_args.append(n) assert i == len(args) return call_args + +def addr_add_bytes(addr, ofs): + if (isinstance(ofs, int) and + getattr(addr.adr.ptr._TYPE.TO, 'OF', None) == lltype.Char): + return addr + ofs + ptr = rffi.cast(rffi.CCHARP, addr.adr) + ptr = lltype.direct_ptradd(ptr, ofs) + return cast_to_int(ptr) diff --git a/rpython/jit/backend/ppc/test/test_form.py b/rpython/jit/backend/ppc/test/test_form.py --- a/rpython/jit/backend/ppc/test/test_form.py +++ b/rpython/jit/backend/ppc/test/test_form.py @@ -1,6 +1,3 @@ -from rpython.jit.backend.ppc.codebuilder import b -import random -import sys from py.test import raises from rpython.jit.backend.ppc.form import Form, FormException @@ -28,18 +25,18 @@ w = a.insts[-1].assemble() return struct.pack('>i', w) -class TestForm(Form): +class TForm(Form): fieldmap = test_fieldmap class TestForms(object): def test_bitclash(self): - raises(FormException, TestForm, 'h', 'hh') - raises(FormException, TestForm, + raises(FormException, TForm, 'h', 'hh') + raises(FormException, TForm, Field('t1', 0, 0), Field('t2', 0, 0)) def test_basic(self): class T(Assembler): - i = TestForm('h', 'l')() + i = TForm('h', 'l')() j = i(h=1) k = i(l=3) raises(FormException, k, l=0) @@ -56,7 +53,7 @@ def test_defdesc(self): class T(Assembler): - i = TestForm('hh', 'hl', 'lh', 'll')() + i = TForm('hh', 'hl', 'lh', 'll')() i.default(hl=0).default(hh=1) insts = [] a = T() diff --git a/rpython/jit/backend/ppc/test/test_ppc.py b/rpython/jit/backend/ppc/test/test_ppc.py --- a/rpython/jit/backend/ppc/test/test_ppc.py +++ b/rpython/jit/backend/ppc/test/test_ppc.py @@ -199,9 +199,9 @@ a.load_imm(r10, call_addr) elif IS_BIG_ENDIAN: # load the 3-words descriptor - a.load_from_addr(r10, call_addr) - a.load_from_addr(r2, call_addr+WORD) - a.load_from_addr(r11, call_addr+2*WORD) + a.load_from_addr(r10, SCRATCH2, call_addr) + a.load_from_addr(r2, SCRATCH2, call_addr+WORD) + a.load_from_addr(r11, SCRATCH2, call_addr+2*WORD) else: # no descriptor on little-endian, but the ABI says r12 must # contain the function pointer @@ -304,7 +304,7 @@ addr = rffi.cast(lltype.Signed, p) p[0] = rffi.cast(rffi.LONG, 200) - a.load_from_addr(r3, addr) + a.load_from_addr(r3, SCRATCH2, addr) a.blr() f = a.get_assembler_function() assert f() == 200 diff --git a/rpython/jit/backend/ppc/test/test_regalloc_3.py b/rpython/jit/backend/ppc/test/test_regalloc_3.py --- a/rpython/jit/backend/ppc/test/test_regalloc_3.py +++ b/rpython/jit/backend/ppc/test/test_regalloc_3.py @@ -55,7 +55,7 @@ i22 = int_or(i3, i9) i41 = int_and(i11, -4) i42 = int_or(i41, 1) - i23 = int_mod(i12, i42) + i23 = int_mul(i12, 0) i24 = int_is_true(i6) i25 = uint_rshift(i15, 6) i26 = int_or(-4, i25) @@ -63,11 +63,11 @@ i28 = int_sub(-113, i11) i29 = int_neg(i7) i30 = int_neg(i24) - i31 = int_floordiv(i3, 53) + i31 = int_mul(i3, 53) i32 = int_mul(i28, i27) i43 = int_and(i18, -4) i44 = int_or(i43, 1) - i33 = int_mod(i26, i44) + i33 = int_mul(i26, i44) i34 = int_or(i27, i19) i35 = uint_lt(i13, 1) i45 = int_and(i21, 31) @@ -84,7 +84,7 @@ assert cpu.get_int_value(deadframe, 0) == 0 assert cpu.get_int_value(deadframe, 1) == 0 assert cpu.get_int_value(deadframe, 2) == 0 - assert cpu.get_int_value(deadframe, 3) == 0 + assert cpu.get_int_value(deadframe, 3) == 530 assert cpu.get_int_value(deadframe, 4) == 1 assert cpu.get_int_value(deadframe, 5) == -7 assert cpu.get_int_value(deadframe, 6) == 1 @@ -94,7 +94,7 @@ assert cpu.get_int_value(deadframe, 10) == 1 assert cpu.get_int_value(deadframe, 11) == 18 assert cpu.get_int_value(deadframe, 12) == -1 - assert cpu.get_int_value(deadframe, 13) == 0 + assert cpu.get_int_value(deadframe, 13) == 1 def test_bug_1(): cpu, deadframe = run([17, -20, -6, 6, 1, 13, 13, 9, 49, 8], ''' @@ -112,7 +112,7 @@ i43 = int_and(i14, 31) i19 = int_lshift(7, i43) i20 = int_neg(i19) - i21 = int_mod(i3, 1) + i21 = int_and(i3, 0) i22 = uint_ge(i15, i1) i44 = int_and(i16, 31) i23 = int_lshift(i8, i44) diff --git a/rpython/jit/backend/ppc/vector_ext.py b/rpython/jit/backend/ppc/vector_ext.py --- a/rpython/jit/backend/ppc/vector_ext.py +++ b/rpython/jit/backend/ppc/vector_ext.py @@ -38,13 +38,10 @@ # if v2 == 0 unpacks index 0 of param 2 # if v2 == 1 unpacks index 1 of param 2 mask = 0 - if IS_BIG_ENDIAN: - not_implemented("no big endian support (yet)") - else: - if v1 == 0: mask |= 0b01 - if v1 == 1: mask |= 0b00 - if v2 == 0: mask |= 0b10 - if v2 == 1: mask |= 0b00 + if v1 == 0: mask |= 0b01 + if v1 == 1: mask |= 0b00 + if v2 == 0: mask |= 0b10 + if v2 == 1: mask |= 0b00 return mask @@ -230,26 +227,19 @@ self.mc.stvx(src, r.SCRATCH2.value, r.SP.value) self.mc.load_imm(r.SCRATCH2, PARAM_SAVE_AREA_OFFSET+16) self.mc.stvx(res, r.SCRATCH2.value, r.SP.value) - for i in range(2): # at most 2 operations - if IS_BIG_ENDIAN: - srcoff = (i * osize) - resoff = (i * nsize) - else: - if osize == 4: - srcoff = 8 + (i * osize) - resoff = (i * nsize) - else: - srcoff = (i * osize) - resoff = 8 + (i * nsize) - if osize == 8: - self.mc.load(r.SCRATCH.value, r.SP.value, srcoff + PARAM_SAVE_AREA_OFFSET) - else: - self.mc.lwa(r.SCRATCH.value, r.SP.value, srcoff + PARAM_SAVE_AREA_OFFSET) - if nsize == 8: - self.mc.store(r.SCRATCH.value, r.SP.value, resoff + PARAM_SAVE_AREA_OFFSET+16) - else: - self.mc.stw(r.SCRATCH.value, r.SP.value, resoff + PARAM_SAVE_AREA_OFFSET+16) - + for j in range(2): # at most 2 operations + off = PARAM_SAVE_AREA_OFFSET + i = j + if not IS_BIG_ENDIAN: + i = (16 // osize) - 1 - i + off += osize * i + self._load_from_sp(r.SCRATCH.value, osize, off) + off = PARAM_SAVE_AREA_OFFSET + i = j + if not IS_BIG_ENDIAN: + i = (16 // nsize) - 1 - i + off += nsize * i + self._store_to_sp(r.SCRATCH.value, nsize, off+16) self.mc.lvx(res, r.SCRATCH2.value, r.SP.value) def emit_vec_float_abs(self, op, arglocs, regalloc): @@ -313,10 +303,7 @@ acc = accumloc.value if arg.type == FLOAT: # r = (r[0]+r[1],r[0]+r[1]) - if IS_BIG_ENDIAN: - self.mc.xxpermdi(tgt, acc, acc, 0b00) - else: - self.mc.xxpermdi(tgt, acc, acc, 0b10) + self.mc.xxpermdi(tgt, acc, acc, 0b10) if op == '+': self.mc.xsadddp(tgt, tgt, acc) elif op == '*': @@ -471,23 +458,26 @@ res, l0, off = arglocs size = op.bytesize + idx = 0 + size = op.bytesize + if not IS_BIG_ENDIAN: + idx = (16 // size) - 1 - idx + idx *= size + self._store_to_sp(l0.value, size, idx+PARAM_SAVE_AREA_OFFSET) + if size == 8: + idx = 1 + if not IS_BIG_ENDIAN: + idx = (16 // size) - 1 - idx + idx *= size + self._store_to_sp(l0.value, size, idx+PARAM_SAVE_AREA_OFFSET) self.mc.load_imm(r.SCRATCH2, off.value) self.mc.lvx(res.value, r.SCRATCH2.value, r.SP.value) if size == 1: - if IS_BIG_ENDIAN: - self.mc.vspltb(res.value, res.value, 0b0000) - else: - self.mc.vspltb(res.value, res.value, 0b1111) + self.mc.vspltb(res.value, res.value, 0b0000) elif size == 2: - if IS_BIG_ENDIAN: - self.mc.vsplth(res.value, res.value, 0b000) - else: - self.mc.vsplth(res.value, res.value, 0b111) + self.mc.vsplth(res.value, res.value, 0b000) elif size == 4: - if IS_BIG_ENDIAN: - self.mc.vspltw(res.value, res.value, 0b00) - else: - self.mc.vspltw(res.value, res.value, 0b11) + self.mc.vspltw(res.value, res.value, 0b00) elif size == 8: pass else: @@ -496,7 +486,6 @@ def emit_vec_pack_i(self, op, arglocs, regalloc): assert isinstance(op, VectorOp) resultloc, vloc, sourceloc, residxloc, srcidxloc, countloc = arglocs - srcidx = srcidxloc.value residx = residxloc.value count = countloc.value res = resultloc.value @@ -531,6 +520,37 @@ self.mc.stb(src, r.SP.value, PARAM_SAVE_AREA_OFFSET+idx) self.mc.lvx(res, r.SCRATCH2.value, r.SP.value) + def _load_from_sp(self, res, size, off): + if size == 8: + self.mc.load(res, r.SP.value, off) + return True + elif size == 4: + self.mc.lwa(res, r.SP.value, off) + return True + elif size == 2: + self.mc.lha(res, r.SP.value, off) + return True + elif size == 1: + self.mc.lbz(res, r.SP.value, off) + self.mc.extsb(res, res) + return True + return False + + def _store_to_sp(self, res, size, off): + if size == 8: + self.mc.store(res, r.SP.value, off) + return True + elif size == 4: + self.mc.stw(res, r.SP.value, off) + return True + elif size == 2: + self.mc.sth(res, r.SP.value, off) + return True + elif size == 1: + self.mc.stb(res, r.SP.value, off) + return True + return False + def emit_vec_unpack_i(self, op, arglocs, regalloc): assert isinstance(op, VectorOp) resloc, srcloc, idxloc, countloc, sizeloc = arglocs @@ -539,6 +559,7 @@ src = srcloc.value size = sizeloc.value count = countloc.value + newsize = op.bytesize if count == 1: assert srcloc.is_vector_reg() assert not resloc.is_vector_reg() @@ -548,18 +569,7 @@ if not IS_BIG_ENDIAN: idx = (16 // size) - 1 - idx off += size * idx - if size == 8: - self.mc.load(res, r.SP.value, off) - return - elif size == 4: - self.mc.lwa(res, r.SP.value, off) - return - elif size == 2: - self.mc.lha(res, r.SP.value, off) - return - elif size == 1: - self.mc.lbz(res, r.SP.value, off) - self.mc.extsb(res, res) + if self._load_from_sp(res, size, off): return else: # count is not 1, but only 2 is supported for i32 @@ -571,16 +581,21 @@ self.mc.stvx(src, r.SCRATCH2.value, r.SP.value) self.mc.load_imm(r.SCRATCH2, PARAM_SAVE_AREA_OFFSET+16) self.mc.stvx(res, r.SCRATCH2.value, r.SP.value) - if count * size == 8: + for j in range(count): + off = PARAM_SAVE_AREA_OFFSET + i = j+idx if not IS_BIG_ENDIAN: - endian_off = 8 + i = (16 // size) - 1 - i + off += size * i + self._load_from_sp(r.SCRATCH.value, size, off) off = PARAM_SAVE_AREA_OFFSET - off = off + endian_off - (idx * size) - assert idx * size + 8 <= 16 - self.mc.load(r.SCRATCH.value, r.SP.value, off) - self.mc.store(r.SCRATCH.value, r.SP.value, PARAM_SAVE_AREA_OFFSET+16+endian_off) - self.mc.lvx(res, r.SCRATCH2.value, r.SP.value) - return + i = j + if not IS_BIG_ENDIAN: + i = (16 // size) - 1 - i + off += size * i + self._store_to_sp(r.SCRATCH.value, newsize, off+16) + self.mc.lvx(res, r.SCRATCH2.value, r.SP.value) + return not_implemented("%d bit integer, count %d" % \ (size*8, count)) @@ -591,10 +606,8 @@ vec = vloc.value res = resloc.value src = srcloc.value - count = countloc.value residx = residxloc.value srcidx = srcidxloc.value - size = op.bytesize # srcloc is always a floating point register f, this means it is # vsr[0] == valueof(f) if srcidx == 0: @@ -864,10 +877,6 @@ mc.load_imm(l0, arg.value) else: l0 = self.ensure_reg(arg) - mc.store(l0.value, r.SP.value, PARAM_SAVE_AREA_OFFSET) - size = op.bytesize - if size == 8: - mc.store(l0.value, r.SP.value, PARAM_SAVE_AREA_OFFSET+8) res = self.force_allocate_vector_reg(op) return [res, l0, imm(PARAM_SAVE_AREA_OFFSET)] diff --git a/rpython/jit/metainterp/optimizeopt/test/test_vecopt.py b/rpython/jit/metainterp/optimizeopt/test/test_vecopt.py --- a/rpython/jit/metainterp/optimizeopt/test/test_vecopt.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_vecopt.py @@ -1397,5 +1397,6 @@ assert op not in dups dups.add(op) + class TestLLtype(BaseTestVectorize, LLtypeMixin): pass diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py --- a/rpython/jit/metainterp/resoperation.py +++ b/rpython/jit/metainterp/resoperation.py @@ -1190,6 +1190,8 @@ # Uh, that should be moved to vector_ext really! _cast_ops['CAST_FLOAT_TO_INT'] = ('f', 8, 'i', 8, 2) _cast_ops['VEC_CAST_FLOAT_TO_INT'] = ('f', 8, 'i', 8, 2) + _cast_ops['CAST_INT_TO_FLOAT'] = ('i', 8, 'f', 8, 2) + _cast_ops['VEC_CAST_INT_TO_FLOAT'] = ('i', 8, 'f', 8, 2) # ____________________________________________________________ diff --git a/rpython/jit/metainterp/test/test_vector.py b/rpython/jit/metainterp/test/test_vector.py --- a/rpython/jit/metainterp/test/test_vector.py +++ b/rpython/jit/metainterp/test/test_vector.py @@ -75,16 +75,6 @@ request.cls.a return rs - -def rdiv(v1,v2): - # TODO unused, interpeting this on top of llgraph does not work correctly - try: - return v1 / v2 - except ZeroDivisionError: - if v1 == v2 == 0.0: - return rfloat.NAN - return rfloat.copysign(rfloat.INFINITY, v1 * v2) - class VectorizeTests(object): enable_opts = 'intbounds:rewrite:virtualize:string:earlyforce:pure:heap:unroll' @@ -292,7 +282,7 @@ myjitdriver.jit_merge_point() a = va[i] b = vb[i] - ec = intmask(a) + intmask(b) + ec = intmask(intmask(a) + intmask(b)) va[i] = rffi.r_short(ec) i += 1 @@ -544,33 +534,6 @@ res = self.meta_interp(f, [i], vec=True) assert res == f(i) - @py.test.mark.parametrize('i,v1,v2',[(25,2.5,0.3),(25,2.5,0.3)]) - def test_list_vectorize(self,i,v1,v2): - myjitdriver = JitDriver(greens = [], - reds = 'auto') - class ListF(object): - def __init__(self, size, init): - self.list = [init] * size - def __getitem__(self, key): - return self.list[key] - def __setitem__(self, key, value): - self.list[key] = value - def f(d, v1, v2): - a = ListF(d, v1) - b = ListF(d, v2) - i = 0 - while i < d: - myjitdriver.jit_merge_point() - a[i] = a[i] + b[i] - i += 1 - s = 0 - for i in range(d): - s += a[i] - return s - res = self.meta_interp(f, [i,v1,v2], vec=True, vec_all=True) - # sum helps to generate the rounding error of floating points - # return 69.999 ... instead of 70, (v1+v2)*i == 70.0 - assert res == f(i,v1,v2) == sum([v1+v2]*i) @py.test.mark.parametrize('size',[12]) def test_body_multiple_accesses(self, size): @@ -880,17 +843,18 @@ j += 4 i += 8 - va = alloc_raw_storage(4*30, zero=True) - vb = alloc_raw_storage(8*30, zero=True) - for i,v in enumerate([1]*30): + count = 32 + va = alloc_raw_storage(4*count, zero=True) + vb = alloc_raw_storage(8*count, zero=True) + for i,v in enumerate([1,2,3,4]*(count/4)): raw_storage_setitem(va, i*4, rffi.cast(rffi.INT,v)) - for i,v in enumerate([-9.0]*30): + for i,v in enumerate([-1.0,-2.0,-3.0,-4.0]*(count/4)): raw_storage_setitem(vb, i*8, rffi.cast(rffi.DOUBLE,v)) - vc = alloc_raw_storage(8*30, zero=True) - self.meta_interp(f, [8*30, va, vb, vc], vec=True) + vc = alloc_raw_storage(8*count, zero=True) + self.meta_interp(f, [8*count, va, vb, vc], vec=True) - for i in range(30): - assert raw_storage_getitem(rffi.DOUBLE,vc,i*8) == -8.0 + for i in range(count): + assert raw_storage_getitem(rffi.DOUBLE,vc,i*8) == 0.0 free_raw_storage(va) free_raw_storage(vb) @@ -898,4 +862,14 @@ class TestLLtype(LLJitMixin, VectorizeTests): - pass + # skip some tests on this backend + def test_unpack_f(self): + pass + def test_unpack_i64(self): + pass + def test_unpack_i(self): + pass + def test_unpack_several(self): + pass + def test_vec_int_sum(self): + pass diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py --- a/rpython/rlib/rarithmetic.py +++ b/rpython/rlib/rarithmetic.py @@ -323,50 +323,48 @@ def __add__(self, other): x = long(self) - y = long(other) + y = other # may be a float return self._widen(other, x + y) __radd__ = __add__ def __sub__(self, other): x = long(self) - y = long(other) + y = other # may be a float return self._widen(other, x - y) def __rsub__(self, other): y = long(self) - x = long(other) + x = other # may be a float return self._widen(other, x - y) def __mul__(self, other): x = long(self) - if not isinstance(other, (int, long)): - return x * other - y = long(other) + y = other # may be a float return self._widen(other, x * y) __rmul__ = __mul__ def __div__(self, other): x = long(self) - y = long(other) - return self._widen(other, x // y) + y = other # may be a float + return self._widen(other, x / y) __floordiv__ = __div__ def __rdiv__(self, other): y = long(self) - x = long(other) - return self._widen(other, x // y) + x = other # may be a float + return self._widen(other, x / y) __rfloordiv__ = __rdiv__ def __mod__(self, other): x = long(self) - y = long(other) + y = other # not rpython if it is a float return self._widen(other, x % y) def __rmod__(self, other): y = long(self) - x = long(other) + x = other # not rpython if it is a float return self._widen(other, x % y) def __divmod__(self, other): diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py --- a/rpython/rlib/rposix.py +++ b/rpython/rlib/rposix.py @@ -679,21 +679,22 @@ raise OSError(error, "readdir failed") return result -def fdlistdir(dirfd): - """ - Like listdir(), except that the directory is specified as an open - file descriptor. +if not _WIN32: + def fdlistdir(dirfd): + """ + Like listdir(), except that the directory is specified as an open + file descriptor. - Note: fdlistdir() closes the file descriptor. To emulate the - Python 3.x 'os.opendir(dirfd)', you must first duplicate the - file descriptor. - """ - dirp = c_fdopendir(dirfd) - if not dirp: - error = get_saved_errno() - c_close(dirfd) - raise OSError(error, "opendir failed") - return _listdir(dirp, rewind=True) + Note: fdlistdir() closes the file descriptor. To emulate the + Python 3.x 'os.opendir(dirfd)', you must first duplicate the + file descriptor. + """ + dirp = c_fdopendir(dirfd) + if not dirp: + error = get_saved_errno() + c_close(dirfd) + raise OSError(error, "opendir failed") + return _listdir(dirp, rewind=True) @replace_os_function('listdir') @specialize.argtype(0) @@ -1166,6 +1167,10 @@ @replace_os_function('pipe') def pipe(flags=0): # 'flags' might be ignored. Check the result. + # The handles returned are always inheritable on Posix. + # The situation on Windows is not completely clear: I think + # it should always return non-inheritable handles, but CPython + # uses SECURITY_ATTRIBUTES to ensure that and we don't. if _WIN32: # 'flags' ignored ralloc = lltype.scoped_alloc(rwin32.LPHANDLE.TO, 1) @@ -2146,8 +2151,9 @@ handle_posix_error('mknodat', error) -eci_inheritable = eci.merge(ExternalCompilationInfo( - separate_module_sources=[r""" +if not _WIN32: + eci_inheritable = eci.merge(ExternalCompilationInfo( + separate_module_sources=[r""" #include <errno.h> #include <sys/ioctl.h> @@ -2200,10 +2206,6 @@ RPY_EXTERN int rpy_dup_noninheritable(int fd) { -#ifdef _WIN32 -#error NotImplementedError -#endif - #ifdef F_DUPFD_CLOEXEC return fcntl(fd, F_DUPFD_CLOEXEC, 0); #else @@ -2221,10 +2223,6 @@ RPY_EXTERN int rpy_dup2_noninheritable(int fd, int fd2) { -#ifdef _WIN32 -#error NotImplementedError -#endif - #ifdef F_DUP2FD_CLOEXEC return fcntl(fd, F_DUP2FD_CLOEXEC, fd2); @@ -2249,33 +2247,41 @@ return 0; #endif } - """ % {'HAVE_DUP3': HAVE_DUP3}], - post_include_bits=['RPY_EXTERN int rpy_set_inheritable(int, int);\n' - 'RPY_EXTERN int rpy_get_inheritable(int);\n' - 'RPY_EXTERN int rpy_dup_noninheritable(int);\n' - 'RPY_EXTERN int rpy_dup2_noninheritable(int, int);\n'])) + """ % {'HAVE_DUP3': HAVE_DUP3}], + post_include_bits=['RPY_EXTERN int rpy_set_inheritable(int, int);\n' + 'RPY_EXTERN int rpy_get_inheritable(int);\n' + 'RPY_EXTERN int rpy_dup_noninheritable(int);\n' + 'RPY_EXTERN int rpy_dup2_noninheritable(int, int);\n' + ])) -c_set_inheritable = external('rpy_set_inheritable', [rffi.INT, rffi.INT], - rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO, - compilation_info=eci_inheritable) -c_get_inheritable = external('rpy_get_inheritable', [rffi.INT], - rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO, - compilation_info=eci_inheritable) -c_dup_noninheritable = external('rpy_dup_noninheritable', [rffi.INT], - rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO, - compilation_info=eci_inheritable) -c_dup2_noninheritable = external('rpy_dup2_noninheritable', [rffi.INT,rffi.INT], - rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO, - compilation_info=eci_inheritable) + _c_set_inheritable = external('rpy_set_inheritable', [rffi.INT, rffi.INT], + rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO, + compilation_info=eci_inheritable) + _c_get_inheritable = external('rpy_get_inheritable', [rffi.INT], + rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO, + compilation_info=eci_inheritable) + c_dup_noninheritable = external('rpy_dup_noninheritable', [rffi.INT], + rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO, + compilation_info=eci_inheritable) + c_dup2_noninheritable = external('rpy_dup2_noninheritable', [rffi.INT,rffi.INT], + rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO, + compilation_info=eci_inheritable) -def set_inheritable(fd, inheritable): - result = c_set_inheritable(fd, inheritable) - handle_posix_error('set_inheritable', result) + def set_inheritable(fd, inheritable): + result = _c_set_inheritable(fd, inheritable) + handle_posix_error('set_inheritable', result) -def get_inheritable(fd): - res = c_get_inheritable(fd) - res = handle_posix_error('get_inheritable', res) - return res != 0 + def get_inheritable(fd): + res = _c_get_inheritable(fd) + res = handle_posix_error('get_inheritable', res) + return res != 0 + +else: + # _WIN32 + from rpython.rlib.rwin32 import set_inheritable, get_inheritable + from rpython.rlib.rwin32 import c_dup_noninheritable + from rpython.rlib.rwin32 import c_dup2_noninheritable + class SetNonInheritableCache(object): """Make one prebuilt instance of this for each path that creates @@ -2315,20 +2321,20 @@ _pipe2_syscall = ENoSysCache() -post_include_bits=['RPY_EXTERN int _cpu_count(void);'] +post_include_bits=['RPY_EXTERN int rpy_cpu_count(void);'] # cpu count for linux, windows and mac (+ bsds) # note that the code is copied from cpython and split up here if sys.platform.startswith('linux'): cpucount_eci = ExternalCompilationInfo(includes=["unistd.h"], separate_module_sources=[""" - RPY_EXTERN int _cpu_count(void) { + RPY_EXTERN int rpy_cpu_count(void) { return sysconf(_SC_NPROCESSORS_ONLN); } """], post_include_bits=post_include_bits) elif sys.platform == "win32": cpucount_eci = ExternalCompilationInfo(includes=["Windows.h"], separate_module_sources=[""" - RPY_EXTERN int _cpu_count(void) { + RPY_EXTERN int rpy_cpu_count(void) { SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); return sysinfo.dwNumberOfProcessors; @@ -2337,7 +2343,7 @@ else: cpucount_eci = ExternalCompilationInfo(includes=["sys/types.h", "sys/sysctl.h"], separate_module_sources=[""" - RPY_EXTERN int _cpu_count(void) { + RPY_EXTERN int rpy_cpu_count(void) { int ncpu = 0; #if defined(__DragonFly__) || \ defined(__OpenBSD__) || \ @@ -2355,7 +2361,7 @@ } """], post_include_bits=post_include_bits) -_cpu_count = rffi.llexternal('_cpu_count', [], rffi.INT_real, +_cpu_count = rffi.llexternal('rpy_cpu_count', [], rffi.INT_real, compilation_info=cpucount_eci) def cpu_count(): diff --git a/rpython/rlib/rposix_environ.py b/rpython/rlib/rposix_environ.py --- a/rpython/rlib/rposix_environ.py +++ b/rpython/rlib/rposix_environ.py @@ -201,6 +201,8 @@ # default implementation for platforms without a real unsetenv() r_putenv(name, '') +REAL_UNSETENV = False + if hasattr(__import__(os.name), 'unsetenv'): os_unsetenv = rffi.llexternal('unsetenv', [rffi.CCHARP], rffi.INT, save_err=rffi.RFFI_SAVE_ERRNO) @@ -222,3 +224,4 @@ register_external(r_unsetenv, [str0], annmodel.s_None, export_name='ll_os.ll_os_unsetenv', llimpl=unsetenv_llimpl) + REAL_UNSETENV = True diff --git a/rpython/rlib/rposix_stat.py b/rpython/rlib/rposix_stat.py --- a/rpython/rlib/rposix_stat.py +++ b/rpython/rlib/rposix_stat.py @@ -641,6 +641,7 @@ @specialize.arg(0) def win32_xstat(traits, path, traverse=False): + # XXX 'traverse' is ignored win32traits = make_win32_traits(traits) with lltype.scoped_alloc( win32traits.WIN32_FILE_ATTRIBUTE_DATA) as data: diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py --- a/rpython/rlib/rsocket.py +++ b/rpython/rlib/rsocket.py @@ -1062,11 +1062,32 @@ return result make_socket._annspecialcase_ = 'specialize:arg(4)' -def sock_set_inheritable(fd, inheritable): - try: - rposix.set_inheritable(fd, inheritable) - except OSError as e: - raise CSocketError(e.errno) +if _c.WIN32: + def sock_set_inheritable(fd, inheritable): + handle = rffi.cast(rwin32.HANDLE, fd) + try: + rwin32.set_handle_inheritable(handle, inheritable) + except WindowsError: + raise RSocketError("SetHandleInformation failed") # xxx + + def sock_get_inheritable(fd): + handle = rffi.cast(rwin32.HANDLE, fd) + try: + return rwin32.get_handle_inheritable(handle) + except WindowsError: + raise RSocketError("GetHandleInformation failed") # xxx +else: + def sock_set_inheritable(fd, inheritable): + try: + rposix.set_inheritable(fd, inheritable) + except OSError as e: + raise CSocketError(e.errno) + + def sock_get_inheritable(fd): + try: + return rposix.get_inheritable(fd) + except OSError as e: + raise CSocketError(e.errno) class SocketError(Exception): applevelerrcls = 'error' diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py --- a/rpython/rlib/rwin32.py +++ b/rpython/rlib/rwin32.py @@ -112,7 +112,7 @@ CTRL_C_EVENT CTRL_BREAK_EVENT MB_ERR_INVALID_CHARS ERROR_NO_UNICODE_TRANSLATION WC_NO_BEST_FIT_CHARS STD_INPUT_HANDLE STD_OUTPUT_HANDLE - STD_ERROR_HANDLE + STD_ERROR_HANDLE HANDLE_FLAG_INHERIT FILE_TYPE_CHAR """ from rpython.translator.platform import host_factory static_platform = host_factory() @@ -473,3 +473,64 @@ CONSOLE_SCREEN_BUFFER_INFO_P = lltype.Ptr(CONSOLE_SCREEN_BUFFER_INFO) GetConsoleScreenBufferInfo = winexternal( "GetConsoleScreenBufferInfo", [HANDLE, CONSOLE_SCREEN_BUFFER_INFO_P], BOOL) + + _GetHandleInformation = winexternal( + 'GetHandleInformation', [HANDLE, LPDWORD], BOOL) + _SetHandleInformation = winexternal( + 'SetHandleInformation', [HANDLE, DWORD, DWORD], BOOL) + + def set_inheritable(fd, inheritable): + handle = get_osfhandle(fd) + set_handle_inheritable(handle, inheritable) + + def set_handle_inheritable(handle, inheritable): + assert lltype.typeOf(handle) is HANDLE + if inheritable: + flags = HANDLE_FLAG_INHERIT + else: + flags = 0 + if not _SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags): + raise lastSavedWindowsError("SetHandleInformation") + + def get_inheritable(fd): + handle = get_osfhandle(fd) + return get_handle_inheritable(handle) + + def get_handle_inheritable(handle): + assert lltype.typeOf(handle) is HANDLE + pflags = lltype.malloc(LPDWORD.TO, 1, flavor='raw') + try: + if not _GetHandleInformation(handle, pflags): + raise lastSavedWindowsError("GetHandleInformation") + flags = pflags[0] + finally: + lltype.free(pflags, flavor='raw') + return (flags & HANDLE_FLAG_INHERIT) != 0 + + _GetFileType = winexternal('GetFileType', [HANDLE], DWORD) + + def c_dup_noninheritable(fd1): + from rpython.rlib.rposix import c_dup + + ftype = _GetFileType(get_osfhandle(fd1)) + fd2 = c_dup(fd1) # the inheritable version + if fd2 >= 0 and ftype != FILE_TYPE_CHAR: + try: + set_inheritable(fd2, False) + except: + os.close(fd2) + raise + return fd2 + + def c_dup2_noninheritable(fd1, fd2): + from rpython.rlib.rposix import c_dup2 + + ftype = _GetFileType(get_osfhandle(fd1)) + res = c_dup2(fd1, fd2) # the inheritable version + if res >= 0 and ftype != FILE_TYPE_CHAR: + try: + set_inheritable(fd2, False) + except: + os.close(fd2) + raise + return res diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py --- a/rpython/rlib/test/test_rarithmetic.py +++ b/rpython/rlib/test/test_rarithmetic.py @@ -602,3 +602,12 @@ assert r_uint64(self._64_umax) + r_uint64(1) == r_uint64(0) assert r_uint64(0) - r_uint64(1) == r_uint64(self._64_umax) + + def test_operation_with_float(self): + def f(x): + assert r_longlong(x) + 0.5 == 43.5 + assert r_longlong(x) - 0.5 == 42.5 + assert r_longlong(x) * 0.5 == 21.5 + assert r_longlong(x) / 0.8 == 53.75 + f(43) + interpret(f, [43]) diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py --- a/rpython/rlib/test/test_rposix.py +++ b/rpython/rlib/test/test_rposix.py @@ -470,11 +470,18 @@ assert rposix.is_valid_fd(fd) == 0 def test_putenv(self): + from rpython.rlib import rposix_environ + def f(): rposix.putenv(self.path, self.path) rposix.unsetenv(self.path) - interpret(f, []) # does not crash + interpret(f, [], # does not crash + malloc_check=rposix_environ.REAL_UNSETENV) + # If we have a real unsetenv(), check that it frees the string + # kept alive by putenv(). Otherwise, we can't check that, + # because unsetenv() will keep another string alive itself. + test_putenv.dont_track_allocations = True class TestPosixAscii(BasePosixUnicodeOrAscii): @@ -604,6 +611,9 @@ def test_SetNonInheritableCache(): cache = rposix.SetNonInheritableCache() fd1, fd2 = os.pipe() + if sys.platform == 'win32': + rposix.set_inheritable(fd1, True) + rposix.set_inheritable(fd2, True) assert rposix.get_inheritable(fd1) == True assert rposix.get_inheritable(fd1) == True assert cache.cached_inheritable == -1 @@ -616,6 +626,24 @@ os.close(fd1) os.close(fd2) +def test_dup_dup2_non_inheritable(): + for preset in [False, True]: + fd1, fd2 = os.pipe() + rposix.set_inheritable(fd1, preset) + rposix.set_inheritable(fd2, preset) + fd3 = rposix.dup(fd1, True) + assert rposix.get_inheritable(fd3) == True + fd4 = rposix.dup(fd1, False) + assert rposix.get_inheritable(fd4) == False + rposix.dup2(fd2, fd4, False) + assert rposix.get_inheritable(fd4) == False + rposix.dup2(fd2, fd3, True) + assert rposix.get_inheritable(fd3) == True + os.close(fd1) + os.close(fd2) + os.close(fd3) + os.close(fd4) + def test_sync(): if sys.platform != 'win32': rposix.sync() diff --git a/rpython/rlib/test/test_rsocket.py b/rpython/rlib/test/test_rsocket.py --- a/rpython/rlib/test/test_rsocket.py +++ b/rpython/rlib/test/test_rsocket.py @@ -124,8 +124,8 @@ py.test.skip('No socketpair on Windows') for inh in [False, True]: s1, s2 = socketpair(inheritable=inh) - assert rposix.get_inheritable(s1.fd) == inh - assert rposix.get_inheritable(s2.fd) == inh + assert sock_get_inheritable(s1.fd) == inh + assert sock_get_inheritable(s2.fd) == inh s1.close() s2.close() @@ -391,7 +391,7 @@ def test_inheritable(): for inh in [False, True]: s1 = RSocket(inheritable=inh) - assert rposix.get_inheritable(s1.fd) == inh + assert sock_get_inheritable(s1.fd) == inh s1.close() def test_getaddrinfo_http(): diff --git a/rpython/tool/jitlogparser/storage.py b/rpython/tool/jitlogparser/storage.py --- a/rpython/tool/jitlogparser/storage.py +++ b/rpython/tool/jitlogparser/storage.py @@ -62,7 +62,7 @@ guard_dict = {} for loop_no, loop in enumerate(loops): for op in loop.operations: - if op.name.startswith('guard_'): + if op.name.startswith('guard_') or op.name.startswith('vec_guard_'): guard_dict[int(op.descr[len('<Guard0x'):-1], 16)] = (op, loop) for loop in loops: if loop.comment: _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit