aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2020-09-14 20:53:54 +0300
committerMatti Picus <matti.picus@gmail.com>2020-09-14 20:53:54 +0300
commit6a11f6822c83c0761e2ddea8588c05faf0a8b904 (patch)
tree0dd7d1b8766f0a4001be2811f677b429789b1cac /rpython
parentdo not display IRC_TOPIC even on this alpha release. Can be overridden from env (diff)
parentmerge default into py3.7 (diff)
downloadpypy-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.py16
-rw-r--r--rpython/doc/requirements.txt1
-rw-r--r--rpython/jit/backend/aarch64/opassembler.py18
-rw-r--r--rpython/jit/backend/aarch64/regalloc.py2
-rw-r--r--rpython/jit/backend/arm/opassembler.py18
-rw-r--r--rpython/jit/backend/arm/regalloc.py2
-rw-r--r--rpython/jit/backend/test/runner_test.py34
-rw-r--r--rpython/jit/metainterp/optimizeopt/heap.py9
-rw-r--r--rpython/jit/metainterp/optimizeopt/info.py37
-rw-r--r--rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py158
-rw-r--r--rpython/jit/metainterp/optimizeopt/virtualize.py30
-rw-r--r--rpython/rlib/test/test_rposix.py17
-rw-r--r--rpython/rlib/test/test_rsocket.py9
-rw-r--r--rpython/rtyper/lltypesystem/ll2ctypes.py2
-rw-r--r--rpython/rtyper/rpbc.py15
-rw-r--r--rpython/rtyper/test/test_rpbc.py70
-rw-r--r--rpython/translator/platform/posix.py3
-rw-r--r--rpython/translator/platform/windows.py8
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