[pypy-svn] r18731 - in pypy/dist/pypy/rpython/ootypesystem: . test
arigo at codespeak.net
arigo at codespeak.net
Tue Oct 18 11:19:33 CEST 2005
Author: arigo
Date: Tue Oct 18 11:19:32 2005
New Revision: 18731
Modified:
pypy/dist/pypy/rpython/ootypesystem/rclass.py
pypy/dist/pypy/rpython/ootypesystem/rpbc.py
pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py
Log:
Mangle attribute and method names to avoid clashes with attributes
like _TYPE. Temporarily, it looks like a good idea to mangle names
systematically to trap bugs related to a confusion between mangled
and non-mangled names. Later a more subtle mangling that doesn't
modify common names would be better.
Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Tue Oct 18 11:19:32 2005
@@ -21,6 +21,17 @@
# FIXME
pass
+
+def mangle(name):
+ # XXX temporary: for now it looks like a good idea to mangle names
+ # systematically to trap bugs related to a confusion between mangled
+ # and non-mangled names
+ return 'o' + name
+
+def unmangle(mangled):
+ assert mangled.startswith('o')
+ return mangled[1:]
+
class InstanceRepr(AbstractInstanceRepr):
def __init__(self, rtyper, classdef, does_need_gc=True):
AbstractInstanceRepr.__init__(self, rtyper, classdef)
@@ -46,14 +57,20 @@
allclassattributes = {}
fields = {}
+ fielddefaults = {}
attrs = self.classdef.attrs.items()
for name, attrdef in attrs:
if not attrdef.readonly:
+ mangled = mangle(name)
repr = self.rtyper.getrepr(attrdef.s_value)
- allfields[name] = repr
+ allfields[mangled] = repr
oot = repr.lowleveltype
- fields[name] = oot
+ fields[mangled] = oot
+ try:
+ fielddefaults[mangled] = getattr(self.classdef.cls, name)
+ except AttributeError:
+ pass
ootype.addFields(self.lowleveltype, fields)
@@ -71,19 +88,20 @@
impl = self.classdef.cls.__dict__[name]
except KeyError:
continue
+ mangled = mangle(name)
if classrepr.prepare_method(attrdef.s_value) is not None:
# a regular method
f, inputs, ret = getsignature(self.rtyper, impl)
M = ootype.Meth([r.lowleveltype for r in inputs[1:]], ret.lowleveltype)
- m = ootype.meth(M, _name=name, _callable=impl,
+ m = ootype.meth(M, _name=mangled, _callable=impl,
graph=f.graph)
- methods[name] = m
- allmethods[name] = True
+ methods[mangled] = m
+ allmethods[mangled] = True
else:
# a non-method class attribute
- allclassattributes[name] = True
+ allclassattributes[mangled] = True
if not attrdef.s_value.is_constant():
- classattributes[name] = attrdef.s_value, impl
+ classattributes[mangled] = attrdef.s_value, impl
ootype.addMethods(self.lowleveltype, methods)
self.allfields = allfields
@@ -94,64 +112,66 @@
# convert_const can require 'self' to be fully initialized.
# step 2: provide default values for fields
- for name, oot in fields.items():
- try:
- impl = getattr(self.classdef.cls, name)
- except AttributeError:
- pass
- else:
- r = allfields[name]
- oovalue = r.convert_const(impl)
- ootype.addFields(self.lowleveltype, {name: (oot, oovalue)})
+ for mangled, impl in fielddefaults.items():
+ oot = fields[mangled]
+ r = allfields[mangled]
+ oovalue = r.convert_const(impl)
+ ootype.addFields(self.lowleveltype, {mangled: (oot, oovalue)})
# step 3: provide accessor methods for class attributes that are
# really overridden in subclasses
- for name, (s_value, impl) in classattributes.items():
+ for mangled, (s_value, impl) in classattributes.items():
r = self.rtyper.getrepr(s_value)
oovalue = r.convert_const(impl)
- m = self.attach_class_attr_accessor(name, oovalue, r.lowleveltype)
+ m = self.attach_class_attr_accessor(mangled, oovalue,
+ r.lowleveltype)
- def attach_class_attr_accessor(self, name, oovalue, oovaluetype):
+ def attach_class_attr_accessor(self, mangled, oovalue, oovaluetype):
def ll_getclassattr(self):
return oovalue
- ll_getclassattr = func_with_new_name(ll_getclassattr, 'll_get_' + name)
+ ll_getclassattr = func_with_new_name(ll_getclassattr,
+ 'll_get_' + mangled)
sm = self.rtyper.annotate_helper(ll_getclassattr, [self.lowleveltype])
M = ootype.Meth([], oovaluetype)
- m = ootype.meth(M, _name=name, _callable=ll_getclassattr,
+ m = ootype.meth(M, _name=mangled, _callable=ll_getclassattr,
graph=sm.graph)
- ootype.addMethods(self.lowleveltype, {name: m})
+ ootype.addMethods(self.lowleveltype, {mangled: m})
def rtype_getattr(self, hop):
- vlist = hop.inputargs(self, ootype.Void)
- attr = hop.args_s[1].const
+ v_inst, _ = hop.inputargs(self, ootype.Void)
s_inst = hop.args_s[0]
- if attr in self.allfields:
+ attr = hop.args_s[1].const
+ mangled = mangle(attr)
+ v_attr = hop.inputconst(ootype.Void, mangled)
+ if mangled in self.allfields:
# regular instance attributes
- self.lowleveltype._check_field(attr)
- return hop.genop("oogetfield", vlist,
+ self.lowleveltype._check_field(mangled)
+ return hop.genop("oogetfield", [v_inst, v_attr],
resulttype = hop.r_result.lowleveltype)
- elif attr in self.allmethods:
+ elif mangled in self.allmethods:
# special case for methods: represented as their 'self' only
# (see MethodsPBCRepr)
- return hop.r_result.get_method_from_instance(self, vlist[0],
+ return hop.r_result.get_method_from_instance(self, v_inst,
hop.llops)
- elif attr in self.allclassattributes:
+ elif mangled in self.allclassattributes:
# class attributes
if hop.s_result.is_constant():
oovalue = hop.r_result.convert_const(hop.s_result.const)
return hop.inputconst(hop.r_result, oovalue)
else:
- cname = hop.inputconst(ootype.Void, attr)
- return hop.genop("oosend", [cname, vlist[0]],
+ cname = hop.inputconst(ootype.Void, mangled)
+ return hop.genop("oosend", [cname, v_inst],
resulttype = hop.r_result.lowleveltype)
else:
raise TyperError("no attribute %r on %r" % (attr, self))
def rtype_setattr(self, hop):
attr = hop.args_s[1].const
- self.lowleveltype._check_field(attr)
- vlist = hop.inputargs(self, ootype.Void, hop.args_r[2])
- return hop.genop('oosetfield', vlist)
+ mangled = mangle(attr)
+ self.lowleveltype._check_field(mangled)
+ v_inst, _, v_newval = hop.inputargs(self, ootype.Void, hop.args_r[2])
+ v_attr = hop.inputconst(ootype.Void, mangled)
+ return hop.genop('oosetfield', [v_inst, v_attr, v_newval])
def convert_const(self, value):
if value is None:
@@ -189,7 +209,8 @@
def initialize_prebuilt_instance(self, value, result):
# then add instance attributes from this level
- for name, (oot, default) in self.lowleveltype._allfields().items():
+ for mangled, (oot, default) in self.lowleveltype._allfields().items():
+ name = unmangle(mangled)
if oot is ootype.Void:
llattrvalue = None
elif name == '_hash_cache_': # hash() support
@@ -201,8 +222,8 @@
warning("prebuilt instance %r has no attribute %r" % (
value, name))
continue
- llattrvalue = self.allfields[name].convert_const(attrvalue)
- setattr(result, name, llattrvalue)
+ llattrvalue = self.allfields[mangled].convert_const(attrvalue)
+ setattr(result, mangled, llattrvalue)
class __extend__(pairtype(InstanceRepr, InstanceRepr)):
Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rpbc.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py Tue Oct 18 11:19:32 2005
@@ -1,7 +1,7 @@
from pypy.rpython.rpbc import AbstractClassesPBCRepr, AbstractMethodsPBCRepr
from pypy.rpython.rclass import rtype_new_instance
from pypy.rpython.ootypesystem import ootype
-from pypy.rpython.ootypesystem.rclass import InstanceRepr
+from pypy.rpython.ootypesystem.rclass import InstanceRepr, mangle
from pypy.annotation.pairtype import pairtype
class ClassesPBCRepr(AbstractClassesPBCRepr):
@@ -18,7 +18,8 @@
def rtype_simple_call(self, hop):
vlist = hop.inputargs(self, *hop.args_r[1:])
- cname = hop.inputconst(ootype.Void, self.methodname)
+ mangled = mangle(self.methodname)
+ cname = hop.inputconst(ootype.Void, mangled)
return hop.genop("oosend", [cname]+vlist,
resulttype = hop.r_result.lowleveltype)
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Tue Oct 18 11:19:32 2005
@@ -178,3 +178,16 @@
return x.a
res = interpret(dummyfn, [], type_system='ootype')
assert res == 4
+
+def test_name_clashes():
+ class NameClash1(object):
+ def _TYPE(self):
+ return 6
+ def dummyfn(n):
+ x = NameClash1()
+ y = EmptyBase()
+ y._TYPE = n+1
+ return x._TYPE() * y._TYPE
+ res = interpret(dummyfn, [6], type_system='ootype')
+ assert res == 42
+
More information about the Pypy-commit
mailing list