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)
return 1
return 0
-def mangle(name):
- return name
-
class CodeGenerator:
"""Defines basic code generator for Python bytecode
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:
"""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):
self._nameOp('DELETE', name)
def _nameOp(self, prefix, name):
+ name = self.mangle(name)
if not self.optimized:
self.emit(prefix + '_NAME', name)
return
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)
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
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
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":
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:
(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)
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
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)
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)
self.setDocstring(klass.doc)
def _nameOp(self, prefix, name):
+ name = self.mangle(name)
# Class namespaces are always unoptimized
self.emit(prefix + '_NAME', name)
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
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
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)
return 1
return 0
-def mangle(name):
- return name
-
class CodeGenerator:
"""Defines basic code generator for Python bytecode
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:
"""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):
self._nameOp('DELETE', name)
def _nameOp(self, prefix, name):
+ name = self.mangle(name)
if not self.optimized:
self.emit(prefix + '_NAME', name)
return
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)
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
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
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":
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:
(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)
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
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)
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)
self.setDocstring(klass.doc)
def _nameOp(self, prefix, name):
+ name = self.mangle(name)
# Class namespaces are always unoptimized
self.emit(prefix + '_NAME', name)
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
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