[pypy-svn] r11546 - in pypy/dist/pypy: annotation translator

tismer at codespeak.net tismer at codespeak.net
Wed Apr 27 21:14:28 CEST 2005


Author: tismer
Date: Wed Apr 27 21:14:28 2005
New Revision: 11546

Modified:
   pypy/dist/pypy/annotation/binaryop.py
   pypy/dist/pypy/translator/annrpython.py
Log:
- added the special attribute "can_only_throw" to
  integer binary operations.

- changed annrpython to respect this attribute
  and to not follow exceptions which cannot happen.
  Both unaryop and binaryop are handled

- need to add more of these. unaryop didn't get any entries,yet.

Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py	(original)
+++ pypy/dist/pypy/annotation/binaryop.py	Wed Apr 27 21:14:28 2005
@@ -147,6 +147,14 @@
     def coerce((obj1, obj2)):
         return pair(obj1, obj2).union()   # reasonable enough
 
+# cloning a function with identical code, for the can_only_throw attribute
+def _clone(f, can_only_throw = None):
+    newfunc = type(f)(f.func_code, f.func_globals, f.func_name,
+                      f.func_defaults, f.func_closure)
+    if can_only_throw is not None:
+        newfunc.can_only_throw = can_only_throw
+    return newfunc
+
 class __extend__(pairtype(SomeInteger, SomeInteger)):
     # unsignedness is considered a rare and contagious disease
 
@@ -156,30 +164,35 @@
                            unsigned=unsigned)
                            
 
-    add = mul = div = floordiv = mod = or_ = xor = union
+    add = mul = or_ = xor = _clone(union, [])
+    div = floordiv = mod = _clone(union, [ZeroDivisionError])
 
     def truediv((int1, int2)):
         return SomeFloat()
+    truediv.can_only_throw = [ZeroDivisionError]
 
     def sub((int1, int2)):
         return SomeInteger(unsigned = int1.unsigned or int2.unsigned)
+    sub.can_only_throw = []
 
     def and_((int1, int2)):
         unsigned = int1.unsigned or int2.unsigned
         return SomeInteger(nonneg = unsigned or int1.nonneg or int2.nonneg,
                            unsigned = unsigned)
+    and_.can_only_throw = []
 
     def lshift((int1, int2)):
         if int1.unsigned:
             return SomeInteger(unsigned=True)
         return SomeInteger()
-
+    lshift.can_only_throw = []
     rshift = lshift
 
     def pow((int1, int2), obj3):
         if int1.unsigned or int2.unsigned or getattr(obj3, 'unsigned', False):
             return SomeInteger(unsigned=True)
         return SomeInteger()
+    pow.can_only_throw = [ZeroDivisionError]
 
 class __extend__(pairtype(SomeBool, SomeBool)):
 

Modified: pypy/dist/pypy/translator/annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/annrpython.py	(original)
+++ pypy/dist/pypy/translator/annrpython.py	Wed Apr 27 21:14:28 2005
@@ -397,6 +397,32 @@
                                   if link.exitcase == s_exitswitch.const]
         knownvars, knownvarvalue = getattr(self.bindings.get(block.exitswitch),
                                           "knowntypedata", (None, None))
+        
+        if block.exitswitch == Constant(last_exception):
+            op = block.operations[-1]
+            if op.opname in annmodel.BINARY_OPERATIONS:
+                arg1 = self.binding(op.args[0])
+                arg2 = self.binding(op.args[1])
+                binop = getattr(pair(arg1, arg2), op.opname, None)
+                can_only_throw = getattr(binop, "can_only_throw", None)
+            elif op.opname in annmodel.UNARY_OPERATIONS:
+                arg1 = self.binding(op.args[0])
+                unop = getattr(arg1, op.opname, None)
+                can_only_throw = getattr(unop, "can_only_throw", None)
+            else:
+                can_only_throw = None
+            if can_only_throw is not None:
+                exits = [link
+                         for link in exits
+                         if link.exitcase is None
+                         or link.exitcase in can_only_throw ]
+                print can_only_throw
+                print exits
+                print len(exits)
+                for link in exits:
+                    print link, link.exitcase
+                print 100*"*"
+
         for link in exits:
             self.links_followed[link] = True
             import types



More information about the Pypy-commit mailing list