[pypy-svn] r6893 - in pypy/trunk/src/pypy: objspace objspace/flow objspace/std objspace/std/test translator translator/tool translator/tool/pygame

arigo at codespeak.net arigo at codespeak.net
Sun Oct 10 19:41:48 CEST 2004


Author: arigo
Date: Sun Oct 10 19:41:45 2004
New Revision: 6893

Modified:
   pypy/trunk/src/pypy/objspace/flow/flowcontext.py
   pypy/trunk/src/pypy/objspace/flow/model.py
   pypy/trunk/src/pypy/objspace/flow/objspace.py
   pypy/trunk/src/pypy/objspace/std/fake.py
   pypy/trunk/src/pypy/objspace/std/test/test_intobject.py
   pypy/trunk/src/pypy/objspace/std/test/test_unicodestring.py
   pypy/trunk/src/pypy/objspace/trace.py
   pypy/trunk/src/pypy/translator/genc.h
   pypy/trunk/src/pypy/translator/genc.py
   pypy/trunk/src/pypy/translator/simplify.py
   pypy/trunk/src/pypy/translator/tool/buildcl.py
   pypy/trunk/src/pypy/translator/tool/pygame/drawgraph.py
   pypy/trunk/src/pypy/translator/tool/pygame/flowviewer.py
   pypy/trunk/src/pypy/translator/transform.py
   pypy/trunk/src/pypy/translator/translator.py
Log:
Lots of small changes to lots of files: trying to get Python 2.2 to work
again.  Some tests still fail.  Not sure if it's worth the effort...

Also contains a new checkgraph() that checks various invariants of flow
graphs, e.g. that variables are used consistently and never in more than one
block.  Graphs now have a method show() to view them using the pygame code,
which is handy to figure out what's really wrong with a graph when an
assertion in checkgraph() fails.



Modified: pypy/trunk/src/pypy/objspace/flow/flowcontext.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/flow/flowcontext.py	(original)
+++ pypy/trunk/src/pypy/objspace/flow/flowcontext.py	Sun Oct 10 19:41:45 2004
@@ -139,6 +139,7 @@
                 # directly at the new block which is its generalization
                 block.dead = True
                 block.operations = ()
+                block.exitswitch = None
                 outputargs = block.framestate.getoutputargs(newstate)
                 block.recloseblock(Link(outputargs, newblock))
             newblock.patchframe(frame, self)

Modified: pypy/trunk/src/pypy/objspace/flow/model.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/flow/model.py	(original)
+++ pypy/trunk/src/pypy/objspace/flow/model.py	Sun Oct 10 19:41:45 2004
@@ -32,6 +32,10 @@
             block.exits      = ()
         return block
 
+    def show(self):
+        from pypy.translator.tool.pygame.flowviewer import SingleGraphLayout
+        SingleGraphLayout(self).display()
+
 class Link:
     def __init__(self, args, target, exitcase=None):
         assert len(args) == len(target.inputargs), "output args mismatch"
@@ -225,3 +229,46 @@
             lst.append(link)
     traverse(visit, funcgraph)
     return result
+
+def checkgraph(graph):
+    "Check the consistency of a flow graph."
+    if __debug__:
+        exitblocks = [graph.returnblock] + graph.exceptblocks.values()
+        for block in exitblocks:
+            assert len(block.inputargs) == 1
+            assert not block.operations
+            assert not block.exits
+
+        vars_previous_blocks = {}
+
+        def visit(node):
+            if isinstance(node, Block):
+                assert bool(node.isstartblock) == (node is graph.startblock)
+                if not node.exits:
+                    assert node in exitblocks
+                vars = {}
+                for v in node.inputargs + [op.result for op in node.operations]:
+                    assert isinstance(v, Variable)
+                    assert v not in vars, "duplicate variable %r" % (v,)
+                    assert v not in vars_previous_blocks, (
+                        "variable %r used in more than one block" % (v,))
+                    vars[v] = True
+                for op in node.operations:
+                    for v in op.args:
+                        assert isinstance(v, (Constant, Variable))
+                        if isinstance(v, Variable):
+                            assert v in vars
+                if node.exitswitch is not None:
+                    assert isinstance(node.exitswitch, (Constant, Variable))
+                    if isinstance(node.exitswitch, Variable):
+                        assert node.exitswitch in vars
+                for link in node.exits:
+                    assert len(link.args) == len(link.target.inputargs)
+                    assert link.prevblock is node
+                    for v in link.args:
+                        assert isinstance(v, (Constant, Variable))
+                        if isinstance(v, Variable):
+                            assert v in vars
+                vars_previous_blocks.update(vars)
+
+        traverse(visit, graph)

Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/flow/objspace.py	(original)
+++ pypy/trunk/src/pypy/objspace/flow/objspace.py	Sun Oct 10 19:41:45 2004
@@ -122,6 +122,7 @@
         for c in "<>&!":
             name = name.replace(c, '_')
         ec.graph.name = name
+        checkgraph(ec.graph)
         return ec.graph
 
     def unpacktuple(self, w_tuple, expected_length=None):

Modified: pypy/trunk/src/pypy/objspace/std/fake.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/fake.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/fake.py	Sun Oct 10 19:41:45 2004
@@ -60,10 +60,13 @@
         def __init__(w_self, space, val):
             W_Object.__init__(w_self, space)
             w_self.val = val
+    # cannot write to W_Fake.__name__ in Python 2.2!
+    W_Fake = type(W_Object)('W_Fake%s'%(cpy_type.__name__.capitalize()),
+                            (W_Object,),
+                            dict(W_Fake.__dict__.items()))
     def fake_unwrap(space, w_obj):
         return w_obj.val
     StdObjSpace.unwrap.register(fake_unwrap, W_Fake)
-    W_Fake.__name__ = 'W_Fake%s'%(cpy_type.__name__.capitalize())
     W_Fake.typedef.fakedcpytype = cpy_type
     _fake_type_cache[cpy_type] = W_Fake
     return W_Fake

Modified: pypy/trunk/src/pypy/objspace/std/test/test_intobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/test/test_intobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/test/test_intobject.py	Sun Oct 10 19:41:45 2004
@@ -294,7 +294,7 @@
 
     def test_int_string(self):
         self.assertEquals(42, int("42"))
-        self.assertEquals(10000000000, int("10000000000"))
+        self.assertEquals(10000000000, long("10000000000"))
 
     def test_int_float(self):
         self.assertEquals(4, int(4.2))

Modified: pypy/trunk/src/pypy/objspace/std/test/test_unicodestring.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/test/test_unicodestring.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/test/test_unicodestring.py	Sun Oct 10 19:41:45 2004
@@ -1,7 +1,7 @@
 # test the integration of unicode and strings (even though we don't
 # really implement unicode yet).
 
-import autopath
+import autopath, sys
 from pypy.tool import testit
 
 
@@ -31,8 +31,13 @@
         check(', '.join(['a', u'b']), u'a, b')
         check(u', '.join(['a', 'b']), u'a, b')
 
+    if sys.version_info >= (2,3):
+        def test_contains_ex(self):
+            self.failUnless(u'' in 'abc')
+            self.failUnless(u'bc' in 'abc')
+            self.failUnless('bc' in 'abc')
+
     def test_contains(self):
-        self.failUnless(u'' in 'abc')
         self.failUnless(u'a' in 'abc')
         self.failUnless('a' in u'abc')
         

Modified: pypy/trunk/src/pypy/objspace/trace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/trace.py	(original)
+++ pypy/trunk/src/pypy/objspace/trace.py	Sun Oct 10 19:41:45 2004
@@ -4,6 +4,7 @@
 
 """
 
+from __future__ import generators
 from pypy.tool import pydis 
 from pypy.interpreter.baseobjspace import ObjSpace
 

Modified: pypy/trunk/src/pypy/translator/genc.h
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.h	(original)
+++ pypy/trunk/src/pypy/translator/genc.h	Sun Oct 10 19:41:45 2004
@@ -67,8 +67,8 @@
 #define OP_INPLACE_XOR(x,y,r,err)    if (!(r=PyNumber_InPlaceXor(x,y)))        \
 								     goto err;
 
-#define OP_GETITEM(x,y,r,err)     if (!(r=PyObject_GetItem(x,y)))    goto err;
-#define OP_SETITEM(x,y,z,r,err)   if ((PyObject_SetItem(x,y,z))<0)   goto err; \
+#define OP_GETITEM(x,y,r,err)     if (!(r=PyObject_GetItem1(x,y)))   goto err;
+#define OP_SETITEM(x,y,z,r,err)   if ((PyObject_SetItem1(x,y,z))<0)  goto err; \
 				  r=Py_None; Py_INCREF(r);
 
 #define OP_GETATTR(x,y,r,err)     if (!(r=PyObject_GetAttr(x,y)))    goto err;
@@ -211,6 +211,73 @@
 }
 #endif
 
+#if PY_VERSION_HEX >= 0x02030000   /* 2.3 */
+# define PyObject_GetItem1  PyObject_GetItem
+# define PyObject_SetItem1  PyObject_SetItem
+#else
+/* for Python 2.2 only */
+static PyObject* PyObject_GetItem1(PyObject* obj, PyObject* index)
+{
+  int start, stop, step;
+  if (!PySlice_Check(index))
+    return PyObject_GetItem(obj, index);
+  if (((PySliceObject*) index)->start == Py_None)
+    start = -INT_MAX-1;
+  else
+    {
+      start = PyInt_AsLong(((PySliceObject*) index)->start);
+      if (start == -1 && PyErr_Occurred()) return NULL;
+    }
+  if (((PySliceObject*) index)->stop == Py_None)
+    stop = INT_MAX;
+  else
+    {
+      stop = PyInt_AsLong(((PySliceObject*) index)->stop);
+      if (stop == -1 && PyErr_Occurred()) return NULL;
+    }
+  if (((PySliceObject*) index)->step != Py_None)
+    {
+      step = PyInt_AsLong(((PySliceObject*) index)->step);
+      if (step == -1 && PyErr_Occurred()) return NULL;
+      if (step != 1) {
+        PyErr_SetString(PyExc_ValueError, "obj[slice]: no step allowed");
+        return NULL;
+      }
+    }
+  return PySequence_GetSlice(obj, start, stop);
+}
+static PyObject* PyObject_SetItem1(PyObject* obj, PyObject* index, PyObject* v)
+{
+  int start, stop, step;
+  if (!PySlice_Check(index))
+    return PyObject_SetItem(obj, index, v);
+  if (((PySliceObject*) index)->start == Py_None)
+    start = -INT_MAX-1;
+  else
+    {
+      start = PyInt_AsLong(((PySliceObject*) index)->start);
+      if (start == -1 && PyErr_Occurred()) return NULL;
+    }
+  if (((PySliceObject*) index)->stop == Py_None)
+    stop = INT_MAX;
+  else
+    {
+      stop = PyInt_AsLong(((PySliceObject*) index)->stop);
+      if (stop == -1 && PyErr_Occurred()) return NULL;
+    }
+  if (((PySliceObject*) index)->step != Py_None)
+    {
+      step = PyInt_AsLong(((PySliceObject*) index)->step);
+      if (step == -1 && PyErr_Occurred()) return NULL;
+      if (step != 1) {
+        PyErr_SetString(PyExc_ValueError, "obj[slice]: no step allowed");
+        return NULL;
+      }
+    }
+  return PySequence_SetSlice(obj, start, stop, v);
+}
+#endif
+
 
 /************************************************************/
  /***  The rest is produced by genc.py                     ***/

Modified: pypy/trunk/src/pypy/translator/genc.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.py	(original)
+++ pypy/trunk/src/pypy/translator/genc.py	Sun Oct 10 19:41:45 2004
@@ -6,7 +6,8 @@
 import autopath, os
 from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
 from pypy.objspace.flow.model import FunctionGraph, Block, Link
-from pypy.objspace.flow.model import traverse, uniqueitems
+from pypy.objspace.flow.model import traverse, uniqueitems, checkgraph
+from pypy.translator.simplify import remove_direct_loops
 
 # ____________________________________________________________
 
@@ -134,6 +135,8 @@
         self.initcode.extend(lines)
         return name
 
+    nameof_class = nameof_classobj   # for Python 2.2
+
     def nameof_type(self, cls):
         assert hasattr(cls, '__weakref__'), (
             "%r is not a user-defined class" % (cls,))
@@ -227,6 +230,9 @@
 
     def cfunction_body(self, func):
         graph = self.translator.getflowgraph(func)
+        remove_direct_loops(graph)
+        checkgraph(graph)
+
         blocknum = {}
         allblocks = []
 
@@ -315,9 +321,10 @@
 
     C_INIT_HEADER = C_SEP + '''
 
+static PyMethodDef no_methods[] = { NULL, NULL };
 void init%(modname)s(void)
 {
-\tPyObject* m = Py_InitModule("%(modname)s", NULL);
+\tPyObject* m = Py_InitModule("%(modname)s", no_methods);
 \tSETUP_MODULE
 '''
 

Modified: pypy/trunk/src/pypy/translator/simplify.py
==============================================================================
--- pypy/trunk/src/pypy/translator/simplify.py	(original)
+++ pypy/trunk/src/pypy/translator/simplify.py	Sun Oct 10 19:41:45 2004
@@ -81,9 +81,11 @@
 
 def simplify_graph(graph):
     """Apply all the existing optimisations to the graph."""
+    checkgraph(graph)
     eliminate_empty_blocks(graph)
     remove_implicit_exceptions(graph)
     join_blocks(graph)
+    checkgraph(graph)
     return graph
 
 

Modified: pypy/trunk/src/pypy/translator/tool/buildcl.py
==============================================================================
--- pypy/trunk/src/pypy/translator/tool/buildcl.py	(original)
+++ pypy/trunk/src/pypy/translator/tool/buildcl.py	Sun Oct 10 19:41:45 2004
@@ -36,12 +36,6 @@
             content = "'" + content # quote Lisp list
         return content
 
-# for test
-# ultimately, GenCL's str and conv will move to here
-def f(): pass
-fun = FlowObjSpace().build_flow(f)
-gen = GenCL(fun)
-
 def _make_cl_func(func, cl, path, argtypes=[]):
     fun = FlowObjSpace().build_flow(func)
     gen = GenCL(fun, argtypes)
@@ -61,6 +55,12 @@
     return _
 
 if __name__ == '__main__':
+    # for test
+    # ultimately, GenCL's str and conv will move to here
+    def f(): pass
+    fun = FlowObjSpace().build_flow(f)
+    gen = GenCL(fun)
+
     what = [True, "universe", 42, None, ("of", "them", ["eternal", 95])]
     it = writelisp(gen, what)
     print what

Modified: pypy/trunk/src/pypy/translator/tool/pygame/drawgraph.py
==============================================================================
--- pypy/trunk/src/pypy/translator/tool/pygame/drawgraph.py	(original)
+++ pypy/trunk/src/pypy/translator/tool/pygame/drawgraph.py	Sun Oct 10 19:41:45 2004
@@ -46,6 +46,10 @@
                 break
         self.links = {}
 
+    def display(self):
+        from graphdisplay import GraphDisplay
+        GraphDisplay(self).run()
+
 class Node:
     def __init__(self, name, x, y, w, h, label, style, shape, color, fillcolor):
         self.name = name

Modified: pypy/trunk/src/pypy/translator/tool/pygame/flowviewer.py
==============================================================================
--- pypy/trunk/src/pypy/translator/tool/pygame/flowviewer.py	(original)
+++ pypy/trunk/src/pypy/translator/tool/pygame/flowviewer.py	Sun Oct 10 19:41:45 2004
@@ -6,6 +6,15 @@
 from pypy.annotation import model, factory
 
 
+class SingleGraphLayout(GraphLayout):
+    """ A GraphLayout showing a single precomputed FlowGraph."""
+
+    def __init__(self, graph):
+        from pypy.translator.tool.make_dot import make_dot
+        fn = make_dot(graph.name, graph, target='plain')
+        GraphLayout.__init__(self, fn)
+
+
 class FlowGraphLayout(GraphLayout):
     """ A GraphLayout showing a Flow Graph (or a few flow graphs).
     """

Modified: pypy/trunk/src/pypy/translator/transform.py
==============================================================================
--- pypy/trunk/src/pypy/translator/transform.py	(original)
+++ pypy/trunk/src/pypy/translator/transform.py	Sun Oct 10 19:41:45 2004
@@ -299,9 +299,13 @@
 
 def transform_graph(ann):
     """Apply set of transformations available."""
+    if ann.translator:
+        ann.translator.checkgraphs()
     transform_allocate(ann)
     transform_slice(ann)
     transform_listextend(ann)
     # do this last, after the previous transformations had a
     # chance to remove dependency on certain variables
     transform_dead_op_vars(ann)
+    if ann.translator:
+        ann.translator.checkgraphs()

Modified: pypy/trunk/src/pypy/translator/translator.py
==============================================================================
--- pypy/trunk/src/pypy/translator/translator.py	(original)
+++ pypy/trunk/src/pypy/translator/translator.py	Sun Oct 10 19:41:45 2004
@@ -105,9 +105,8 @@
     def view(self, *functions):
         """Shows the control flow graph with annotations if computed.
         Requires 'dot' and pygame."""
-        from pypy.translator.tool.pygame.graphdisplay import GraphDisplay
         from pypy.translator.tool.pygame.flowviewer import FlowGraphLayout
-        GraphDisplay(FlowGraphLayout(self)).run()
+        FlowGraphLayout(self).display()
 
     def simplify(self, func=None):
         """Simplifies the control flow graph (default: for all functions)."""
@@ -130,6 +129,10 @@
         self.annotator.build_types(graph, input_args_types, func)
         return self.annotator
 
+    def checkgraphs(self):
+        for graph in self.flowgraphs.itervalues():
+            checkgraph(graph)
+
     def source(self, func=None):
         """Returns original Python source.
         



More information about the Pypy-commit mailing list