diff options
author | Matti Picus <matti.picus@gmail.com> | 2020-09-14 20:53:54 +0300 |
---|---|---|
committer | Matti Picus <matti.picus@gmail.com> | 2020-09-14 20:53:54 +0300 |
commit | 6a11f6822c83c0761e2ddea8588c05faf0a8b904 (patch) | |
tree | 0dd7d1b8766f0a4001be2811f677b429789b1cac /rpython | |
parent | do not display IRC_TOPIC even on this alpha release. Can be overridden from env (diff) | |
parent | merge default into py3.7 (diff) | |
download | pypy-release-pypy3.7-v7.3.2rc2.tar.gz pypy-release-pypy3.7-v7.3.2rc2.tar.bz2 pypy-release-pypy3.7-v7.3.2rc2.zip |
merge py3.7 into release3.7.xrelease-pypy3.7-v7.3.2rc2
Diffstat (limited to 'rpython')
-rw-r--r-- | rpython/doc/conf.py | 16 | ||||
-rw-r--r-- | rpython/doc/requirements.txt | 1 | ||||
-rw-r--r-- | rpython/jit/backend/aarch64/opassembler.py | 18 | ||||
-rw-r--r-- | rpython/jit/backend/aarch64/regalloc.py | 2 | ||||
-rw-r--r-- | rpython/jit/backend/arm/opassembler.py | 18 | ||||
-rw-r--r-- | rpython/jit/backend/arm/regalloc.py | 2 | ||||
-rw-r--r-- | rpython/jit/backend/test/runner_test.py | 34 | ||||
-rw-r--r-- | rpython/jit/metainterp/optimizeopt/heap.py | 9 | ||||
-rw-r--r-- | rpython/jit/metainterp/optimizeopt/info.py | 37 | ||||
-rw-r--r-- | rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py | 158 | ||||
-rw-r--r-- | rpython/jit/metainterp/optimizeopt/virtualize.py | 30 | ||||
-rw-r--r-- | rpython/rlib/test/test_rposix.py | 17 | ||||
-rw-r--r-- | rpython/rlib/test/test_rsocket.py | 9 | ||||
-rw-r--r-- | rpython/rtyper/lltypesystem/ll2ctypes.py | 2 | ||||
-rw-r--r-- | rpython/rtyper/rpbc.py | 15 | ||||
-rw-r--r-- | rpython/rtyper/test/test_rpbc.py | 70 | ||||
-rw-r--r-- | rpython/translator/platform/posix.py | 3 | ||||
-rw-r--r-- | rpython/translator/platform/windows.py | 8 |
18 files changed, 394 insertions, 55 deletions
diff --git a/rpython/doc/conf.py b/rpython/doc/conf.py index 0fed63ea2a..c8c845e0cb 100644 --- a/rpython/doc/conf.py +++ b/rpython/doc/conf.py @@ -43,7 +43,21 @@ if not on_rtd: # only import and set the theme if we're building docs locally # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.extlinks', 'sphinx.ext.intersphinx', 'sphinx.ext.graphviz'] +extensions = ['sphinx.ext.extlinks', + 'sphinx.ext.intersphinx', + 'sphinx.ext.graphviz', + 'sphinx_affiliates', + ] + +# Canonical URL (including the '/') so searching from pypy docs finds these +affiliate_options = { + 'canonical_url': "https://rpython.readthedocs.io/en/latest" +} + +# Other sites to add to the search of this site +sphinx_affiliates = [ + 'https://doc.pypy.org/en/latest/affiliate_searchindex.js', +] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] diff --git a/rpython/doc/requirements.txt b/rpython/doc/requirements.txt new file mode 100644 index 0000000000..ff999fd3c2 --- /dev/null +++ b/rpython/doc/requirements.txt @@ -0,0 +1 @@ +sphinx-affiliates diff --git a/rpython/jit/backend/aarch64/opassembler.py b/rpython/jit/backend/aarch64/opassembler.py index e6383b2e06..27649cc914 100644 --- a/rpython/jit/backend/aarch64/opassembler.py +++ b/rpython/jit/backend/aarch64/opassembler.py @@ -382,8 +382,13 @@ class ResOpAssembler(BaseAssembler): value_loc, base_loc, index_loc, size_loc, ofs_loc = arglocs assert index_loc.is_core_reg() # add the base offset - if ofs_loc.value > 0: - self.mc.ADD_ri(r.ip0.value, index_loc.value, ofs_loc.value) + if ofs_loc.value != 0: + if check_imm_arg(ofs_loc.value): + self.mc.ADD_ri(r.ip0.value, index_loc.value, ofs_loc.value) + else: + # ofs_loc.value is too large for an ADD_ri + self.load(r.ip0, ofs_loc) + self.mc.ADD_rr(r.ip0.value, r.ip0.value, index_loc.value) index_loc = r.ip0 scale = get_scale(size_loc.value) self._write_to_mem(value_loc, base_loc, index_loc, scale) @@ -394,8 +399,13 @@ class ResOpAssembler(BaseAssembler): nsize = nsize_loc.value signed = (nsize < 0) # add the base offset - if ofs_loc.value > 0: - self.mc.ADD_ri(r.ip0.value, index_loc.value, ofs_loc.value) + if ofs_loc.value != 0: + if check_imm_arg(ofs_loc.value): + self.mc.ADD_ri(r.ip0.value, index_loc.value, ofs_loc.value) + else: + # ofs_loc.value is too large for an ADD_ri + self.load(r.ip0, ofs_loc) + self.mc.ADD_rr(r.ip0.value, r.ip0.value, index_loc.value) index_loc = r.ip0 # scale = get_scale(abs(nsize)) diff --git a/rpython/jit/backend/aarch64/regalloc.py b/rpython/jit/backend/aarch64/regalloc.py index 7ecb455ec8..e87bd8a51e 100644 --- a/rpython/jit/backend/aarch64/regalloc.py +++ b/rpython/jit/backend/aarch64/regalloc.py @@ -557,7 +557,6 @@ class Regalloc(BaseRegalloc): assert boxes[3].getint() == 1 # scale ofs = boxes[4].getint() size = boxes[5].getint() - assert check_imm_arg(ofs) return [value_loc, base_loc, index_loc, imm(size), imm(ofs)] def _prepare_op_gc_load_indexed(self, op): @@ -567,7 +566,6 @@ class Regalloc(BaseRegalloc): assert boxes[2].getint() == 1 # scale ofs = boxes[3].getint() nsize = boxes[4].getint() - assert check_imm_arg(ofs) self.possibly_free_vars_for_op(op) self.free_temp_vars() res_loc = self.force_allocate_reg(op) diff --git a/rpython/jit/backend/arm/opassembler.py b/rpython/jit/backend/arm/opassembler.py index 2f82e73b21..f65f11e51a 100644 --- a/rpython/jit/backend/arm/opassembler.py +++ b/rpython/jit/backend/arm/opassembler.py @@ -704,8 +704,13 @@ class ResOpAssembler(BaseAssembler): value_loc, base_loc, index_loc, size_loc, ofs_loc = arglocs assert index_loc.is_core_reg() # add the base offset - if ofs_loc.value > 0: - self.mc.ADD_ri(r.ip.value, index_loc.value, imm=ofs_loc.value) + if ofs_loc.value != 0: + if check_imm_arg(ofs_loc.value): + self.mc.ADD_ri(r.ip.value, index_loc.value, imm=ofs_loc.value) + else: + # ofs_loc.value is too large for an ADD_ri + self.load(r.ip, ofs_loc) + self.mc.ADD_rr(r.ip.value, r.ip.value, index_loc.value) index_loc = r.ip scale = get_scale(size_loc.value) self._write_to_mem(value_loc, base_loc, index_loc, imm(scale), fcond) @@ -760,8 +765,13 @@ class ResOpAssembler(BaseAssembler): nsize = nsize_loc.value signed = (nsize < 0) # add the base offset - if ofs_loc.value > 0: - self.mc.ADD_ri(r.ip.value, index_loc.value, imm=ofs_loc.value) + if ofs_loc.value != 0: + if check_imm_arg(ofs_loc.value): + self.mc.ADD_ri(r.ip.value, index_loc.value, imm=ofs_loc.value) + else: + # ofs_loc.value is too large for an ADD_ri + self.load(r.ip, ofs_loc) + self.mc.ADD_rr(r.ip.value, r.ip.value, index_loc.value) index_loc = r.ip # scale = get_scale(abs(nsize)) diff --git a/rpython/jit/backend/arm/regalloc.py b/rpython/jit/backend/arm/regalloc.py index ab50d505c1..dc8e93ea61 100644 --- a/rpython/jit/backend/arm/regalloc.py +++ b/rpython/jit/backend/arm/regalloc.py @@ -857,7 +857,6 @@ class Regalloc(BaseRegalloc): assert boxes[3].getint() == 1 # scale ofs = boxes[4].getint() size = boxes[5].getint() - assert check_imm_arg(ofs) return [value_loc, base_loc, index_loc, imm(size), imm(ofs)] def _prepare_op_gc_load_indexed(self, op, fcond): @@ -867,7 +866,6 @@ class Regalloc(BaseRegalloc): assert boxes[2].getint() == 1 # scale ofs = boxes[3].getint() nsize = boxes[4].getint() - assert check_imm_arg(ofs) self.possibly_free_vars_for_op(op) self.free_temp_vars() res_loc = self.force_allocate_reg(op) diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py index cbe9f0c72c..6cb760abd7 100644 --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -5092,6 +5092,40 @@ class LLtypeBackendTest(BaseBackendTest): assert rffi.cast(lltype.Signed, a[1]) == 777 lltype.free(a, flavor='raw') + def test_gc_indexed_box_plus_large_offset(self): + A = lltype.GcArray(lltype.Signed) + arraydescr = self.cpu.arraydescrof(A) + for offset in [10**8, -10**8]: + loop = parse(""" + [p0, i0] + i1 = int_add(i0, %d) + i2 = getarrayitem_gc_i(p0, i1, descr=arraydescr) + finish(i2, descr=finaldescr) + """ % offset, namespace={"finaldescr": BasicFinalDescr(1), + "arraydescr": arraydescr}) + looptoken = JitCellToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + a = lltype.malloc(A, 100) + a[42] = 102030 + a_ref = lltype.cast_opaque_ptr(llmemory.GCREF, a) + deadframe = self.cpu.execute_token(looptoken, a_ref, 42 - offset) + assert self.cpu.get_int_value(deadframe, 0) == 102030 + # + for offset in [10**8, -10**8]: + loop = parse(""" + [p0, i0] + i1 = int_add(i0, %d) + setarrayitem_gc(p0, i1, 102030, descr=arraydescr) + finish(0, descr=finaldescr) + """ % offset, namespace={"finaldescr": BasicFinalDescr(1), + "arraydescr": arraydescr}) + looptoken = JitCellToken() + self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken) + a = lltype.malloc(A, 100) + a_ref = lltype.cast_opaque_ptr(llmemory.GCREF, a) + self.cpu.execute_token(looptoken, a_ref, 42 - offset) + assert a[42] == 102030 + def test_increment_debug_counter(self): foo = lltype.malloc(rffi.CArray(lltype.Signed), 1, flavor='raw') foo[0] = 1789200 diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py index 53c8b3a883..2a845f118f 100644 --- a/rpython/jit/metainterp/optimizeopt/heap.py +++ b/rpython/jit/metainterp/optimizeopt/heap.py @@ -179,6 +179,7 @@ class CachedField(AbstractCachedEntry): class ArrayCachedItem(AbstractCachedEntry): def __init__(self, index): + assert index >= 0 self.index = index AbstractCachedEntry.__init__(self) @@ -556,7 +557,7 @@ class OptHeap(Optimization): arrayinfo = self.ensure_ptr_info_arg0(op) indexb = self.getintbound(op.getarg(1)) cf = None - if indexb.is_constant(): + if indexb.is_constant() and indexb.getint() >= 0: index = indexb.getint() arrayinfo.getlenbound(None).make_gt_const(index) # use the cache on (arraydescr, index), which is a constant @@ -578,7 +579,7 @@ class OptHeap(Optimization): # then remember the result of reading the array item arrayinfo = self.ensure_ptr_info_arg0(op) indexb = self.getintbound(op.getarg(1)) - if indexb.is_constant(): + if indexb.is_constant() and indexb.getint() >= 0: index = indexb.getint() cf = self.arrayitem_cache(op.getdescr(), index) arrayinfo.setitem(op.getdescr(), indexb.getint(), @@ -595,7 +596,7 @@ class OptHeap(Optimization): arrayinfo = self.ensure_ptr_info_arg0(op) indexb = self.getintbound(op.getarg(1)) cf = None - if indexb.is_constant(): + if indexb.is_constant() and indexb.getint() >= 0: index = indexb.getint() arrayinfo.getlenbound(None).make_gt_const(index) # use the cache on (arraydescr, index), which is a constant @@ -616,7 +617,7 @@ class OptHeap(Optimization): def optimize_SETARRAYITEM_GC(self, op): indexb = self.getintbound(op.getarg(1)) - if indexb.is_constant(): + if indexb.is_constant() and indexb.getint() >= 0: arrayinfo = self.ensure_ptr_info_arg0(op) # arraybound arrayinfo.getlenbound(None).make_gt_const(indexb.getint()) diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py index 760b78dc10..c22bd0749f 100644 --- a/rpython/jit/metainterp/optimizeopt/info.py +++ b/rpython/jit/metainterp/optimizeopt/info.py @@ -486,6 +486,13 @@ class RawSlicePtrInfo(AbstractRawPtrInfo): return visitor.visit_vrawslice(self.offset) +def reasonable_array_index(index): + """Check a given constant array index or array size for sanity. + In case of invalid loops or very large arrays, we shouldn't try + to optimize them.""" + return index >= 0 and index <= 150000 + + class ArrayPtrInfo(AbstractVirtualPtrInfo): _attrs_ = ('length', '_items', 'lenbound', '_clear', 'descr', '_is_virtual') @@ -551,19 +558,27 @@ class ArrayPtrInfo(AbstractVirtualPtrInfo): optforce.emit_extra(setop) optforce.pure_from_args(rop.ARRAYLEN_GC, [op], ConstInt(len(self._items))) - def setitem(self, descr, index, struct, op, optheap=None, cf=None): + def _setitem_index(self, index, op): + if not reasonable_array_index(index): + if self._items is None: + self._items = [] + return if self._items is None: self._items = [None] * (index + 1) - if index >= len(self._items): - assert not self.is_virtual() + elif index >= len(self._items): + if self.is_virtual(): + return # bogus setarrayitem_gc into virtual, drop the operation self._items = self._items + [None] * (index - len(self._items) + 1) self._items[index] = op + + def setitem(self, descr, index, struct, op, optheap=None, cf=None): + self._setitem_index(index, op) if cf is not None: assert not self.is_virtual() cf.register_info(struct, self) def getitem(self, descr, index, optheap=None): - if self._items is None or index >= len(self._items): + if self._items is None or index >= len(self._items) or index < 0: return None return self._items[index] @@ -588,7 +603,7 @@ class ArrayPtrInfo(AbstractVirtualPtrInfo): shortboxes): if self._items is None: return - if index >= len(self._items): + if index >= len(self._items) or index < 0: # we don't know about this item return item = self._items[index] @@ -637,18 +652,22 @@ class ArrayStructInfo(ArrayPtrInfo): def _compute_index(self, index, fielddescr): all_fdescrs = fielddescr.get_arraydescr().get_all_fielddescrs() - if all_fdescrs is None: - return 0 # annotation hack + if all_fdescrs is None or index < 0 or index >= self.length: + return -1 one_size = len(all_fdescrs) return index * one_size + fielddescr.get_field_descr().get_index() def setinteriorfield_virtual(self, index, fielddescr, fld): index = self._compute_index(index, fielddescr) - self._items[index] = fld + if index >= 0: + self._items[index] = fld def getinteriorfield_virtual(self, index, fielddescr): index = self._compute_index(index, fielddescr) - return self._items[index] + if index >= 0: + return self._items[index] + else: + return None def _force_elements(self, op, optforce, descr): i = 0 diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py index 62407a3276..8f1ce2bfb0 100644 --- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py @@ -5,6 +5,7 @@ from rpython.rlib.rarithmetic import intmask from rpython.rlib.rarithmetic import LONG_BIT from rpython.rtyper import rclass from rpython.rtyper.lltypesystem import lltype +from rpython.jit.metainterp.optimize import InvalidLoop from rpython.jit.metainterp.optimizeopt.test.test_util import ( BaseTest, convert_old_style_to_targets) from rpython.jit.metainterp.history import ( @@ -1069,6 +1070,163 @@ class TestOptimizeBasic(BaseTestBasic): """ self.optimize_loop(ops, expected) + def test_varray_huge_size(self): + ops = """ + [] + p1 = new_array(150100, descr=arraydescr) + jump() + """ + self.optimize_loop(ops, ops) + + def test_varray_negative_items_from_invalid_loop(self): + ops = """ + [p1, p2] + i2 = getarrayitem_gc_i(p1, -1, descr=arraydescr) + setarrayitem_gc(p2, -1, i2, descr=arraydescr) + jump(p1, p2) + """ + self.optimize_loop(ops, ops) + + def test_varray_too_large_items(self): + ops = """ + [p1, p2] + i2 = getarrayitem_gc_i(p1, 150100, descr=arraydescr) + i3 = getarrayitem_gc_i(p1, 150100, descr=arraydescr) # not cached + setarrayitem_gc(p2, 150100, i2, descr=arraydescr) + i4 = getarrayitem_gc_i(p2, 150100, descr=arraydescr) # cached, heap.py + jump(p1, p2, i3, i4) + """ + expected = """ + [p1, p2] + i2 = getarrayitem_gc_i(p1, 150100, descr=arraydescr) + i3 = getarrayitem_gc_i(p1, 150100, descr=arraydescr) # not cached + setarrayitem_gc(p2, 150100, i2, descr=arraydescr) + jump(p1, p2, i3, i2) + """ + self.optimize_loop(ops, expected) + + def test_varray_negative_items_from_invalid_loop_v(self): + ops = """ + [] + p1 = new_array(10, descr=arraydescr) + i2 = getarrayitem_gc_i(p1, -1, descr=arraydescr) + jump(i2) + """ + py.test.raises(InvalidLoop, self.optimize_loop, ops, ops) + # + ops = """ + [i2] + p1 = new_array(10, descr=arraydescr) + setarrayitem_gc(p1, -1, i2, descr=arraydescr) + jump() + """ + expected = """ + [i2] + jump() + """ + # the setarrayitem_gc is completely dropped because of invalid index. + # we could also raise InvalidLoop, but both choices seem OK + self.optimize_loop(ops, expected) + + def test_varray_too_large_items_from_invalid_loop_v(self): + ops = """ + [] + p1 = new_array(10, descr=arraydescr) + i2 = getarrayitem_gc_i(p1, 10, descr=arraydescr) + jump(i2) + """ + py.test.raises(InvalidLoop, self.optimize_loop, ops, ops) + # + ops = """ + [i2] + p1 = new_array(10, descr=arraydescr) + setarrayitem_gc(p1, 10, i2, descr=arraydescr) + jump() + """ + expected = """ + [i2] + jump() + """ + # the setarrayitem_gc is completely dropped because of invalid index. + # we could also raise InvalidLoop, but both choices seem OK + self.optimize_loop(ops, expected) + + def test_varray_huge_size_struct(self): + ops = """ + [] + p1 = new_array(150100, descr=complexarraydescr) + jump() + """ + self.optimize_loop(ops, ops) + + def test_varray_struct_negative_items_from_invalid_loop(self): + ops = """ + [p1, p2] + f0 = getinteriorfield_gc_f(p1, -1, descr=complexrealdescr) + setinteriorfield_gc(p2, -1, f0, descr=compleximagdescr) + jump(p1, p2) + """ + self.optimize_loop(ops, ops) + + def test_varray_struct_too_large_items(self): + ops = """ + [p1, p2] + f2 = getinteriorfield_gc_f(p1, 150100, descr=compleximagdescr) + # not cached: + f3 = getinteriorfield_gc_f(p1, 150100, descr=compleximagdescr) + setinteriorfield_gc(p2, 150100, f2, descr=complexrealdescr) + # this is not cached so far (it could be cached by heap.py) + f4 = getinteriorfield_gc_f(p2, 150100, descr=complexrealdescr) + jump(p1, p2, f3, f4) + """ + self.optimize_loop(ops, ops) + + def test_varray_struct_negative_items_from_invalid_loop_v(self): + ops = """ + [] + p1 = new_array_clear(10, descr=complexarraydescr) + f0 = getinteriorfield_gc_f(p1, -1, descr=complexrealdescr) + jump(f0) + """ + py.test.raises(InvalidLoop, self.optimize_loop, ops, ops) + # + ops = """ + [f0] + p1 = new_array_clear(10, descr=complexarraydescr) + setinteriorfield_gc(p1, -1, f0, descr=complexrealdescr) + jump() + """ + expected = """ + [f0] + jump() + """ + # the setinteriorfield_gc is completely dropped because of invalid + # index. we could also raise InvalidLoop, but both choices seem OK + self.optimize_loop(ops, expected) + + def test_varray_struct_too_large_items_from_invalid_loop_v(self): + ops = """ + [] + p1 = new_array_clear(10, descr=complexarraydescr) + f0 = getinteriorfield_gc_f(p1, 10, descr=complexrealdescr) + jump(f0) + """ + py.test.raises(InvalidLoop, self.optimize_loop, ops, ops) + # + ops = """ + [f0] + p1 = new_array_clear(10, descr=complexarraydescr) + setinteriorfield_gc(p1, 10, f0, descr=complexrealdescr) + jump() + """ + expected = """ + [f0] + jump() + """ + # the setinteriorfield_gc is completely dropped because of invalid + # index. we could also raise InvalidLoop, but both choices seem OK + self.optimize_loop(ops, expected) + def test_p123_vstruct(self): ops = """ [i1, p2, p3] diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py b/rpython/jit/metainterp/optimizeopt/virtualize.py index dda6b4f3fa..70bf235edc 100644 --- a/rpython/jit/metainterp/optimizeopt/virtualize.py +++ b/rpython/jit/metainterp/optimizeopt/virtualize.py @@ -1,6 +1,7 @@ from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.jit.metainterp.history import ConstInt from rpython.jit.metainterp.history import CONST_NULL +from rpython.jit.metainterp.optimize import InvalidLoop from rpython.jit.metainterp.optimizeopt import info, optimizer from rpython.jit.metainterp.optimizeopt.optimizer import REMOVED from rpython.jit.metainterp.optimizeopt.util import ( @@ -24,6 +25,8 @@ class OptVirtualize(optimizer.Optimization): return opinfo def make_varray(self, arraydescr, size, source_op, clear=False): + if not info.reasonable_array_index(size): + return False if arraydescr.is_array_of_structs(): assert clear opinfo = info.ArrayStructInfo(arraydescr, size, is_virtual=True) @@ -37,7 +40,7 @@ class OptVirtualize(optimizer.Optimization): newop = self.replace_op_with(source_op, source_op.getopnum(), args=[ConstInt(size)]) newop.set_forwarded(opinfo) - return opinfo + return True def make_vstruct(self, structdescr, source_op): opinfo = info.StructPtrInfo(structdescr, is_virtual=True) @@ -210,17 +213,17 @@ class OptVirtualize(optimizer.Optimization): def optimize_NEW_ARRAY(self, op): sizebox = self.get_constant_box(op.getarg(0)) - if sizebox is not None: - self.make_varray(op.getdescr(), sizebox.getint(), op) - else: - return self.emit(op) + if (sizebox is not None and + self.make_varray(op.getdescr(), sizebox.getint(), op)): + return + return self.emit(op) def optimize_NEW_ARRAY_CLEAR(self, op): sizebox = self.get_constant_box(op.getarg(0)) - if sizebox is not None: - self.make_varray(op.getdescr(), sizebox.getint(), op, clear=True) - else: - return self.emit(op) + if (sizebox is not None and + self.make_varray(op.getdescr(), sizebox.getint(), op, clear=True)): + return + return self.emit(op) def optimize_CALL_N(self, op): effectinfo = op.getdescr().get_extra_info() @@ -279,8 +282,8 @@ class OptVirtualize(optimizer.Optimization): if indexbox is not None: item = opinfo.getitem(op.getdescr(), indexbox.getint()) if item is None: # reading uninitialized array items? - assert False, "can't read uninitialized items" - itemvalue = value.constvalue # bah, just return 0 + raise InvalidLoop("reading uninitialized virtual " + "array items") self.make_equal_to(op, item) return self.make_nonnull(op.getarg(0)) @@ -391,9 +394,8 @@ class OptVirtualize(optimizer.Optimization): descr = op.getdescr() fld = opinfo.getinteriorfield_virtual(indexbox.getint(), descr) if fld is None: - raise Exception("I think this is illegal") - xxx - fieldvalue = self.optimizer.new_const(descr) + raise InvalidLoop("reading uninitialized virtual interior " + "array items") self.make_equal_to(op, fld) return self.make_nonnull(op.getarg(0)) diff --git a/rpython/rlib/test/test_rposix.py b/rpython/rlib/test/test_rposix.py index 09f747725e..7071fe0146 100644 --- a/rpython/rlib/test/test_rposix.py +++ b/rpython/rlib/test/test_rposix.py @@ -948,15 +948,12 @@ def test_get_and_set_scheduler_and_param(): rposix.sched_setparam(-1, param) with pytest.raises(OSError): rposix.sched_setscheduler(-1, mine, param) - with pytest.raises(TypeError): - rposix.sched_setscheduler(0, mine, None) - with pytest.raises(TypeError): - rposix.sched_setparam(0, None) large = 214748364700 - param = large # rposix.sched_param(large) - with pytest.raises(OSError): - rposix.sched_setparam(0, param) - # param = rposix.sched_param(sched_priority=-large) - # with pytest.raises(OverflowError): - # rposix.sched_setparam(0, param) + if large < sys.maxint: + param = large # rposix.sched_param(large) + with pytest.raises(OSError): + rposix.sched_setparam(0, param) + # param = rposix.sched_param(sched_priority=-large) + # with pytest.raises(OverflowError): + # rposix.sched_setparam(0, param) diff --git a/rpython/rlib/test/test_rsocket.py b/rpython/rlib/test/test_rsocket.py index 24ab1e2fc8..9e0e22acd3 100644 --- a/rpython/rlib/test/test_rsocket.py +++ b/rpython/rlib/test/test_rsocket.py @@ -576,7 +576,14 @@ def test_inet_ntop(): @pytest.mark.skipif(getattr(rsocket, 'AF_UNIX', None) is None, reason='AF_UNIX not supported.') def test_unix_socket_connect(tmpdir, do_recv): - sockpath = str(tmpdir.join('test_unix_socket_connect')) + prev_dir = tmpdir.chdir() # workaround for limited path length + try: + do_test_unix_socket_connect(do_recv) + finally: + prev_dir.chdir() + +def do_test_unix_socket_connect(do_recv): + sockpath = './test_unix_socket_connect' a = UNIXAddress(sockpath) serversock = RSocket(AF_UNIX) diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py b/rpython/rtyper/lltypesystem/ll2ctypes.py index 79294824d2..bf6d627597 100644 --- a/rpython/rtyper/lltypesystem/ll2ctypes.py +++ b/rpython/rtyper/lltypesystem/ll2ctypes.py @@ -1183,7 +1183,7 @@ if sys.platform == 'darwin': expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) fdout, ccout = tempfile.mkstemp() os.close(fdout) - cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; else CC=cc; fi;' \ + cmd = 'if type gcc >/dev/null 2>&1; then : ${CC:=gcc}; else : ${CC:=cc}; fi;' \ '$CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name try: f = os.popen(cmd) diff --git a/rpython/rtyper/rpbc.py b/rpython/rtyper/rpbc.py index aa4bdeaeca..c4344afa61 100644 --- a/rpython/rtyper/rpbc.py +++ b/rpython/rtyper/rpbc.py @@ -815,6 +815,21 @@ class __extend__(pairtype(MultipleFrozenPBCReprBase, def convert_from_to((r_pbc1, r_pbc2), v, llops): return inputconst(Void, r_pbc2.frozendesc) +class __extend__(pairtype(FunctionRepr, MultipleFrozenPBCRepr)): + def convert_from_to((r_fn1, r_frozen2), v, llops): + if r_fn1.s_pbc.is_constant(): + value = r_frozen2.convert_const(r_fn1.s_pbc.const) + lltype = r_frozen2.lowleveltype + return Constant(value, lltype) + return NotImplemented + +class __extend__(pairtype(MultipleFrozenPBCRepr, FunctionRepr)): + def convert_from_to((r_frozen1, r_fn2), v, llops): + if r_fn2.lowleveltype is Void: + value = r_fn2.s_pbc.const + return Constant(value, Void) + return NotImplemented + class MethodOfFrozenPBCRepr(Repr): """Representation selected for a PBC of method object(s) of frozen PBCs. diff --git a/rpython/rtyper/test/test_rpbc.py b/rpython/rtyper/test/test_rpbc.py index cf1ce40887..fcc3a01781 100644 --- a/rpython/rtyper/test/test_rpbc.py +++ b/rpython/rtyper/test/test_rpbc.py @@ -1769,6 +1769,76 @@ class TestRPBC(BaseRtypingTest): return f() self.interpret(f, [-5]) + def test_single_function_to_noncallable_pbcs(self): + from rpython.annotator import annrpython + a = annrpython.RPythonAnnotator() + + def h1(i): + return i + 5 + def h3(i): + "NOT_RPYTHON" # should not be annotated + return i + 7 + + def other_func(i): + h1(i) + return h1 + + def g(i): + fn = other_func(i) + if i > 5: + return fn + return h3 + self.interpret(g, [-5]) + + def test_multiple_functions_to_noncallable_pbcs(self): + py.test.skip("unsupported") + + from rpython.annotator import annrpython + a = annrpython.RPythonAnnotator() + + def h1(i): + return i + 5 + def h2(i): + return i + 5 + def h3(i): + "NOT_RPYTHON" # should not be annotated + return i + 7 + + def g(i): + if i & 1: + fn = h1 + else: + fn = h2 + fn(i) + if i > 5: + return fn + return h3 + self.interpret(g, [-5]) + + def test_single_function_from_noncallable_pbcs(self): + from rpython.annotator import annrpython + a = annrpython.RPythonAnnotator() + + def h1(i): + return i + 5 + def h3(i): + "NOT_RPYTHON" # should not be annotated + return i + 7 + + def other_func(i): + h1(i) + return h1 + + def g(i): + if i & 1: + fn = h1 + else: + fn = h3 + h1(i) + if fn is h1: + fn(i) + self.interpret(g, [-5]) + # ____________________________________________________________ def test_hlinvoke_simple(): diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py index d53449abe5..4463831b9e 100644 --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -62,7 +62,8 @@ class BasePosix(Platform): def _pkg_config(self, lib, opt, default, check_result_dir=False): try: - ret, out, err = _run_subprocess("pkg-config", [lib, opt]) + pkg_config = os.environ.get('PKG_CONFIG', 'pkg-config') + ret, out, err = _run_subprocess(pkg_config, [lib, opt]) except OSError as e: err = str(e) ret = 1 diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py index 0144889de5..26fb31c981 100644 --- a/rpython/translator/platform/windows.py +++ b/rpython/translator/platform/windows.py @@ -191,10 +191,14 @@ class MsvcPlatform(Platform): if msvc_compiler_environ: self.c_environ.update(msvc_compiler_environ) self.version = "MSVC %s" % str(self.vsver) + if self.vsver > 90: + tag = '14x' + else: + tag = '%d' % self.vsver if x64: - self.externals_branch = 'win64_%d' % self.vsver + self.externals_branch = 'win64_%s' % tag else: - self.externals_branch = 'win32_%d' % self.vsver + self.externals_branch = 'win32_%s' % tag else: self.cc = cc |