[pypy-svn] r50371 - in pypy/branch/astcompilertests/pypy/interpreter/astcompiler: . test

arigo at codespeak.net arigo at codespeak.net
Sun Jan 6 14:00:18 CET 2008


Author: arigo
Date: Sun Jan  6 14:00:17 2008
New Revision: 50371

Modified:
   pypy/branch/astcompilertests/pypy/interpreter/astcompiler/pyassem.py
   pypy/branch/astcompilertests/pypy/interpreter/astcompiler/pycodegen.py
   pypy/branch/astcompilertests/pypy/interpreter/astcompiler/test/test_compiler.py
Log:
* avoid these strange "raise RuntimeError" here and there.
* a test showing a messy problem and a comment at the place
  which is buggy.  Not fixed.


Modified: pypy/branch/astcompilertests/pypy/interpreter/astcompiler/pyassem.py
==============================================================================
--- pypy/branch/astcompilertests/pypy/interpreter/astcompiler/pyassem.py	(original)
+++ pypy/branch/astcompilertests/pypy/interpreter/astcompiler/pyassem.py	Sun Jan  6 14:00:17 2008
@@ -10,6 +10,10 @@
 from pypy.tool import stdlib_opcode as pythonopcode
 from pypy.interpreter.error import OperationError
 
+class InternalCompilerError(Exception):
+    """Something went wrong in the ast compiler."""
+
+
 class BlockSet:
     """A Set implementation specific to Blocks
     it uses Block.bid as keys to underlying dict"""
@@ -285,6 +289,11 @@
                         if index[c.bid] < i:
                             forward_p = 0
                             for inst in b.insts:
+                                # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+                                # other bytecodes need the same logic, but
+                                # trying to do that throws this function into
+                                # an infinite loop.  Sad sad sad.
+                                # XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
                                 if inst.op == 'JUMP_FORWARD':
                                     assert isinstance(inst, InstrBlock)
                                     if inst.block == c:
@@ -494,7 +503,7 @@
             self.makeByteCode()
         if self.stage == DONE:
             return self.newCodeObject()
-        raise RuntimeError, "inconsistent PyFlowGraph state"
+        raise InternalCompilerError("inconsistent PyFlowGraph state")
 
     def dump(self, io=None):
         if io:
@@ -621,6 +630,8 @@
             abspos = begin[block]
             if opname in self.hasjrel:
                 offset = abspos - pc - 3
+                if offset < 0:
+                    raise InternalCompilerError("unexpected backward jump")
                 inst.intval = offset
             else:
                 inst.intval = abspos
@@ -872,6 +883,7 @@
 def twobyte(val):
     """Convert an int argument into high and low bytes"""
     assert isinstance(val,int)
+    assert 0 <= val < 65536
     hi = val // 256
     lo = val % 256
     return hi, lo

Modified: pypy/branch/astcompilertests/pypy/interpreter/astcompiler/pycodegen.py
==============================================================================
--- pypy/branch/astcompilertests/pypy/interpreter/astcompiler/pycodegen.py	(original)
+++ pypy/branch/astcompilertests/pypy/interpreter/astcompiler/pycodegen.py	Sun Jan  6 14:00:17 2008
@@ -198,7 +198,7 @@
         tree.accept(s)
 
     def get_module(self):
-        raise RuntimeError, "should be implemented by subclasses"
+        raise NotImplementedError("should be implemented by subclasses")
 
     # Next five methods handle name access
     def storeName(self, name, lineno):
@@ -239,8 +239,9 @@
             else:
                 self.emitop(prefix + '_NAME', name)
         else:
-            raise RuntimeError, "unsupported scope for var %s in %s: %d" % \
-                  (name, self.scope.name, scope)
+            raise pyassem.InternalCompilerError(
+                  "unsupported scope for var %s in %s: %d" %
+                  (name, self.scope.name, scope))
 
     def _implicitNameOp(self, prefix, name):
         """Emit name ops for names generated implicitly by for loops
@@ -1567,7 +1568,7 @@
         self.main = main_visitor
 
     def default(self, node):
-        raise RuntimeError("shouldn't arrive here!")
+        raise pyassem.InternalCompilerError("shouldn't arrive here!")
     
     def visitName(self, node ):
         self.main.loadName(node.varname, node.lineno)
@@ -1589,7 +1590,7 @@
         self.main = main_visitor
         
     def default(self, node):
-        raise RuntimeError("shouldn't arrive here!")
+        raise pyassem.InternalCompilerError("shouldn't arrive here!")
     
     def visitName(self, node):
         self.main.storeName(node.varname, node.lineno)

Modified: pypy/branch/astcompilertests/pypy/interpreter/astcompiler/test/test_compiler.py
==============================================================================
--- pypy/branch/astcompilertests/pypy/interpreter/astcompiler/test/test_compiler.py	(original)
+++ pypy/branch/astcompilertests/pypy/interpreter/astcompiler/test/test_compiler.py	Sun Jan  6 14:00:17 2008
@@ -362,3 +362,93 @@
         yield self.st, "x = sum(n+2 for n in (6, 1, 2))", 'x', 15
         yield self.st, "k=2; x = sum(n+2 for n in [6, 1, k])", 'x', 15
         yield self.st, "k=2; x = sum(n+2 for n in (6, 1, k))", 'x', 15
+
+    def test_pprint(self):
+        # a larger example that showed a bug with jumps
+        # over more than 256 bytes
+        decl = py.code.Source("""
+            def _safe_repr(object, context, maxlevels, level):
+                typ = _type(object)
+                if typ is str:
+                    if 'locale' not in _sys.modules:
+                        return repr(object), True, False
+                    if "'" in object and '"' not in object:
+                        closure = '"'
+                        quotes = {'"': '\\"'}
+                    else:
+                        closure = "'"
+                        quotes = {"'": "\\'"}
+                    qget = quotes.get
+                    sio = _StringIO()
+                    write = sio.write
+                    for char in object:
+                        if char.isalpha():
+                            write(char)
+                        else:
+                            write(qget(char, repr(char)[1:-1]))
+                    return ("%s%s%s" % (closure, sio.getvalue(), closure)), True, False
+
+                r = getattr(typ, "__repr__", None)
+                if issubclass(typ, dict) and r is dict.__repr__:
+                    if not object:
+                        return "{}", True, False
+                    objid = _id(object)
+                    if maxlevels and level > maxlevels:
+                        return "{...}", False, objid in context
+                    if objid in context:
+                        return _recursion(object), False, True
+                    context[objid] = 1
+                    readable = True
+                    recursive = False
+                    components = []
+                    append = components.append
+                    level += 1
+                    saferepr = _safe_repr
+                    for k, v in object.iteritems():
+                        krepr, kreadable, krecur = saferepr(k, context, maxlevels, level)
+                        vrepr, vreadable, vrecur = saferepr(v, context, maxlevels, level)
+                        append("%s: %s" % (krepr, vrepr))
+                        readable = readable and kreadable and vreadable
+                        if krecur or vrecur:
+                            recursive = True
+                    del context[objid]
+                    return "{%s}" % _commajoin(components), readable, recursive
+
+                if (issubclass(typ, list) and r is list.__repr__) or \
+                   (issubclass(typ, tuple) and r is tuple.__repr__):
+                    if issubclass(typ, list):
+                        if not object:
+                            return "[]", True, False
+                        format = "[%s]"
+                    elif _len(object) == 1:
+                        format = "(%s,)"
+                    else:
+                        if not object:
+                            return "()", True, False
+                        format = "(%s)"
+                    objid = _id(object)
+                    if maxlevels and level > maxlevels:
+                        return format % "...", False, objid in context
+                    if objid in context:
+                        return _recursion(object), False, True
+                    context[objid] = 1
+                    readable = True
+                    recursive = False
+                    components = []
+                    append = components.append
+                    level += 1
+                    for o in object:
+                        orepr, oreadable, orecur = _safe_repr(o, context, maxlevels, level)
+                        append(orepr)
+                        if not oreadable:
+                            readable = False
+                        if orecur:
+                            recursive = True
+                    del context[objid]
+                    return format % _commajoin(components), readable, recursive
+
+                rep = repr(object)
+                return rep, (rep and not rep.startswith('<')), False
+        """)
+        decl = str(decl) + '\n'
+        yield self.st, decl + 'x=_safe_repr([5], {}, 3, 0)', 'x', '[5]'



More information about the Pypy-commit mailing list