[pypy-svn] r12917 - in pypy/dist/pypy/rpython: . test

arigo at codespeak.net arigo at codespeak.net
Tue May 31 14:12:47 CEST 2005


Author: arigo
Date: Tue May 31 14:12:46 2005
New Revision: 12917

Modified:
   pypy/dist/pypy/rpython/rbuiltin.py
   pypy/dist/pypy/rpython/robject.py
   pypy/dist/pypy/rpython/rtyper.py
   pypy/dist/pypy/rpython/test/test_rtyper.py
Log:
Debugging help for the rtyper:

- try hard to raise a TyperError when there is a problem

- TyperErrors no longer interrupt the whole process,
  but are recorded as a 'TYPER ERROR' operation in the
  graph for inspection

- the first TyperError is re-raised at the end.


Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Tue May 31 14:12:46 2005
@@ -19,12 +19,20 @@
         if s_blt.s_self is None:
             if not s_blt.is_constant():
                 raise TyperError("non-constant built-in")
-            bltintyper = BUILTIN_TYPER[s_blt.const]
+            try:
+                bltintyper = BUILTIN_TYPER[s_blt.const]
+            except KeyError:
+                raise TyperError("don't know about built-in function %r" % (
+                    s_blt.const,))
             hop.s_popfirstarg()
         else:
             # methods: look up the rtype_method_xxx()
             name = 'rtype_method_' + s_blt.methodname
-            bltintyper = getattr(s_blt.s_self, name)
+            try:
+                bltintyper = getattr(s_blt.s_self, name)
+            except AttributeError:
+                raise TyperError("missing %s.%s" % (
+                    s_blt.s_self.__class__.__name__, name))
         return bltintyper(hop)
 
 

Modified: pypy/dist/pypy/rpython/robject.py
==============================================================================
--- pypy/dist/pypy/rpython/robject.py	(original)
+++ pypy/dist/pypy/rpython/robject.py	Tue May 31 14:12:46 2005
@@ -1,5 +1,6 @@
 from pypy.annotation.pairtype import pair, pairtype
 from pypy.annotation.model import SomeObject, annotation_to_lltype
+from pypy.annotation import model as annmodel
 from pypy.rpython.lltype import PyObject, GcPtr, Void
 from pypy.rpython.rtyper import TyperError
 
@@ -7,6 +8,17 @@
 PyObjPtr = GcPtr(PyObject)
 
 
+def missing_rtype_operation(args, hop):
+    raise TyperError("unimplemented operation: '%s' on %r" % (
+        hop.spaceop.opname, args))
+
+for opname in annmodel.UNARY_OPERATIONS:
+    setattr(SomeObject, 'rtype_' + opname, missing_rtype_operation)
+for opname in annmodel.BINARY_OPERATIONS:
+    setattr(pairtype(SomeObject, SomeObject),
+            'rtype_' + opname, missing_rtype_operation)
+
+
 class __extend__(SomeObject):
 
     def lowleveltype(s_obj):

Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py	(original)
+++ pypy/dist/pypy/rpython/rtyper.py	Tue May 31 14:12:46 2005
@@ -1,3 +1,4 @@
+import sys
 from pypy.annotation.pairtype import pair
 from pypy.annotation import model as annmodel
 from pypy.objspace.flow.model import Variable, Constant, Block, Link
@@ -25,6 +26,7 @@
     def __init__(self, annotator):
         self.annotator = annotator
         self.specialized_ll_functions = {}
+        self.typererror = None
 
     def specialize(self):
         """Main entry point: specialize all annotated blocks of the program."""
@@ -38,6 +40,11 @@
                 already_seen[block] = True
             pending = [block for block in self.annotator.annotated
                              if block not in already_seen]
+        if self.typererror:
+            exc, value, tb = self.typererror
+            self.typererror = None
+            #self.annotator.translator.view()
+            raise exc, value, tb
 
     def setconcretetype(self, v):
         assert isinstance(v, Variable)
@@ -60,8 +67,7 @@
                 hop = HighLevelOp(self, op, newops)
                 self.translate_hl_to_ll(hop, varmapping)
             except TyperError, e:
-                e.where = (block, op)
-                raise
+                self.gottypererror(e, block, op, newops)
 
         block.operations[:] = newops
         # multiple renamings (v1->v2->v3->...) are possible
@@ -80,40 +86,41 @@
         # insert the needed conversions on the links
         can_insert_here = block.exitswitch is None and len(block.exits) == 1
         for link in block.exits:
-            try:
-                for i in range(len(link.args)):
-                    a1 = link.args[i]
-                    ##if a1 in (link.last_exception, link.last_exc_value):# treated specially in gen_link
-                    ##    continue
-                    a2 = link.target.inputargs[i]
-                    s_a2 = self.annotator.binding(a2)
-                    if isinstance(a1, Constant):
-                        link.args[i] = inputconst(s_a2.lowleveltype(), a1.value)
-                        continue   # the Constant was typed, done
-                    s_a1 = self.annotator.binding(a1)
-                    if s_a1 == s_a2:
-                        continue   # no conversion needed
-                    newops = LowLevelOpList(self)
+            for i in range(len(link.args)):
+                a1 = link.args[i]
+                ##if a1 in (link.last_exception, link.last_exc_value):# treated specially in gen_link
+                ##    continue
+                a2 = link.target.inputargs[i]
+                s_a2 = self.annotator.binding(a2)
+                if isinstance(a1, Constant):
+                    link.args[i] = inputconst(s_a2.lowleveltype(), a1.value)
+                    continue   # the Constant was typed, done
+                s_a1 = self.annotator.binding(a1)
+                if s_a1 == s_a2:
+                    continue   # no conversion needed
+                newops = LowLevelOpList(self)
+                try:
                     a1 = newops.convertvar(a1, s_a1, s_a2)
-                    if newops and not can_insert_here:
-                        # cannot insert conversion operations around a single
-                        # link, unless it is the only exit of this block.
-                        # create a new block along the link...
-                        newblock = insert_empty_block(self.annotator.translator,
-                                                      link)
-                        # ...and do the conversions there.
-                        self.insert_link_conversions(newblock)
-                        break   # done with this link
-                    else:
-                        block.operations.extend(newops)
-                        link.args[i] = a1
-            except TyperError, e:
-                e.where = (block, link)
-                raise
+                except TyperError, e:
+                    self.gottypererror(e, block, link, newops)
+
+                if newops and not can_insert_here:
+                    # cannot insert conversion operations around a single
+                    # link, unless it is the only exit of this block.
+                    # create a new block along the link...
+                    newblock = insert_empty_block(self.annotator.translator,
+                                                  link)
+                    # ...and do the conversions there.
+                    self.insert_link_conversions(newblock)
+                    break   # done with this link
+                else:
+                    block.operations.extend(newops)
+                    link.args[i] = a1
 
     def translate_hl_to_ll(self, hop, varmapping):
         op = hop.spaceop
-        translate_meth = getattr(self, 'translate_op_'+op.opname)
+        translate_meth = getattr(self, 'translate_op_'+op.opname,
+                                 self.missing_operation)
         resultvar = translate_meth(hop)
         if resultvar is None:
             # no return value
@@ -146,6 +153,16 @@
                     resultvar.value, hop.s_result.const))
             op.result.concretetype = hop.s_result.lowleveltype()
 
+    def gottypererror(self, e, block, position, llops):
+        """Record a TyperError without crashing immediately.
+        Put a 'TyperError' operation in the graph instead.
+        """
+        e.where = (block, position)
+        if self.typererror is None:
+            self.typererror = sys.exc_info()
+        c1 = inputconst(Void, Exception.__str__(e))
+        llops.genop('TYPER ERROR', [c1], resulttype=Void)
+
     # __________ regular operations __________
 
     def _registeroperations(loc):
@@ -173,6 +190,9 @@
     def translate_op_newlist(self, hop):
         return rlist.rtype_newlist(hop)
 
+    def missing_operation(self, hop):
+        raise TyperError("unimplemented operation: '%s'" % hop.spaceop.opname)
+
     # __________ utilities __________
 
     def getfunctionptr(self, func):

Modified: pypy/dist/pypy/rpython/test/test_rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rtyper.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rtyper.py	Tue May 31 14:12:46 2005
@@ -1,3 +1,4 @@
+from pypy.annotation import model as annmodel
 from pypy.translator.translator import Translator
 from pypy.rpython.lltype import *
 from pypy.rpython.rtyper import RPythonTyper



More information about the Pypy-commit mailing list