[pypy-svn] r12261 - pypy/dist/pypy/annotation

arigo at codespeak.net arigo at codespeak.net
Sat May 14 13:22:05 CEST 2005


Author: arigo
Date: Sat May 14 13:22:04 2005
New Revision: 12261

Modified:
   pypy/dist/pypy/annotation/binaryop.py
   pypy/dist/pypy/annotation/listdef.py
   pypy/dist/pypy/annotation/model.py
Log:
Made SomeObject.contains() robust: now union() methods always raise UnionError
if they fail; in addition, they are not allowed to have side-effects if called
by contains() -- a thread-local hack :-(



Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py	(original)
+++ pypy/dist/pypy/annotation/binaryop.py	Sat May 14 13:22:04 2005
@@ -8,7 +8,7 @@
 from pypy.annotation.model import SomeTuple, SomeImpossibleValue
 from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeIterator
 from pypy.annotation.model import SomePBC, SomeSlice, SomeFloat
-from pypy.annotation.model import unionof, set, setunion, missing_operation
+from pypy.annotation.model import unionof, UnionError, set, missing_operation
 from pypy.annotation.bookkeeper import getbookkeeper
 from pypy.annotation.classdef import isclassdef
 from pypy.objspace.flow.model import Constant
@@ -379,8 +379,7 @@
 
     def union((bltn1, bltn2)):
         if bltn1.analyser != bltn2.analyser:
-            assert False, "merging incompatible builtins == BAD!"
-            return SomeObject()
+            raise UnionError("merging incompatible builtins == BAD!")
         else:
             s_self = unionof(bltn1.s_self, bltn2.s_self)
             return SomeBuiltin(bltn1.analyser, s_self)
@@ -393,7 +392,7 @@
         for x, classdef in pbc2.prebuiltinstances.items():
             if x in d:
                 if bool(isclassdef(classdef)) ^ bool(isclassdef(d[x])):
-                    raise Exception(
+                    raise UnionError(
                         "union failed for %r with classdefs %r and %r" % 
                         (x, classdef, d[x]))
                 if isclassdef(classdef):
@@ -404,9 +403,10 @@
                             if x in cand.cls.__dict__.values():
                                 break
                         else:
-                            assert False, ("confused pbc union trying unwarranted"
-                                           "moving up of method %s from pair %s %s" %
-                                           (x, d[x], classdef2))
+                            raise UnionError(
+                                "confused pbc union trying unwarranted"
+                                "moving up of method %s from pair %s %s" %
+                                (x, d[x], classdef2))
             d[x] = classdef
         result =  SomePBC(d)
         return result

Modified: pypy/dist/pypy/annotation/listdef.py
==============================================================================
--- pypy/dist/pypy/annotation/listdef.py	(original)
+++ pypy/dist/pypy/annotation/listdef.py	Sat May 14 13:22:04 2005
@@ -1,4 +1,5 @@
-from pypy.annotation.model import SomeObject, SomeImpossibleValue, tracking_unionof
+from pypy.annotation.model import SomeObject, SomeImpossibleValue
+from pypy.annotation.model import tracking_unionof, TLS, UnionError
 
 
 class ListItem:
@@ -11,6 +12,8 @@
 
     def merge(self, other):
         if self is not other:
+            if getattr(TLS, 'no_side_effects_in_union', 0):
+                raise UnionError("merging list/dict items")
             self.itemof.update(other.itemof)
             self.read_locations.update(other.read_locations)
             self.patch()    # which should patch all refs to 'other'

Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py	(original)
+++ pypy/dist/pypy/annotation/model.py	Sat May 14 13:22:04 2005
@@ -95,7 +95,19 @@
         return t.__name__
     
     def contains(self, other):
-        return self == other or pair(self, other).union() == self
+        if self == other:
+            return True
+        try:
+            TLS.no_side_effects_in_union += 1
+        except AttributeError:
+            TLS.no_side_effects_in_union = 1
+        try:
+            try:
+                return pair(self, other).union() == self
+            except UnionError:
+                return False
+        finally:
+            TLS.no_side_effects_in_union -= 1
 
     def is_constant(self):
         return hasattr(self, 'const')
@@ -306,6 +318,7 @@
     (SomeInteger(), lltypes.Signed),
     (SomeInteger(nonneg=True, unsigned=True), lltypes.Unsigned),    
     (SomeChar(), lltypes.Char),
+    (SomePBC({None: True}), lltypes.Void),
 ]
 
 def annotation_to_lltype(s_val, info=None):
@@ -336,6 +349,10 @@
 
 # ____________________________________________________________
 
+class UnionError(Exception):
+    """Signals an suspicious attempt at taking the union of
+    deeply incompatible SomeXxx instances."""
+
 def unionof(*somevalues):
     "The most precise SomeValue instance that contains all the values."
     s1 = SomeImpossibleValue()



More information about the Pypy-commit mailing list