[pypy-commit] pypy jit-targets: hg merge 8de6f245c959
hakanardo
noreply at buildbot.pypy.org
Sat Dec 10 12:20:37 CET 2011
Author: Hakan Ardo <hakan at debian.org>
Branch: jit-targets
Changeset: r50340:38465568087c
Date: 2011-12-10 12:20 +0100
http://bitbucket.org/pypy/pypy/changeset/38465568087c/
Log: hg merge 8de6f245c959
diff --git a/lib-python/modified-2.7/ctypes/__init__.py b/lib-python/modified-2.7/ctypes/__init__.py
--- a/lib-python/modified-2.7/ctypes/__init__.py
+++ b/lib-python/modified-2.7/ctypes/__init__.py
@@ -351,7 +351,7 @@
self._FuncPtr = _FuncPtr
if handle is None:
- self._handle = _ffi.CDLL(name)
+ self._handle = _ffi.CDLL(name, mode)
else:
self._handle = handle
diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py
--- a/lib_pypy/_collections.py
+++ b/lib_pypy/_collections.py
@@ -379,12 +379,14 @@
class defaultdict(dict):
def __init__(self, *args, **kwds):
- self.default_factory = None
- if 'default_factory' in kwds:
- self.default_factory = kwds.pop('default_factory')
- elif len(args) > 0 and (callable(args[0]) or args[0] is None):
- self.default_factory = args[0]
+ if len(args) > 0:
+ default_factory = args[0]
args = args[1:]
+ if not callable(default_factory) and default_factory is not None:
+ raise TypeError("first argument must be callable")
+ else:
+ default_factory = None
+ self.default_factory = default_factory
super(defaultdict, self).__init__(*args, **kwds)
def __missing__(self, key):
@@ -404,7 +406,7 @@
recurse.remove(id(self))
def copy(self):
- return type(self)(self, default_factory=self.default_factory)
+ return type(self)(self.default_factory, self)
def __copy__(self):
return self.copy()
diff --git a/py/_code/code.py b/py/_code/code.py
--- a/py/_code/code.py
+++ b/py/_code/code.py
@@ -164,6 +164,7 @@
# if something: # assume this causes a NameError
# # _this_ lines and the one
# below we don't want from entry.getsource()
+ end = min(end, len(source))
for i in range(self.lineno, end):
if source[i].rstrip().endswith(':'):
end = i + 1
diff --git a/pypy/bin/checkmodule.py b/pypy/bin/checkmodule.py
--- a/pypy/bin/checkmodule.py
+++ b/pypy/bin/checkmodule.py
@@ -1,43 +1,45 @@
#! /usr/bin/env python
"""
-Usage: checkmodule.py [-b backend] <module-name>
+Usage: checkmodule.py <module-name>
-Compiles the PyPy extension module from pypy/module/<module-name>/
-into a fake program which does nothing. Useful for testing whether a
-modules compiles without doing a full translation. Default backend is cli.
-
-WARNING: this is still incomplete: there are chances that the
-compilation fails with strange errors not due to the module. If a
-module is known to compile during a translation but don't pass
-checkmodule.py, please report the bug (or, better, correct it :-).
+Check annotation and rtyping of the PyPy extension module from
+pypy/module/<module-name>/. Useful for testing whether a
+modules compiles without doing a full translation.
"""
import autopath
-import sys
+import sys, os
from pypy.objspace.fake.checkmodule import checkmodule
def main(argv):
- try:
- assert len(argv) in (2, 4)
- if len(argv) == 2:
- backend = 'cli'
- modname = argv[1]
- if modname in ('-h', '--help'):
- print >> sys.stderr, __doc__
- sys.exit(0)
- if modname.startswith('-'):
- print >> sys.stderr, "Bad command line"
- print >> sys.stderr, __doc__
- sys.exit(1)
- else:
- _, b, backend, modname = argv
- assert b == '-b'
- except AssertionError:
+ if len(argv) != 2:
print >> sys.stderr, __doc__
sys.exit(2)
+ modname = argv[1]
+ if modname in ('-h', '--help'):
+ print >> sys.stderr, __doc__
+ sys.exit(0)
+ if modname.startswith('-'):
+ print >> sys.stderr, "Bad command line"
+ print >> sys.stderr, __doc__
+ sys.exit(1)
+ if os.path.sep in modname:
+ if os.path.basename(modname) == '':
+ modname = os.path.dirname(modname)
+ if os.path.basename(os.path.dirname(modname)) != 'module':
+ print >> sys.stderr, "Must give '../module/xxx', or just 'xxx'."
+ sys.exit(1)
+ modname = os.path.basename(modname)
+ try:
+ checkmodule(modname)
+ except Exception, e:
+ import traceback, pdb
+ traceback.print_exc()
+ pdb.post_mortem(sys.exc_info()[2])
+ return 1
else:
- checkmodule(modname, backend, interactive=True)
- print 'Module compiled succesfully'
+ print 'Passed.'
+ return 0
if __name__ == '__main__':
- main(sys.argv)
+ sys.exit(main(sys.argv))
diff --git a/pypy/interpreter/astcompiler/optimize.py b/pypy/interpreter/astcompiler/optimize.py
--- a/pypy/interpreter/astcompiler/optimize.py
+++ b/pypy/interpreter/astcompiler/optimize.py
@@ -1,6 +1,5 @@
"""codegen helpers and AST constant folding."""
import sys
-import itertools
from pypy.interpreter.astcompiler import ast, consts, misc
from pypy.tool import stdlib_opcode as ops
@@ -146,8 +145,7 @@
}
unrolling_unary_folders = unrolling_iterable(unary_folders.items())
-for folder in itertools.chain(binary_folders.itervalues(),
- unary_folders.itervalues()):
+for folder in binary_folders.values() + unary_folders.values():
folder._always_inline_ = True
del folder
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1,4 +1,3 @@
-import itertools
import pypy
from pypy.interpreter.executioncontext import ExecutionContext, ActionFlag
from pypy.interpreter.executioncontext import UserDelAction, FrameTraceAction
@@ -519,8 +518,8 @@
exception_types_w = self.export_builtin_exceptions()
# initialize with "bootstrap types" from objspace (e.g. w_None)
- types_w = itertools.chain(self.get_builtin_types().iteritems(),
- exception_types_w.iteritems())
+ types_w = (self.get_builtin_types().items() +
+ exception_types_w.items())
for name, w_type in types_w:
self.setitem(self.builtin.w_dict, self.wrap(name), w_type)
@@ -1608,6 +1607,8 @@
'UnicodeError',
'ValueError',
'ZeroDivisionError',
+ 'UnicodeEncodeError',
+ 'UnicodeDecodeError',
]
## Irregular part of the interface:
diff --git a/pypy/jit/backend/llsupport/regalloc.py b/pypy/jit/backend/llsupport/regalloc.py
--- a/pypy/jit/backend/llsupport/regalloc.py
+++ b/pypy/jit/backend/llsupport/regalloc.py
@@ -23,9 +23,12 @@
return self.frame_bindings.get(box, None)
def loc(self, box):
- res = self.get(box)
- if res is not None:
- return res
+ try:
+ return self.frame_bindings[box]
+ except KeyError:
+ return self.get_new_loc(box)
+
+ def get_new_loc(self, box):
size = self.frame_size(box.type)
self.frame_depth += ((-self.frame_depth) & (size-1))
# ^^^ frame_depth is rounded up to a multiple of 'size', assuming
@@ -73,8 +76,17 @@
self.position = -1
self.frame_manager = frame_manager
self.assembler = assembler
+ self.hint_frame_locations = {} # {Box: StackLoc}
+ self.freed_frame_locations = {} # {StackLoc: None}
+
+ def is_still_alive(self, v):
+ # Check if 'v' is alive at the current position.
+ # Return False if the last usage is strictly before.
+ return self.longevity[v][1] >= self.position
def stays_alive(self, v):
+ # Check if 'v' stays alive after the current position.
+ # Return False if the last usage is before or at position.
return self.longevity[v][1] > self.position
def next_instruction(self, incr=1):
@@ -90,11 +102,16 @@
point for all variables that might be in registers.
"""
self._check_type(v)
- if isinstance(v, Const) or v not in self.reg_bindings:
+ if isinstance(v, Const):
return
if v not in self.longevity or self.longevity[v][1] <= self.position:
- self.free_regs.append(self.reg_bindings[v])
- del self.reg_bindings[v]
+ if v in self.reg_bindings:
+ self.free_regs.append(self.reg_bindings[v])
+ del self.reg_bindings[v]
+ if self.frame_manager is not None:
+ if v in self.frame_manager.frame_bindings:
+ loc = self.frame_manager.frame_bindings[v]
+ self.freed_frame_locations[loc] = None
def possibly_free_vars(self, vars):
""" Same as 'possibly_free_var', but for all v in vars.
@@ -166,6 +183,23 @@
self.reg_bindings[v] = loc
return loc
+ def _frame_loc(self, v):
+ # first check if it's already in the frame_manager
+ try:
+ return self.frame_manager.frame_bindings[v]
+ except KeyError:
+ pass
+ # check if we have a hint for this box
+ if v in self.hint_frame_locations:
+ # if we do, check that the hinted location is known to be free
+ loc = self.hint_frame_locations[v]
+ if loc in self.freed_frame_locations:
+ del self.freed_frame_locations[loc]
+ self.frame_manager.frame_bindings[v] = loc
+ return loc
+ # no valid hint. make up a new free location
+ return self.frame_manager.get_new_loc(v)
+
def _spill_var(self, v, forbidden_vars, selected_reg,
need_lower_byte=False):
v_to_spill = self._pick_variable_to_spill(v, forbidden_vars,
@@ -173,7 +207,7 @@
loc = self.reg_bindings[v_to_spill]
del self.reg_bindings[v_to_spill]
if self.frame_manager.get(v_to_spill) is None:
- newloc = self.frame_manager.loc(v_to_spill)
+ newloc = self._frame_loc(v_to_spill)
self.assembler.regalloc_mov(loc, newloc)
return loc
@@ -250,7 +284,7 @@
except KeyError:
if box in self.bindings_to_frame_reg:
return self.frame_reg
- return self.frame_manager.loc(box)
+ return self._frame_loc(box)
def return_constant(self, v, forbidden_vars=[], selected_reg=None):
""" Return the location of the constant v. If 'selected_reg' is
@@ -298,7 +332,7 @@
self.reg_bindings[v] = loc
self.assembler.regalloc_mov(prev_loc, loc)
else:
- loc = self.frame_manager.loc(v)
+ loc = self._frame_loc(v)
self.assembler.regalloc_mov(prev_loc, loc)
def force_result_in_reg(self, result_v, v, forbidden_vars=[]):
@@ -317,7 +351,7 @@
self.reg_bindings[result_v] = loc
return loc
if v not in self.reg_bindings:
- prev_loc = self.frame_manager.loc(v)
+ prev_loc = self._frame_loc(v)
loc = self.force_allocate_reg(v, forbidden_vars)
self.assembler.regalloc_mov(prev_loc, loc)
assert v in self.reg_bindings
@@ -337,7 +371,7 @@
def _sync_var(self, v):
if not self.frame_manager.get(v):
reg = self.reg_bindings[v]
- to = self.frame_manager.loc(v)
+ to = self._frame_loc(v)
self.assembler.regalloc_mov(reg, to)
# otherwise it's clean
diff --git a/pypy/jit/backend/llsupport/test/test_regalloc.py b/pypy/jit/backend/llsupport/test/test_regalloc.py
--- a/pypy/jit/backend/llsupport/test/test_regalloc.py
+++ b/pypy/jit/backend/llsupport/test/test_regalloc.py
@@ -348,3 +348,50 @@
spilled2 = rm.force_allocate_reg(b5)
assert spilled2 is loc
rm._check_invariants()
+
+
+ def test_hint_frame_locations_1(self):
+ b0, b1 = newboxes(0, 1)
+ longevity = {b0: (0, 1), b1: (0, 1)}
+ fm = TFrameManager()
+ asm = MockAsm()
+ rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
+ rm.hint_frame_locations[b0] = "some_stack_loc"
+ rm.freed_frame_locations["some_stack_loc"] = None
+ rm.force_allocate_reg(b0)
+ rm.force_allocate_reg(b1)
+ rm.force_spill_var(b0)
+ rm.force_spill_var(b1)
+ assert rm.loc(b0) == "some_stack_loc"
+ assert isinstance(rm.loc(b1), FakeFramePos)
+ rm._check_invariants()
+
+ def test_hint_frame_locations_2(self):
+ b0, b1, b2 = newboxes(0, 1, 2)
+ longevity = {b0: (0, 1), b1: (0, 2), b2: (0, 2)}
+ fm = TFrameManager()
+ asm = MockAsm()
+ rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
+ rm.force_allocate_reg(b0)
+ rm.force_allocate_reg(b1)
+ rm.force_allocate_reg(b2)
+ rm.force_spill_var(b0)
+ loc = rm.loc(b0)
+ assert isinstance(loc, FakeFramePos)
+ rm.position = 1
+ assert loc not in rm.freed_frame_locations
+ rm.possibly_free_var(b0)
+ assert loc in rm.freed_frame_locations
+ #
+ rm.hint_frame_locations[b1] = loc
+ rm.force_spill_var(b1)
+ loc1 = rm.loc(b1)
+ assert loc1 is loc
+ assert rm.freed_frame_locations == {}
+ #
+ rm.hint_frame_locations[b2] = loc
+ rm.force_spill_var(b2)
+ loc2 = rm.loc(b2)
+ assert loc2 is not loc1 # because it's not in freed_frame_locations
+ #
+ rm._check_invariants()
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -698,6 +698,7 @@
def _assemble(self, regalloc, operations):
self._regalloc = regalloc
+ regalloc.compute_hint_frame_locations(operations)
regalloc.walk_operations(operations)
if we_are_translated() or self.cpu.dont_keepalive_stuff:
self._regalloc = None # else keep it around for debugging
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -1319,6 +1319,29 @@
self.rm.possibly_free_var(tmpbox_low)
self.rm.possibly_free_var(tmpbox_high)
+ def compute_hint_frame_locations(self, operations):
+ # optimization only: fill in the 'hint_frame_locations' dictionary
+ # of rm and xrm based on the JUMP at the end of the loop, by looking
+ # at where we would like the boxes to be after the jump.
+ op = operations[-1]
+ if op.getopnum() != rop.JUMP:
+ return
+ descr = op.getdescr()
+ assert isinstance(descr, LoopToken)
+ nonfloatlocs, floatlocs = self.assembler.target_arglocs(descr)
+ for i in range(op.numargs()):
+ box = op.getarg(i)
+ if isinstance(box, Box):
+ loc = nonfloatlocs[i]
+ if isinstance(loc, StackLoc):
+ assert box.type != FLOAT
+ self.rm.hint_frame_locations[box] = loc
+ else:
+ loc = floatlocs[i]
+ if isinstance(loc, StackLoc):
+ assert box.type == FLOAT
+ self.xrm.hint_frame_locations[box] = loc
+
def consider_jump(self, op):
assembler = self.assembler
assert self.jump_target_descr is None
diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -371,7 +371,7 @@
pass
class ResumeGuardDescr(ResumeDescr):
- _counter = 0 # if < 0, there is one counter per value;
+ _counter = 0 # on a GUARD_VALUE, there is one counter per value;
_counters = None # they get stored in _counters then.
# this class also gets the following attributes stored by resume.py code
@@ -382,10 +382,13 @@
rd_virtuals = None
rd_pendingfields = lltype.nullptr(PENDINGFIELDSP.TO)
- CNT_INT = -0x20000000
- CNT_REF = -0x40000000
- CNT_FLOAT = -0x60000000
- CNT_MASK = 0x1FFFFFFF
+ CNT_BASE_MASK = 0x0FFFFFFF # the base counter value
+ CNT_BUSY_FLAG = 0x10000000 # if set, busy tracing from the guard
+ CNT_TYPE_MASK = 0x60000000 # mask for the type
+
+ CNT_INT = 0x20000000
+ CNT_REF = 0x40000000
+ CNT_FLOAT = 0x60000000
def store_final_boxes(self, guard_op, boxes):
guard_op.setfailargs(boxes)
@@ -399,6 +402,8 @@
except ValueError:
return # xxx probably very rare
else:
+ if i > self.CNT_BASE_MASK:
+ return # probably never, but better safe than sorry
if box.type == history.INT:
cnt = self.CNT_INT
elif box.type == history.REF:
@@ -407,14 +412,17 @@
cnt = self.CNT_FLOAT
else:
assert 0, box.type
- # we build the following value for _counter, which is always
- # a negative value
+ assert cnt > self.CNT_BASE_MASK
self._counter = cnt | i
def handle_fail(self, metainterp_sd, jitdriver_sd):
if self.must_compile(metainterp_sd, jitdriver_sd):
- return self._trace_and_compile_from_bridge(metainterp_sd,
- jitdriver_sd)
+ self.start_compiling()
+ try:
+ return self._trace_and_compile_from_bridge(metainterp_sd,
+ jitdriver_sd)
+ finally:
+ self.done_compiling()
else:
from pypy.jit.metainterp.blackhole import resume_in_blackhole
resume_in_blackhole(metainterp_sd, jitdriver_sd, self)
@@ -432,12 +440,22 @@
def must_compile(self, metainterp_sd, jitdriver_sd):
trace_eagerness = jitdriver_sd.warmstate.trace_eagerness
- if self._counter >= 0:
+ #
+ if self._counter <= self.CNT_BASE_MASK:
+ # simple case: just counting from 0 to trace_eagerness
self._counter += 1
return self._counter >= trace_eagerness
- else:
- index = self._counter & self.CNT_MASK
- typetag = self._counter & ~ self.CNT_MASK
+ #
+ # do we have the BUSY flag? If so, we're tracing right now, e.g. in an
+ # outer invocation of the same function, so don't trace again for now.
+ elif self._counter & self.CNT_BUSY_FLAG:
+ return False
+ #
+ else: # we have a GUARD_VALUE that fails. Make a _counters instance
+ # (only now, when the guard is actually failing at least once),
+ # and use it to record some statistics about the failing values.
+ index = self._counter & self.CNT_BASE_MASK
+ typetag = self._counter & self.CNT_TYPE_MASK
counters = self._counters
if typetag == self.CNT_INT:
intvalue = metainterp_sd.cpu.get_latest_value_int(index)
@@ -464,7 +482,16 @@
assert 0, typetag
return counter >= trace_eagerness
- def reset_counter_from_failure(self):
+ def start_compiling(self):
+ # start tracing and compiling from this guard.
+ self._counter |= self.CNT_BUSY_FLAG
+
+ def done_compiling(self):
+ # done tracing and compiling from this guard. Either the bridge has
+ # been successfully compiled, in which case whatever value we store
+ # in self._counter will not be seen any more, or not, in which case
+ # we should reset the counter to 0, in order to wait a bit until the
+ # next attempt.
if self._counter >= 0:
self._counter = 0
self._counters = None
@@ -670,9 +697,6 @@
self.original_greenkey, jitcell_token)
metainterp_sd.stats.add_jitcell_token(jitcell_token)
- def reset_counter_from_failure(self):
- pass
-
def compile_trace(metainterp, resumekey, start_resumedescr=None):
"""Try to compile a new bridge leading from the beginning of the history
diff --git a/pypy/jit/metainterp/optimizeopt/fficall.py b/pypy/jit/metainterp/optimizeopt/fficall.py
--- a/pypy/jit/metainterp/optimizeopt/fficall.py
+++ b/pypy/jit/metainterp/optimizeopt/fficall.py
@@ -234,6 +234,9 @@
# longlongs are treated as floats, see
# e.g. llsupport/descr.py:getDescrClass
is_float = True
+ elif kind == 'u':
+ # they're all False
+ pass
else:
assert False, "unsupported ffitype or kind"
#
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1796,7 +1796,6 @@
self.staticdata.profiler.count(reason)
debug_print('~~~ ABORTING TRACING')
self.staticdata.stats.aborted()
- self.resumekey.reset_counter_from_failure()
def blackhole_if_trace_too_long(self):
warmrunnerstate = self.jitdriver_sd.warmstate
diff --git a/pypy/jit/metainterp/test/test_fficall.py b/pypy/jit/metainterp/test/test_fficall.py
--- a/pypy/jit/metainterp/test/test_fficall.py
+++ b/pypy/jit/metainterp/test/test_fficall.py
@@ -147,6 +147,29 @@
self.check_resops({'jump': 1, 'int_lt': 2, 'setinteriorfield_raw': 4,
'getinteriorfield_raw': 8, 'int_add': 6, 'guard_true': 2})
+ def test_array_getitem_uint8(self):
+ myjitdriver = JitDriver(
+ greens = [],
+ reds = ["n", "i", "s", "data"],
+ )
+ def f(data, n):
+ i = s = 0
+ while i < n:
+ myjitdriver.jit_merge_point(n=n, i=i, s=s, data=data)
+ s += rffi.cast(lltype.Signed, array_getitem(types.uchar, 1, data, 0, 0))
+ i += 1
+ return s
+
+ def main(n):
+ with lltype.scoped_alloc(rffi.CArray(rffi.UCHAR), 1) as data:
+ data[0] = rffi.cast(rffi.UCHAR, 200)
+ return f(data, n)
+
+ assert self.meta_interp(main, [10]) == 2000
+ self.check_resops({'jump': 2, 'int_lt': 2, 'getinteriorfield_raw': 2,
+ 'guard_true': 2, 'int_add': 4})
+
+
class TestFfiCall(FfiCallTests, LLJitMixin):
supports_all = False
diff --git a/pypy/jit/metainterp/test/test_math.py b/pypy/jit/metainterp/test/test_math.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/metainterp/test/test_math.py
@@ -0,0 +1,47 @@
+import math
+from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
+from pypy.rlib.rfloat import isinf, isnan, INFINITY, NAN
+
+class MathTests:
+
+ def test_math_sqrt(self):
+ def f(x):
+ try:
+ return math.sqrt(x)
+ except ValueError:
+ return -INFINITY
+
+ res = self.interp_operations(f, [0.0])
+ assert res == 0.0
+ self.check_operations_history(call_pure=1)
+ #
+ res = self.interp_operations(f, [25.0])
+ assert res == 5.0
+ self.check_operations_history(call_pure=1)
+ #
+ res = self.interp_operations(f, [-0.0])
+ assert str(res) == '-0.0'
+ self.check_operations_history(call_pure=1)
+ #
+ res = self.interp_operations(f, [1000000.0])
+ assert res == 1000.0
+ self.check_operations_history(call_pure=1)
+ #
+ res = self.interp_operations(f, [-1.0])
+ assert res == -INFINITY
+ self.check_operations_history(call_pure=0)
+ #
+ res = self.interp_operations(f, [INFINITY])
+ assert isinf(res) and not isnan(res) and res > 0.0
+ self.check_operations_history(call_pure=0)
+ #
+ res = self.interp_operations(f, [NAN])
+ assert isnan(res) and not isinf(res)
+ self.check_operations_history(call_pure=0)
+
+
+class TestOOtype(MathTests, OOJitMixin):
+ pass
+
+class TestLLtype(MathTests, LLJitMixin):
+ pass
diff --git a/pypy/jit/metainterp/test/test_recursive.py b/pypy/jit/metainterp/test/test_recursive.py
--- a/pypy/jit/metainterp/test/test_recursive.py
+++ b/pypy/jit/metainterp/test/test_recursive.py
@@ -1238,6 +1238,31 @@
self.meta_interp(portal, [0, 0, 0], inline=True)
self.check_resops(call_may_force=0, call=0)
+ def test_dont_repeatedly_trace_from_the_same_guard(self):
+ driver = JitDriver(greens = [], reds = ['level', 'i'])
+
+ def portal(level):
+ if level == 0:
+ i = -10
+ else:
+ i = 0
+ #
+ while True:
+ driver.jit_merge_point(level=level, i=i)
+ if level == 25:
+ return 42
+ i += 1
+ if i <= 0: # <- guard
+ continue # first make a loop
+ else:
+ # then we fail the guard above, doing a recursive call,
+ # which will itself fail the same guard above, and so on
+ return portal(level + 1)
+
+ self.meta_interp(portal, [0])
+ self.check_loop_count_at_most(2) # and not, e.g., 24
+
+
class TestLLtype(RecursiveTests, LLJitMixin):
pass
diff --git a/pypy/module/_bisect/test/test_ztranslation.py b/pypy/module/_bisect/test/test_ztranslation.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_bisect/test/test_ztranslation.py
@@ -0,0 +1,4 @@
+from pypy.objspace.fake.checkmodule import checkmodule
+
+def test_checkmodule():
+ checkmodule('_bisect')
diff --git a/pypy/module/_collections/app_defaultdict.py b/pypy/module/_collections/app_defaultdict.py
--- a/pypy/module/_collections/app_defaultdict.py
+++ b/pypy/module/_collections/app_defaultdict.py
@@ -13,12 +13,14 @@
class defaultdict(dict):
def __init__(self, *args, **kwds):
- self.default_factory = None
- if 'default_factory' in kwds:
- self.default_factory = kwds.pop('default_factory')
- elif len(args) > 0 and (callable(args[0]) or args[0] is None):
- self.default_factory = args[0]
+ if len(args) > 0:
+ default_factory = args[0]
args = args[1:]
+ if not callable(default_factory) and default_factory is not None:
+ raise TypeError("first argument must be callable")
+ else:
+ default_factory = None
+ self.default_factory = default_factory
super(defaultdict, self).__init__(*args, **kwds)
def __missing__(self, key):
@@ -36,7 +38,7 @@
recurse.remove(id(self))
def copy(self):
- return type(self)(self, default_factory=self.default_factory)
+ return type(self)(self.default_factory, self)
def __copy__(self):
return self.copy()
diff --git a/pypy/module/_collections/test/test_defaultdict.py b/pypy/module/_collections/test/test_defaultdict.py
--- a/pypy/module/_collections/test/test_defaultdict.py
+++ b/pypy/module/_collections/test/test_defaultdict.py
@@ -19,11 +19,41 @@
def test_keyerror_without_factory(self):
from _collections import defaultdict
- d1 = defaultdict()
- for key in ['foo', (1,)]:
- try:
- d1[key]
- except KeyError, err:
- assert err.args[0] == key
- else:
- assert 0, "expected KeyError"
+ for d1 in [defaultdict(), defaultdict(None)]:
+ for key in ['foo', (1,)]:
+ try:
+ d1[key]
+ except KeyError, err:
+ assert err.args[0] == key
+ else:
+ assert 0, "expected KeyError"
+
+ def test_noncallable(self):
+ from _collections import defaultdict
+ raises(TypeError, defaultdict, [('a', 5)])
+ d = defaultdict(None, [('a', 5)])
+ assert d.items() == [('a', 5)]
+
+ def test_kwds(self):
+ from _collections import defaultdict
+ d = defaultdict(default_factory=5)
+ assert d.keys() == ['default_factory']
+
+ def test_copy(self):
+ import _collections
+ def f():
+ return 42
+ d = _collections.defaultdict(f, {2: 3})
+ #
+ d1 = d.copy()
+ assert type(d1) is _collections.defaultdict
+ assert len(d1) == 1
+ assert d1[2] == 3
+ assert d1[3] == 42
+ #
+ import copy
+ d2 = copy.deepcopy(d)
+ assert type(d2) is _collections.defaultdict
+ assert len(d2) == 1
+ assert d2[2] == 3
+ assert d2[3] == 42
diff --git a/pypy/module/_ffi/interp_ffi.py b/pypy/module/_ffi/interp_ffi.py
--- a/pypy/module/_ffi/interp_ffi.py
+++ b/pypy/module/_ffi/interp_ffi.py
@@ -457,14 +457,14 @@
# ========================================================================
class W_CDLL(Wrappable):
- def __init__(self, space, name):
+ def __init__(self, space, name, mode):
self.space = space
if name is None:
self.name = "<None>"
else:
self.name = name
try:
- self.cdll = libffi.CDLL(name)
+ self.cdll = libffi.CDLL(name, mode)
except DLOpenError, e:
raise operationerrfmt(space.w_OSError, '%s: %s', self.name,
e.msg or 'unspecified error')
@@ -492,9 +492,9 @@
"No symbol %s found in library %s", name, self.name)
return space.wrap(address_as_uint)
- at unwrap_spec(name='str_or_None')
-def descr_new_cdll(space, w_type, name):
- return space.wrap(W_CDLL(space, name))
+ at unwrap_spec(name='str_or_None', mode=int)
+def descr_new_cdll(space, w_type, name, mode=-1):
+ return space.wrap(W_CDLL(space, name, mode))
W_CDLL.typedef = TypeDef(
@@ -509,6 +509,6 @@
def get_libc(space):
from pypy.rlib.clibffi import get_libc_name
try:
- return space.wrap(W_CDLL(space, get_libc_name()))
+ return space.wrap(W_CDLL(space, get_libc_name(), -1))
except OSError, e:
raise wrap_oserror(space, e)
diff --git a/pypy/module/_multiprocessing/test/test_semaphore.py b/pypy/module/_multiprocessing/test/test_semaphore.py
--- a/pypy/module/_multiprocessing/test/test_semaphore.py
+++ b/pypy/module/_multiprocessing/test/test_semaphore.py
@@ -70,8 +70,10 @@
maxvalue = 1
sem = SemLock(kind, value, maxvalue)
- assert sem.acquire()
- assert not sem.acquire(timeout=0.1)
+ res = sem.acquire()
+ assert res == True
+ res = sem.acquire(timeout=0.1)
+ assert res == False
def test_semaphore_rebuild(self):
from _multiprocessing import SemLock
diff --git a/pypy/module/_random/test/test_ztranslation.py b/pypy/module/_random/test/test_ztranslation.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_random/test/test_ztranslation.py
@@ -0,0 +1,4 @@
+from pypy.objspace.fake.checkmodule import checkmodule
+
+def test_checkmodule():
+ checkmodule('_random')
diff --git a/pypy/module/_socket/interp_func.py b/pypy/module/_socket/interp_func.py
--- a/pypy/module/_socket/interp_func.py
+++ b/pypy/module/_socket/interp_func.py
@@ -1,7 +1,7 @@
from pypy.interpreter.gateway import unwrap_spec
from pypy.module._socket.interp_socket import converted_error, W_RSocket
from pypy.rlib import rsocket
-from pypy.rlib.rsocket import SocketError
+from pypy.rlib.rsocket import SocketError, INVALID_SOCKET
from pypy.interpreter.error import OperationError
def gethostname(space):
@@ -284,7 +284,7 @@
space.wrap(socktype),
space.wrap(protocol),
space.wrap(canonname),
- addr.as_object(-1, space)]) # -1 as per cpython
+ addr.as_object(INVALID_SOCKET, space)]) # -1 as per cpython
for (family, socktype, protocol, canonname, addr) in lst]
return space.newlist(lst1)
diff --git a/pypy/module/cStringIO/test/test_ztranslation.py b/pypy/module/cStringIO/test/test_ztranslation.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cStringIO/test/test_ztranslation.py
@@ -0,0 +1,4 @@
+from pypy.objspace.fake.checkmodule import checkmodule
+
+def test_checkmodule():
+ checkmodule('cStringIO')
diff --git a/pypy/module/clr/boxing_rules.py b/pypy/module/clr/boxing_rules.py
--- a/pypy/module/clr/boxing_rules.py
+++ b/pypy/module/clr/boxing_rules.py
@@ -43,11 +43,11 @@
def tocli(self):
return box(self._value)
-from pypy.objspace.fake.objspace import W_Object as W_Object_Fake
-from pypy.rlib.nonconst import NonConstant
+##from pypy.objspace.fake.objspace import W_Object as W_Object_Fake
+##from pypy.rlib.nonconst import NonConstant
-class __extend__(W_Object_Fake):
- __metaclass__ = extendabletype
+##class __extend__(W_Object_Fake):
+## __metaclass__ = extendabletype
- def tocli(self):
- return NonConstant(None)
+## def tocli(self):
+## return NonConstant(None)
diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -439,9 +439,6 @@
self.w_it = self.space.iter(self.space.next(self.w_iterables))
def next_w(self):
- if not self.w_iterables:
- # already stopped
- raise OperationError(self.space.w_StopIteration, self.space.w_None)
if not self.w_it:
self._advance()
try:
diff --git a/pypy/module/itertools/test/test_ztranslation.py b/pypy/module/itertools/test/test_ztranslation.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/itertools/test/test_ztranslation.py
@@ -0,0 +1,4 @@
+from pypy.objspace.fake.checkmodule import checkmodule
+
+def test_checkmodule():
+ checkmodule('itertools')
diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -32,6 +32,7 @@
'int_': 'interp_boxes.W_LongBox',
'inexact': 'interp_boxes.W_InexactBox',
'floating': 'interp_boxes.W_FloatingBox',
+ 'float32': 'interp_boxes.W_Float32Box',
'float64': 'interp_boxes.W_Float64Box',
}
@@ -76,4 +77,5 @@
'inf': 'app_numpy.inf',
'e': 'app_numpy.e',
'arange': 'app_numpy.arange',
+ 'reshape': 'app_numpy.reshape',
}
diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py
--- a/pypy/module/micronumpy/app_numpy.py
+++ b/pypy/module/micronumpy/app_numpy.py
@@ -36,3 +36,40 @@
j += 1
i += step
return arr
+
+
+def reshape(a, shape):
+ '''reshape(a, newshape)
+ Gives a new shape to an array without changing its data.
+
+ Parameters
+ ----------
+ a : array_like
+ Array to be reshaped.
+ newshape : int or tuple of ints
+ The new shape should be compatible with the original shape. If
+ an integer, then the result will be a 1-D array of that length.
+ One shape dimension can be -1. In this case, the value is inferred
+ from the length of the array and remaining dimensions.
+
+ Returns
+ -------
+ reshaped_array : ndarray
+ This will be a new view object if possible; otherwise, it will
+ be a copy.
+
+
+ See Also
+ --------
+ ndarray.reshape : Equivalent method.
+
+ Notes
+ -----
+
+ It is not always possible to change the shape of an array without
+ copying the data. If you want an error to be raise if the data is copied,
+ you should assign the new shape to the shape attribute of the array
+'''
+ if not hasattr(a, 'reshape'):
+ a = numpypy.array(a)
+ return a.reshape(shape)
diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -4,7 +4,6 @@
from pypy.interpreter.typedef import TypeDef
from pypy.objspace.std.floattype import float_typedef
from pypy.objspace.std.inttype import int_typedef
-from pypy.objspace.std.typeobject import W_TypeObject
from pypy.rlib.rarithmetic import LONG_BIT
from pypy.tool.sourcetools import func_with_new_name
@@ -33,9 +32,8 @@
_attrs_ = ()
def descr__new__(space, w_subtype, __args__):
- assert isinstance(w_subtype, W_TypeObject)
raise operationerrfmt(space.w_TypeError, "cannot create '%s' instances",
- w_subtype.get_module_type_name()
+ w_subtype.getname(space, '?')
)
def descr_str(self, space):
@@ -258,10 +256,12 @@
W_Float32Box.typedef = TypeDef("float32", W_FloatingBox.typedef,
__module__ = "numpypy",
+
+ __new__ = interp2app(W_Float32Box.descr__new__.im_func),
)
W_Float64Box.typedef = TypeDef("float64", (W_FloatingBox.typedef, float_typedef),
__module__ = "numpypy",
__new__ = interp2app(W_Float64Box.descr__new__.im_func),
-)
\ No newline at end of file
+)
diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -18,7 +18,7 @@
VOID_STORAGE = lltype.Array(lltype.Char, hints={'nolength': True, 'render_as_void': True})
class W_Dtype(Wrappable):
- _immuable_fields_ = ["itemtype", "num", "kind"]
+ _immutable_fields_ = ["itemtype", "num", "kind"]
def __init__(self, itemtype, num, kind, name, char, w_box_type, alternate_constructors=[]):
self.signature = signature.BaseSignature()
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -98,6 +98,105 @@
endshape[i] = remainder[i]
return endshape
+def get_shape_from_iterable(space, old_size, w_iterable):
+ new_size = 0
+ new_shape = []
+ if space.isinstance_w(w_iterable, space.w_int):
+ new_size = space.int_w(w_iterable)
+ if new_size < 0:
+ new_size = old_size
+ new_shape = [new_size]
+ else:
+ neg_dim = -1
+ batch = space.listview(w_iterable)
+ new_size = 1
+ if len(batch) < 1:
+ if old_size == 1:
+ # Scalars can have an empty size.
+ new_size = 1
+ else:
+ new_size = 0
+ new_shape = []
+ i = 0
+ for elem in batch:
+ s = space.int_w(elem)
+ if s < 0:
+ if neg_dim >= 0:
+ raise OperationError(space.w_ValueError, space.wrap(
+ "can only specify one unknown dimension"))
+ s = 1
+ neg_dim = i
+ new_size *= s
+ new_shape.append(s)
+ i += 1
+ if neg_dim >= 0:
+ new_shape[neg_dim] = old_size / new_size
+ new_size *= new_shape[neg_dim]
+ if new_size != old_size:
+ raise OperationError(space.w_ValueError,
+ space.wrap("total size of new array must be unchanged"))
+ return new_shape
+
+# Recalculating strides. Find the steps that the iteration does for each
+# dimension, given the stride and shape. Then try to create a new stride that
+# fits the new shape, using those steps. If there is a shape/step mismatch
+# (meaning that the realignment of elements crosses from one step into another)
+# return None so that the caller can raise an exception.
+def calc_new_strides(new_shape, old_shape, old_strides):
+ # Return the proper strides for new_shape, or None if the mapping crosses
+ # stepping boundaries
+
+ # Assumes that prod(old_shape) == prod(new_shape), len(old_shape) > 1, and
+ # len(new_shape) > 0
+ steps = []
+ last_step = 1
+ oldI = 0
+ new_strides = []
+ if old_strides[0] < old_strides[-1]:
+ for i in range(len(old_shape)):
+ steps.append(old_strides[i] / last_step)
+ last_step *= old_shape[i]
+ cur_step = steps[0]
+ n_new_elems_used = 1
+ n_old_elems_to_use = old_shape[0]
+ for s in new_shape:
+ new_strides.append(cur_step * n_new_elems_used)
+ n_new_elems_used *= s
+ while n_new_elems_used > n_old_elems_to_use:
+ oldI += 1
+ if steps[oldI] != steps[oldI - 1]:
+ return None
+ n_old_elems_to_use *= old_shape[oldI]
+ if n_new_elems_used == n_old_elems_to_use:
+ oldI += 1
+ if oldI >= len(old_shape):
+ break
+ cur_step = steps[oldI]
+ n_old_elems_to_use *= old_shape[oldI]
+ else:
+ for i in range(len(old_shape) - 1, -1, -1):
+ steps.insert(0, old_strides[i] / last_step)
+ last_step *= old_shape[i]
+ cur_step = steps[-1]
+ n_new_elems_used = 1
+ oldI = -1
+ n_old_elems_to_use = old_shape[-1]
+ for i in range(len(new_shape) - 1, -1, -1):
+ s = new_shape[i]
+ new_strides.insert(0, cur_step * n_new_elems_used)
+ n_new_elems_used *= s
+ while n_new_elems_used > n_old_elems_to_use:
+ oldI -= 1
+ if steps[oldI] != steps[oldI + 1]:
+ return None
+ n_old_elems_to_use *= old_shape[oldI]
+ if n_new_elems_used == n_old_elems_to_use:
+ oldI -= 1
+ if oldI < -len(old_shape):
+ break
+ cur_step = steps[oldI]
+ n_old_elems_to_use *= old_shape[oldI]
+ return new_strides
# Iterators for arrays
# --------------------
@@ -444,6 +543,7 @@
return False
i = i.next(shapelen)
return True
+
def descr_all(self, space):
return space.wrap(self._all())
@@ -459,6 +559,7 @@
return True
i = i.next(shapelen)
return False
+
def descr_any(self, space):
return space.wrap(self._any())
@@ -483,6 +584,12 @@
def descr_get_shape(self, space):
return space.newtuple([space.wrap(i) for i in self.shape])
+ def descr_set_shape(self, space, w_iterable):
+ concrete = self.get_concrete()
+ new_shape = get_shape_from_iterable(space,
+ concrete.find_size(), w_iterable)
+ concrete.setshape(space, new_shape)
+
def descr_get_size(self, space):
return space.wrap(self.find_size())
@@ -607,11 +714,6 @@
def _index_of_single_item(self, space, w_idx):
if space.isinstance_w(w_idx, space.w_int):
idx = space.int_w(w_idx)
- if not self.shape:
- if idx != 0:
- raise OperationError(space.w_IndexError,
- space.wrap("index out of range"))
- return 0
if idx < 0:
idx = self.shape[0] + idx
if idx < 0 or idx >= self.shape[0]:
@@ -730,10 +832,49 @@
strides += self.strides[s:]
backstrides += self.backstrides[s:]
new_sig = signature.Signature.find_sig([
- NDimSlice.signature, self.signature,
+ W_NDimSlice.signature, self.signature,
])
- return NDimSlice(self, new_sig, start, strides[:], backstrides[:],
- shape[:])
+ return W_NDimSlice(self, new_sig, start, strides[:], backstrides[:],
+ shape[:])
+
+ def descr_reshape(self, space, args_w):
+ """reshape(...)
+ a.reshape(shape)
+
+ Returns an array containing the same data with a new shape.
+
+ Refer to `numpypy.reshape` for full documentation.
+
+ See Also
+ --------
+ numpypy.reshape : equivalent function
+"""
+ if len(args_w) == 1:
+ w_shape = args_w[0]
+ else:
+ w_shape = space.newtuple(args_w)
+ concrete = self.get_concrete()
+ new_shape = get_shape_from_iterable(space,
+ concrete.find_size(), w_shape)
+ # Since we got to here, prod(new_shape) == self.size
+ new_strides = calc_new_strides(new_shape,
+ concrete.shape, concrete.strides)
+ if new_strides:
+ # We can create a view, strides somehow match up.
+ new_sig = signature.Signature.find_sig([
+ W_NDimSlice.signature, self.signature
+ ])
+ ndims = len(new_shape)
+ new_backstrides = [0] * ndims
+ for nd in range(ndims):
+ new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd]
+ arr = W_NDimSlice(self, new_sig, self.start, new_strides,
+ new_backstrides, new_shape)
+ else:
+ # Create copy with contiguous data
+ arr = concrete.copy()
+ arr.setshape(space, new_shape)
+ return arr
def descr_mean(self, space):
return space.div(self.descr_sum(space), space.wrap(self.find_size()))
@@ -751,7 +892,7 @@
if len(concrete.shape) < 2:
return space.wrap(self)
new_sig = signature.Signature.find_sig([
- NDimSlice.signature, self.signature
+ W_NDimSlice.signature, self.signature
])
strides = []
backstrides = []
@@ -760,8 +901,8 @@
strides.append(concrete.strides[i])
backstrides.append(concrete.backstrides[i])
shape.append(concrete.shape[i])
- return space.wrap(NDimSlice(concrete, new_sig, self.start, strides[:],
- backstrides[:], shape[:]))
+ return space.wrap(W_NDimSlice(concrete, new_sig, self.start, strides[:],
+ backstrides[:], shape[:]))
def descr_get_flatiter(self, space):
return space.wrap(W_FlatIterator(self))
@@ -775,6 +916,15 @@
def descr_debug_repr(self, space):
return space.wrap(self.debug_repr())
+ def descr_array_iface(self, space):
+ concrete = self.get_concrete()
+ storage = concrete.get_storage(space)
+ addr = rffi.cast(lltype.Signed, storage)
+ w_d = space.newdict()
+ space.setitem_str(w_d, 'data', space.newtuple([space.wrap(addr),
+ space.w_False]))
+ return w_d
+
def convert_to_array(space, w_obj):
if isinstance(w_obj, BaseArray):
return w_obj
@@ -830,6 +980,14 @@
def debug_repr(self):
return 'Scalar'
+ def setshape(self, space, new_shape):
+ # In order to get here, we already checked that prod(new_shape) == 1,
+ # so in order to have a consistent API, let it go through.
+ pass
+
+ def get_storage(self, space):
+ raise OperationError(space.w_TypeError, space.wrap("Cannot get array interface on scalars in pypy"))
+
class VirtualArray(BaseArray):
"""
Class for representing virtual arrays, such as binary ops or ufuncs
@@ -1022,13 +1180,46 @@
return space.wrap(self.shape[0])
return space.wrap(1)
+ def setshape(self, space, new_shape):
+ if len(self.shape) < 1:
+ return
+ elif len(self.shape) < 2:
+ # TODO: this code could be refactored into calc_strides
+ # but then calc_strides would have to accept a stepping factor
+ strides = []
+ backstrides = []
+ s = self.strides[0]
+ if self.order == 'C':
+ new_shape.reverse()
+ for sh in new_shape:
+ strides.append(s)
+ backstrides.append(s * (sh - 1))
+ s *= sh
+ if self.order == 'C':
+ strides.reverse()
+ backstrides.reverse()
+ new_shape.reverse()
+ self.strides = strides[:]
+ self.backstrides = backstrides[:]
+ self.shape = new_shape[:]
+ return
+ new_strides = calc_new_strides(new_shape, self.shape, self.strides)
+ if new_strides is None:
+ raise OperationError(space.w_AttributeError, space.wrap(
+ "incompatible shape for a non-contiguous array"))
+ new_backstrides = [0] * len(new_shape)
+ for nd in range(len(new_shape)):
+ new_backstrides[nd] = (new_shape[nd] - 1) * new_strides[nd]
+ self.strides = new_strides[:]
+ self.backstrides = new_backstrides[:]
+ self.shape = new_shape[:]
-class NDimSlice(ViewArray):
+class W_NDimSlice(ViewArray):
signature = signature.BaseSignature()
def __init__(self, parent, signature, start, strides, backstrides,
shape):
- if isinstance(parent, NDimSlice):
+ if isinstance(parent, W_NDimSlice):
parent = parent.parent
ViewArray.__init__(self, parent, signature, strides, backstrides, shape)
self.start = start
@@ -1077,11 +1268,16 @@
def copy(self):
array = W_NDimArray(self.size, self.shape[:], self.find_dtype())
iter = self.start_iter()
+ a_iter = array.start_iter()
while not iter.done():
- array.setitem(iter.offset, self.getitem(iter.offset))
+ array.setitem(a_iter.offset, self.getitem(iter.offset))
iter = iter.next(len(self.shape))
+ a_iter = a_iter.next(len(array.shape))
return array
+ def get_storage(self, space):
+ return self.parent.get_storage(space)
+
class W_NDimArray(BaseArray):
""" A class representing contiguous array. We know that each iteration
by say ufunc will increase the data index by one
@@ -1137,9 +1333,16 @@
return ArrayIterator(self.size)
raise NotImplementedError # use ViewIterator simply, test it
+ def setshape(self, space, new_shape):
+ self.shape = new_shape
+ self.calc_strides(new_shape)
+
def debug_repr(self):
return 'Array'
+ def get_storage(self, space):
+ return self.storage
+
def __del__(self):
lltype.free(self.storage, flavor='raw', track_allocation=False)
@@ -1259,9 +1462,11 @@
__repr__ = interp2app(BaseArray.descr_repr),
__str__ = interp2app(BaseArray.descr_str),
__debug_repr__ = interp2app(BaseArray.descr_debug_repr),
+ __array_interface__ = GetSetProperty(BaseArray.descr_array_iface),
dtype = GetSetProperty(BaseArray.descr_get_dtype),
- shape = GetSetProperty(BaseArray.descr_get_shape),
+ shape = GetSetProperty(BaseArray.descr_get_shape,
+ BaseArray.descr_set_shape),
size = GetSetProperty(BaseArray.descr_get_size),
T = GetSetProperty(BaseArray.descr_get_transpose),
@@ -1279,6 +1484,7 @@
dot = interp2app(BaseArray.descr_dot),
copy = interp2app(BaseArray.descr_copy),
+ reshape = interp2app(BaseArray.descr_reshape),
)
diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -173,7 +173,7 @@
raises(TypeError, numpy.number, 0)
raises(TypeError, numpy.integer, 0)
exc = raises(TypeError, numpy.signedinteger, 0)
- assert str(exc.value) == "cannot create 'numpypy.signedinteger' instances"
+ assert str(exc.value) == "cannot create 'signedinteger' instances"
raises(TypeError, numpy.floating, 0)
raises(TypeError, numpy.inexact, 0)
@@ -240,6 +240,13 @@
assert numpy.dtype(numpy.int64).type is numpy.int64
assert numpy.int64(3) == 3
+ def test_float32(self):
+ import numpypy as numpy
+
+ assert numpy.float32.mro() == [numpy.float32, numpy.floating, numpy.inexact, numpy.number, numpy.generic, object]
+
+ assert numpy.float32(12) == numpy.float64(12)
+
def test_float64(self):
import numpypy as numpy
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -158,6 +158,13 @@
assert shape_agreement(self.space,
[5, 2], [4, 3, 5, 2]) == [4, 3, 5, 2]
+ def test_calc_new_strides(self):
+ from pypy.module.micronumpy.interp_numarray import calc_new_strides
+ assert calc_new_strides([2, 4], [4, 2], [4, 2]) == [8, 2]
+ assert calc_new_strides([2, 4, 3], [8, 3], [1, 16]) == [1, 2, 16]
+ assert calc_new_strides([2, 3, 4], [8, 3], [1, 16]) is None
+ assert calc_new_strides([24], [2, 4, 3], [48, 6, 1]) is None
+ assert calc_new_strides([24], [2, 4, 3], [24, 6, 2]) == [2]
class AppTestNumArray(BaseNumpyAppTest):
def test_ndarray(self):
@@ -216,8 +223,8 @@
assert a[2] == 4
def test_copy(self):
- from numpypy import array
- a = array(range(5))
+ from numpypy import arange, array
+ a = arange(5)
b = a.copy()
for i in xrange(5):
assert b[i] == a[i]
@@ -227,6 +234,11 @@
a = array(1)
assert a.copy() == a
+ a = arange(8)
+ b = a[::2]
+ c = b.copy()
+ assert (c == b).all()
+
def test_iterator_init(self):
from numpypy import array
a = array(range(5))
@@ -318,8 +330,8 @@
def test_scalar(self):
from numpypy import array, dtype
a = array(3)
- #assert a[0] == 3
raises(IndexError, "a[0]")
+ raises(IndexError, "a[0] = 5")
assert a.size == 1
assert a.shape == ()
assert a.dtype is dtype(int)
@@ -339,6 +351,81 @@
c = a[:3]
assert c.shape == (3,)
+ def test_set_shape(self):
+ from numpypy import array, zeros
+ a = array([])
+ a.shape = []
+ a = array(range(12))
+ a.shape = (3, 4)
+ assert (a == [range(4), range(4, 8), range(8, 12)]).all()
+ a.shape = (3, 2, 2)
+ assert a[1, 1, 1] == 7
+ a.shape = (3, -1, 2)
+ assert a.shape == (3, 2, 2)
+ a.shape = 12
+ assert a.shape == (12, )
+ exc = raises(ValueError, "a.shape = 10")
+ assert str(exc.value) == "total size of new array must be unchanged"
+ a = array(3)
+ a.shape = ()
+ #numpy allows this
+ a.shape = (1,)
+
+ def test_reshape(self):
+ from numpypy import array, zeros
+ a = array(range(12))
+ exc = raises(ValueError, "b = a.reshape((3, 10))")
+ assert str(exc.value) == "total size of new array must be unchanged"
+ b = a.reshape((3, 4))
+ assert b.shape == (3, 4)
+ assert (b == [range(4), range(4, 8), range(8, 12)]).all()
+ b[:, 0] = 1000
+ assert (a == [1000, 1, 2, 3, 1000, 5, 6, 7, 1000, 9, 10, 11]).all()
+ a = zeros((4, 2, 3))
+ a.shape = (12, 2)
+
+ def test_slice_reshape(self):
+ from numpypy import zeros, arange
+ a = zeros((4, 2, 3))
+ b = a[::2, :, :]
+ b.shape = (2, 6)
+ exc = raises(AttributeError, "b.shape = 12")
+ assert str(exc.value) == \
+ "incompatible shape for a non-contiguous array"
+ b = a[::2, :, :].reshape((2, 6))
+ assert b.shape == (2, 6)
+ b = arange(20)[1:17:2]
+ b.shape = (4, 2)
+ assert (b == [[1, 3], [5, 7], [9, 11], [13, 15]]).all()
+ c = b.reshape((2, 4))
+ assert (c == [[1, 3, 5, 7], [9, 11, 13, 15]]).all()
+
+ z = arange(96).reshape((12, -1))
+ assert z.shape == (12, 8)
+ y = z.reshape((4, 3, 8))
+ v = y[:, ::2, :]
+ w = y.reshape(96)
+ u = v.reshape(64)
+ assert y[1, 2, 1] == z[5, 1]
+ y[1, 2, 1] = 1000
+ # z, y, w, v are views of eachother
+ assert z[5, 1] == 1000
+ assert v[1, 1, 1] == 1000
+ assert w[41] == 1000
+ # u is not a view, it is a copy!
+ assert u[25] == 41
+
+ a = zeros((5, 2))
+ assert a.reshape(-1).shape == (10,)
+
+ raises(ValueError, arange(10).reshape, (5, -1, -1))
+
+ def test_reshape_varargs(self):
+ from numpypy import arange
+ z = arange(96).reshape(12, -1)
+ y = z.reshape(4, 3, 8)
+ assert y.shape == (4, 3, 8)
+
def test_add(self):
from numpypy import array
a = array(range(5))
@@ -1027,6 +1114,16 @@
b = a[0].copy()
assert (b == zeros(10)).all()
+ def test_array_interface(self):
+ from numpypy import array
+ a = array([1, 2, 3])
+ i = a.__array_interface__
+ assert isinstance(i['data'][0], int)
+ a = a[::2]
+ i = a.__array_interface__
+ assert isinstance(i['data'][0], int)
+ raises(TypeError, getattr, array(3), '__array_interface__')
+
class AppTestSupport(BaseNumpyAppTest):
def setup_class(cls):
import struct
@@ -1155,3 +1252,14 @@
a = arange(0, 0.8, 0.1)
assert len(a) == 8
assert arange(False, True, True).dtype is dtype(int)
+
+
+class AppTestRanges(BaseNumpyAppTest):
+ def test_app_reshape(self):
+ from numpypy import arange, array, dtype, reshape
+ a = arange(12)
+ b = reshape(a, (3, 4))
+ assert b.shape == (3, 4)
+ a = range(12)
+ b = reshape(a, (3, 4))
+ assert b.shape == (3, 4)
diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -8,13 +8,12 @@
from pypy.jit.metainterp import pyjitpl
from pypy.jit.metainterp.test.support import LLJitMixin
from pypy.jit.metainterp.warmspot import reset_stats
-from pypy.module.micronumpy import interp_boxes, interp_ufuncs, signature
-from pypy.module.micronumpy.compile import (numpy_compile, FakeSpace,
- FloatObject, IntObject, BoolObject, Parser, InterpreterState)
-from pypy.module.micronumpy.interp_numarray import (W_NDimArray, NDimSlice,
+from pypy.module.micronumpy import interp_boxes
+from pypy.module.micronumpy.compile import (FakeSpace,
+ IntObject, Parser, InterpreterState)
+from pypy.module.micronumpy.interp_numarray import (W_NDimArray,
BaseArray)
from pypy.rlib.nonconst import NonConstant
-from pypy.rpython.annlowlevel import llstr, hlstr
class TestNumpyJIt(LLJitMixin):
diff --git a/pypy/module/micronumpy/test/test_ztranslation.py b/pypy/module/micronumpy/test/test_ztranslation.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/test/test_ztranslation.py
@@ -0,0 +1,5 @@
+
+from pypy.objspace.fake.checkmodule import checkmodule
+
+def test_numpy_translates():
+ checkmodule('micronumpy')
diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py b/pypy/module/pypyjit/test_pypy_c/test_containers.py
--- a/pypy/module/pypyjit/test_pypy_c/test_containers.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py
@@ -117,3 +117,14 @@
--TICK--
jump(p0, p1, p2, p3, p4, i35, p13, i7, descr=...)
""")
+
+ def test_floatlist_unpack_without_calls(self):
+ def fn(n):
+ l = [2.3, 3.4, 4.5]
+ for i in range(n):
+ x, y, z = l # ID: look
+ #
+ log = self.run(fn, [1000])
+ loop, = log.loops_by_filename(self.filepath)
+ ops = loop.ops_by_id('look')
+ assert 'call' not in log.opnames(ops)
diff --git a/pypy/module/test_lib_pypy/test_collections.py b/pypy/module/test_lib_pypy/test_collections.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/test_lib_pypy/test_collections.py
@@ -0,0 +1,27 @@
+
+"""
+Extra tests for the pure Python PyPy _collections module
+(not used in normal PyPy's)
+"""
+
+from pypy.conftest import gettestobjspace
+
+class AppTestcStringIO:
+ def test_copy(self):
+ import _collections
+ def f():
+ return 42
+ d = _collections.defaultdict(f, {2: 3})
+ #
+ d1 = d.copy()
+ assert type(d1) is _collections.defaultdict
+ assert len(d1) == 1
+ assert d1[2] == 3
+ assert d1[3] == 42
+ #
+ import copy
+ d2 = copy.deepcopy(d)
+ assert type(d2) is _collections.defaultdict
+ assert len(d2) == 1
+ assert d2[2] == 3
+ assert d2[3] == 42
diff --git a/pypy/objspace/fake/__init__.py b/pypy/objspace/fake/__init__.py
--- a/pypy/objspace/fake/__init__.py
+++ b/pypy/objspace/fake/__init__.py
@@ -1,2 +0,0 @@
-from objspace import FakeObjSpace
-Space = FakeObjSpace
diff --git a/pypy/objspace/fake/checkmodule.py b/pypy/objspace/fake/checkmodule.py
--- a/pypy/objspace/fake/checkmodule.py
+++ b/pypy/objspace/fake/checkmodule.py
@@ -1,108 +1,12 @@
-import re
-from copy import copy
-from pypy.tool.error import debug
-from pypy.interpreter.argument import Arguments
-from pypy.interpreter.gateway import interp2app
-from pypy.rlib.nonconst import NonConstant
+from pypy.objspace.fake.objspace import FakeObjSpace, W_Root
-def my_import(name):
- mod = __import__(name)
- components = name.split('.')
- for comp in components[1:]:
- mod = getattr(mod, comp)
- return mod
-def find_gateways(modname, basepath, module):
- identifier = r'[a-zA-Z0-9][a-zA-Z0-9_]*'
- r_simplename = re.compile(r'(%s)[.](%s)$' % (identifier, identifier))
- res = []
- for name in module.interpleveldefs.values():
- match = r_simplename.match(name)
- if match:
- submod_name, obj_name = match.groups()
- submod_name = '%s.%s.%s' % (basepath, modname, submod_name)
- submod = my_import(submod_name)
- obj = getattr(submod, obj_name)
- res += find_gw_in_obj(obj)
- return res
-
-def find_gw_in_obj(obj):
- if hasattr(obj, 'typedef'):
- typedef = obj.typedef
- return [gw for gw in typedef.rawdict.values()
- if isinstance(gw, interp2app)]
- elif hasattr(obj, 'func_code'):
- return [interp2app(obj)]
- else:
- assert False
-
-## Since the fake objspace is more a hack than a real object space, it
-## happens that the annotator complains about operations that cannot
-## succeed because it knows too much about the objects involved. For
-## example, if it knows that a list is always empty, it will block
-## each operations that tries to access that list. This is not what we
-## want, because we know that with real objectspaces that operations
-## will succeed.
-
-## As a workaround, we insert dummy rpython code (the function
-## dummy_rpython) that manipulates the variables in order to give
-## them a more sensible annotation. This is the preferred way to solve
-## the problems so far.
-
-## If the solution above doesn't work, the alternative is to
-## substitute the interpreter code with something that doesn't hurt
-## the annotator. It's a very ugly hack, better solutions are welcome
-## :-)
-
-
-# dummy rpython code to give some variables more sensible annotations
-def dummy_rpython(dummy_function):
- # to make the annotator flow-in without executing the code
- if NonConstant(False):
- dummy_function.defs_w = [None] # else the annotator would see an always empty list
-
-def patch_pypy():
- from pypy.interpreter.baseobjspace import W_Root
-
- def descr_call_mismatch(self, space, opname, RequiredClass, args):
- from pypy.interpreter.error import OperationError
- msg = 'This message will never be displayed :-)'
- raise OperationError(space.w_TypeError, space.wrap(msg))
- W_Root.descr_call_mismatch = descr_call_mismatch
-
-
-def checkmodule(modname, backend, interactive=False, basepath='pypy.module'):
- "Compile a fake PyPy module."
- from pypy.objspace.fake.objspace import FakeObjSpace, W_Object
- from pypy.translator.driver import TranslationDriver
-
+def checkmodule(modname):
space = FakeObjSpace()
- space.config.translating = True
- ModuleClass = __import__(basepath + '.%s' % modname,
- None, None, ['Module']).Module
- module = ModuleClass(space, space.wrap(modname))
- w_moduledict = module.getdict(space)
-
- gateways = find_gateways(modname, basepath, module)
- functions = [gw.__spacebind__(space) for gw in gateways]
- arguments = Arguments.frompacked(space, W_Object(), W_Object())
- dummy_function = copy(functions[0])
-
- def main(argv): # use the standalone mode not to allow SomeObject
- dummy_rpython(dummy_function)
- for func in functions:
- func.call_args(arguments)
- return 0
-
- patch_pypy()
- driver = TranslationDriver()
- driver.setup(main, None)
- try:
- driver.proceed(['compile_' + backend])
- except SystemExit:
- raise
- except:
- if not interactive:
- raise
- debug(driver)
- raise SystemExit(1)
+ mod = __import__('pypy.module.%s' % modname, None, None, ['__doc__'])
+ # force computation and record what we wrap
+ module = mod.Module(space, W_Root())
+ for name in module.loaders:
+ module._load_lazily(space, name)
+ #
+ space.translates(**{'translation.list_comprehension_operations':True})
diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py
--- a/pypy/objspace/fake/objspace.py
+++ b/pypy/objspace/fake/objspace.py
@@ -1,147 +1,302 @@
-from pypy.interpreter.baseobjspace import ObjSpace, Wrappable, W_Root
-from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.baseobjspace import W_Root, ObjSpace
+from pypy.interpreter.baseobjspace import Wrappable, SpaceCache
+from pypy.interpreter import argument, gateway
+from pypy.interpreter.typedef import TypeDef, GetSetProperty
+from pypy.annotation.model import SomeInstance, s_None
+from pypy.rpython.extregistry import ExtRegistryEntry
+from pypy.rpython.lltypesystem import lltype
+from pypy.tool.sourcetools import compile2, func_with_new_name
+from pypy.rlib.unroll import unrolling_iterable
+from pypy.rlib.objectmodel import instantiate, we_are_translated
from pypy.rlib.nonconst import NonConstant
from pypy.rlib.rarithmetic import r_uint
-from pypy.rlib.rbigint import rbigint
+from pypy.translator.translator import TranslationContext
+from pypy.tool.option import make_config
-#class W_Type(W_Root):
-# _attrs_ = ()
-class W_Object(W_Root):
- _attrs_ = ()
-W_Object.typedef = TypeDef('foobar')
+class W_MyObject(Wrappable):
+ typedef = None
-def make_dummy(a=W_Object(), b=W_Object()):
- def fn(*args):
- if NonConstant(True):
- return a
- else:
- return b
- return fn
+ def getdict(self, space):
+ return w_obj_or_none()
-int_dummy = make_dummy(42, 43)
-float_dummy = make_dummy(42.0, 42.1)
-uint_dummy = make_dummy(r_uint(42), r_uint(43))
-str_dummy = make_dummy('foo', 'bar')
-bool_dummy = make_dummy(True, False)
-unicode_dummy = make_dummy(u'abc', u'cde')
-bigint_dummy = make_dummy(rbigint.fromint(0), rbigint.fromint(1))
+ def getdictvalue(self, space, attr):
+ attr + "xx" # check that it's a string
+ return w_obj_or_none()
+
+ def setdictvalue(self, space, attr, w_value):
+ attr + "xx" # check that it's a string
+ is_root(w_value)
+ return NonConstant(True)
+
+ def deldictvalue(self, space, attr):
+ attr + "xx" # check that it's a string
+ return NonConstant(True)
+
+ def setdict(self, space, w_dict):
+ is_root(w_dict)
+
+ def setclass(self, space, w_subtype):
+ is_root(w_subtype)
+
+ def str_w(self, space):
+ return NonConstant("foobar")
+
+ def unicode_w(self, space):
+ return NonConstant(u"foobar")
+
+ def int_w(self, space):
+ return NonConstant(-42)
+
+ def uint_w(self, space):
+ return r_uint(NonConstant(42))
+
+ def bigint_w(self, space):
+ from pypy.rlib.rbigint import rbigint
+ return rbigint.fromint(NonConstant(42))
+
+
+def w_some_obj():
+ if NonConstant(False):
+ return W_Root()
+ return W_MyObject()
+
+def w_obj_or_none():
+ if NonConstant(False):
+ return None
+ return w_some_obj()
+
+def is_root(w_obj):
+ assert isinstance(w_obj, W_Root)
+is_root.expecting = W_Root
+
+def is_arguments(arg):
+ assert isinstance(arg, argument.Arguments)
+is_arguments.expecting = argument.Arguments
+
+
+class Entry(ExtRegistryEntry):
+ _about_ = is_root, is_arguments
+
+ def compute_result_annotation(self, s_w_obj):
+ cls = self.instance.expecting
+ s_inst = SomeInstance(self.bookkeeper.getuniqueclassdef(cls),
+ can_be_None=True)
+ assert s_inst.contains(s_w_obj)
+ return s_None
+
+ def specialize_call(self, hop):
+ return hop.inputconst(lltype.Void, None)
+
+# ____________________________________________________________
+
class FakeObjSpace(ObjSpace):
- w_None = W_Object()
- w_False = W_Object()
- w_True = W_Object()
- w_Ellipsis = W_Object()
- w_NotImplemented = W_Object()
- w_int = W_Object()
- w_dict = W_Object()
- w_float = W_Object()
- w_long = W_Object()
- w_tuple = W_Object()
- w_str = W_Object()
- w_basestring = W_Object()
- w_unicode = W_Object()
- w_type = W_Object()
- w_instance = W_Object()
- w_slice = W_Object()
- w_hex = W_Object()
- w_oct = W_Object()
-
- def initialize(self):
- self.config.objspace.geninterp = False
- self.config.objspace.disable_call_speedhacks = True
- self.wrap_cache = {}
- self.make_builtins()
- def _freeze_(self):
- return True
+ def __init__(self):
+ self._seen_extras = []
+ ObjSpace.__init__(self)
+
+ def float_w(self, w_obj):
+ is_root(w_obj)
+ return NonConstant(42.5)
+
+ def is_true(self, w_obj):
+ is_root(w_obj)
+ return NonConstant(False)
+
+ def unwrap(self, w_obj):
+ "NOT_RPYTHON"
+ raise NotImplementedError
+
+ def newdict(self, module=False, instance=False, classofinstance=None,
+ strdict=False):
+ return w_some_obj()
+
+ def newtuple(self, list_w):
+ for w_x in list_w:
+ is_root(w_x)
+ return w_some_obj()
+
+ def newlist(self, list_w):
+ for w_x in list_w:
+ is_root(w_x)
+ return w_some_obj()
+
+ def newslice(self, w_start, w_end, w_step):
+ is_root(w_start)
+ is_root(w_end)
+ is_root(w_step)
+ return w_some_obj()
+
+ def newint(self, x):
+ return w_some_obj()
+
+ def newfloat(self, x):
+ return w_some_obj()
+
+ def marshal_w(self, w_obj):
+ "NOT_RPYTHON"
+ raise NotImplementedError
def wrap(self, x):
- if isinstance(x, Wrappable):
- w_result = x.__spacebind__(self)
- return w_result
- return W_Object()
+ if not we_are_translated():
+ if isinstance(x, gateway.interp2app):
+ self._see_interp2app(x)
+ if isinstance(x, GetSetProperty):
+ self._see_getsetproperty(x)
+ return w_some_obj()
wrap._annspecialcase_ = "specialize:argtype(1)"
- def unwrap(self, w_obj):
- assert isinstance(w_obj, W_Object)
- return None
+ def _see_interp2app(self, interp2app):
+ "NOT_RPYTHON"
+ activation = interp2app._code.activation
+ def check():
+ scope_w = [w_some_obj()] * NonConstant(42)
+ w_result = activation._run(self, scope_w)
+ is_root(w_result)
+ check = func_with_new_name(check, 'check__' + interp2app.name)
+ self._seen_extras.append(check)
- lookup = make_dummy()
- allocate_instance = make_dummy()
- getattr = make_dummy()
- setattr = make_dummy()
- getitem = make_dummy()
- setitem = make_dummy()
- delitem = make_dummy()
- int_w = int_dummy
- uint_w = uint_dummy
- float_w = float_dummy
- unicode_w = unicode_dummy
- bigint_w = bigint_dummy
- iter = make_dummy()
- type = make_dummy()
- str = make_dummy()
- int = make_dummy()
- float = make_dummy()
- repr = make_dummy()
- id = make_dummy()
- len = make_dummy()
- str_w = str_dummy
- call_args = make_dummy()
- new_interned_str = make_dummy()
- newint = make_dummy()
- newlong = make_dummy()
- newfloat = make_dummy()
- def newdict(self, module=False):
- return self.newfloat()
- newlist = make_dummy()
- emptylist = make_dummy()
- newtuple = make_dummy()
- newslice = make_dummy()
- lt = make_dummy()
- le = make_dummy()
- eq = make_dummy()
- ne = make_dummy()
- gt = make_dummy()
- ge = make_dummy()
- lt_w = bool_dummy
- le_w = bool_dummy
- eq_w = bool_dummy
- ne_w = bool_dummy
- gt_w = bool_dummy
- ge_w = bool_dummy
- is_w = bool_dummy
- is_ = make_dummy()
- next = make_dummy()
- is_true = bool_dummy
- nonzero = make_dummy()
- issubtype = make_dummy()
- ord = make_dummy()
- hash = make_dummy()
- delattr = make_dummy() # should return None?
- contains = make_dummy()
- hex = make_dummy()
- oct = make_dummy()
- pow = make_dummy()
- inplace_pow = make_dummy()
- cmp = make_dummy()
+ def _see_getsetproperty(self, getsetproperty):
+ "NOT_RPYTHON"
+ space = self
+ def checkprop():
+ getsetproperty.fget(getsetproperty, space, w_some_obj())
+ if getsetproperty.fset is not None:
+ getsetproperty.fset(getsetproperty, space, w_some_obj(),
+ w_some_obj())
+ if getsetproperty.fdel is not None:
+ getsetproperty.fdel(getsetproperty, space, w_some_obj())
+ if not getsetproperty.name.startswith('<'):
+ checkprop = func_with_new_name(checkprop,
+ 'checkprop__' + getsetproperty.name)
+ self._seen_extras.append(checkprop)
- # XXsX missing operations
- def coerce(self, *args): raise NotImplementedError("space.coerce()")
- def get(self, *args): raise NotImplementedError("space.get()")
- def set(self, *args): raise NotImplementedError("space.set()")
- def delete(self, *args): raise NotImplementedError("space.delete()")
- def userdel(self, *args): raise NotImplementedError("space.userdel()")
- def marshal_w(self, *args):raise NotImplementedError("space.marshal_w()")
+ def call_obj_args(self, w_callable, w_obj, args):
+ is_root(w_callable)
+ is_root(w_obj)
+ is_arguments(args)
+ return w_some_obj()
- gettypefor = make_dummy()
- gettypeobject = make_dummy()
- unpackiterable = make_dummy([W_Object()], [W_Object()])
+ def call(self, w_callable, w_args, w_kwds=None):
+ is_root(w_callable)
+ is_root(w_args)
+ is_root(w_kwds)
+ return w_some_obj()
+ def call_function(self, w_func, *args_w):
+ is_root(w_func)
+ for w_arg in list(args_w):
+ is_root(w_arg)
+ return w_some_obj()
-## Register all exceptions
-import exceptions
-for name in ObjSpace.ExceptionTable:
- exc = getattr(exceptions, name)
- setattr(FakeObjSpace, 'w_' + name, W_Object())
+ def call_args(self, w_func, args):
+ is_root(w_func)
+ is_arguments(args)
+ return w_some_obj()
+
+ def gettypefor(self, cls):
+ return self.gettypeobject(cls.typedef)
+
+ def gettypeobject(self, typedef):
+ assert typedef is not None
+ return self.fromcache(TypeCache).getorbuild(typedef)
+
+ def unpackiterable(self, w_iterable, expected_length=-1):
+ is_root(w_iterable)
+ if expected_length < 0:
+ expected_length = 3
+ return [w_some_obj()] * expected_length
+
+ def allocate_instance(self, cls, w_subtype):
+ is_root(w_subtype)
+ return instantiate(cls)
+ allocate_instance._annspecialcase_ = "specialize:arg(1)"
+
+ def decode_index(self, w_index_or_slice, seqlength):
+ is_root(w_index_or_slice)
+ return (NonConstant(42), NonConstant(42), NonConstant(42))
+
+ def decode_index4(self, w_index_or_slice, seqlength):
+ is_root(w_index_or_slice)
+ return (NonConstant(42), NonConstant(42),
+ NonConstant(42), NonConstant(42))
+
+ def exec_(self, *args, **kwds):
+ pass
+
+ # ----------
+
+ def translates(self, func=None, argtypes=None, **kwds):
+ config = make_config(None, **kwds)
+ if func is not None:
+ if argtypes is None:
+ nb_args = func.func_code.co_argcount
+ argtypes = [W_Root] * nb_args
+ #
+ t = TranslationContext(config=config)
+ self.t = t # for debugging
+ ann = t.buildannotator()
+ if func is not None:
+ ann.build_types(func, argtypes, complete_now=False)
+ #
+ # annotate all _seen_extras, knowing that annotating some may
+ # grow the list
+ done = 0
+ while done < len(self._seen_extras):
+ print self._seen_extras
+ ann.build_types(self._seen_extras[done], [],
+ complete_now=False)
+ done += 1
+ ann.complete()
+ #t.viewcg()
+ t.buildrtyper().specialize()
+ t.checkgraphs()
+
+
+def setup():
+ for name in (ObjSpace.ConstantTable +
+ ObjSpace.ExceptionTable +
+ ['int', 'str', 'float', 'long', 'tuple', 'list',
+ 'dict', 'unicode', 'complex', 'slice', 'bool',
+ 'type', 'basestring']):
+ setattr(FakeObjSpace, 'w_' + name, w_some_obj())
+ #
+ for (name, _, arity, _) in ObjSpace.MethodTable:
+ args = ['w_%d' % i for i in range(arity)]
+ d = {'is_root': is_root,
+ 'w_some_obj': w_some_obj}
+ exec compile2("""\
+ def meth(self, %s):
+ %s
+ return w_some_obj()
+ """ % (', '.join(args),
+ '; '.join(['is_root(%s)' % arg for arg in args]))) in d
+ meth = func_with_new_name(d['meth'], name)
+ setattr(FakeObjSpace, name, meth)
+ #
+ for name in ObjSpace.IrregularOpTable:
+ assert hasattr(FakeObjSpace, name) # missing?
+
+setup()
+
+# ____________________________________________________________
+
+class TypeCache(SpaceCache):
+ def build(cache, typedef):
+ assert isinstance(typedef, TypeDef)
+ for value in typedef.rawdict.values():
+ cache.space.wrap(value)
+ return w_some_obj()
+
+class FakeCompiler(object):
+ pass
+FakeObjSpace.default_compiler = FakeCompiler()
+
+class FakeModule(object):
+ def get(self, name):
+ name + "xx" # check that it's a string
+ return w_some_obj()
+FakeObjSpace.sys = FakeModule()
+FakeObjSpace.sys.filesystemencoding = 'foobar'
diff --git a/pypy/objspace/fake/test/__init__.py b/pypy/objspace/fake/test/__init__.py
deleted file mode 100644
diff --git a/pypy/objspace/fake/test/test_checkmodule.py b/pypy/objspace/fake/test/test_checkmodule.py
--- a/pypy/objspace/fake/test/test_checkmodule.py
+++ b/pypy/objspace/fake/test/test_checkmodule.py
@@ -1,7 +1,63 @@
import py
-from pypy.objspace.fake.checkmodule import checkmodule
+from pypy.objspace.fake.objspace import FakeObjSpace, is_root
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.typedef import TypeDef, GetSetProperty
+from pypy.interpreter.gateway import interp2app, W_Root, ObjSpace
-def test_dotnet():
- # the only module known to pass checkmodule is _dotnet so far
- py.test.skip('fixme')
- checkmodule('_dotnet', 'cli')
+
+def make_checker():
+ check = []
+ def see():
+ check.append(True)
+ see._annspecialcase_ = 'specialize:memo'
+ return see, check
+
+def test_wrap_interp2app():
+ see, check = make_checker()
+ space = FakeObjSpace()
+ assert len(space._seen_extras) == 0
+ assert len(check) == 0
+ space.wrap(interp2app(lambda space: see()))
+ assert len(space._seen_extras) == 1
+ assert len(check) == 0
+ space.translates()
+ assert len(check) == 1
+
+def test_wrap_interp2app_int():
+ see, check = make_checker()
+ def foobar(space, x, w_y, z):
+ is_root(w_y)
+ see()
+ return space.wrap(x - z)
+ space = FakeObjSpace()
+ space.wrap(interp2app(foobar, unwrap_spec=[ObjSpace, int, W_Root, int]))
+ space.translates()
+ assert check
+
+def test_wrap_GetSetProperty():
+ see, check = make_checker()
+ def foobar(w_obj, space):
+ is_root(w_obj)
+ see()
+ return space.w_None
+ space = FakeObjSpace()
+ space.wrap(GetSetProperty(foobar))
+ space.translates()
+ assert check
+
+
+def test_gettypefor_untranslated():
+ see, check = make_checker()
+ class W_Foo(Wrappable):
+ def do_it(self, space, w_x):
+ is_root(w_x)
+ see()
+ return W_Root()
+ W_Foo.typedef = TypeDef('foo',
+ __module__ = 'barmod',
+ do_it = interp2app(W_Foo.do_it))
+ space = FakeObjSpace()
+ space.gettypefor(W_Foo)
+ assert not check
+ space.translates()
+ assert check
diff --git a/pypy/objspace/fake/test/test_objspace.py b/pypy/objspace/fake/test/test_objspace.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/fake/test/test_objspace.py
@@ -0,0 +1,74 @@
+import py
+from pypy.objspace.fake.objspace import FakeObjSpace, W_Root
+from pypy.interpreter.argument import Arguments
+from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.rlib.unroll import unrolling_iterable
+
+def test_create():
+ FakeObjSpace()
+
+
+class TestTranslate:
+ def setup_method(self, meth):
+ self.space = FakeObjSpace()
+
+ def test_simple(self):
+ space = self.space
+ space.translates(lambda w_x, w_y: space.add(w_x, w_y))
+
+ def test_methodtable(self):
+ space = self.space
+ for fixed_arity in [1, 2, 3, 4]:
+ #
+ methodtable = [name for (name, _, arity, _) in space.MethodTable
+ if arity == fixed_arity]
+ methodtable = unrolling_iterable(methodtable)
+ args_w = (W_Root(),) * fixed_arity
+ #
+ def f():
+ for name in methodtable:
+ getattr(space, name)(*args_w)
+ #
+ space.translates(f)
+
+ def test_newdict(self):
+ space = self.space
+ space.translates(lambda: (space.newdict(),
+ space.newdict(strdict=True)))
+
+ def test_constants(self):
+ space = self.space
+ space.translates(lambda: (space.w_None, space.w_True, space.w_False,
+ space.w_int, space.w_str,
+ space.w_TypeError))
+
+ def test_wrap(self):
+ space = self.space
+ space.translates(lambda: (space.wrap(42), space.wrap(42.5),
+ space.wrap("foo")))
+
+ def test_call_args(self):
+ space = self.space
+ args = Arguments(space, [W_Root()])
+ space.translates(lambda: space.call_args(W_Root(), args))
+
+ def test_gettypefor(self):
+ space = self.space
+ class W_Foo(Wrappable):
+ typedef = TypeDef("foo")
+ space.translates(lambda: space.gettypefor(W_Foo))
+
+ def test_is_true(self):
+ space = self.space
+ space.translates(lambda: space.is_true(W_Root()))
+ py.test.raises(AssertionError,
+ space.translates, lambda: space.is_true(42))
+
+ def test_unpackiterable(self):
+ space = self.space
+ space.translates(lambda: (space.unpackiterable(W_Root()),
+ space.unpackiterable(W_Root(), 42)))
+
+ def test_newlist(self):
+ self.space.newlist([W_Root(), W_Root()])
diff --git a/pypy/objspace/std/iterobject.py b/pypy/objspace/std/iterobject.py
--- a/pypy/objspace/std/iterobject.py
+++ b/pypy/objspace/std/iterobject.py
@@ -33,9 +33,6 @@
"""Sequence iterator specialized for lists, accessing
directly their RPython-level list of wrapped objects.
"""
- def __init__(w_self, w_seq):
- W_AbstractSeqIterObject.__init__(w_self, w_seq)
- w_self.w_seq = w_seq
class W_FastTupleIterObject(W_AbstractSeqIterObject):
"""Sequence iterator specialized for tuples, accessing
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -9,8 +9,9 @@
from pypy.interpreter import gateway, baseobjspace
from pypy.rlib.objectmodel import instantiate, specialize
from pypy.rlib.listsort import make_timsort_class
-from pypy.rlib import rerased, jit
+from pypy.rlib import rerased, jit, debug
from pypy.interpreter.argument import Signature
+from pypy.tool.sourcetools import func_with_new_name
UNROLL_CUTOFF = 5
@@ -170,6 +171,19 @@
share with the storage, if possible."""
return self.strategy.getitems(self)
+ def getitems_fixedsize(self):
+ """Returns a fixed-size list of all items after wrapping them."""
+ l = self.strategy.getitems_fixedsize(self)
+ debug.make_sure_not_resized(l)
+ return l
+
+ def getitems_unroll(self):
+ """Returns a fixed-size list of all items after wrapping them. The JIT
+ will fully unroll this function. """
+ l = self.strategy.getitems_unroll(self)
+ debug.make_sure_not_resized(l)
+ return l
+
def getitems_copy(self):
"""Returns a copy of all items in the list. Same as getitems except for
ObjectListStrategy."""
@@ -366,6 +380,8 @@
def getitems_copy(self, w_list):
return []
+ getitems_fixedsize = func_with_new_name(getitems_copy, "getitems_fixedsize")
+ getitems_unroll = getitems_fixedsize
def getstorage_copy(self, w_list):
return self.erase(None)
@@ -496,7 +512,6 @@
# tuple is unmutable
return w_list.lstorage
-
@specialize.arg(2)
def _getitems_range(self, w_list, wrap_items):
l = self.unerase(w_list.lstorage)
@@ -519,6 +534,13 @@
return r
+ @jit.dont_look_inside
+ def getitems_fixedsize(self, w_list):
+ return self._getitems_range_unroll(w_list, True)
+ def getitems_unroll(self, w_list):
+ return self._getitems_range_unroll(w_list, True)
+ _getitems_range_unroll = jit.unroll_safe(func_with_new_name(_getitems_range, "_getitems_range_unroll"))
+
def getslice(self, w_list, start, stop, step, length):
v = self.unerase(w_list.lstorage)
old_start = v[0]
@@ -676,6 +698,13 @@
def getitems_copy(self, w_list):
return [self.wrap(item) for item in self.unerase(w_list.lstorage)]
+ @jit.unroll_safe
+ def getitems_unroll(self, w_list):
+ return [self.wrap(item) for item in self.unerase(w_list.lstorage)]
+ @jit.dont_look_inside
+ def getitems_fixedsize(self, w_list):
+ return self.getitems_unroll(w_list)
+
def getstorage_copy(self, w_list):
items = self.unerase(w_list.lstorage)[:]
return self.erase(items)
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -408,8 +408,10 @@
if isinstance(w_obj, W_TupleObject):
t = w_obj.wrappeditems
elif isinstance(w_obj, W_ListObject):
- # XXX this can copy twice
- t = w_obj.getitems()[:]
+ if unroll:
+ t = w_obj.getitems_unroll()
+ else:
+ t = w_obj.getitems_fixedsize()
else:
if unroll:
return make_sure_not_resized(ObjSpace.unpackiterable_unroll(
diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -48,6 +48,46 @@
for i in range(7):
assert self.space.eq_w(l[i], l2[i])
+ def test_getitems_fixedsize(self):
+ w = self.space.wrap
+ from pypy.objspace.std.listobject import make_range_list
+ rangelist = make_range_list(self.space, 1,1,7)
+ emptylist = W_ListObject(self.space, [])
+ intlist = W_ListObject(self.space, [w(1),w(2),w(3),w(4),w(5),w(6),w(7)])
+ strlist = W_ListObject(self.space, [w('1'),w('2'),w('3'),w('4'),w('5'),w('6'),w('7')])
+ floatlist = W_ListObject(self.space, [w(1.0),w(2.0),w(3.0),w(4.0),w(5.0),w(6.0),w(7.0)])
+ objlist = W_ListObject(self.space, [w(1),w('2'),w(3.0),w(4),w(5),w(6),w(7)])
+
+ emptylist_copy = emptylist.getitems_fixedsize()
+ assert emptylist_copy == []
+
+ rangelist_copy = rangelist.getitems_fixedsize()
+ intlist_copy = intlist.getitems_fixedsize()
+ strlist_copy = strlist.getitems_fixedsize()
+ floatlist_copy = floatlist.getitems_fixedsize()
+ objlist_copy = objlist.getitems_fixedsize()
+ for i in range(7):
+ assert self.space.eq_w(rangelist_copy[i], rangelist.getitem(i))
+ assert self.space.eq_w(intlist_copy[i], intlist.getitem(i))
+ assert self.space.eq_w(strlist_copy[i], strlist.getitem(i))
+ assert self.space.eq_w(floatlist_copy[i], floatlist.getitem(i))
+ assert self.space.eq_w(objlist_copy[i], objlist.getitem(i))
+
+ emptylist_copy = emptylist.getitems_unroll()
+ assert emptylist_copy == []
+
+ rangelist_copy = rangelist.getitems_unroll()
+ intlist_copy = intlist.getitems_unroll()
+ strlist_copy = strlist.getitems_unroll()
+ floatlist_copy = floatlist.getitems_unroll()
+ objlist_copy = objlist.getitems_unroll()
+ for i in range(7):
+ assert self.space.eq_w(rangelist_copy[i], rangelist.getitem(i))
+ assert self.space.eq_w(intlist_copy[i], intlist.getitem(i))
+ assert self.space.eq_w(strlist_copy[i], strlist.getitem(i))
+ assert self.space.eq_w(floatlist_copy[i], floatlist.getitem(i))
+ assert self.space.eq_w(objlist_copy[i], objlist.getitem(i))
+
def test_random_getitem(self):
w = self.space.wrap
s = list('qedx387tn3uixhvt 7fh387fymh3dh238 dwd-wq.dwq9')
diff --git a/pypy/rlib/_rsocket_rffi.py b/pypy/rlib/_rsocket_rffi.py
--- a/pypy/rlib/_rsocket_rffi.py
+++ b/pypy/rlib/_rsocket_rffi.py
@@ -418,7 +418,7 @@
if _MSVC:
def invalid_socket(fd):
return fd == INVALID_SOCKET
- INVALID_SOCKET = intmask(cConfig.INVALID_SOCKET)
+ INVALID_SOCKET = r_uint(cConfig.INVALID_SOCKET)
else:
def invalid_socket(fd):
return fd < 0
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -639,11 +639,11 @@
return dlsym(self.lib, name)
class CDLL(RawCDLL):
- def __init__(self, libname):
+ def __init__(self, libname, mode=-1):
"""Load the library, or raises DLOpenError."""
RawCDLL.__init__(self, rffi.cast(DLLHANDLE, -1))
with rffi.scoped_str2charp(libname) as ll_libname:
- self.lib = dlopen(ll_libname)
+ self.lib = dlopen(ll_libname, mode)
def __del__(self):
if self.lib != rffi.cast(DLLHANDLE, -1):
diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py
--- a/pypy/rlib/libffi.py
+++ b/pypy/rlib/libffi.py
@@ -393,11 +393,11 @@
# XXX: it partially duplicate the code in clibffi.py
class CDLL(object):
- def __init__(self, libname):
+ def __init__(self, libname, mode=-1):
"""Load the library, or raises DLOpenError."""
self.lib = rffi.cast(DLLHANDLE, 0)
with rffi.scoped_str2charp(libname) as ll_libname:
- self.lib = dlopen(ll_libname)
+ self.lib = dlopen(ll_libname, mode)
def __del__(self):
if self.lib:
diff --git a/pypy/rlib/rdynload.py b/pypy/rlib/rdynload.py
--- a/pypy/rlib/rdynload.py
+++ b/pypy/rlib/rdynload.py
@@ -87,9 +87,10 @@
"""
if mode == -1:
if RTLD_LOCAL is not None:
- mode = RTLD_LOCAL | RTLD_NOW
+ mode = RTLD_LOCAL
else:
- mode = RTLD_NOW
+ mode = 0
+ mode |= RTLD_NOW
res = c_dlopen(name, rffi.cast(rffi.INT, mode))
if not res:
err = dlerror()
diff --git a/pypy/rlib/rmmap.py b/pypy/rlib/rmmap.py
--- a/pypy/rlib/rmmap.py
+++ b/pypy/rlib/rmmap.py
@@ -420,7 +420,11 @@
low, high = _get_file_size(self.file_handle)
if not high and low <= sys.maxint:
return low
+ # not so sure if the signed/unsigned strictness is a good idea:
+ high = rffi.cast(lltype.Unsigned, high)
+ low = rffi.cast(lltype.Unsigned, low)
size = (high << 32) + low
+ size = rffi.cast(lltype.Signed, size)
elif _POSIX:
st = os.fstat(self.fd)
size = st[stat.ST_SIZE]
diff --git a/pypy/rlib/rsocket.py b/pypy/rlib/rsocket.py
--- a/pypy/rlib/rsocket.py
+++ b/pypy/rlib/rsocket.py
@@ -20,6 +20,7 @@
from pypy.rlib.rarithmetic import intmask, r_uint
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.rpython.lltypesystem.rffi import sizeof, offsetof
+INVALID_SOCKET = _c.INVALID_SOCKET
def mallocbuf(buffersize):
return lltype.malloc(rffi.CCHARP.TO, buffersize, flavor='raw')
diff --git a/pypy/rlib/test/test_libffi.py b/pypy/rlib/test/test_libffi.py
--- a/pypy/rlib/test/test_libffi.py
+++ b/pypy/rlib/test/test_libffi.py
@@ -443,3 +443,4 @@
assert p[1] == 34
lltype.free(p, flavor='raw')
lltype.free(ffi_point_struct, flavor='raw')
+
diff --git a/pypy/rpython/lltypesystem/ll2ctypes.py b/pypy/rpython/lltypesystem/ll2ctypes.py
--- a/pypy/rpython/lltypesystem/ll2ctypes.py
+++ b/pypy/rpython/lltypesystem/ll2ctypes.py
@@ -112,7 +112,7 @@
rffi.LONGLONG: ctypes.c_longlong,
rffi.ULONGLONG: ctypes.c_ulonglong,
rffi.SIZE_T: ctypes.c_size_t,
- lltype.Bool: getattr(ctypes, "c_bool", ctypes.c_long),
+ lltype.Bool: getattr(ctypes, "c_bool", ctypes.c_byte),
llmemory.Address: ctypes.c_void_p,
llmemory.GCREF: ctypes.c_void_p,
llmemory.WeakRef: ctypes.c_void_p, # XXX
diff --git a/pypy/rpython/tool/rffi_platform.py b/pypy/rpython/tool/rffi_platform.py
--- a/pypy/rpython/tool/rffi_platform.py
+++ b/pypy/rpython/tool/rffi_platform.py
@@ -56,6 +56,12 @@
DEFINED = DefinedConstantDouble(macro)
return configure(CConfig)['DEFINED']
+def getdefinedinteger(macro, c_header_source):
+ class CConfig:
+ _compilation_info_ = eci_from_header(c_header_source)
+ DEFINED = DefinedConstantInteger(macro)
+ return configure(CConfig)['DEFINED']
+
def has(name, c_header_source, include_dirs=None):
class CConfig:
_compilation_info_ = eci_from_header(c_header_source, include_dirs)
diff --git a/pypy/rpython/tool/test/test_rffi_platform.py b/pypy/rpython/tool/test/test_rffi_platform.py
--- a/pypy/rpython/tool/test/test_rffi_platform.py
+++ b/pypy/rpython/tool/test/test_rffi_platform.py
@@ -108,6 +108,12 @@
'#define ALFKJLKJFLKJFKLEJDLKEWMECEE')
assert res
+def test_defined_constant():
+ res = rffi_platform.getdefineddouble('ABCDFGH', '#define ABCDFGH 2.0')
+ assert res == 2.0
+ res = rffi_platform.getdefinedinteger('ABCDFGH', '#define ABCDFGH 2')
+ assert res == 2
+
def test_defined_constant_float():
value = rffi_platform.getdefineddouble('BLAH', '#define BLAH 1.0')
assert value == 1.0
diff --git a/pypy/translator/c/test/test_typed.py b/pypy/translator/c/test/test_typed.py
--- a/pypy/translator/c/test/test_typed.py
+++ b/pypy/translator/c/test/test_typed.py
@@ -275,6 +275,14 @@
fn = self.getcompiled(f, [r_longlong])
assert fn(0) == 0
+ def test_upcast_int(self):
+ from pypy.rpython.lltypesystem import rffi
+ def f(v):
+ v = rffi.cast(rffi.USHORT, v)
+ return intmask(v)
+ fn = self.getcompiled(f, [int])
+ assert fn(0x1234CDEF) == 0xCDEF
+
def test_function_ptr(self):
def f1():
return 1
diff --git a/pypy/translator/translator.py b/pypy/translator/translator.py
--- a/pypy/translator/translator.py
+++ b/pypy/translator/translator.py
@@ -150,11 +150,11 @@
from pypy.translator.tool.graphpage import FlowGraphPage
FlowGraphPage(self).display()
- def viewcg(self, center_graph=None):
+ def viewcg(self, center_graph=None, huge=100):
"""Shows the whole call graph and the class hierarchy, based on
the computed annotations."""
from pypy.translator.tool.graphpage import TranslatorPage
- TranslatorPage(self, center_graph=center_graph).display()
+ TranslatorPage(self, center_graph=center_graph, huge=huge).display()
More information about the pypy-commit
mailing list