[Python-checkins] CVS: python/dist/src/Tools/compiler/compiler misc.py,1.7,1.8 pycodegen.py,1.41,1.42 symbols.py,1.6,1.7
Jeremy Hylton
jhylton@users.sourceforge.net
Mon, 27 Aug 2001 15:56:19 -0700
Update of /cvsroot/python/python/dist/src/Tools/compiler/compiler
In directory usw-pr-cvs1:/tmp/cvs-serv24399
Modified Files:
misc.py pycodegen.py symbols.py
Log Message:
Handle private names
(Hard to believe these were never handled before)
Add misc.mangle() that mangles based on the rules in compile.c.
XXX Need to test the corner cases
Update CodeGenerator with a class_name attribute bound to None. If a
particular instance is created within a class scope, the instance's
class_name is bound to that class's name.
Add mangle() method to CodeGenerator that mangles if the class_name
has a class_name in it.
Modify the FunctionCodeGenerator family to handle an extra argument--
the class_name.
Wrap all name ops and attrnames in calls to self.mangle()
Index: misc.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/misc.py,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** misc.py 2000/11/06 03:43:11 1.7
--- misc.py 2001/08/27 22:56:16 1.8
***************
*** 40,41 ****
--- 40,64 ----
def top(self):
return self.stack[-1]
+
+ MANGLE_LEN = 256 # magic constant from compile.c
+
+ def mangle(name, klass):
+ if not name.startswith('__'):
+ return name
+ if len(name) + 2 >= MANGLE_LEN:
+ return name
+ if name.endswith('__'):
+ return name
+ try:
+ i = 0
+ while klass[i] == '_':
+ i = i + 1
+ except IndexError:
+ return name
+ klass = klass[i:]
+
+ tlen = len(klass) + len(name)
+ if tlen > MANGLE_LEN:
+ klass = klass[:MANGLE_LEN-tlen]
+
+ return "_%s%s" % (klass, name)
Index: pycodegen.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/pycodegen.py,v
retrieving revision 1.41
retrieving revision 1.42
diff -C2 -d -r1.41 -r1.42
*** pycodegen.py 2001/08/27 21:58:09 1.41
--- pycodegen.py 2001/08/27 22:56:16 1.42
***************
*** 118,124 ****
return 0
- def mangle(name):
- return name
-
class CodeGenerator:
"""Defines basic code generator for Python bytecode
--- 118,121 ----
***************
*** 137,140 ****
--- 134,138 ----
optimized = 0 # is namespace access optimized?
__initialized = None
+ class_name = None # provide default for instance variable
def __init__(self, filename):
***************
*** 176,179 ****
--- 174,183 ----
return self.graph.getCode()
+ def mangle(self, name):
+ if self.class_name is not None:
+ return misc.mangle(name, self.class_name)
+ else:
+ return name
+
# Next five methods handle name access
***************
*** 191,194 ****
--- 195,199 ----
def _nameOp(self, prefix, name):
+ name = self.mangle(name)
if not self.optimized:
self.emit(prefix + '_NAME', name)
***************
*** 259,263 ****
def _visitFuncOrLambda(self, node, isLambda=0):
! gen = self.FunctionGen(node, self.filename, self.scopes, isLambda)
walk(node.code, gen)
gen.finish()
--- 264,269 ----
def _visitFuncOrLambda(self, node, isLambda=0):
! gen = self.FunctionGen(node, self.filename, self.scopes, isLambda,
! self.class_name)
walk(node.code, gen)
gen.finish()
***************
*** 646,650 ****
def visitGetattr(self, node):
self.visit(node.expr)
! self.emit('LOAD_ATTR', node.attrname)
# next five implement assignments
--- 652,656 ----
def visitGetattr(self, node):
self.visit(node.expr)
! self.emit('LOAD_ATTR', self.mangle(node.attrname))
# next five implement assignments
***************
*** 672,678 ****
self.visit(node.expr)
if node.flags == 'OP_ASSIGN':
! self.emit('STORE_ATTR', node.attrname)
elif node.flags == 'OP_DELETE':
! self.emit('DELETE_ATTR', node.attrname)
else:
print "warning: unexpected flags:", node.flags
--- 678,684 ----
self.visit(node.expr)
if node.flags == 'OP_ASSIGN':
! self.emit('STORE_ATTR', self.mangle(node.attrname))
elif node.flags == 'OP_DELETE':
! self.emit('DELETE_ATTR', self.mangle(node.attrname))
else:
print "warning: unexpected flags:", node.flags
***************
*** 729,736 ****
self.visit(node.expr)
self.emit('DUP_TOP')
! self.emit('LOAD_ATTR', node.attrname)
elif mode == "store":
self.emit('ROT_TWO')
! self.emit('STORE_ATTR', node.attrname)
def visitAugSlice(self, node, mode):
--- 735,742 ----
self.visit(node.expr)
self.emit('DUP_TOP')
! self.emit('LOAD_ATTR', self.mangle(node.attrname))
elif mode == "store":
self.emit('ROT_TWO')
! self.emit('STORE_ATTR', self.mangle(node.attrname))
def visitAugSlice(self, node, mode):
***************
*** 988,991 ****
--- 994,998 ----
def _nameOp(self, prefix, name):
+ name = self.mangle(name)
scope = self.scope.check_name(name)
if scope == SC_LOCAL:
***************
*** 1003,1007 ****
def _visitFuncOrLambda(self, node, isLambda=0):
! gen = self.FunctionGen(node, self.filename, self.scopes, isLambda)
walk(node.code, gen)
gen.finish()
--- 1010,1015 ----
def _visitFuncOrLambda(self, node, isLambda=0):
! gen = self.FunctionGen(node, self.filename, self.scopes, isLambda,
! self.class_name)
walk(node.code, gen)
gen.finish()
***************
*** 1080,1084 ****
lambdaCount = 0
! def __init__(self, func, filename, scopes, isLambda):
if isLambda:
klass = FunctionCodeGenerator
--- 1088,1093 ----
lambdaCount = 0
! def __init__(self, func, filename, scopes, isLambda, class_name):
! self.class_name = class_name
if isLambda:
klass = FunctionCodeGenerator
***************
*** 1143,1150 ****
__super_init = AbstractFunctionCode.__init__
! def __init__(self, func, filename, scopes, isLambda):
self.scopes = scopes
self.scope = scopes[func]
! self.__super_init(func, filename, scopes, isLambda)
self.graph.setFreeVars(self.scope.get_free_vars())
self.graph.setCellVars(self.scope.get_cell_vars())
--- 1152,1159 ----
__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())
***************
*** 1154,1157 ****
--- 1163,1167 ----
def __init__(self, klass, filename, scopes):
+ self.class_name = klass.name
self.graph = pyassem.PyFlowGraph(klass.name, filename,
optimized=0)
***************
*** 1164,1167 ****
--- 1174,1178 ----
def _nameOp(self, prefix, name):
+ name = self.mangle(name)
# Class namespaces are always unoptimized
self.emit(prefix + '_NAME', name)
Index: symbols.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Tools/compiler/compiler/symbols.py,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** symbols.py 2001/08/27 21:06:35 1.6
--- symbols.py 2001/08/27 22:56:16 1.7
***************
*** 3,8 ****
--- 3,10 ----
from compiler import ast
from compiler.consts import SC_LOCAL, SC_GLOBAL, SC_FREE, SC_CELL, SC_UNKNOWN
+ from compiler.misc import mangle
import types
+
import sys
***************
*** 36,47 ****
def mangle(self, name):
if self.klass is None:
- return name
- if not name.startswith('__'):
- return name
- if len(name) + 2 >= MANGLE_LEN:
- return name
- if name.endswith('__'):
return name
! return "_%s%s" % (self.klass, name)
def add_def(self, name):
--- 38,43 ----
def mangle(self, name):
if self.klass is None:
return name
! return mangle(name, self.klass)
def add_def(self, name):