[pypy-svn] r32858 - in pypy/dist/pypy: objspace/flow translator/tool

arigo at codespeak.net arigo at codespeak.net
Tue Oct 3 19:46:56 CEST 2006


Author: arigo
Date: Tue Oct  3 19:42:44 2006
New Revision: 32858

Modified:
   pypy/dist/pypy/objspace/flow/model.py
   pypy/dist/pypy/translator/tool/graphpage.py
   pypy/dist/pypy/translator/tool/make_dot.py
Log:
(arre, arigo, pedronis not too far)

Make graph display robust against broken graphs.


Modified: pypy/dist/pypy/objspace/flow/model.py
==============================================================================
--- pypy/dist/pypy/objspace/flow/model.py	(original)
+++ pypy/dist/pypy/objspace/flow/model.py	Tue Oct  3 19:42:44 2006
@@ -702,3 +702,31 @@
             if op.opname != 'same_as':
                 insns[op.opname] = insns.get(op.opname, 0) + 1
     return insns
+
+def safe_iterblocks(graph):
+    # for debugging or displaying broken graphs.
+    # You still have to check that the yielded blocks are really Blocks.
+    block = getattr(graph, 'startblock', None)
+    yield block
+    seen = {block: True}
+    stack = list(getattr(block, 'exits', [])[::-1])
+    while stack:
+        block = stack.pop().target
+        if block not in seen:
+            yield block
+            seen[block] = True
+            stack += getattr(block, 'exits', [])[::-1]
+
+def safe_iterlinks(graph):
+    # for debugging or displaying broken graphs.
+    # You still have to check that the yielded links are really Links.
+    block = getattr(graph, 'startblock', None)
+    seen = {block: True}
+    stack = list(getattr(block, 'exits', [])[::-1])
+    while stack:
+        link = stack.pop()
+        yield link
+        block = getattr(link, 'target', None)
+        if block not in seen:
+            seen[block] = True
+            stack += getattr(block, 'exits', [])[::-1]

Modified: pypy/dist/pypy/translator/tool/graphpage.py
==============================================================================
--- pypy/dist/pypy/translator/tool/graphpage.py	(original)
+++ pypy/dist/pypy/translator/tool/graphpage.py	Tue Oct  3 19:42:44 2006
@@ -1,5 +1,6 @@
 import inspect, types
-from pypy.objspace.flow.model import traverse, Block, Link, FunctionGraph
+from pypy.objspace.flow.model import Block, Link, FunctionGraph
+from pypy.objspace.flow.model import safe_iterblocks, safe_iterlinks
 from pypy.translator.tool.make_dot import DotGen, make_dot, make_dot_graphs
 from pypy.annotation.model import SomePBC
 from pypy.annotation.description import MethodDesc
@@ -150,24 +151,23 @@
         if isinstance(self.annotator, HintAnnotator):
             return
 
-        def visit(node):
-            if isinstance(node, Block):
-                vars = node.getvariables()
-            elif isinstance(node, Link):
-                vars = node.getextravars()
-            else:
-                return
-            for var in vars:
-                if hasattr(var, 'concretetype'):
-                    #info = self.links.get(var.name, var.name)
-                    #info = '(%s) %s' % (var.concretetype, info)
-                    info = str(var.concretetype)
-                    if info == 'Void':     # gray out Void variables
-                        info = info, (160,160,160)
-                    self.links[var.name] = info
-
-        for graph in graphs:
-            traverse(visit, graph)
+        vars = {}
+        for block in safe_iterblocks(graph):
+            if isinstance(block, Block):
+                for v in block.getvariables():
+                    vars[v] = True
+        for link in safe_iterlinks(graph):
+            if isinstance(link, Link):
+                for v in link.getextravars():
+                    vars[v] = True
+        for var in vars:
+            if hasattr(var, 'concretetype'):
+                #info = self.links.get(var.name, var.name)
+                #info = '(%s) %s' % (var.concretetype, info)
+                info = str(var.concretetype)
+                if info == 'Void':     # gray out Void variables
+                    info = info, (160,160,160)
+                self.links[var.name] = info
 
     def followlink(self, varname):
         # clicking on a variable name shows its binding history

Modified: pypy/dist/pypy/translator/tool/make_dot.py
==============================================================================
--- pypy/dist/pypy/translator/tool/make_dot.py	(original)
+++ pypy/dist/pypy/translator/tool/make_dot.py	Tue Oct  3 19:42:44 2006
@@ -87,7 +87,7 @@
         self.prefix = name
         self.enter_subgraph(name)
         self.visit_FunctionGraph(node)
-        for block in node.iterblocks():
+        for block in safe_iterblocks(node):
             self.visit_Block(block)
         self.leave_subgraph()
 
@@ -121,6 +121,11 @@
     def visit_Block(self, block):
         # do the block itself
         name = self.blockname(block)
+        if not isinstance(block, Block):
+            data = "BROKEN BLOCK\\n%r" % (block,)
+            self.emit_node(name, label=data)
+            return
+            
         lines = []
         for op in block.operations:
             lines.extend(repr(op).split('\n'))



More information about the Pypy-commit mailing list