summaryrefslogtreecommitdiffstats
path: root/Tools/compiler
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-08-29 18:09:50 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-08-29 18:09:50 (GMT)
commite4e9cd4c01b996430232069970eab9579d71d628 (patch)
tree7fd388f37150a325aa9b17c239bc7a528b3b4913 /Tools/compiler
parent5477f529d6f3b25e51ac6b321a6fe7b28fafe1f4 (diff)
downloadcpython-e4e9cd4c01b996430232069970eab9579d71d628.zip
cpython-e4e9cd4c01b996430232069970eab9579d71d628.tar.gz
cpython-e4e9cd4c01b996430232069970eab9579d71d628.tar.bz2
Modify name conversion to be (hopefully) a bit more efficient.
Use a dictionary instead of a list to map objects to their offsets in a const/name tuple of a code object. XXX The conversion is perhaps incomplete, in that we shouldn't have to do the list2dict to start.
Diffstat (limited to 'Tools/compiler')
-rw-r--r--Tools/compiler/compiler/pyassem.py69
1 files changed, 52 insertions, 17 deletions
diff --git a/Tools/compiler/compiler/pyassem.py b/Tools/compiler/compiler/pyassem.py
index 3063b5b..0cdc6ea 100644
--- a/Tools/compiler/compiler/pyassem.py
+++ b/Tools/compiler/compiler/pyassem.py
@@ -15,6 +15,17 @@ def xxx_sort(l):
l.sort(sorter)
return l
+def list2dict(l):
+ d = {}
+ for i in range(len(l)):
+ d[l[i]] = i
+ return d
+
+def dict2list(d):
+ l = [(v, k) for k, v in d.items()]
+ l.sort()
+ return [k for v, k in l]
+
class FlowGraph:
def __init__(self):
self.current = self.entry = Block()
@@ -326,13 +337,14 @@ DONE = "DONE"
class PyFlowGraph(FlowGraph):
super_init = FlowGraph.__init__
- def __init__(self, name, filename, args=(), optimized=0):
+ def __init__(self, name, filename, args=(), optimized=0, klass=None):
self.super_init()
self.name = name
self.filename = filename
self.docstring = None
self.args = args # XXX
self.argcount = getArgCount(args)
+ self.klass = klass
if optimized:
self.flags = CO_OPTIMIZED | CO_NEWLOCALS
else:
@@ -445,14 +457,25 @@ class PyFlowGraph(FlowGraph):
assert self.stage == FLAT
self.consts.insert(0, self.docstring)
self.sort_cellvars()
+
+ self.c_varnames = list2dict(self.varnames)
+ self.c_names = list2dict(self.names)
+ self.c_consts = list2dict(self.consts)
+ self.c_closure = list2dict(self.closure)
+
for i in range(len(self.insts)):
t = self.insts[i]
if len(t) == 2:
- opname = t[0]
- oparg = t[1]
+ opname, oparg = t
conv = self._converters.get(opname, None)
if conv:
self.insts[i] = opname, conv(self, oparg)
+
+ self.varnames = dict2list(self.c_varnames)
+ self.names = dict2list(self.c_names)
+ self.consts = dict2list(self.c_consts)
+ self.closure = dict2list(self.c_closure)
+
self.stage = CONV
def sort_cellvars(self):
@@ -468,12 +491,23 @@ class PyFlowGraph(FlowGraph):
self.cellvars = self.cellvars + cells.keys()
self.closure = self.cellvars + self.freevars
- def _lookupName(self, name, list):
+ def _lookupName(self, name, dict):
+ i = dict.get(name, None)
+ if i is None:
+ i = dict[name] = len(dict)
+ return i
+
+ def XXX_lookupName(self, name, list):
"""Return index of name in list, appending if necessary"""
+ # XXX It should be possible to replace this with some
+ # dictionary operations, but not sure how
t = type(name)
for i in range(len(list)):
- # must do a comparison on type first to prevent UnicodeErrors
- if t == type(list[i]) and list[i] == name:
+ # must do a comparison on type first to prevent UnicodeErrors
+ # not clear that a dictionary would work, because we could
+ # get UnicodeErrors on lookups
+ elt = list[i]
+ if isinstance(elt, t) and elt == name:
return i
end = len(list)
list.append(name)
@@ -483,20 +517,21 @@ class PyFlowGraph(FlowGraph):
def _convert_LOAD_CONST(self, arg):
if hasattr(arg, 'getCode'):
arg = arg.getCode()
- return self._lookupName(arg, self.consts)
+ return self._lookupName(arg, self.c_consts)
def _convert_LOAD_FAST(self, arg):
- self._lookupName(arg, self.names)
- return self._lookupName(arg, self.varnames)
+ self._lookupName(arg, self.c_names)
+ return self._lookupName(arg, self.c_varnames)
_convert_STORE_FAST = _convert_LOAD_FAST
_convert_DELETE_FAST = _convert_LOAD_FAST
def _convert_LOAD_NAME(self, arg):
- return self._lookupName(arg, self.names)
+ return self._lookupName(arg, self.c_names)
def _convert_NAME(self, arg):
- self._lookupName(arg, self.varnames)
- return self._lookupName(arg, self.names)
+ if self.klass is None:
+ self._lookupName(arg, self.c_varnames)
+ return self._lookupName(arg, self.c_names)
_convert_STORE_NAME = _convert_NAME
_convert_DELETE_NAME = _convert_NAME
_convert_IMPORT_NAME = _convert_NAME
@@ -509,15 +544,15 @@ class PyFlowGraph(FlowGraph):
_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)
+ self._lookupName(arg, self.c_names)
+ self._lookupName(arg, self.c_varnames)
+ return self._lookupName(arg, self.c_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)
+ self._lookupName(arg, self.c_varnames)
+ return self._lookupName(arg, self.c_closure)
_cmp = list(dis.cmp_op)
def _convert_COMPARE_OP(self, arg):