diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-04-12 06:40:42 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-04-12 06:40:42 (GMT) |
commit | 364f9b9e2f798e4d28ed21122faffb030a6ccac5 (patch) | |
tree | bc709b0d46eeba0c737bdd7bb58371ad06d70739 /Lib/compiler/pyassem.py | |
parent | 53ee2a94c70875b7b334ddca59900933409eaa63 (diff) | |
download | cpython-364f9b9e2f798e4d28ed21122faffb030a6ccac5.zip cpython-364f9b9e2f798e4d28ed21122faffb030a6ccac5.tar.gz cpython-364f9b9e2f798e4d28ed21122faffb030a6ccac5.tar.bz2 |
Preliminary support for nested scopes
XXX Still doesn't work right for classes
XXX Still doesn't do sufficient error checking
Diffstat (limited to 'Lib/compiler/pyassem.py')
-rw-r--r-- | Lib/compiler/pyassem.py | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/Lib/compiler/pyassem.py b/Lib/compiler/pyassem.py index 43bf6f4..447a8e7 100644 --- a/Lib/compiler/pyassem.py +++ b/Lib/compiler/pyassem.py @@ -99,12 +99,6 @@ class FlowGraph: if not self.exit in order: order.append(self.exit) -## for b in order: -## print repr(b) -## print "\t", b.get_children() -## print b -## print - return order def getBlocks(self): @@ -222,6 +216,7 @@ CO_OPTIMIZED = 0x0001 CO_NEWLOCALS = 0x0002 CO_VARARGS = 0x0004 CO_VARKEYWORDS = 0x0008 +CO_NESTED = 0x0010 # the FlowGraph is transformed in place; it exists in one of these states RAW = "RAW" @@ -245,6 +240,15 @@ class PyFlowGraph(FlowGraph): self.flags = 0 self.consts = [] self.names = [] + # Free variables found by the symbol table scan, including + # 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(args) or [] for i in range(len(self.varnames)): var = self.varnames[i] @@ -260,6 +264,12 @@ class PyFlowGraph(FlowGraph): if flag == CO_VARARGS: self.argcount = self.argcount - 1 + def setFreeVars(self, names): + self.freevars = list(names) + + def setCellVars(self, names): + self.cellvars = names + def getCode(self): """Get a Python code object""" if self.stage == RAW: @@ -335,6 +345,7 @@ class PyFlowGraph(FlowGraph): """Convert arguments from symbolic to concrete form""" assert self.stage == FLAT self.consts.insert(0, self.docstring) + self.sort_cellvars() for i in range(len(self.insts)): t = self.insts[i] if len(t) == 2: @@ -345,6 +356,19 @@ class PyFlowGraph(FlowGraph): self.insts[i] = opname, conv(self, oparg) self.stage = CONV + def sort_cellvars(self): + """Sort cellvars in the order of varnames and prune from freevars. + """ + cells = {} + for name in self.cellvars: + cells[name] = 1 + self.cellvars = [name for name in self.varnames + if cells.has_key(name)] + for name in self.cellvars: + del cells[name] + self.cellvars = self.cellvars + cells.keys() + self.closure = self.cellvars + self.freevars + def _lookupName(self, name, list): """Return index of name in list, appending if necessary""" t = type(name) @@ -382,6 +406,17 @@ class PyFlowGraph(FlowGraph): _convert_STORE_GLOBAL = _convert_NAME _convert_DELETE_GLOBAL = _convert_NAME + def _convert_DEREF(self, arg): + self._lookupName(arg, self.names) + self._lookupName(arg, self.varnames) + return self._lookupName(arg, self.closure) + _convert_LOAD_DEREF = _convert_DEREF + _convert_STORE_DEREF = _convert_DEREF + + def _convert_LOAD_CLOSURE(self, arg): + self._lookupName(arg, self.varnames) + return self._lookupName(arg, self.closure) + _cmp = list(dis.cmp_op) def _convert_COMPARE_OP(self, arg): return self._cmp.index(arg) @@ -432,7 +467,8 @@ class PyFlowGraph(FlowGraph): self.lnotab.getCode(), self.getConsts(), tuple(self.names), tuple(self.varnames), self.filename, self.name, self.lnotab.firstline, - self.lnotab.getTable()) + self.lnotab.getTable(), tuple(self.freevars), + tuple(self.cellvars)) def getConsts(self): """Return a tuple for the const slot of the code object |