[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):