Commits

Maciej Fijalkowski committed f3cfd5e Merge

merge default

  • Participants
  • Parent commits 1dc6fdd, 092d0cd
  • Branches jitframe-on-heap

Comments (0)

Files changed (21)

File pypy/doc/test/test_whatsnew.py

                       merge() and \
                       branch(default)) and \
               not branch(default)' % (startrev, endrev)
-    cmd = r"hg log -R '%s' -r '%s' --template '{branches}\n'" % (path, revset)
+    cmd = r'hg log -R "%s" -r "%s" --template "{branches}\n"' % (path, revset)
     out = getoutput(cmd)
     branches = set(map(str.strip, out.splitlines()))
     return branches

File pypy/doc/whatsnew-head.rst

 
 .. branch: numpypy-longdouble
 Long double support for numpypy
+.. branch: numpypy-real-as-view
+Convert real, imag from ufuncs to views. This involves the beginning of 
+view() functionality
 
 .. branch: signatures
 Improved RPython typing

File pypy/interpreter/pyopcode.py

             else:
                 oparg = 0
 
+            # note: the structure of the code here is such that it makes
+            # (after translation) a big "if/elif" chain, which is then
+            # turned into a switch().  It starts here: even if the first
+            # one is not an "if" but a "while" the effect is the same.
+
             while opcode == self.opcodedesc.EXTENDED_ARG.index:
                 opcode = ord(co_code[next_instr])
                 if opcode < self.HAVE_ARGUMENT:
                         'END_FINALLY', 'JUMP_ABSOLUTE'):
                         continue   # opcodes implemented above
 
+                    # the following "if" is part of the big switch described
+                    # above.
                     if opcode == opdesc.index:
                         # dispatch to the opcode method
                         meth = getattr(self, opdesc.methodname)

File pypy/jit/backend/test/calling_convention_test.py

             ops = '[%s]\n' % arguments
             ops += '%s\n' % spill_ops
             ops += 'f99 = call(ConstClass(func_ptr), %s, descr=calldescr)\n' % arguments
-            ops += 'finish(f99, %s)\n' % arguments
+            ops += 'i99 = same_as(0)\n'
+            ops += 'guard_true(i99) [f99, %s]\n' % arguments
+            ops += 'finish()\n'
 
             loop = parse(ops, namespace=locals())
             looptoken = JitCellToken()
-            done_number = self.cpu.get_fail_descr_number(loop.operations[-1].getdescr())
+            done_number = self.cpu.get_fail_descr_number(loop.operations[-2].getdescr())
             self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
             argvals, expected_result = self._prepare_args(args, floats, ints)
 

File pypy/jit/backend/test/runner_test.py

                     values.append(longlong.getfloatstorage(r.random()))
             #
             looptoken = JitCellToken()
-            faildescr = BasicFinalDescr(42)
+            guarddescr = BasicFailDescr(42)
+            faildescr = BasicFinalDescr(43)
             operations = []
             retboxes = []
             retvalues = []
                 retboxes.insert(kk, newbox)
                 retvalues.insert(kk, y)
             #
-            operations.append(
-                ResOperation(rop.FINISH, retboxes, None, descr=faildescr)
-                )
+            zero = BoxInt()
+            operations.extend([
+                ResOperation(rop.SAME_AS, [ConstInt(0)], zero),
+                ResOperation(rop.GUARD_TRUE, [zero], None, descr=guarddescr),
+                ResOperation(rop.FINISH, [], None, descr=faildescr)
+                ])
+            operations[-2].setfailargs(retboxes)
             print inputargs
             for op in operations:
                 print op
         i2 = BoxInt()
         targettoken = TargetToken()
         faildescr1 = BasicFailDescr(1)
-        faildescr2 = BasicFinalDescr(2)
+        faildescr2 = BasicFailDescr(2)
+        faildescr3 = BasicFinalDescr(3)
         operations = [
             ResOperation(rop.LABEL, fboxes, None, descr=targettoken),
             ResOperation(rop.FLOAT_LE, [fboxes[0], constfloat(9.2)], i2),
             ResOperation(rop.GUARD_TRUE, [i2], None, descr=faildescr1),
-            ResOperation(rop.FINISH, fboxes, None, descr=faildescr2),
+            ResOperation(rop.GUARD_FALSE, [i2], None, descr=faildescr2),
+            ResOperation(rop.FINISH, [], None, descr=faildescr3),
             ]
+        operations[-3].setfailargs(fboxes)
         operations[-2].setfailargs(fboxes)
         looptoken = JitCellToken()
         self.cpu.compile_loop(fboxes, operations, looptoken)
         if not self.cpu.supports_floats:
             py.test.skip("requires floats")
         fboxes = [BoxFloat() for i in range(3)]
-        faildescr1 = BasicFinalDescr(100)
+        faildescr1 = BasicFailDescr(100)
+        faildescr2 = BasicFinalDescr(102)
         loopops = """
         [i0,f1, f2]
         f3 = float_add(f1, f2)
         assert longlong.getrealfloat(f2) == 0.75
         assert longlong.getrealfloat(f3) == 133.0
 
+        zero = BoxInt()
         bridgeops = [
-            ResOperation(rop.FINISH, fboxes, None, descr=faildescr1),
+            ResOperation(rop.SAME_AS, [ConstInt(0)], zero),
+            ResOperation(rop.GUARD_TRUE, [zero], None, descr=faildescr1),
+            ResOperation(rop.FINISH, [], None, descr=faildescr2),
             ]
+        bridgeops[-2].setfailargs(fboxes[:])
         self.cpu.compile_bridge(loop.operations[-2].getdescr(), fboxes,
                                                         bridgeops, looptoken)
         args = [1,
         i1 = same_as(1)
         call(ConstClass(fptr), i0, descr=calldescr)
         p0 = guard_exception(ConstClass(xtp)) [i1]
-        finish(0, p0)
+        finish(p0)
         '''
         FPTR = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
         fptr = llhelper(FPTR, func)
         looptoken = JitCellToken()
         self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
         deadframe = self.cpu.execute_token(looptoken, 1)
-        assert self.cpu.get_int_value(deadframe, 0) == 0
-        assert self.cpu.get_ref_value(deadframe, 1) == xptr
+        assert self.cpu.get_ref_value(deadframe, 0) == xptr
         excvalue = self.cpu.grab_exc_value(deadframe)
         assert not excvalue
         deadframe = self.cpu.execute_token(looptoken, 0)

File pypy/jit/backend/x86/test/test_recompilation.py

         force_spill(i5)
         i8 = int_add(i7, 1)
         i9 = int_add(i8, 1)
-        finish(i3, i4, i5, i6, i7, i8, i9, descr=fdescr2)
+        guard_false(i3, descr=fdescr2) [i3, i4, i5, i6, i7, i8, i9]
+        finish()
         '''
         bridge = self.attach_bridge(ops, loop, -2)
         descr = loop.operations[3].getdescr()

File pypy/jit/backend/x86/test/test_regalloc.py

         assert self.getint(0) == 0
         bridge_ops = '''
         [i0, i1]
-        finish(1, 2)
+        finish(2)
         '''
         self.attach_bridge(bridge_ops, loop, 0)
         self.run(loop, 0, 1)
         ops = '''
         [i0, i1, i2, i3, i4, i5, i6, i7]
         guard_value(i6, i1) [i0, i2, i3, i4, i5, i6]
-        finish(i0, i2, i3, i4, i5, i6)
+        finish(i0)
         '''
         self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0])
         assert self.getint(0) == 0
         [i0, i1, i2, i3, i4, i5, i6, i7, i8]
         i9 = same_as(0)
         guard_true(i0) [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8]
-        finish(1, i0, i1, i2, i3, i4, i5, i6, i7, i8)
+        finish(1)
         '''
         loop = self.interpret(ops, [0, 1, 2, 3, 4, 5, 6, 7, 8])
         assert self.getint(0) == 0
         bridge_ops = '''
         [i9, i0, i1, i2, i3, i4, i5, i6, i7, i8]
         call(ConstClass(raising_fptr), 0, descr=raising_calldescr)
-        finish(i0, i1, i2, i3, i4, i5, i6, i7, i8)
+        guard_true(i9) [i0, i1, i2, i3, i4, i5, i6, i7, i8]
+        finish()
         '''
         self.attach_bridge(bridge_ops, loop, 1)
         self.run(loop, 0, 1, 2, 3, 4, 5, 6, 7, 8)
         i1 = same_as(1)
         i2 = int_lt(i0, 100)
         guard_true(i3) [i1, i2]
-        finish(0, i2)
+        i4 = int_neg(i2)
+        finish(0)
         '''
         self.interpret(ops, [0, 1])
         assert self.getint(0) == 0
         i15 = int_is_true(i5)
         i16 = int_is_true(i6)
         i17 = int_is_true(i7)
-        finish(i10, i11, i12, i13, i14, i15, i16, i17)
+        guard_true(i0) [i10, i11, i12, i13, i14, i15, i16, i17]
+        finish()
         '''
         self.interpret(ops, [0, 42, 12, 0, 13, 0, 0, 3333])
         assert self.getints(8) == [0, 1, 1, 0, 1, 0, 0, 1]
         i13 = int_eq(i5, i6)
         i14 = int_gt(i6, i2)
         i15 = int_ne(i2, i6)
-        finish(i10, i11, i12, i13, i14, i15)
+        guard_true(i0) [i10, i11, i12, i13, i14, i15]
+        finish()
         '''
         self.interpret(ops, [0, 1, 2, 3, 4, 5, 6])
         assert self.getints(6) == [1, 1, 0, 0, 1, 1]
         ops = '''
         [f0, f1]
         f2 = float_add(f0, f1)
-        finish(f2, f0, f1)
+        i0 = same_as(0)
+        guard_true(i0) [f2, f0, f1]
+        finish()
         '''
         self.interpret(ops, [3.0, 1.5])
         assert self.getfloats(3) == [4.5, 3.0, 1.5]
         [f0, f1, f2, f3, f4, f5, f6, f7, f8]
         f9 = float_add(f0, f1)
         f10 = float_add(f8, 3.5)
-        finish(f9, f10, f2, f3, f4, f5, f6, f7, f8)
+        i0 = same_as(0)
+        guard_true(i0) [f9, f10, f2, f3, f4, f5, f6, f7, f8]
+        finish()
         '''
         self.interpret(ops, [0.1, .2, .3, .4, .5, .6, .7, .8, .9])
         assert self.getfloats(9) == [.1+.2, .9+3.5, .3, .4, .5, .6, .7, .8, .9]
         i7 = float_ne(f7, 0.0)
         i8 = float_ne(f8, 0.0)
         i9 = float_ne(f9, 0.0)
-        finish(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9)
+        guard_true(i0) [i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
+        finish()
         '''
         loop = self.interpret(ops, [0.0, .1, .2, .3, .4, .5, .6, .7, .8, .9])
         assert self.getints(9) == [0, 1, 1, 1, 1, 1, 1, 1, 1]

File pypy/jit/backend/x86/test/test_regalloc2.py

     v2 = BoxInt()
     v3 = BoxInt()
     v4 = BoxInt()
+    zero = BoxInt()
     inputargs = [v1]
     operations = [
         ResOperation(rop.INT_ADD, [v1, v1], v2),
         ResOperation(rop.INT_INVERT, [v2], v3),
         ResOperation(rop.UINT_RSHIFT, [v1, ConstInt(3)], v4),
-        ResOperation(rop.FINISH, [v4, v3], None, descr=BasicFailDescr()),
+        ResOperation(rop.SAME_AS, [ConstInt(0)], zero),
+        ResOperation(rop.GUARD_TRUE, [zero], None, descr=BasicFailDescr()),
+        ResOperation(rop.FINISH, [], None, descr=BasicFailDescr())
         ]
+    operations[-2].setfailargs([v4, v3])
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
     v2 = BoxInt()
     v3 = BoxInt()
     v4 = BoxInt()
+    zero = BoxInt()
     tmp5 = BoxInt()
     inputargs = [v1]
     operations = [
         ResOperation(rop.INT_MUL, [v2, v1], v3),
         ResOperation(rop.INT_IS_TRUE, [v2], tmp5),
         ResOperation(rop.INT_IS_ZERO, [tmp5], v4),
-        ResOperation(rop.FINISH, [v4, v3, tmp5], None, descr=BasicFailDescr()),
+        ResOperation(rop.SAME_AS, [ConstInt(0)], zero),
+        ResOperation(rop.GUARD_TRUE, [zero], None, descr=BasicFailDescr()),
+        ResOperation(rop.FINISH, [], None, descr=BasicFailDescr())
             ]
+    operations[-2].setfailargs([v4, v3, tmp5])
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
     v38 = BoxInt()
     v39 = BoxInt()
     v40 = BoxInt()
+    zero = BoxInt()
     tmp41 = BoxInt()
     tmp42 = BoxInt()
     tmp43 = BoxInt()
         ResOperation(rop.UINT_GT, [v33, ConstInt(-11)], v38),
         ResOperation(rop.INT_NEG, [v7], v39),
         ResOperation(rop.INT_GT, [v24, v32], v40),
-        ResOperation(rop.FINISH, [v40, v36, v37, v31, v16, v34, v35, v23, v22, v29, v14, v39, v30, v38], None, descr=BasicFailDescr()),
+        ResOperation(rop.SAME_AS, [ConstInt(0)], zero),
+        ResOperation(rop.GUARD_TRUE, [zero], None, descr=BasicFailDescr()),
+        ResOperation(rop.FINISH, [], None, descr=BasicFailDescr())
             ]
+    operations[-2].setfailargs([v40, v36, v37, v31, v16, v34, v35, v23,
+                                v22, v29, v14, v39, v30, v38])
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
     v38 = BoxInt()
     v39 = BoxInt()
     v40 = BoxInt()
+    zero = BoxInt()
     tmp41 = BoxInt()
     tmp42 = BoxInt()
     tmp43 = BoxInt()
         ResOperation(rop.INT_GT, [v4, v11], v38),
         ResOperation(rop.INT_LT, [v27, v22], v39),
         ResOperation(rop.INT_NEG, [v27], v40),
-        ResOperation(rop.FINISH, [v40, v10, v36, v26, v13, v30, v21, v33, v18, v25, v31, v32, v28, v29, v35, v38, v20, v39, v34, v23, v37], None, descr=BasicFailDescr()),
+        ResOperation(rop.SAME_AS, [ConstInt(0)], zero),
+        ResOperation(rop.GUARD_TRUE, [zero], None, descr=BasicFailDescr()),
+        ResOperation(rop.FINISH, [], None, descr=BasicFailDescr())
             ]
+    operations[-2].setfailargs([v40, v10, v36, v26, v13, v30, v21, v33,
+                                v18, v25, v31, v32, v28, v29, v35, v38,
+                                v20, v39, v34, v23, v37])
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()

File pypy/jit/backend/x86/test/test_runner.py

                          i6, descr=calldescr),
             ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),
 
-            ResOperation(rop.FINISH, [i3, i4, i5, i6], None,
-                         descr=BasicFailDescr(0))
+            ResOperation(rop.GUARD_FALSE, [i3], None,
+                         descr=BasicFailDescr(0)),
+            ResOperation(rop.FINISH, [], None,
+                         descr=BasicFailDescr(1))
             ]
+            ops[-2].setfailargs([i3, i4, i5, i6])
             ops[1].setfailargs([])
             ops[3].setfailargs([])
             ops[5].setfailargs([])

File pypy/jit/codewriter/support.py

 from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.translator.simplify import get_funcobj
 from pypy.translator.unsimplify import split_block
-from pypy.objspace.flow.model import Constant
+from pypy.objspace.flow.model import Variable, Constant
 from pypy.translator.translator import TranslationContext
 from pypy.annotation.policy import AnnotatorPolicy
 from pypy.annotation import model as annmodel
     rtyper = annotate(func, values)
     return rtyper.annotator.translator.graphs[0]
 
+def autodetect_jit_markers_redvars(graph):
+    # the idea is to find all the jit_merge_point and
+    # add all the variables across the links to the reds.
+    for block, op in graph.iterblockops():
+        if op.opname == 'jit_marker':
+            jitdriver = op.args[1].value
+            if not jitdriver.autoreds:
+                continue
+            # if we want to support also can_enter_jit, we should find a
+            # way to detect a consistent set of red vars to pass *both* to
+            # jit_merge_point and can_enter_jit. The current simple
+            # solution doesn't work because can_enter_jit might be in
+            # another block, so the set of alive_v will be different.
+            methname = op.args[0].value
+            assert methname == 'jit_merge_point', (
+                "reds='auto' is supported only for jit drivers which " 
+                "calls only jit_merge_point. Found a call to %s" % methname)
+            #
+            # compute the set of live variables across the jit_marker
+            alive_v = set()
+            for link in block.exits:
+                alive_v.update(link.args)
+                alive_v.difference_update(link.getextravars())
+            for op1 in block.operations[::-1]:
+                if op1 is op:
+                    break # stop when the meet the jit_marker
+                alive_v.discard(op1.result)
+                alive_v.update(op1.args)
+            greens_v = op.args[2:]
+            reds_v = alive_v - set(greens_v)
+            reds_v = [v for v in reds_v if isinstance(v, Variable) and
+                                           v.concretetype is not lltype.Void]
+            reds_v = sort_vars(reds_v)
+            op.args.extend(reds_v)
+            if jitdriver.numreds is None:
+                jitdriver.numreds = len(reds_v)
+            else:
+                assert jitdriver.numreds == len(reds_v), 'inconsistent number of reds_v'
+
 def split_before_jit_merge_point(graph, portalblock, portalopindex):
     """Split the block just before the 'jit_merge_point',
     making sure the input args are in the canonical order.

File pypy/jit/metainterp/resoperation.py

 
     def initarglist(self, args):
         self._args = args
+        if not we_are_translated() and \
+               self.__class__.__name__.startswith('FINISH'):   # XXX remove me
+            assert len(args) <= 1      # FINISH operations take 0 or 1 arg now
 
     def getarglist(self):
         return self._args

File pypy/jit/metainterp/test/test_warmspot.py

         assert res == expected
         self.check_resops(int_sub=2, int_mul=0, int_add=2)
 
+    def test_loop_automatic_reds_not_too_many_redvars(self):
+        myjitdriver = JitDriver(greens = ['m'], reds = 'auto')
+        def one():
+            return 1
+        def f(n, m):
+            res = 0
+            while n > 0:
+                n -= one()
+                myjitdriver.jit_merge_point(m=m)
+                res += m*2
+            return res
+        expected = f(21, 5)
+        res = self.meta_interp(f, [21, 5])
+        assert res == expected
+        oplabel = get_stats().loops[0].operations[0]
+        assert len(oplabel.getarglist()) == 2     # 'n', 'res' in some order
+
     def test_inline_jit_merge_point(self):
         # test that the machinery to inline jit_merge_points in callers
         # works. The final user does not need to mess manually with the

File pypy/jit/metainterp/warmspot.py

         self.jitdrivers_sd = []
         graphs = self.translator.graphs
         for graph, block, pos in find_jit_merge_points(graphs):
-            self.autodetect_jit_markers_redvars(graph)
+            support.autodetect_jit_markers_redvars(graph)
             self.split_graph_and_record_jitdriver(graph, block, pos)
         #
         assert (len(set([jd.jitdriver for jd in self.jitdrivers_sd])) ==
                 len(self.jitdrivers_sd)), \
                 "there are multiple jit_merge_points with the same jitdriver"
 
-    def autodetect_jit_markers_redvars(self, graph):
-        # the idea is to find all the jit_merge_point and can_enter_jit and
-        # add all the variables across the links to the reds.
-        for block, op in graph.iterblockops():
-            if op.opname == 'jit_marker':
-                jitdriver = op.args[1].value
-                if not jitdriver.autoreds:
-                    continue
-                # if we want to support also can_enter_jit, we should find a
-                # way to detect a consistent set of red vars to pass *both* to
-                # jit_merge_point and can_enter_jit. The current simple
-                # solution doesn't work because can_enter_jit might be in
-                # another block, so the set of alive_v will be different.
-                methname = op.args[0].value
-                assert methname == 'jit_merge_point', (
-                    "reds='auto' is supported only for jit drivers which " 
-                    "calls only jit_merge_point. Found a call to %s" % methname)
-                #
-                # compute the set of live variables before the jit_marker
-                alive_v = set(block.inputargs)
-                for op1 in block.operations:
-                    if op1 is op:
-                        break # stop when the meet the jit_marker
-                    if op1.result.concretetype != lltype.Void:
-                        alive_v.add(op1.result)
-                greens_v = op.args[2:]
-                reds_v = alive_v - set(greens_v)
-                reds_v = [v for v in reds_v if v.concretetype is not lltype.Void]
-                reds_v = support.sort_vars(reds_v)
-                op.args.extend(reds_v)
-                if jitdriver.numreds is None:
-                    jitdriver.numreds = len(reds_v)
-                else:
-                    assert jitdriver.numreds == len(reds_v), 'inconsistent number of reds_v'
-
-
     def split_graph_and_record_jitdriver(self, graph, block, pos):
         op = block.operations[pos]
         jd = JitDriverStaticData()
             jitdriver = op.args[1].value
             assert jitdriver in sublists, \
                    "can_enter_jit with no matching jit_merge_point"
+            assert not jitdriver.autoreds, (
+                   "can_enter_jit not supported with a jitdriver that "
+                   "has reds='auto'")
             jd, sublist = sublists[jitdriver]
             origportalgraph = jd._jit_merge_point_in
             if graph is not origportalgraph:

File pypy/module/micronumpy/arrayimpl/concrete.py

 from pypy.rlib.debug import make_sure_not_resized
 
 class ConcreteArrayIterator(base.BaseArrayIterator):
+    _immutable_fields_ = ['dtype', 'skip', 'size']
     def __init__(self, array):
         self.array = array
         self.offset = 0
         self.size = array.size
 
     def setitem(self, elem):
-        self.array.setitem(self.offset, elem)
+        self.dtype.setitem(self.array, self.offset, elem)
 
     def getitem(self):
-        return self.array.getitem(self.offset)
+        return self.dtype.getitem(self.array, self.offset)
 
     def getitem_bool(self):
         return self.dtype.getitem_bool(self.array, self.offset)
         self.offset %= self.size
 
 class OneDimViewIterator(ConcreteArrayIterator):
-    def __init__(self, array):
+    ''' The view iterator dtype can be different from the
+    array.dtype, this is what makes it a View
+    '''
+    def __init__(self, array, dtype, start, strides, shape):
         self.array = array
-        self.offset = array.start
-        self.skip = array.get_strides()[0]
-        self.dtype = array.dtype
+        self.dtype = dtype
+        self.offset = start
+        self.skip = strides[0]
         self.index = 0
-        self.size = array.get_shape()[0]
+        self.size = shape[0]
 
     def next(self):
         self.offset += self.skip
         self.offset %= self.size
 
 class MultiDimViewIterator(ConcreteArrayIterator):
-    def __init__(self, array, start, strides, backstrides, shape):
+    ''' The view iterator dtype can be different from the
+    array.dtype, this is what makes it a View
+    '''
+    def __init__(self, array, dtype, start, strides, backstrides, shape):
         self.indexes = [0] * len(shape)
         self.array = array
+        self.dtype = dtype
         self.shape = shape
         self.offset = start
         self.shapelen = len(shape)
         self.offset = array.start
         self.dim = dim
         self.array = array
+        self.dtype = array.dtype
         
     def setitem(self, elem):
-        self.array.setitem(self.offset, elem)
+        self.dtype.setitem(self.array, self.offset, elem)
 
     def getitem(self):
-        return self.array.getitem(self.offset)
+        return self.dtype.getitem(self.array, self.offset)
 
     @jit.unroll_safe
     def next(self):
                               new_shape, self)
         else:
             return None
+    
+    def get_real(self):
+        strides = self.get_strides()
+        backstrides = self.get_backstrides()
+        if self.dtype.is_complex_type():
+            dtype =  self.dtype.float_type
+            return SliceArray(self.start, strides, backstrides,
+                          self.get_shape(), self, dtype=dtype)
+        return SliceArray(self.start, strides, backstrides, 
+                          self.get_shape(), self)
+
+    def get_imag(self):
+        strides = self.get_strides()
+        backstrides = self.get_backstrides()
+        if self.dtype.is_complex_type():
+            dtype =  self.dtype.float_type
+            return SliceArray(self.start + dtype.get_size(), strides, 
+                    backstrides, self.get_shape(), self, dtype=dtype)
+        if self.dtype.is_flexible_type():
+            # numpy returns self for self.imag
+            return SliceArray(self.start, strides, backstrides,
+                    self.get_shape(), self)
+        impl = NonWritableArray(self.get_shape(), self.dtype, self.order, strides,
+                             backstrides)
+        impl.fill(self.dtype.box(0))
+        return impl
 
     # -------------------- applevel get/setitem -----------------------
 
     def create_dot_iter(self, shape, skip):
         r = calculate_dot_strides(self.get_strides(), self.get_backstrides(),
                                   shape, skip)
-        return MultiDimViewIterator(self, self.start, r[0], r[1], shape)
+        return MultiDimViewIterator(self, self.dtype, self.start, r[0], r[1], shape)
 
     def swapaxes(self, axis1, axis2):
         shape = self.get_shape()[:]
         r = calculate_broadcast_strides(self.get_strides(),
                                         self.get_backstrides(),
                                         self.get_shape(), shape)
-        return MultiDimViewIterator(self, 0, r[0], r[1], shape)
+        return MultiDimViewIterator(self, self.dtype, 0, r[0], r[1], shape)
 
     def fill(self, box):
         self.dtype.fill(self.storage, box, 0, self.size)
                                                     self.order)
         return SliceArray(0, strides, backstrides, new_shape, self)
 
+class NonWritableArray(ConcreteArray):
+    def descr_setitem(self, space, w_index, w_value):
+        raise OperationError(space.w_RuntimeError, space.wrap(
+            "array is not writable"))
+        
+
 class SliceArray(BaseConcreteArray):
     def __init__(self, start, strides, backstrides, shape, parent, dtype=None):
         self.strides = strides
             r = calculate_broadcast_strides(self.get_strides(),
                                             self.get_backstrides(),
                                             self.get_shape(), shape)
-            return MultiDimViewIterator(self.parent,
+            return MultiDimViewIterator(self.parent, self.dtype,
                                         self.start, r[0], r[1], shape)
         if len(self.get_shape()) == 1:
-            return OneDimViewIterator(self)
-        return MultiDimViewIterator(self.parent, self.start,
+            return OneDimViewIterator(self.parent, self.dtype, self.start, 
+                    self.get_strides(), self.get_shape())
+        return MultiDimViewIterator(self.parent, self.dtype, self.start,
                                     self.get_strides(),
                                     self.get_backstrides(), self.get_shape())
 

File pypy/module/micronumpy/interp_dtype.py

         return self.kind == SIGNEDLTR
 
     def is_complex_type(self):
-        return (self.num == 14 or self.num == 15 or self.num == 16)
+        return False
 
     def is_bool_type(self):
         return self.kind == BOOLLTR
     def get_size(self):
         return self.itemtype.get_element_size()
 
+class W_ComplexDtype(W_Dtype):
+
+    def __init__(self, itemtype, num, kind, name, char, w_box_type,
+                 alternate_constructors=[], aliases=[],
+                 fields=None, fieldnames=None, native=True, float_type=None):
+        W_Dtype.__init__(self, itemtype, num, kind, name, char, w_box_type,
+                 alternate_constructors=alternate_constructors, aliases=aliases,
+                 fields=fields, fieldnames=fieldnames, native=native)
+        self.float_type = float_type
+
+    def is_complex_type(self):
+        return True
+
 def dtype_from_list(space, w_lst):
     lst_w = space.listview(w_lst)
     fields = {}
             alternate_constructors=[space.w_float],
             aliases=["float"],
         )
-        self.w_complex64dtype = W_Dtype(
+        self.w_complex64dtype = W_ComplexDtype(
             types.Complex64(),
             num=14,
             kind=COMPLEXLTR,
             name="complex64",
             char="F",
             w_box_type = space.gettypefor(interp_boxes.W_Complex64Box),
+            float_type = self.w_float32dtype,
         )
-        self.w_complex128dtype = W_Dtype(
+        self.w_complex128dtype = W_ComplexDtype(
             types.Complex128(),
             num=15,
             kind=COMPLEXLTR,
             w_box_type = space.gettypefor(interp_boxes.W_Complex128Box),
             alternate_constructors=[space.w_complex],
             aliases=["complex"],
+            float_type = self.w_float64dtype,
         )
         if interp_boxes.long_double_size == 12:
             self.w_float96dtype = W_Dtype(
             )
             self.w_longdouble = self.w_float96dtype
 
-            self.w_complex192dtype = W_Dtype(
+            self.w_complex192dtype = W_ComplexDtype(
                 types.Complex192(),
                 num=16,
                 kind=COMPLEXLTR,
                 w_box_type = space.gettypefor(interp_boxes.W_Complex192Box),
                 alternate_constructors=[space.w_complex],
                 aliases=["clongdouble", "clongfloat"],
+                float_type = self.w_float96dtype,
             )
             self.w_clongdouble = self.w_complex192dtype
 
             )
             self.w_longdouble = self.w_float128dtype
 
-            self.w_complex256dtype = W_Dtype(
+            self.w_complex256dtype = W_ComplexDtype(
                 types.Complex256(),
                 num=16,
                 kind=COMPLEXLTR,
                 w_box_type = space.gettypefor(interp_boxes.W_Complex256Box),
                 alternate_constructors=[space.w_complex],
                 aliases=["clongdouble", "clongfloat"],
+                float_type = self.w_float128dtype,
             )
             self.w_clongdouble = self.w_complex256dtype
         else:

File pypy/module/micronumpy/interp_numarray.py

     def descr_copy(self, space):
         return W_NDimArray(self.implementation.copy())
 
+    def descr_get_real(self, space):
+        return W_NDimArray(self.implementation.get_real())
+
+    def descr_get_imag(self, space):
+        ret = self.implementation.get_imag()
+        if ret:
+            return W_NDimArray(ret)
+        raise OperationError(space.w_NotImplementedError, 
+                    space.wrap('imag not implemented for this dtype'))
+
+    def descr_set_real(self, space, w_value):
+        # copy (broadcast) values into self
+        tmp = self.implementation.get_real()
+        tmp.setslice(space, convert_to_array(space, w_value))
+
+    def descr_set_imag(self, space, w_value):
+        # if possible, copy (broadcast) values into self
+        if not self.get_dtype().is_complex_type():
+            raise OperationError(space.w_TypeError, 
+                    space.wrap('array does not have imaginary part to set'))
+        tmp = self.implementation.get_imag()
+        tmp.setslice(space, convert_to_array(space, w_value))
+
     def descr_reshape(self, space, args_w):
         """reshape(...)
         a.reshape(shape)
     descr_neg = _unaryop_impl("negative")
     descr_abs = _unaryop_impl("absolute")
     descr_invert = _unaryop_impl("invert")
-    descr_get_real = _unaryop_impl("real")
-    descr_get_imag = _unaryop_impl("imag")
 
     def descr_nonzero(self, space):
         if self.get_size() > 1:
     swapaxes = interp2app(W_NDimArray.descr_swapaxes),
     flat = GetSetProperty(W_NDimArray.descr_get_flatiter),
     item = interp2app(W_NDimArray.descr_item),
-    real = GetSetProperty(W_NDimArray.descr_get_real),
-    imag = GetSetProperty(W_NDimArray.descr_get_imag),
-
+    real = GetSetProperty(W_NDimArray.descr_get_real, 
+                          W_NDimArray.descr_set_real),
+    imag = GetSetProperty(W_NDimArray.descr_get_imag,
+                          W_NDimArray.descr_set_imag),
     __array_interface__ = GetSetProperty(W_NDimArray.descr_array_iface),
 )
 

File pypy/module/micronumpy/test/test_iter.py

         strides = [5, 1]
         backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
         assert backstrides == [10, 4]
-        i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+        i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
         i.next()
         i.next()
         i.next()
         strides = [1, 3]
         backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
         assert backstrides == [2, 12]
-        i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+        i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
         i.next()
         i.next()
         i.next()
         strides = [5, 1]
         backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
         assert backstrides == [10, 4]
-        i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+        i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
         i.next_skip_x(2)
         i.next_skip_x(2)
         i.next_skip_x(2)
         strides = [1, 3]
         backstrides = [x * (y - 1) for x,y in zip(strides, shape)]
         assert backstrides == [2, 12]
-        i = MultiDimViewIterator(MockArray, start, strides, backstrides, shape)
+        i = MultiDimViewIterator(MockArray, None, start, strides, backstrides, shape)
         i.next_skip_x(2)
         i.next_skip_x(2)
         i.next_skip_x(2)

File pypy/module/micronumpy/test/test_numarray.py

         assert (d == [[1, 0, 0], [0, 1, 0], [0, 0, 1]]).all()
    
     def test_eye(self):
-        from _numpypy import eye, array
-        from _numpypy import int32, float64, dtype
+        from _numpypy import eye
+        from _numpypy import int32, dtype
         a = eye(0)
         assert len(a) == 0
         assert a.dtype == dtype('float64')
         assert b[0] == 3
         assert b[1] == 2
 
+    def test_realimag_views(self):
+        from _numpypy import arange, array
+        a = arange(15)
+        b = a.real
+        b[5]=50
+        assert a[5] == 50
+        b = a.imag
+        assert b[7] == 0
+        raises(RuntimeError, 'b[7] = -2')
+        raises(TypeError, 'a.imag = -2')
+        a = array(['abc','def'],dtype='S3')
+        b = a.real
+        assert a[0] == b[0]
+        assert a[1] == b[1]
+        b[1] = 'xyz'
+        assert a[1] == 'xyz'
+        assert a.imag[0] == 'abc'
+        raises(TypeError, 'a.imag = "qop"')
+        a=array([[1+1j, 2-3j, 4+5j],[-6+7j, 8-9j, -2-1j]]) 
+        assert a.real[0,1] == 2
+        a.real[0,1] = -20
+        assert a[0,1].real == -20
+        b = a.imag
+        assert b[1,2] == -1
+        b[1,2] = 30
+        assert a[1,2].imag == 30
+        a.real = 13
+        assert a[1,1].real == 13
+        a=array([1+1j, 2-3j, 4+5j, -6+7j, 8-9j, -2-1j]) 
+        a.real = 13
+        assert a[3].real == 13
+        a.imag = -5
+        a.imag[3] = -10
+        assert a[3].imag == -10
+        assert a[2].imag == -5
+
     def test_tolist_scalar(self):
         from _numpypy import int32, bool_
         x = int32(23)
         assert a[0]['x'] == 'a'
 
     def test_stringarray(self):
-        from _numpypy import array, flexible
+        from _numpypy import array
         a = array(['abc'],'S3')
         assert str(a.dtype) == '|S3'
         a = array(['abc'])
 
     def test_flexible_repr(self):
         # import overrides str(), repr() for array
-        from numpypy.core import arrayprint
         from _numpypy import array
         a = array(['abc'],'S3')
         s = repr(a)

File pypy/objspace/flow/test/test_objspace.py

 from pypy.objspace.flow.objspace import FlowObjSpace
 from pypy.objspace.flow.flowcontext import FlowingError, FlowSpaceFrame
 from pypy import conftest
-from pypy.tool.stdlib_opcode import bytecode_spec, host_bytecode_spec
+from pypy.tool.stdlib_opcode import host_bytecode_spec
 
 import os
 import operator
 is_operator = getattr(operator, 'is_', operator.eq) # it's not there 2.2
 
 @contextmanager
-def patching_opcodes(*opcodes):
+def patching_opcodes(**opcodes):
     meth_names = host_bytecode_spec.method_names
-    opnums = [bytecode_spec.opmap[name] for name in opcodes]
     old_name = {}
-    for name, num in zip(opcodes, opnums):
+    for name, num in opcodes.items():
         old_name[num] = meth_names[num]
         meth_names[num] = name
     yield
         """ Tests code generated by pypy-c compiled with CALL_METHOD
         bytecode
         """
-        with patching_opcodes('CALL_METHOD', 'LOOKUP_METHOD'):
+        with patching_opcodes(CALL_METHOD=202, LOOKUP_METHOD=201):
             class X:
                 def m(self):
                     return 3
         """ Tests code generated by pypy-c compiled with BUILD_LIST_FROM_ARG
         bytecode
         """
-        with patching_opcodes('BUILD_LIST_FROM_ARG'):
+        with patching_opcodes(BUILD_LIST_FROM_ARG=203):
             def f():
                 return [i for i in "abc"]
 

File pypy/rpython/lltypesystem/rffi.py

 from pypy.annotation import model as annmodel
 from pypy.rpython.lltypesystem import lltype, rstr
 from pypy.rpython.lltypesystem import ll2ctypes
-from pypy.rpython.lltypesystem.llmemory import cast_adr_to_ptr, cast_ptr_to_adr
+from pypy.rpython.lltypesystem.llmemory import cast_ptr_to_adr
 from pypy.rpython.lltypesystem.llmemory import itemoffsetof, raw_memcopy
 from pypy.annotation.model import lltype_to_annotation
 from pypy.tool.sourcetools import func_with_new_name
-from pypy.rlib.objectmodel import Symbolic, CDefinedIntSymbolic
-from pypy.rlib.objectmodel import keepalive_until_here
+from pypy.rlib.objectmodel import Symbolic
+from pypy.rlib.objectmodel import keepalive_until_here, enforceargs
 from pypy.rlib import rarithmetic, rgc
 from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.rlib.unroll import unrolling_iterable
 
     # (char*, str, int, int) -> None
     @jit.dont_look_inside
+    @enforceargs(None, None, int, int)
     def str_from_buffer(raw_buf, gc_buf, allocated_size, needed_size):
         """
         Converts from a pair returned by alloc_buffer to a high-level string.
             lltype.free(raw_buf, flavor='raw')
 
     # char* -> str, with an upper bound on the length in case there is no \x00
+    @enforceargs(None, int)
     def charp2strn(cp, maxlen):
         b = builder_class(maxlen)
         i = 0

File pypy/translator/driver.py

     @taskdef([RTYPE], "JIT compiler generation")
     def task_pyjitpl_lltype(self):
         """ Generate bytecodes for JIT and flow the JIT helper functions
-        ootype version
+        lltype version
         """
         get_policy = self.extra['jitpolicy']
         self.jitpolicy = get_policy(self)