[pypy-svn] r28143 - in pypy/dist/pypy/translator/js2: . test

fijal at codespeak.net fijal at codespeak.net
Sat Jun 3 12:27:34 CEST 2006


Author: fijal
Date: Sat Jun  3 12:27:32 2006
New Revision: 28143

Modified:
   pypy/dist/pypy/translator/js2/asmgen.py
   pypy/dist/pypy/translator/js2/function.py
   pypy/dist/pypy/translator/js2/test/test_snippet.py
Log:
Reverted to using magic for(;;) as goto replacement. Works pretty slow.


Modified: pypy/dist/pypy/translator/js2/asmgen.py
==============================================================================
--- pypy/dist/pypy/translator/js2/asmgen.py	(original)
+++ pypy/dist/pypy/translator/js2/asmgen.py	Sat Jun  3 12:27:32 2006
@@ -122,6 +122,10 @@
         self.codegenerator.write("while ( %s == %s )"%(arg_name, str(exitcase).lower()))
         self.codegenerator.openblock()
     
+    def branch_while_true(self):
+        self.codegenerator.write("while (true)")
+        self.codegenerator.openblock()
+    
     def branch_else(self):
         self.codegenerator.closeblock()
         self.codegenerator.write("else")
@@ -228,6 +232,24 @@
     def end_try(self):
         self.codegenerator.closeblock()
     
+    def begin_for(self):
+        self.codegenerator.writeline("var block = 0;")
+        self.codegenerator.write("for(;;)")
+        self.codegenerator.openblock()
+        self.codegenerator.write("switch(block)")
+        self.codegenerator.openblock()
+    
+    def write_case(self, num):
+        self.codegenerator.writeline("case %d:"%num)
+    
+    def jump_block(self, num):
+        self.codegenerator.writeline("block = %d;"%num)
+        self.codegenerator.writeline("break;")
+    
+    def end_for(self):
+        self.codegenerator.closeblock()
+        self.codegenerator.closeblock()
+    
     def inherits(self, subclass_name, parent_name):
         self.codegenerator.writeline("%s.inherits(%s);"%(subclass_name, parent_name))
     

Modified: pypy/dist/pypy/translator/js2/function.py
==============================================================================
--- pypy/dist/pypy/translator/js2/function.py	(original)
+++ pypy/dist/pypy/translator/js2/function.py	Sat Jun  3 12:27:32 2006
@@ -39,10 +39,14 @@
 
     def visit_Link(self, link, switches):
         if link.target in switches:
+            #if self.loops.has_key(link.target):
+            #    # double loop
+            #    pass
+            block_switch = self.block_seeing_order[link.target]
             if len(self.block_seeing_order[link.target]) == 1:
-                self.loops[link.target] = self.block_seeing_order[link.target][0].exitcase
+                self.loops[(block_switch[0].exitcase,link.target)] = block_switch[0].exitcase
             else:
-                self.loops[link.target] = self.block_seeing_order[link.target][1].exitcase
+                self.loops[(block_switch[1].exitcase,link.target)] = block_switch[1].exitcase
             
         if not link.target in self.seen:
             self.parents[link.target] = self.parents[link.prevblock]
@@ -75,14 +79,16 @@
         return cmp(self.order, other.order)
 
     def _is_return_block(self, block):
-        return (not block.exits) and len(block.inputargs) == 1
-
+        return self.graph.returnblock is block
+    
     def _is_raise_block(self, block):
-        return (not block.exits) and len(block.inputargs) == 2        
-
-    def render_block(self, block, stop_block = None):
-        if block is stop_block:
+        return self.graph.exceptblock is block
+        
+    def loop_render_block(self, block, stop_blocks = []):
+        # FIXME: This code is awfull, some refactoring please
+        if block in stop_blocks:
             return
+        log("Rendering block %r"%block)
         
         handle_exc = (block.exitswitch == flowmodel.c_last_exception)
         if handle_exc:
@@ -102,35 +108,98 @@
             assert(len(block.exits) == 1)
             link = block.exits[0]
             self._setup_link(link)
-            self.render_block(link.target, stop_block)
+            self.render_block(link.target, stop_blocks)
         elif block.exitswitch is flowmodel.c_last_exception:
             # we've got exception block
             raise NotImplementedError("Exception handling not implemented")
         else:
-            if self.loops.has_key(block):
+            if self.loops.has_key((True,block)) and self.loops.has_key((False,block)):
+                # double loop
+                #self.ilasm.branch_while
+                self.ilasm.branch_while_true()
+                self.ilasm.branch_if(block.exitswitch, self.loops[(True,block)])
+                self._setup_link(block.exits[True])
+                self.render_block(block.exits[True].target, stop_blocks+[block])
+                self.ilasm.branch_else()
+                self._setup_link(block.exits[False])
+                self.render_block(block.exits[False].target, stop_blocks+[block])
+                self.ilasm.close_branch()
+                for op in block.operations:
+                    self._render_op(op)
+                self.ilasm.close_branch()
+            elif self.loops.has_key((True, block)) or self.loops.has_key((False, block)):
                 # we've got loop
-                self.ilasm.branch_while(block.exitswitch, self.loops[block])
-                exit_case = block.exits[self.loops[block]]
+                try:
+                    loop_case = self.loops[(True, block)]
+                except KeyError:
+                    loop_case = self.loops[(False, block)]
+                self.ilasm.branch_while(block.exitswitch, loop_case)
+                exit_case = block.exits[loop_case]
                 self._setup_link(exit_case)
-                self.render_block(exit_case.target, block)
+                self.render_block(exit_case.target, stop_blocks+[block])
                 for op in block.operations:
                     self._render_op(op)
                 self.ilasm.close_branch()
-                exit_case = block.exits[not self.loops[block]]
+                exit_case = block.exits[not loop_case]
                 self._setup_link(exit_case)
                 #log (  )
-                self.render_block(exit_case.target,block)
+                self.render_block(exit_case.target, stop_blocks+[block])
                 #raise NotImplementedError ( "loop" )
             else:
                 # just a simple if
                 assert(len(block.exits) == 2)
                 self.ilasm.branch_if(block.exitswitch, True)
                 self._setup_link(block.exits[True])
-                self.render_block(block.exits[True].target, stop_block)
+                self.render_block(block.exits[True].target, stop_blocks)
+                self.ilasm.branch_else()
+                self._setup_link(block.exits[False])
+                self.render_block(block.exits[False].target, stop_blocks)
+                self.ilasm.close_branch()
+    
+    def render_block_operations(self, block):
+        for op in block.operations:
+            self._render_op(op)
+    
+    def render_block(self, startblock):
+        """ Block rendering routine using for variable trick
+        """
+        self.ilasm.begin_for()
+        
+        block_map = {}
+        blocknum = 0
+        
+        graph = self.graph
+        
+        for block in graph.iterblocks():
+            block_map[block] = blocknum
+            blocknum += 1
+        
+        for block in graph.iterblocks():
+            self.ilasm.write_case(block_map[block])
+            self.render_block_operations(block)
+            if self._is_return_block(block):
+                return_var = block.inputargs[0]
+                #if return_var.concretetype is not Void:
+                self.load(return_var)
+                self.ilasm.ret()
+            elif block.exitswitch is None:
+                self._setup_link(block.exits[0])
+                self.ilasm.jump_block(block_map[block.exits[0].target])
+            elif block.exitswitch.concretetype is Bool:
+                self.ilasm.branch_if(block.exitswitch, True)
+                self._setup_link(block.exits[True])
+                self.ilasm.jump_block(block_map[block.exits[True].target])
                 self.ilasm.branch_else()
                 self._setup_link(block.exits[False])
-                self.render_block(block.exits[False].target, stop_block)
+                self.ilasm.jump_block(block_map[block.exits[False].target])
                 self.ilasm.close_branch()
+            elif block.exitswitch is flowmodel.c_last_exception:
+                raise NotImplementedError("Exception work in progress")
+            else:
+                raise TypeError("Unknow block.exitswitch type %r"%block.exitswitch)
+        
+        self.ilasm.end_for()
+        #self.render_operations(
 
     def render(self,ilasm):
         if self.db.graph_name(self.graph) is not None and not self.is_method:
@@ -143,16 +212,17 @@
         
         self.ilasm = ilasm
         
-        self.loops = LoopFinder(self.graph.startblock).loops
+        #self.loops = LoopFinder(self.graph.startblock).loops
         if self.is_method:
             self.ilasm.begin_method(self.name, self._class, args)
         else:
             self.ilasm.begin_function(self.name, args)
-        log("loops: %r"%self.loops)
+        #log("loops: %r"%self.loops)
 
         # render all variables
         
         self.ilasm.set_locals(",".join(self.locals))
+        
         self.render_block(self.graph.startblock)
 
         self.ilasm.end_function()
@@ -206,7 +276,7 @@
         seen = {}
         for v in mix:
             is_var = isinstance(v, flowmodel.Variable)
-            if id(v) not in seen and is_var and v.name not in args and v.concretetype is not Void:
+            if id(v) not in seen and is_var and v.name not in args:
                 locals.append(v.name)
                 seen[id(v)] = True
 

Modified: pypy/dist/pypy/translator/js2/test/test_snippet.py
==============================================================================
--- pypy/dist/pypy/translator/js2/test/test_snippet.py	(original)
+++ pypy/dist/pypy/translator/js2/test/test_snippet.py	Sat Jun  3 12:27:32 2006
@@ -33,12 +33,12 @@
         assert f() == 4
 
     def test_sieve_of_eratosthenes(self):
-        py.test.skip("Loop error in loop detection software")
+        #py.test.skip("Loop error in loop detection software")
         f = compile_function(test.sieve_of_eratosthenes, [])
         assert f() == 1028
     
     def test_nested_whiles(self):
-        py.test.skip("Loop error in loop detection software")
+        #py.test.skip("Loop error in loop detection software")
         f = compile_function(test.nested_whiles, [int, int])
         assert test.nested_whiles(3,2) == f(3,2)
 
@@ -51,7 +51,7 @@
         assert while_func(10) == 55
 
     def test_time_waster(self):
-        py.test.skip("Loop error in loop detection software")
+        #py.test.skip("Loop error in loop detection software")
         f = compile_function(test.time_waster, [int])
         assert f(1) == 1
         assert f(2) == 2



More information about the Pypy-commit mailing list