Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 364f9b9

Browse files
committed
Preliminary support for nested scopes
XXX Still doesn't work right for classes XXX Still doesn't do sufficient error checking
1 parent 53ee2a9 commit 364f9b9

6 files changed

Lines changed: 792 additions & 178 deletions

File tree

Lib/compiler/pyassem.py

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,6 @@ def getBlocksInOrder(self):
9999
if not self.exit in order:
100100
order.append(self.exit)
101101

102-
## for b in order:
103-
## print repr(b)
104-
## print "\t", b.get_children()
105-
## print b
106-
## print
107-
108102
return order
109103

110104
def getBlocks(self):
@@ -222,6 +216,7 @@ def getContainedGraphs(self):
222216
CO_NEWLOCALS = 0x0002
223217
CO_VARARGS = 0x0004
224218
CO_VARKEYWORDS = 0x0008
219+
CO_NESTED = 0x0010
225220

226221
# the FlowGraph is transformed in place; it exists in one of these states
227222
RAW = "RAW"
@@ -245,6 +240,15 @@ def __init__(self, name, filename, args=(), optimized=0):
245240
self.flags = 0
246241
self.consts = []
247242
self.names = []
243+
# Free variables found by the symbol table scan, including
244+
# variables used only in nested scopes, are included here.
245+
self.freevars = []
246+
self.cellvars = []
247+
# The closure list is used to track the order of cell
248+
# variables and free variables in the resulting code object.
249+
# The offsets used by LOAD_CLOSURE/LOAD_DEREF refer to both
250+
# kinds of variables.
251+
self.closure = []
248252
self.varnames = list(args) or []
249253
for i in range(len(self.varnames)):
250254
var = self.varnames[i]
@@ -260,6 +264,12 @@ def setFlag(self, flag):
260264
if flag == CO_VARARGS:
261265
self.argcount = self.argcount - 1
262266

267+
def setFreeVars(self, names):
268+
self.freevars = list(names)
269+
270+
def setCellVars(self, names):
271+
self.cellvars = names
272+
263273
def getCode(self):
264274
"""Get a Python code object"""
265275
if self.stage == RAW:
@@ -335,6 +345,7 @@ def convertArgs(self):
335345
"""Convert arguments from symbolic to concrete form"""
336346
assert self.stage == FLAT
337347
self.consts.insert(0, self.docstring)
348+
self.sort_cellvars()
338349
for i in range(len(self.insts)):
339350
t = self.insts[i]
340351
if len(t) == 2:
@@ -345,6 +356,19 @@ def convertArgs(self):
345356
self.insts[i] = opname, conv(self, oparg)
346357
self.stage = CONV
347358

359+
def sort_cellvars(self):
360+
"""Sort cellvars in the order of varnames and prune from freevars.
361+
"""
362+
cells = {}
363+
for name in self.cellvars:
364+
cells[name] = 1
365+
self.cellvars = [name for name in self.varnames
366+
if cells.has_key(name)]
367+
for name in self.cellvars:
368+
del cells[name]
369+
self.cellvars = self.cellvars + cells.keys()
370+
self.closure = self.cellvars + self.freevars
371+
348372
def _lookupName(self, name, list):
349373
"""Return index of name in list, appending if necessary"""
350374
t = type(name)
@@ -382,6 +406,17 @@ def _convert_NAME(self, arg):
382406
_convert_STORE_GLOBAL = _convert_NAME
383407
_convert_DELETE_GLOBAL = _convert_NAME
384408

409+
def _convert_DEREF(self, arg):
410+
self._lookupName(arg, self.names)
411+
self._lookupName(arg, self.varnames)
412+
return self._lookupName(arg, self.closure)
413+
_convert_LOAD_DEREF = _convert_DEREF
414+
_convert_STORE_DEREF = _convert_DEREF
415+
416+
def _convert_LOAD_CLOSURE(self, arg):
417+
self._lookupName(arg, self.varnames)
418+
return self._lookupName(arg, self.closure)
419+
385420
_cmp = list(dis.cmp_op)
386421
def _convert_COMPARE_OP(self, arg):
387422
return self._cmp.index(arg)
@@ -432,7 +467,8 @@ def newCodeObject(self):
432467
self.lnotab.getCode(), self.getConsts(),
433468
tuple(self.names), tuple(self.varnames),
434469
self.filename, self.name, self.lnotab.firstline,
435-
self.lnotab.getTable())
470+
self.lnotab.getTable(), tuple(self.freevars),
471+
tuple(self.cellvars))
436472

437473
def getConsts(self):
438474
"""Return a tuple for the const slot of the code object

0 commit comments

Comments
 (0)