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

arigo at codespeak.net arigo at codespeak.net
Mon Jan 7 23:29:33 CET 2008


Author: arigo
Date: Mon Jan  7 23:29:32 2008
New Revision: 50441

Modified:
   pypy/branch/astcompilertests/pypy/interpreter/astcompiler/pyassem.py
   pypy/branch/astcompilertests/pypy/interpreter/astcompiler/test/test_compiler.py
   pypy/branch/astcompilertests/pypy/interpreter/nestedscope.py
   pypy/branch/astcompilertests/pypy/interpreter/pycode.py
Log:
Fix for cleverness that I forgot from the old pyassem.py.
The fix consists of removing the cleverness and fixing the
interpreter instead; see comments about why I think it's
a good idea.


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	Mon Jan  7 23:29:32 2008
@@ -35,11 +35,6 @@
         # variables used only in nested scopes, are included here.
         self.freevars = []
         self.cellvars = []
-        # The closure list is used to track the order of cell
-        # variables and free variables in the resulting code object.
-        # The offsets used by LOAD_CLOSURE/LOAD_DEREF refer to both
-        # kinds of variables.
-        self.closure = []
         self.varnames = list(argnames)
         # The bytecode we are building, as a list of characters
         self.co_code = []
@@ -143,6 +138,21 @@
         list.append(name)
         return end
 
+    def _lookupClosureName(self, name):
+        """Return index of name in (self.cellvars + self.freevars)
+        """
+        assert isinstance(name, str)
+        list = self.cellvars
+        for i in range(len(list)):
+            if list[i] == name:
+                return i
+        list = self.freevars
+        for i in range(len(list)):
+            if list[i] == name:
+                return len(self.cellvars) + i
+        raise InternalCompilerError("name '%s' not found in cell or free vars"
+                                    % name)
+
     def _convert_LOAD_FAST(self, arg):
         self._lookupName(arg, self.names)
         return self._lookupName(arg, self.varnames)
@@ -166,12 +176,12 @@
 
     def _convert_DEREF(self, arg):
         self._lookupName(arg, self.names)
-        return self._lookupName(arg, self.closure)
+        return self._lookupClosureName(arg)
     _convert_LOAD_DEREF = _convert_DEREF
     _convert_STORE_DEREF = _convert_DEREF
 
     def _convert_LOAD_CLOSURE(self, arg):
-        return self._lookupName(arg, self.closure)
+        return self._lookupClosureName(arg)
 
     _cmp = list(pythonopcode.cmp_op)
     def _convert_COMPARE_OP(self, arg):

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	Mon Jan  7 23:29:32 2008
@@ -378,6 +378,21 @@
         decl = str(decl) + "\n"
         yield self.st, decl + "x = make_adder(40)(2)", 'x', 42
 
+        decl = py.code.Source("""
+            def f(a, g, e, c):
+                def b(n, d):
+                    return (a, c, d, g, n)
+                def f(b, a):
+                    return (a, b, c, g)
+                return (a, g, e, c, b, f)
+            A, G, E, C, B, F = f(6, 2, 8, 5)
+            A1, C1, D1, G1, N1 = B(7, 3)
+            A2, B2, C2, G2 = F(1, 4)
+        """)
+        decl = str(decl) + "\n"
+        yield self.st, decl, 'A,A1,A2,B2,C,C1,C2,D1,E,G,G1,G2,N1', \
+                             (6,6 ,4 ,1 ,5,5 ,5 ,3 ,8,2,2 ,2 ,7 )
+
     def test_try_except_finally(self):
         yield self.simple_test, """
             try:

Modified: pypy/branch/astcompilertests/pypy/interpreter/nestedscope.py
==============================================================================
--- pypy/branch/astcompilertests/pypy/interpreter/nestedscope.py	(original)
+++ pypy/branch/astcompilertests/pypy/interpreter/nestedscope.py	Mon Jan  7 23:29:32 2008
@@ -149,7 +149,8 @@
         args_to_copy = self.pycode._args_as_cellvars
         for i in range(len(args_to_copy)):
             argnum = args_to_copy[i]
-            self.cells[i] = Cell(self.fastlocals_w[argnum])
+            if argnum >= 0:
+                self.cells[i].set(self.fastlocals_w[argnum])
 
     def getfreevarname(self, index):
         freevarnames = self.pycode.co_cellvars + self.pycode.co_freevars

Modified: pypy/branch/astcompilertests/pypy/interpreter/pycode.py
==============================================================================
--- pypy/branch/astcompilertests/pypy/interpreter/pycode.py	(original)
+++ pypy/branch/astcompilertests/pypy/interpreter/pycode.py	Mon Jan  7 23:29:32 2008
@@ -89,21 +89,25 @@
                 argcount += 1
             if self.co_flags & CO_VARKEYWORDS:
                 argcount += 1
-            # the first few cell vars could shadow already-set arguments,
-            # in the same order as they appear in co_varnames
+            # Cell vars could shadow already-set arguments.
+            # astcompiler.pyassem used to be clever about the order of
+            # the variables in both co_varnames and co_cellvars, but
+            # it no longer is for the sake of simplicity.  Moreover
+            # code objects loaded from CPython don't necessarily follow
+            # an order, which could lead to strange bugs if .pyc files
+            # produced by CPython are loaded by PyPy.  Note that CPython
+            # contains the following bad-looking nested loops at *every*
+            # function call!
             argvars  = self.co_varnames
             cellvars = self.co_cellvars
-            next     = 0
-            nextname = cellvars[0]
-            for i in range(argcount):
-                if argvars[i] == nextname:
-                    # argument i has the same name as the next cell var
-                    self._args_as_cellvars.append(i)
-                    next += 1
-                    try:
-                        nextname = cellvars[next]
-                    except IndexError:
-                        break   # all cell vars initialized this way
+            for i in range(len(cellvars)):
+                cellname = cellvars[i]
+                for j in range(argcount):
+                    if cellname == argvars[j]:
+                        # argument j has the same name as the cell var i
+                        while len(self._args_as_cellvars) <= i:
+                            self._args_as_cellvars.append(-1)   # pad
+                        self._args_as_cellvars[i] = j
 
     co_names = property(lambda self: [self.space.unwrap(w_name) for w_name in self.co_names_w]) # for trace
 


More information about the pypy-svn mailing list