[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