[Python-checkins] CVS: python/dist/src/Tools/compiler/compiler pyassem.py,1.26,1.27 pycodegen.py,1.49,1.50

Jeremy Hylton jhylton@users.sourceforge.net
2001年9月14日 15:49:10 -0700


Update of /cvsroot/python/python/dist/src/Tools/compiler/compiler
In directory usw-pr-cvs1:/tmp/cvs-serv23974
Modified Files:
	pyassem.py pycodegen.py 
Log Message:
Various sundry changes for 2.2 compatibility
Remove the option to have nested scopes or old LGB scopes. This has a
large impact on the code base, by removing the need for two variants
of each CodeGenerator.
Add a get_module() method to CodeGenerator objects, used to get the
future features for the current module.
Set CO_GENERATOR, CO_GENERATOR_ALLOWED, and CO_FUTURE_DIVISION flags
as appropriate.
Attempt to fix the value of nlocals in newCodeObject(), assuming that
nlocals is 0 if CO_NEWLOCALS is not defined.
Index: pyassem.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/pyassem.py,v
retrieving revision 1.26
retrieving revision 1.27
diff -C2 -d -r1.26 -r1.27
*** pyassem.py	2001年08月30日 20:25:54	1.26
--- pyassem.py	2001年09月14日 22:49:08	1.27
***************
*** 362,365 ****
--- 362,369 ----
 self.argcount = self.argcount - 1
 
+ def checkFlag(self, flag):
+ if self.flags & flag:
+ return 1
+ 
 def setFreeVars(self, names):
 self.freevars = list(names)
***************
*** 565,569 ****
 def newCodeObject(self):
 assert self.stage == DONE
! if self.flags == 0:
 nlocals = 0
 else:
--- 569,573 ----
 def newCodeObject(self):
 assert self.stage == DONE
! if (self.flags & CO_NEWLOCALS) == 0:
 nlocals = 0
 else:
***************
*** 762,768 ****
 ]
 
- # special cases:
- # UNPACK_SEQUENCE, BUILD_TUPLE,
- # BUILD_LIST, CALL_FUNCTION, MAKE_FUNCTION, BUILD_SLICE
 def UNPACK_SEQUENCE(self, count):
 return count-1
--- 766,769 ----
Index: pycodegen.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/pycodegen.py,v
retrieving revision 1.49
retrieving revision 1.50
diff -C2 -d -r1.49 -r1.50
*** pycodegen.py	2001年08月30日 20:25:55	1.49
--- pycodegen.py	2001年09月14日 22:49:08	1.50
***************
*** 13,17 ****
 from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
 from compiler.consts import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,\
! CO_NESTED, CO_GENERATOR
 from compiler.pyassem import TupleArg
 
--- 13,17 ----
 from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL
 from compiler.consts import CO_VARARGS, CO_VARKEYWORDS, CO_NEWLOCALS,\
! CO_NESTED, CO_GENERATOR, CO_GENERATOR_ALLOWED, CO_FUTURE_DIVISION
 from compiler.pyassem import TupleArg
 
***************
*** 35,38 ****
--- 35,47 ----
 END_FINALLY = 4
 
+ class BlockStack(misc.Stack):
+ __super_init = misc.Stack.__init__
+ 
+ def __init__(self):
+ self.__super_init(self)
+ self.loop = None
+ 
+ 
+ 
 def compile(filename, display=0):
 f = open(filename)
***************
*** 53,58 ****
 def compile(self, display=0):
 tree = parse(self.source)
! gen = NestedScopeModuleCodeGenerator(self.filename)
! walk(tree, gen, verbose=1)
 if display:
 import pprint
--- 62,66 ----
 def compile(self, display=0):
 tree = parse(self.source)
! gen = ModuleCodeGenerator(self.filename, tree)
 if display:
 import pprint
***************
*** 155,158 ****
--- 163,174 ----
 self._setupGraphDelegation()
 
+ # XXX set flags based on future features
+ futures = self.get_module().futures
+ for feature in futures:
+ if feature == "division":
+ self.graph.setFlag(CO_FUTURE_DIVISION)
+ elif feature == "generators":
+ self.graph.setFlag(CO_GENERATOR_ALLOWED)
+ 
 def initClass(self):
 """This method is called once for each class"""
***************
*** 186,189 ****
--- 202,213 ----
 return name
 
+ def parseSymbols(self, tree):
+ s = symbols.SymbolVisitor()
+ walk(tree, s)
+ return s.scopes
+ 
+ def get_module(self):
+ raise RuntimeError, "should be implemented by subclasses"
+ 
 # Next five methods handle name access
 
***************
*** 202,212 ****
 def _nameOp(self, prefix, name):
 name = self.mangle(name)
! if not self.optimized:
! self.emit(prefix + '_NAME', name)
! return
! if self.isLocalName(name):
! self.emit(prefix + '_FAST', name)
 else:
! self.emit(prefix + '_GLOBAL', name)
 
 def _implicitNameOp(self, prefix, name):
--- 226,245 ----
 def _nameOp(self, prefix, name):
 name = self.mangle(name)
! scope = self.scope.check_name(name)
! if scope == SC_LOCAL:
! if not self.optimized:
! self.emit(prefix + '_NAME', name)
! else:
! self.emit(prefix + '_FAST', name)
! elif scope == SC_GLOBAL:
! if not self.optimized:
! self.emit(prefix + '_NAME', name)
! else:
! self.emit(prefix + '_GLOBAL', name)
! elif scope == SC_FREE or scope == SC_CELL:
! self.emit(prefix + '_DEREF', name)
 else:
! raise RuntimeError, "unsupported scope for var %s: %d" % \
! (name, scope)
 
 def _implicitNameOp(self, prefix, name):
***************
*** 250,253 ****
--- 283,288 ----
 
 def visitModule(self, node):
+ self.scopes = self.parseSymbols(node)
+ self.scope = self.scopes[node]
 self.emit('SET_LINENO', 0)
 if node.doc:
***************
*** 271,275 ****
 def _visitFuncOrLambda(self, node, isLambda=0):
 gen = self.FunctionGen(node, self.filename, self.scopes, isLambda,
! self.class_name)
 walk(node.code, gen)
 gen.finish()
--- 306,310 ----
 def _visitFuncOrLambda(self, node, isLambda=0):
 gen = self.FunctionGen(node, self.filename, self.scopes, isLambda,
! self.class_name, self.get_module())
 walk(node.code, gen)
 gen.finish()
***************
*** 277,285 ****
 for default in node.defaults:
 self.visit(default)
! self.emit('LOAD_CONST', gen)
! self.emit('MAKE_FUNCTION', len(node.defaults))
 
 def visitClass(self, node):
! gen = self.ClassGen(node, self.filename, self.scopes)
 if node.doc:
 self.emit('LOAD_CONST', node.doc)
--- 312,328 ----
 for default in node.defaults:
 self.visit(default)
! frees = gen.scope.get_free_vars()
! if frees:
! for name in frees:
! self.emit('LOAD_CLOSURE', name)
! self.emit('LOAD_CONST', gen)
! self.emit('MAKE_CLOSURE', len(node.defaults))
! else:
! self.emit('LOAD_CONST', gen)
! self.emit('MAKE_FUNCTION', len(node.defaults))
 
 def visitClass(self, node):
! gen = self.ClassGen(node, self.filename, self.scopes,
! self.get_module())
 if node.doc:
 self.emit('LOAD_CONST', node.doc)
***************
*** 292,297 ****
 self.visit(base)
 self.emit('BUILD_TUPLE', len(node.bases))
 self.emit('LOAD_CONST', gen)
! self.emit('MAKE_FUNCTION', 0)
 self.emit('CALL_FUNCTION', 0)
 self.emit('BUILD_CLASS')
--- 335,346 ----
 self.visit(base)
 self.emit('BUILD_TUPLE', len(node.bases))
+ frees = gen.scope.get_free_vars()
+ for name in frees:
+ self.emit('LOAD_CLOSURE', name)
 self.emit('LOAD_CONST', gen)
! if frees:
! self.emit('MAKE_CLOSURE', 0)
! else:
! self.emit('MAKE_FUNCTION', 0)
 self.emit('CALL_FUNCTION', 0)
 self.emit('BUILD_CLASS')
***************
*** 1018,1129 ****
 self.emit('STORE_SUBSCR')
 
- class NestedScopeCodeGenerator(CodeGenerator):
- __super_visitModule = CodeGenerator.visitModule
- __super_visitClass = CodeGenerator.visitClass
- __super__visitFuncOrLambda = CodeGenerator._visitFuncOrLambda
- 
- def parseSymbols(self, tree):
- s = symbols.SymbolVisitor()
- walk(tree, s)
- return s.scopes
- 
- def visitModule(self, node):
- self.scopes = self.parseSymbols(node)
- self.scope = self.scopes[node]
- self.__super_visitModule(node)
- 
- def _nameOp(self, prefix, name):
- name = self.mangle(name)
- scope = self.scope.check_name(name)
- if scope == SC_LOCAL:
- if not self.optimized:
- self.emit(prefix + '_NAME', name)
- else:
- self.emit(prefix + '_FAST', name)
- elif scope == SC_GLOBAL:
- if not self.optimized:
- self.emit(prefix + '_NAME', name)
- else:
- self.emit(prefix + '_GLOBAL', name)
- elif scope == SC_FREE or scope == SC_CELL:
- self.emit(prefix + '_DEREF', name)
- else:
- raise RuntimeError, "unsupported scope for var %s: %d" % \
- (name, scope)
- 
- def _visitFuncOrLambda(self, node, isLambda=0):
- gen = self.FunctionGen(node, self.filename, self.scopes, isLambda,
- self.class_name)
- walk(node.code, gen)
- gen.finish()
- self.set_lineno(node)
- for default in node.defaults:
- self.visit(default)
- frees = gen.scope.get_free_vars()
- if frees:
- for name in frees:
- self.emit('LOAD_CLOSURE', name)
- self.emit('LOAD_CONST', gen)
- self.emit('MAKE_CLOSURE', len(node.defaults))
- else:
- self.emit('LOAD_CONST', gen)
- self.emit('MAKE_FUNCTION', len(node.defaults))
- 
- def visitClass(self, node):
- gen = self.ClassGen(node, self.filename, self.scopes)
- if node.doc:
- self.emit('LOAD_CONST', node.doc)
- self.storeName('__doc__')
- walk(node.code, gen)
- gen.finish()
- self.set_lineno(node)
- self.emit('LOAD_CONST', node.name)
- for base in node.bases:
- self.visit(base)
- self.emit('BUILD_TUPLE', len(node.bases))
- frees = gen.scope.get_free_vars()
- for name in frees:
- self.emit('LOAD_CLOSURE', name)
- self.emit('LOAD_CONST', gen)
- if frees:
- self.emit('MAKE_CLOSURE', 0)
- else:
- self.emit('MAKE_FUNCTION', 0)
- self.emit('CALL_FUNCTION', 0)
- self.emit('BUILD_CLASS')
- self.storeName(node.name)
- 
- 
- class LGBScopeMixin:
- """Defines initClass() for Python 2.1-compatible scoping"""
- def initClass(self):
- self.__class__.NameFinder = LocalNameFinder
- self.__class__.FunctionGen = FunctionCodeGenerator
- self.__class__.ClassGen = ClassCodeGenerator
- 
 class NestedScopeMixin:
 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
 def initClass(self):
 self.__class__.NameFinder = LocalNameFinder
! self.__class__.FunctionGen = NestedFunctionCodeGenerator
! self.__class__.ClassGen = NestedClassCodeGenerator
 
! class ModuleCodeGenerator(LGBScopeMixin, CodeGenerator):
 __super_init = CodeGenerator.__init__
 
 scopes = None
 
! def __init__(self, filename):
 self.graph = pyassem.PyFlowGraph("<module>", filename)
 self.__super_init(filename)
 
! class NestedScopeModuleCodeGenerator(NestedScopeMixin,
! NestedScopeCodeGenerator):
! __super_init = CodeGenerator.__init__
! 
! def __init__(self, filename):
! self.graph = pyassem.PyFlowGraph("<module>", filename)
! self.__super_init(filename)
! ## self.graph.setFlag(CO_NESTED)
 
 class AbstractFunctionCode:
--- 1067,1090 ----
 self.emit('STORE_SUBSCR')
 
 class NestedScopeMixin:
 """Defines initClass() for nested scoping (Python 2.2-compatible)"""
 def initClass(self):
 self.__class__.NameFinder = LocalNameFinder
! self.__class__.FunctionGen = FunctionCodeGenerator
! self.__class__.ClassGen = ClassCodeGenerator
 
! class ModuleCodeGenerator(NestedScopeMixin, CodeGenerator):
 __super_init = CodeGenerator.__init__
 
 scopes = None
 
! def __init__(self, filename, tree):
 self.graph = pyassem.PyFlowGraph("<module>", filename)
+ self.futures = future.find_futures(tree)
 self.__super_init(filename)
+ walk(tree, self)
 
! def get_module(self):
! return self
 
 class AbstractFunctionCode:
***************
*** 1131,1136 ****
 lambdaCount = 0
 
! def __init__(self, func, filename, scopes, isLambda, class_name):
 self.class_name = class_name
 if isLambda:
 klass = FunctionCodeGenerator
--- 1092,1098 ----
 lambdaCount = 0
 
! def __init__(self, func, filename, scopes, isLambda, class_name, mod):
 self.class_name = class_name
+ self.module = mod
 if isLambda:
 klass = FunctionCodeGenerator
***************
*** 1158,1161 ****
--- 1120,1126 ----
 self.generateArgUnpack(func.argnames)
 
+ def get_module(self):
+ return self.module
+ 
 def finish(self):
 self.graph.startExitBlock()
***************
*** 1184,1212 ****
 unpackTuple = unpackSequence
 
! class FunctionCodeGenerator(LGBScopeMixin, AbstractFunctionCode,
 CodeGenerator): 
 super_init = CodeGenerator.__init__ # call be other init
 scopes = None
 
- class NestedFunctionCodeGenerator(AbstractFunctionCode,
- NestedScopeMixin,
- NestedScopeCodeGenerator):
- super_init = NestedScopeCodeGenerator.__init__ # call be other init
 __super_init = AbstractFunctionCode.__init__
 
! def __init__(self, func, filename, scopes, isLambda, class_name):
 self.scopes = scopes
 self.scope = scopes[func]
! self.__super_init(func, filename, scopes, isLambda, class_name)
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
! if self.scope.generator is not None:
! self.graph.setFlag(CO_GENERATOR)
! ## self.graph.setFlag(CO_NESTED)
 
 class AbstractClassCode:
 
! def __init__(self, klass, filename, scopes):
 self.class_name = klass.name
 self.graph = pyassem.PyFlowGraph(klass.name, filename,
 optimized=0, klass=1)
--- 1149,1174 ----
 unpackTuple = unpackSequence
 
! class FunctionCodeGenerator(NestedScopeMixin, AbstractFunctionCode,
 CodeGenerator): 
 super_init = CodeGenerator.__init__ # call be other init
 scopes = None
 
 __super_init = AbstractFunctionCode.__init__
 
! def __init__(self, func, filename, scopes, isLambda, class_name, mod):
 self.scopes = scopes
 self.scope = scopes[func]
! self.__super_init(func, filename, scopes, isLambda, class_name, mod)
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
! if self.graph.checkFlag(CO_GENERATOR_ALLOWED):
! if self.scope.generator is not None:
! self.graph.setFlag(CO_GENERATOR)
 
 class AbstractClassCode:
 
! def __init__(self, klass, filename, scopes, module):
 self.class_name = klass.name
+ self.module = module
 self.graph = pyassem.PyFlowGraph(klass.name, filename,
 optimized=0, klass=1)
***************
*** 1218,1225 ****
 self.setDocstring(klass.doc)
 
! def _nameOp(self, prefix, name):
! name = self.mangle(name)
! # Class namespaces are always unoptimized
! self.emit(prefix + '_NAME', name)
 
 def finish(self):
--- 1180,1185 ----
 self.setDocstring(klass.doc)
 
! def get_module(self):
! return self.module
 
 def finish(self):
***************
*** 1228,1245 ****
 self.emit('RETURN_VALUE')
 
! class ClassCodeGenerator(LGBScopeMixin, AbstractClassCode, CodeGenerator):
 super_init = CodeGenerator.__init__
 scopes = None
 
- class NestedClassCodeGenerator(AbstractClassCode,
- NestedScopeMixin,
- NestedScopeCodeGenerator):
- super_init = NestedScopeCodeGenerator.__init__ # call be other init
 __super_init = AbstractClassCode.__init__
 
! def __init__(self, klass, filename, scopes):
 self.scopes = scopes
 self.scope = scopes[klass]
! self.__super_init(klass, filename, scopes)
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())
--- 1188,1201 ----
 self.emit('RETURN_VALUE')
 
! class ClassCodeGenerator(NestedScopeMixin, AbstractClassCode, CodeGenerator):
 super_init = CodeGenerator.__init__
 scopes = None
 
 __super_init = AbstractClassCode.__init__
 
! def __init__(self, klass, filename, scopes, module):
 self.scopes = scopes
 self.scope = scopes[klass]
! self.__super_init(klass, filename, scopes, module)
 self.graph.setFreeVars(self.scope.get_free_vars())
 self.graph.setCellVars(self.scope.get_cell_vars())

AltStyle によって変換されたページ (->オリジナル) /