summaryrefslogtreecommitdiffstats
path: root/Tools
diff options
context:
space:
mode:
Diffstat (limited to 'Tools')
-rw-r--r--Tools/compiler/compiler/misc.py23
-rw-r--r--Tools/compiler/compiler/pycodegen.py37
-rw-r--r--Tools/compiler/compiler/symbols.py10
3 files changed, 50 insertions, 20 deletions
diff --git a/Tools/compiler/compiler/misc.py b/Tools/compiler/compiler/misc.py
index 29ff866..b834a2e 100644
--- a/Tools/compiler/compiler/misc.py
+++ b/Tools/compiler/compiler/misc.py
@@ -39,3 +39,26 @@ class Stack:
self.stack.append(elt)
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)
diff --git a/Tools/compiler/compiler/pycodegen.py b/Tools/compiler/compiler/pycodegen.py
index 37b51bf..ced0f07 100644
--- a/Tools/compiler/compiler/pycodegen.py
+++ b/Tools/compiler/compiler/pycodegen.py
@@ -117,9 +117,6 @@ def is_constant_false(node):
return 1
return 0
-def mangle(name):
- return name
-
class CodeGenerator:
"""Defines basic code generator for Python bytecode
@@ -136,6 +133,7 @@ class CodeGenerator:
optimized = 0 # is namespace access optimized?
__initialized = None
+ class_name = None # provide default for instance variable
def __init__(self, filename):
if self.__initialized is None:
@@ -175,6 +173,12 @@ class CodeGenerator:
"""Return a code object"""
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
def isLocalName(self, name):
@@ -190,6 +194,7 @@ class CodeGenerator:
self._nameOp('DELETE', name)
def _nameOp(self, prefix, name):
+ name = self.mangle(name)
if not self.optimized:
self.emit(prefix + '_NAME', name)
return
@@ -258,7 +263,8 @@ class CodeGenerator:
self._visitFuncOrLambda(node, isLambda=1)
def _visitFuncOrLambda(self, node, isLambda=0):
- gen = self.FunctionGen(node, self.filename, self.scopes, isLambda)
+ gen = self.FunctionGen(node, self.filename, self.scopes, isLambda,
+ self.class_name)
walk(node.code, gen)
gen.finish()
self.set_lineno(node)
@@ -645,7 +651,7 @@ class CodeGenerator:
def visitGetattr(self, node):
self.visit(node.expr)
- self.emit('LOAD_ATTR', node.attrname)
+ self.emit('LOAD_ATTR', self.mangle(node.attrname))
# next five implement assignments
@@ -671,9 +677,9 @@ class CodeGenerator:
def visitAssAttr(self, node):
self.visit(node.expr)
if node.flags == 'OP_ASSIGN':
- self.emit('STORE_ATTR', node.attrname)
+ self.emit('STORE_ATTR', self.mangle(node.attrname))
elif node.flags == 'OP_DELETE':
- self.emit('DELETE_ATTR', node.attrname)
+ self.emit('DELETE_ATTR', self.mangle(node.attrname))
else:
print "warning: unexpected flags:", node.flags
print node
@@ -728,10 +734,10 @@ class CodeGenerator:
if mode == "load":
self.visit(node.expr)
self.emit('DUP_TOP')
- self.emit('LOAD_ATTR', node.attrname)
+ self.emit('LOAD_ATTR', self.mangle(node.attrname))
elif mode == "store":
self.emit('ROT_TWO')
- self.emit('STORE_ATTR', node.attrname)
+ self.emit('STORE_ATTR', self.mangle(node.attrname))
def visitAugSlice(self, node, mode):
if mode == "load":
@@ -987,6 +993,7 @@ class NestedScopeCodeGenerator(CodeGenerator):
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:
@@ -1002,7 +1009,8 @@ class NestedScopeCodeGenerator(CodeGenerator):
(name, scope)
def _visitFuncOrLambda(self, node, isLambda=0):
- gen = self.FunctionGen(node, self.filename, self.scopes, isLambda)
+ gen = self.FunctionGen(node, self.filename, self.scopes, isLambda,
+ self.class_name)
walk(node.code, gen)
gen.finish()
self.set_lineno(node)
@@ -1079,7 +1087,8 @@ class AbstractFunctionCode:
optimized = 1
lambdaCount = 0
- def __init__(self, func, filename, scopes, isLambda):
+ def __init__(self, func, filename, scopes, isLambda, class_name):
+ self.class_name = class_name
if isLambda:
klass = FunctionCodeGenerator
name = "<lambda.%d>" % klass.lambdaCount
@@ -1142,10 +1151,10 @@ class NestedFunctionCodeGenerator(AbstractFunctionCode,
super_init = NestedScopeCodeGenerator.__init__ # call be other init
__super_init = AbstractFunctionCode.__init__
- def __init__(self, func, filename, scopes, isLambda):
+ def __init__(self, func, filename, scopes, isLambda, class_name):
self.scopes = scopes
self.scope = scopes[func]
- self.__super_init(func, filename, scopes, isLambda)
+ 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())
## self.graph.setFlag(CO_NESTED)
@@ -1153,6 +1162,7 @@ class NestedFunctionCodeGenerator(AbstractFunctionCode,
class AbstractClassCode:
def __init__(self, klass, filename, scopes):
+ self.class_name = klass.name
self.graph = pyassem.PyFlowGraph(klass.name, filename,
optimized=0)
self.super_init(filename)
@@ -1163,6 +1173,7 @@ class AbstractClassCode:
self.setDocstring(klass.doc)
def _nameOp(self, prefix, name):
+ name = self.mangle(name)
# Class namespaces are always unoptimized
self.emit(prefix + '_NAME', name)
diff --git a/Tools/compiler/compiler/symbols.py b/Tools/compiler/compiler/symbols.py
index 0ef0d12..40fd127 100644
--- a/Tools/compiler/compiler/symbols.py
+++ b/Tools/compiler/compiler/symbols.py
@@ -2,8 +2,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
MANGLE_LEN = 256
@@ -36,13 +38,7 @@ class Scope:
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)
+ return mangle(name, self.klass)
def add_def(self, name):
self.defs[self.mangle(name)] = 1