[pypy-svn] r10353 - in pypy/dist/pypy/translator/llvm: . test

cfbolz at codespeak.net cfbolz at codespeak.net
Wed Apr 6 01:48:03 CEST 2005


Author: cfbolz
Date: Wed Apr  6 01:48:03 2005
New Revision: 10353

Modified:
   pypy/dist/pypy/translator/llvm/autopath.py
   pypy/dist/pypy/translator/llvm/funcrepr.py
   pypy/dist/pypy/translator/llvm/genllvm.py
   pypy/dist/pypy/translator/llvm/test/autopath.py
   pypy/dist/pypy/translator/llvm/test/llvmsnippet.py
   pypy/dist/pypy/translator/llvm/test/test_genllvm.py
Log:
The Big Rewrite of the code generation mess in FuncRepr. Should be much
cleaner now (and make the implementation of raising exceptions
possible).



Modified: pypy/dist/pypy/translator/llvm/autopath.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/autopath.py	(original)
+++ pypy/dist/pypy/translator/llvm/autopath.py	Wed Apr  6 01:48:03 2005
@@ -46,10 +46,8 @@
     
     while checkpaths:
         orig = checkpaths.pop()
-        fullorig = os.path.join(os.path.realpath(orig), '')
-        if fullorig.startswith(pypy_root):
-            if os.path.exists(os.path.join(fullorig, '__init__.py')):
-                sys.path.remove(orig)
+        if os.path.join(os.path.realpath(orig), '').startswith(pypy_root):
+            sys.path.remove(orig)
     sys.path.insert(0, head)
 
     munged = {}

Modified: pypy/dist/pypy/translator/llvm/funcrepr.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/funcrepr.py	(original)
+++ pypy/dist/pypy/translator/llvm/funcrepr.py	Wed Apr  6 01:48:03 2005
@@ -99,6 +99,7 @@
         remove_double_links(self.translator, self.graph)
         self.get_bbs()
         self.se = False
+        self.lblocks = []
 
     def setup(self):
         if self.se:
@@ -123,173 +124,23 @@
         self.same_origin_block = [False] * len(self.allblocks)
 
     def build_bbs(self):
-        checkgraph(self.graph)
-        a = self.annotator
         for number, pyblock in enumerate(self.allblocks):
-            if debug:
-                print "#" * 20, self.graph.name, number, pyblock
-            pyblock = self.allblocks[number]
             is_tryblock = isinstance(pyblock.exitswitch, Constant) and \
                           pyblock.exitswitch.value == last_exception
             if is_tryblock:
-                regularblock = "block%i" % self.blocknum[
-                    pyblock.exits[0].target]
-                exceptblock = "block%i.except" % self.blocknum[pyblock]
-                lblock = llvmbc.TryBasicBlock("block%i" % number,
-                                              regularblock, exceptblock)
+                block = TryBlockRepr(self, pyblock, self.gen)
+            elif pyblock == self.graph.returnblock:
+                block = ReturnBlockRepr(self, pyblock, self.gen)
+            elif pyblock == self.graph.exceptblock:
+                block = ExceptBlockRepr(self, pyblock, self.gen)
             else:
-                lblock = llvmbc.BasicBlock("block%i" % number)
-            if number == 0:
-                self.llvm_func = llvmbc.Function(self.llvmfuncdef(), lblock)
-            else:
-                self.llvm_func.basic_block(lblock)
-            if is_tryblock:
-                self.build_exc_blocks(number, pyblock)
-            #Create Phi nodes
-            incoming_links = []
-            def visit(node):
-                if isinstance(node, Link) and node.target == pyblock:
-                    incoming_links.append(node)
-            traverse(visit, self.graph)
-            print "***** phi nodes *****"
-            if len(incoming_links) != 0:
-                for i, arg in enumerate(pyblock.inputargs):
-                    print "___", i, arg, "___", 
-                    l_arg = self.gen.get_repr(arg)
-                    l_values = [self.gen.get_repr(l.args[i])
-                                for l in incoming_links]
-                    for j in range(len(l_values)):
-                        print j, l_values[j].llvmtype(), l_arg.llvmtype()
-                        if l_values[j].llvmtype() != l_arg.llvmtype():
-                            try:
-                                l_values[j] = \
-                                        l_values[j].alt_types[l_arg.llvmtype()]
-                            except KeyError:
-                                pass
-                    self.dependencies.add(l_arg)
-                    self.dependencies.update(l_values)
-                    lblock.phi(l_arg, l_values,
-                               ["%%block%i" % self.blocknum[l.prevblock]
-                                for l in incoming_links])
-            #Handle SpaceOperations
-            for opnumber, op in enumerate(pyblock.operations):
-                if opnumber == len(pyblock.operations) - 1 and is_tryblock:
-                    lblock.last_op = True                    
-                l_target = self.gen.get_repr(op.result)
-                self.dependencies.add(l_target)
-                l_arg0 = self.gen.get_repr(op.args[0])
-                self.dependencies.add(l_arg0)
-                l_op = getattr(l_arg0, "op_" + op.opname, None)
-                if l_op is not None:
-                    l_op(l_target, op.args, lblock, self)
-                #XXX need to find more elegant solution for this special case
-                elif op.opname == "newtuple":
-                    l_target.type.t_op_newtuple(l_target, op.args,
-                                                lblock, self)
-                elif op.opname in INTRINSIC_OPS:
-                    l_args = [self.gen.get_repr(arg) for arg in op.args[1:]]
-                    self.dependencies.update(l_args)
-                    lblock.spaceop(l_target, op.opname, [l_arg0] + l_args)
-                else:
-                        s = "SpaceOperation %s not supported. Target: %s " \
-                            "Args: %s " % (op.opname, l_target, op.args) + \
-                            "Dispatched on: %s" % l_arg0
-                            
-                        raise CompileError, s
-            # XXX: If a variable is passed to another block and has a different
-            # type there, we have to make the cast in this block since the phi
-            # instructions in the next block cannot be preceded by any other
-            # instruction
-            print "******Casts:******"
-            for link in pyblock.exits:
-                print "____________block:", link.target
-                for i, arg in enumerate(link.args):
-                    print arg,
-                    l_target = self.gen.get_repr(link.target.inputargs[i])
-                    l_local = self.gen.get_repr(arg)
-                    self.dependencies.update([l_target, l_local])
-                    print "local", l_local.typed_name()
-                    print "target", l_target.typed_name()
-                    print "from ", l_local.llvmtype(),
-                    print "to", l_target.llvmtype(),
-                    if l_target.llvmtype() != l_local.llvmtype():
-                        print "change: ", 
-                        l_tmp = self.gen.get_local_tmp(l_target.type, self)
-                        lblock.cast(l_tmp, l_local)
-                        try:
-                            print l_local.alt_types
-                            l_local.alt_types[l_target.llvmtype()] = l_tmp
-                        except (AttributeError, TypeError):
-                            l_local.alt_types = {l_target.llvmtype(): l_tmp}
-                            print l_local.alt_types
-                    else:
-                        print
-            #Create branches
-            if pyblock.exitswitch is None:
-                if pyblock == self.graph.returnblock:
-                    l_returnvalue = self.gen.get_repr(pyblock.inputargs[0])
-                    self.dependencies.add(l_returnvalue)
-                    lblock.ret(l_returnvalue)
-                elif pyblock == self.graph.exceptblock:
-                    l_exc = self.gen.get_repr(pyblock.inputargs[0])
-                    l_val = self.gen.get_repr(pyblock.inputargs[1])
-                    l_last_exception = self.gen.get_repr(last_exception)
-                    l_last_exc_value = self.gen.get_repr(last_exc_value)
-                    self.dependencies.update([l_exc, l_val, l_last_exception,
-                                              l_last_exc_value])
-                    if "%std.class" != l_exc.llvmtype():
-                        l_tmp = self.gen.get_local_tmp(
-                            PointerTypeRepr("%std.class", self.gen), self)
-                        lblock.cast(l_tmp, l_exc)
-                        l_exc = l_tmp
-                    if  "%std.exception" != l_val.llvmtype():
-                        l_tmp = self.gen.get_local_tmp(
-                            PointerTypeRepr("%std.exception", self.gen), self)
-                        lblock.cast(l_tmp, l_val)
-                        l_val = l_tmp
-                    lblock.store(l_exc, l_last_exception)
-                    lblock.store(l_val, l_last_exc_value)
-                    lblock.unwind()
-                else:
-                    lblock.uncond_branch(
-                        "%%block%i" % self.blocknum[pyblock.exits[0].target])
-            elif isinstance(pyblock.exitswitch, Constant) and \
-                 pyblock.exitswitch.value == last_exception:
-                #The branch has already be created by the last space op
-                assert lblock.closed
-            else:
-                assert isinstance(a.binding(pyblock.exitswitch),
-                                  annmodel.SomeBool)
-                l_switch = self.gen.get_repr(pyblock.exitswitch)
-                self.dependencies.add(l_switch)
-                lblock.cond_branch(
-                    l_switch,
-                    "%%block%i" % self.blocknum[pyblock.exits[1].target],
-                    "%%block%i" % self.blocknum[pyblock.exits[0].target])
-
-    def build_exc_blocks(self, number, pyblock):
-        lexcblock = llvmbc.BasicBlock("block%i.except" % number)
-        self.llvm_func.basic_block(lexcblock)
-        l_excp = self.gen.get_repr(last_exception)
-        l_exc = self.gen.get_local_tmp(PointerTypeRepr("%std.class", self.gen),
-                                       self)
-        l_uip = self.gen.get_local_tmp(PointerTypeRepr("uint", self.gen), self)
-        l_ui = self.gen.get_local_tmp(
-            self.gen.get_repr(annmodel.SomeInteger(True, True)), self)
-        self.dependencies.update([l_excp, l_exc, l_uip, l_ui])
-        lexcblock.load(l_exc, l_excp)
-        lexcblock.getelementptr(l_uip, l_exc, [0, 1])
-        lexcblock.load(l_ui, l_uip)
-        exits = pyblock.exits[1:]
-        l_exitcases = [self.gen.get_repr(ex.exitcase) for ex in exits]
-        self.dependencies.update(l_exitcases)
-        sw = [(str(abs(id(ex.exitcase))),
-               "%%block%i" % self.blocknum[ex.target])
-              for ex in exits]
-        lexcblock.switch(l_ui, "%%block%i.unwind" % number, sw)
-        lunwindblock = llvmbc.BasicBlock("block%i.unwind" % number)
-        lunwindblock.unwind()
-        self.llvm_func.basic_block(lunwindblock)
+                block = BlockRepr(self, pyblock, self.gen)
+        self.llvm_func = llvmbc.Function(self.llvmfuncdef(), self.lblocks[0])
+        for bl in self.lblocks[1:]:
+            self.llvm_func.basic_block(bl)
+
+    def add_block(self, lblock):
+        self.lblocks.append(lblock)
 
     def llvmfuncdef(self):
         s = "internal %s %s(" % (self.retvalue.llvmtype(), self.name)
@@ -315,6 +166,222 @@
         l_func.dependencies.update(l_args)
         lblock.call(l_target, l_args[0], l_args[1:])
 
+class BlockRepr(object):
+    def __init__(self, l_func, pyblock, gen):
+        print "BlockRepr"
+        self.l_func = l_func
+        self.pyblock = pyblock
+        self.gen = gen
+        self.l_args = [self.gen.get_repr(a) for a in pyblock.inputargs]
+        self.l_func.dependencies.update(self.l_args)
+        self.lblock = llvmbc.BasicBlock("block%i" % l_func.blocknum[pyblock])
+        l_func.add_block(self.lblock)
+        self.build_bb()
+
+    def build_bb(self):
+        self.create_phi_nodes()
+        self.create_space_ops()
+        self.create_terminator_instr()
+
+    def create_phi_nodes(self):
+        pyblock = self.pyblock
+        l_incoming_links = []
+        def visit(node):
+            if isinstance(node, Link) and node.target == pyblock:
+                l_incoming_links.append(LinkRepr.get_link(node, self.l_func,
+                                                          self.gen))
+        traverse(visit, self.l_func.graph)
+        if len(l_incoming_links) != 0:
+            for i, arg in enumerate(pyblock.inputargs):
+                l_arg = self.gen.get_repr(arg)
+                l_values = [l_l.l_args[i] for l_l in l_incoming_links]
+                self.l_func.dependencies.add(l_arg)
+                self.lblock.phi(l_arg, l_values, ["%" + l_l.blockname
+                                                  for l_l in l_incoming_links])
+
+    def create_space_ops(self):
+        for opnumber, op in enumerate(self.pyblock.operations):
+            self.create_op(opnumber, op)
+
+    def create_op(self, opnumber, op):
+        l_target = self.gen.get_repr(op.result)
+        l_arg0 = self.gen.get_repr(op.args[0])
+        self.l_func.dependencies.update([l_arg0, l_target])
+        l_op = getattr(l_arg0, "op_" + op.opname, None)
+        if l_op is not None:
+            l_op(l_target, op.args, self.lblock, self.l_func)
+        #XXX need to find more elegant solution for this special case
+        elif op.opname == "newtuple":
+            l_target.type.t_op_newtuple(l_target, op.args,
+                                        self.lblock, self.l_func)
+        elif op.opname in INTRINSIC_OPS:
+            l_args = [self.gen.get_repr(arg) for arg in op.args[1:]]
+            self.l_func.dependencies.update(l_args)
+            self.lblock.spaceop(l_target, op.opname, [l_arg0] + l_args)
+        else:
+            s = "SpaceOperation %s not supported. Target: %s " \
+                "Args: %s " % (op.opname, l_target, op.args) + \
+                "Dispatched on: %s" % l_arg0
+            raise CompileError, s
+
+    def create_terminator_instr(self):
+        print "create_terminator_instr"
+        pyblock = self.pyblock
+        l_func = self.l_func
+        l_link = LinkRepr.get_link(pyblock.exits[0], l_func, self.gen)
+        if self.pyblock.exitswitch is None:
+            self.lblock.uncond_branch("%" + l_link.blockname)
+        else:
+            l_switch = self.gen.get_repr(pyblock.exitswitch)
+            l_link = LinkRepr.get_link(pyblock.exits[0], l_func, self.gen)
+            l_link2 = LinkRepr.get_link(pyblock.exits[1], l_func, self.gen)
+            l_func.dependencies.add(l_switch)
+            self.lblock.cond_branch(l_switch, "%" + l_link2.blockname,
+                                    "%" + l_link.blockname)
+        #1 / 0
+
+
+class ReturnBlockRepr(BlockRepr):
+    def create_space_ops(self):
+        pass
+    
+    def create_terminator_instr(self):
+        l_returnvalue = self.gen.get_repr(self.pyblock.inputargs[0])
+        self.l_func.dependencies.add(l_returnvalue)
+        self.lblock.ret(l_returnvalue)
+
+
+class TryBlockRepr(BlockRepr):
+    def __init__(self, l_func, pyblock, gen):
+        print "TryBlockRepr"
+        self.l_func = l_func
+        self.pyblock = pyblock
+        self.gen = gen
+        self.l_args = [self.gen.get_repr(a) for a in pyblock.inputargs]
+        self.l_func.dependencies.update(self.l_args)
+        #XXXXXXXXXXX
+        regularblock = "DUMMY"
+        exceptblock = "block%i.except" % l_func.blocknum[pyblock]
+        self.lblock = llvmbc.TryBasicBlock("block%i" % \
+                                           l_func.blocknum[pyblock],
+                                           regularblock, exceptblock)
+        l_func.add_block(self.lblock)
+        l_link = LinkRepr.get_link(pyblock.exits[0], l_func, gen)
+        self.lblock.regularblock = l_link.blockname
+        self.build_bb()
+        self.build_exc_block()
+
+    def create_space_ops(self):
+        for opnumber, op in enumerate(self.pyblock.operations):
+            if opnumber == len(self.pyblock.operations) - 1:
+                self.lblock.last_op = True
+            self.create_op(opnumber, op)
+
+    def create_terminator_instr(self):
+        #The branch has already be created by the last space op
+        assert self.lblock.closed
+
+    def build_exc_block(self):
+        lexcblock = llvmbc.BasicBlock(self.lblock.label + ".except")
+        self.l_func.add_block(lexcblock)
+        l_excp = self.gen.get_repr(last_exception)
+        l_exc = self.gen.get_local_tmp(PointerTypeRepr("%std.class", self.gen),
+                                       self.l_func)
+        l_uip = self.gen.get_local_tmp(PointerTypeRepr("uint", self.gen),
+                                       self.l_func)
+        l_ui = self.gen.get_local_tmp(
+            self.gen.get_repr(annmodel.SomeInteger(True, True)), self.l_func)
+        self.l_func.dependencies.update([l_excp, l_exc, l_uip, l_ui])
+        lexcblock.load(l_exc, l_excp)
+        lexcblock.getelementptr(l_uip, l_exc, [0, 1])
+        lexcblock.load(l_ui, l_uip)
+        l_exits = [LinkRepr.get_link(l, self.l_func, self.gen)
+                                     for l in self.pyblock.exits[1:]]
+        l_exitcases = [self.gen.get_repr(ex.exitcase)
+                       for ex in self.pyblock.exits[1:]]
+        self.l_func.dependencies.update(l_exitcases)
+        sw = [(str(abs(id(ex.exitcase))), "%" + l_l.blockname)
+              for ex, l_l in zip(self.pyblock.exits[1:], l_exits)]
+        lexcblock.switch(l_ui, "%" + self.lblock.label + ".unwind", sw)
+        lunwindblock = llvmbc.BasicBlock(self.lblock.label + ".unwind")
+        lunwindblock.unwind()
+        self.l_func.add_block(lunwindblock)
+
+class ExceptBlockRepr(BlockRepr):
+    def create_space_ops(self):
+        pass
+
+    def create_terminator_instr(self):
+        l_exc = self.gen.get_repr(self.pyblock.inputargs[0])
+        l_val = self.gen.get_repr(self.pyblock.inputargs[1])
+        l_last_exception = self.gen.get_repr(last_exception)
+        l_last_exc_value = self.gen.get_repr(last_exc_value)
+        self.l_func.dependencies.update([l_exc, l_val, l_last_exception,
+                                         l_last_exc_value])
+        if "%std.class" != l_exc.llvmtype():
+            l_tmp = self.gen.get_local_tmp(
+                PointerTypeRepr("%std.class", self.gen), self.l_func)
+            self.lblock.cast(l_tmp, l_exc)
+            l_exc = l_tmp
+        if  "%std.exception" != l_val.llvmtype():
+            l_tmp = self.gen.get_local_tmp(
+                PointerTypeRepr("%std.exception", self.gen), self.l_func)
+            self.lblock.cast(l_tmp, l_val)
+            l_val = l_tmp
+        self.lblock.store(l_exc, l_last_exception)
+        self.lblock.store(l_val, l_last_exc_value)
+        self.lblock.unwind()
+
+
+class LinkRepr(object):
+    l_links = {}
+    def get_link(link, l_func, gen):
+        if (link, gen) not in LinkRepr.l_links:
+            LinkRepr.l_links[(link, gen)] = LinkRepr(link, l_func, gen)
+        return LinkRepr.l_links[(link, gen)]
+    get_link = staticmethod(get_link)
+            
+    def __init__(self, link, l_func, gen):
+        self.link = link
+        self.l_func = l_func
+        self.gen = gen
+        self.l_args = [self.gen.get_repr(a) for a in self.link.args]
+        self.l_targetargs = [self.gen.get_repr(a)
+                             for a in self.link.target.inputargs]
+        self.l_func.dependencies.update(self.l_args)
+        self.l_func.dependencies.update(self.l_targetargs)
+        assert len(self.l_args) == len(self.l_targetargs)
+        self.create_link_block()
+
+    def create_link_block(self):
+        link = self.link
+        l_func = self.l_func
+        self.blockname = "bl%i_to_bl%i" % (l_func.blocknum[link.prevblock],
+                                           l_func.blocknum[link.target])
+        self.lblock = llvmbc.BasicBlock(self.blockname)
+        if isinstance(link.prevblock.exitswitch, Constant) and \
+           link.prevblock.exitswitch.value == last_exception and \
+           len(self.l_args) == 2:
+            l_tmp1 = self.gen.get_local_tmp(PointerTypeRepr("%std.class",
+                                                            self.gen),
+                                            self.l_func)
+            l_tmp2 = self.gen.get_local_tmp(PointerTypeRepr("%std.exception",
+                                                            self.gen),
+                                            self.l_func)
+            self.l_func.dependencies.update([l_tmp1, l_tmp2])
+            self.lblock.load(self.l_args[0], l_tmp1)
+            self.lblock.load(self.l_args[1], l_tmp2)
+            self.l_args[0] = l_tmp1
+            self.l_args[1] = l_tmp2
+        for i, (l_a, l_ta) in enumerate(zip(self.l_args, self.l_targetargs)):
+            if l_a.llvmtype() != l_ta.llvmtype():
+                l_tmp = self.gen.get_local_tmp(l_ta.type, l_func)
+                self.lblock.cast(l_tmp, l_a)
+                self.l_args[i] = l_tmp
+        self.lblock.uncond_branch("%%block%i" % l_func.blocknum[link.target])
+        self.l_func.add_block(self.lblock)
+
+
 class EntryFunctionRepr(LLVMRepr):
     def __init__(self, name, function, gen):
         self.gen = gen
@@ -336,7 +403,8 @@
         self.init_block = llvmbc.BasicBlock("init")
         self.init_block.instruction("store bool true, bool* %Initialized.0__")
         real_entry = llvmbc.BasicBlock("real_entry")
-        l_ret = self.gen.get_local_tmp(self.l_function.retvalue.type, self)
+        l_ret = self.gen.get_local_tmp(self.l_function.retvalue.type,
+                                       self)
         self.l_function.op_simple_call(
             l_ret, [self.function] + self.l_function.l_args, real_entry, self)
         real_entry.ret(l_ret)

Modified: pypy/dist/pypy/translator/llvm/genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm/genllvm.py	Wed Apr  6 01:48:03 2005
@@ -175,3 +175,4 @@
             yield l_dep1
     yield l_repr
 
+

Modified: pypy/dist/pypy/translator/llvm/test/autopath.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/autopath.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/autopath.py	Wed Apr  6 01:48:03 2005
@@ -46,10 +46,8 @@
     
     while checkpaths:
         orig = checkpaths.pop()
-        fullorig = os.path.join(os.path.realpath(orig), '')
-        if fullorig.startswith(pypy_root):
-            if os.path.exists(os.path.join(fullorig, '__init__.py')):
-                sys.path.remove(orig)
+        if os.path.join(os.path.realpath(orig), '').startswith(pypy_root):
+            sys.path.remove(orig)
     sys.path.insert(0, head)
 
     munged = {}

Modified: pypy/dist/pypy/translator/llvm/test/llvmsnippet.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/llvmsnippet.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/llvmsnippet.py	Wed Apr  6 01:48:03 2005
@@ -269,6 +269,14 @@
 
 
 #exception snippets:
+def simple_exception(n):
+    lst = range(10)
+    try:
+        lst[n]
+    except IndexError:
+        return 2
+    return 4
+    
 def two_exceptions(n):
     lst = range(10)
     try:
@@ -287,3 +295,18 @@
         return 2
     return 4
 
+
+#doesn't work yet!
+class MyException(Exception):
+    pass
+
+def raises(i):
+    if i:
+        raise MyException
+    return 1
+
+def catches(i):
+    try:
+        return raises(i)
+    except MyException:
+        return 2

Modified: pypy/dist/pypy/translator/llvm/test/test_genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/test_genllvm.py	(original)
+++ pypy/dist/pypy/translator/llvm/test/test_genllvm.py	Wed Apr  6 01:48:03 2005
@@ -251,10 +251,17 @@
         assert f(30) == 30
 
 class TestException(object):
-    def setup_method(self, method):
+    def setup_method(self,method):
         if not llvm_found:
-            py.test.skip("llvm-as not found on path.")
-            
+            py.test.skip("llvm-as not found on path")
+
+    def test_simple_exception(self):
+        f = compile_function(llvmsnippet.simple_exception, [int])
+        for i in range(10):
+            assert f(i) == 4
+        for i in range(10, 20):
+            assert f(i) == 2
+        
     def test_two_exception(self):
         f = compile_function(llvmsnippet.two_exceptions, [int])
         for i in range(10):



More information about the Pypy-commit mailing list