[pypy-svn] rev 2213 - in pypy/trunk/src/pypy: objspace/flow translator

arigo at codespeak.net arigo at codespeak.net
Tue Nov 18 01:03:42 CET 2003


Author: arigo
Date: Tue Nov 18 01:03:41 2003
New Revision: 2213

Modified:
   pypy/trunk/src/pypy/objspace/flow/flowcontext.py
   pypy/trunk/src/pypy/objspace/flow/model.py
   pypy/trunk/src/pypy/translator/annheap.py
   pypy/trunk/src/pypy/translator/annrpython.py
   pypy/trunk/src/pypy/translator/gencl.py
   pypy/trunk/src/pypy/translator/genpyrex.py
Log:
Replaced the hack for uninitialized local variables with its official
equivalent, the 'nothingyet' XCell.  This solves a few type annotation
problems.  For example, all variables of snippet.time_waster() with no
exception are now successfully annotated as ints.


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	Tue Nov 18 01:03:41 2003
@@ -70,8 +70,7 @@
         self.w_globals = w_globals = space.wrap(globals)
         frame = code.create_frame(space, w_globals)
         formalargcount = code.getformalargcount()
-        dummy = Constant(None)
-        dummy.dummy = True
+        dummy = UndefinedConstant()
         arg_list = ([Variable() for i in range(formalargcount)] +
                     [dummy] * (len(frame.fastlocals_w) - formalargcount))
         frame.setfastscope(arg_list)

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	Tue Nov 18 01:03:41 2003
@@ -75,7 +75,7 @@
         self.value = value     # a concrete value
 
     def __eq__(self, other):
-        return isinstance(other, Constant) and self.value == other.value
+        return self.__class__ is other.__class__ and self.value == other.value
 
     def __ne__(self, other):
         return not (self == other)
@@ -86,6 +86,11 @@
     def __repr__(self):
         return '%r' % (self.value,)
 
+class UndefinedConstant(Constant):
+    # for local variables not defined yet.
+    def __init__(self):
+        Constant.__init__(self, None)
+
 class SpaceOperation:
     def __init__(self, opname, args, result): 
         self.opname = opname      # operation name

Modified: pypy/trunk/src/pypy/translator/annheap.py
==============================================================================
--- pypy/trunk/src/pypy/translator/annheap.py	(original)
+++ pypy/trunk/src/pypy/translator/annheap.py	Tue Nov 18 01:03:41 2003
@@ -1,4 +1,5 @@
 from __future__ import generators
+import types
 from annotation import Annotation, XCell, XConstant, nothingyet
 
 
@@ -64,9 +65,10 @@
         elif oldcell is nothingyet:
             return newcell
         else:
+            # any annotation or "constantness" about oldcell that must be killed?
+            deleting = isinstance(oldcell, XConstant)
             # find the annotations common to oldcell and newcell
             common = []
-            deleting = []  # annotations about oldcell that must be killed
             for ann in self.annlist:
                 if oldcell in ann.args or oldcell == ann.result:
                     test1 = rename(ann, oldcell, newcell)
@@ -74,7 +76,7 @@
                     if test1 in self.annlist and test2 in self.annlist:
                         common.append(test1)
                     else:
-                        deleting.append(test1)
+                        deleting = True
             # the involved objects are immutable if we have both
             # 'immutable() -> oldcell' and 'immutable() -> newcell'
             if Annotation('immutable', [], newcell) in common:
@@ -170,7 +172,19 @@
     def set_type(self, cell, type):
         """Register an annotation describing the type of the object 'cell'."""
         self.set('type', [cell], XConstant(type))
+        if type in immutable_types:
+            self.set('immutable', [], cell)
 
     def using(self, ann):
         """Mark 'ann' as used in this transaction."""
         self.using_annotations.append(ann)
+
+
+immutable_types = {
+    int: True,
+    long: True,
+    tuple: True,
+    str: True,
+    bool: True,
+    types.FunctionType: True,
+    }

Modified: pypy/trunk/src/pypy/translator/annrpython.py
==============================================================================
--- pypy/trunk/src/pypy/translator/annrpython.py	(original)
+++ pypy/trunk/src/pypy/translator/annrpython.py	Tue Nov 18 01:03:41 2003
@@ -1,8 +1,10 @@
 from __future__ import generators
 
 from pypy.translator.annheap import AnnotationHeap, Transaction
-from pypy.translator.annotation import XCell, XConstant, Annotation
-from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
+from pypy.translator.annotation import XCell, XConstant, nothingyet
+from pypy.translator.annotation import Annotation
+from pypy.objspace.flow.model import Variable, Constant, UndefinedConstant
+from pypy.objspace.flow.model import SpaceOperation
 
 
 class RPythonAnnotator:
@@ -58,8 +60,11 @@
         except KeyError:
             if not isinstance(arg, Constant):
                 raise   # propagate missing bindings for Variables
-            result = XConstant(arg.value)
-            self.consider_const(result, arg)
+            if isinstance(arg, UndefinedConstant):
+                result = nothingyet  # undefined local variables
+            else:
+                result = XConstant(arg.value)
+                self.consider_const(result, arg)
             self.bindings[arg] = result
             return result
 
@@ -131,23 +136,26 @@
     #___ flowing annotations in blocks _____________________
 
     def processblock(self, block, cells):
+        #print '* processblock', block, cells
         if block not in self.annotated:
             self.annotated[block] = True
             self.flowin(block, cells)
         else:
             # already seen; merge each of the block's input variable
+            oldcells = []
             newcells = []
-            reflow = False
             for a, cell2 in zip(block.inputargs, cells):
                 cell1 = self.bindings[a]   # old binding
-                newcell = self.heap.merge(cell1, cell2)
-                newcells.append(newcell)
-                reflow = reflow or (newcell != cell1 and newcell != cell2)
-            # no need to re-flowin unless there is a completely new cell
-            if reflow:
+                oldcells.append(cell1)
+                newcells.append(self.heap.merge(cell1, cell2))
+            #print '** oldcells = ', oldcells
+            #print '** newcells = ', newcells
+            # re-flowin unless the newcells are equal to the oldcells
+            if newcells != oldcells:
                 self.flowin(block, newcells)
 
     def flowin(self, block, inputcells):
+        #print '...'
         for a, cell in zip(block.inputargs, inputcells):
             self.bindings[a] = cell
         for op in block.operations:
@@ -239,8 +247,6 @@
     def consider_const(self,to_var,const):
         t = self.transaction()
         t.set('immutable', [], to_var)
-        if getattr(const, 'dummy', False):
-            return   # undefined local variables
         t.set_type(to_var,type(const.value))
         if isinstance(const.value, list):
             pass # XXX say something about the type of the elements

Modified: pypy/trunk/src/pypy/translator/gencl.py
==============================================================================
--- pypy/trunk/src/pypy/translator/gencl.py	(original)
+++ pypy/trunk/src/pypy/translator/gencl.py	Tue Nov 18 01:03:41 2003
@@ -270,10 +270,9 @@
         source = link.args
         target = link.target.inputargs
         print "(psetq", # parallel assignment
-        for item in zip(source, target):
-            init, var = map(self.str, item)
-            if var != init:
-                print var, init,
+        for s, t in zip(source, target):
+            if s != t and not isinstance(s, UndefinedConstant):
+                print self.str(t), self.str(s),
         print ")"
         self.emit_jump(link.target)
     typemap = {

Modified: pypy/trunk/src/pypy/translator/genpyrex.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genpyrex.py	(original)
+++ pypy/trunk/src/pypy/translator/genpyrex.py	Tue Nov 18 01:03:41 2003
@@ -3,7 +3,7 @@
 
 """
 from pypy.interpreter.baseobjspace import ObjSpace
-from pypy.objspace.flow.model import Variable, Constant
+from pypy.objspace.flow.model import Variable, Constant, UndefinedConstant
 from pypy.objspace.flow.model import mkentrymap
 from pypy.translator.annrpython import RPythonAnnotator
 
@@ -292,16 +292,18 @@
     def gen_link(self, prevblock, link):
         _str = self._str
         block = link.target
-        sourceargs = [_str(arg, prevblock) for arg in link.args]
-        targetargs = [_str(arg, block) for arg in block.inputargs]
+        sourceargs = link.args
+        targetargs = block.inputargs
         assert len(sourceargs) == len(targetargs)
-        # get rid of identity-assignments
+        # get rid of identity-assignments and assignments of UndefinedConstant
         sargs, targs = [], []
         for s,t in zip(sourceargs, targetargs):
-            if s != t:
+            if s != t and not isinstance(s, UndefinedConstant):
                 sargs.append(s)
                 targs.append(t)
         if sargs:
+            sargs = [_str(arg, prevblock) for arg in sargs]
+            targs = [_str(arg, block) for arg in targs]
             self.putline("%s = %s" % (", ".join(targs), ", ".join(sargs)))
 
         self.gen_block(block)


More information about the Pypy-commit mailing list