mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
Preliminary support for nested scopes
XXX Still doesn't work right for classes XXX Still doesn't do sufficient error checking
This commit is contained in:
parent
53ee2a94c7
commit
364f9b9e2f
6 changed files with 792 additions and 178 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue