[pypy-svn] r13055 - in pypy/dist/pypy/rpython: . test
arigo at codespeak.net
arigo at codespeak.net
Sat Jun 4 14:03:00 CEST 2005
Author: arigo
Date: Sat Jun 4 14:03:00 2005
New Revision: 13055
Modified:
pypy/dist/pypy/rpython/rclass.py
pypy/dist/pypy/rpython/test/test_rclass.py
Log:
Simple class attributes.
Modified: pypy/dist/pypy/rpython/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/rclass.py (original)
+++ pypy/dist/pypy/rpython/rclass.py Sat Jun 4 14:03:00 2005
@@ -63,16 +63,27 @@
def __init__(self, rtyper, classdef):
self.classdef = classdef
+ self.clsfields = {}
if classdef is None:
# 'object' root type
self.vtable_type = OBJECT_VTABLE
self.typeptr = nullptr(OBJECT_VTABLE)
else:
+ # instance attributes
+ llfields = []
+ attrs = classdef.attrs.items()
+ attrs.sort()
+ for name, attrdef in attrs:
+ if attrdef.readonly:
+ r = rtyper.getrepr(attrdef.s_value)
+ mangled_name = name + '_C'
+ self.clsfields[name] = mangled_name, r
+ llfields.append((mangled_name, r.lowleveltype))
+ #
self.rbase = getclassrepr(rtyper, classdef.basedef)
self.vtable_type = Struct('%s_vtable' % classdef.cls.__name__,
('super', self.rbase.vtable_type),
- # XXX class attributes
- )
+ *llfields)
self.lowleveltype = NonGcPtr(self.vtable_type)
self.vtable = None
@@ -102,6 +113,55 @@
# then initialize the 'super' portion of the vtable
self.rbase.setup_vtable(vtable.super, rsubcls)
+ def fromparentpart(self, v_vtableptr, llops):
+ """Return the vtable pointer cast from the parent vtable's type
+ to self's vtable type."""
+ ctype = inputconst(Void, self.lowleveltype)
+ return llops.genop('cast_parent', [ctype, v_vtableptr],
+ resulttype=self.lowleveltype)
+
+ def fromtypeptr(self, vcls, llops):
+ """Return the type pointer cast to self's vtable type."""
+ if self.classdef is None:
+ return vcls
+ else:
+ v_vtableptr = self.rbase.fromtypeptr(vcls, llops)
+ return self.fromparentpart(v_vtableptr, llops)
+
+ def getclsfieldrepr(self, attr):
+ """Return the repr used for the given attribute."""
+ if attr in self.clsfields:
+ mangled_name, r = self.clsfields[attr]
+ return r
+ else:
+ if self.classdef is None:
+ raise MissingRTypeAttribute(attr)
+ return self.rbase.getfieldrepr(attr)
+
+ def getclsfield(self, vcls, attr, llops):
+ """Read the given attribute of 'vcls'."""
+ if attr in self.clsfields:
+ mangled_name, r = self.clsfields[attr]
+ v_vtable = self.fromtypeptr(vcls, llops)
+ cname = inputconst(Void, mangled_name)
+ return llops.genop('getfield', [v_vtable, cname], resulttype=r)
+ else:
+ if self.classdef is None:
+ raise MissingRTypeAttribute(attr)
+ return self.rbase.getclsfield(vcls, attr, llops)
+
+ def setclsfield(self, vcls, attr, vvalue, llops):
+ """Write the given attribute of 'vcls'."""
+ if attr in self.clsfields:
+ mangled_name, r = self.clsfields[attr]
+ v_vtable = self.fromtypeptr(vcls, llops)
+ cname = inputconst(Void, mangled_name)
+ llops.genop('setfield', [v_vtable, cname, vvalue])
+ else:
+ if self.classdef is None:
+ raise MissingRTypeAttribute(attr)
+ self.rbase.setclsfield(vcls, attr, vvalue, llops)
+
root_class_repr = ClassRepr(None, None)
type_repr = root_class_repr
@@ -120,49 +180,44 @@
self.classdef = classdef
self.rclass = getclassrepr(rtyper, classdef)
self.fields = {}
+ self.allinstancefields = {}
if self.classdef is None:
self.fields['__class__'] = 'typeptr', TYPEPTR
self.object_type = OBJECT
else:
- # instance attributes (XXX remove class attributes from here)
+ # instance attributes
llfields = []
attrs = classdef.attrs.items()
attrs.sort()
for name, attrdef in attrs:
- r = rtyper.getrepr(attrdef.s_value)
- mangled_name = name + '_'
- self.fields[name] = mangled_name, r
- llfields.append((mangled_name, r.lowleveltype))
+ if not attrdef.readonly:
+ r = rtyper.getrepr(attrdef.s_value)
+ mangled_name = name + '_'
+ self.fields[name] = mangled_name, r
+ llfields.append((mangled_name, r.lowleveltype))
#
self.rbase = getinstancerepr(rtyper, classdef.basedef)
self.object_type = GcStruct(classdef.cls.__name__,
('super', self.rbase.object_type),
*llfields)
+ self.allinstancefields.update(self.rbase.allinstancefields)
self.lowleveltype = GcPtr(self.object_type)
+ self.allinstancefields.update(self.fields)
def parentpart(self, vinst, llops):
"""Return the pointer 'vinst' cast to the parent type."""
- try:
- supercache = llops.__super_cache
- except AttributeError:
- supercache = llops.__super_cache = {}
- #
- if vinst not in supercache:
- cname = inputconst(Void, 'super')
- supercache[vinst] = llops.genop('getsubstruct', [vinst, cname],
- resulttype=self.rbase.lowleveltype)
- return supercache[vinst]
+ cname = inputconst(Void, 'super')
+ return llops.genop('getsubstruct', [vinst, cname],
+ resulttype=self.rbase.lowleveltype)
def getfieldrepr(self, attr):
"""Return the repr used for the given attribute."""
- if self.classdef is None:
- if attr == '__class__':
- return TYPEPTR
- raise MissingRTypeAttribute(attr)
- elif attr in self.fields:
+ if attr in self.fields:
mangled_name, r = self.fields[attr]
return r
else:
+ if self.classdef is None:
+ raise MissingRTypeAttribute(attr)
return self.rbase.getfieldrepr(attr)
def getfield(self, vinst, attr, llops):
@@ -206,7 +261,11 @@
def rtype_getattr(self, hop):
attr = hop.args_s[1].const
vinst, vattr = hop.inputargs(self, Void)
- return self.getfield(vinst, attr, hop.llops)
+ if attr in self.allinstancefields:
+ return self.getfield(vinst, attr, hop.llops)
+ else:
+ vcls = self.getfield(vinst, '__class__', hop.llops)
+ return self.rclass.getclsfield(vcls, attr, hop.llops)
def rtype_setattr(self, hop):
attr = hop.args_s[1].const
Modified: pypy/dist/pypy/rpython/test/test_rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rclass.py (original)
+++ pypy/dist/pypy/rpython/test/test_rclass.py Sat Jun 4 14:03:00 2005
@@ -33,3 +33,20 @@
typer.specialize()
#t.view()
t.checkgraphs()
+
+
+class Random:
+ xyzzy = 12
+ yadda = 21
+
+def test_classattr():
+ def dummyfn():
+ x = Random()
+ return x.xyzzy
+
+ t = Translator(dummyfn)
+ t.annotate([])
+ typer = RPythonTyper(t.annotator)
+ typer.specialize()
+ #t.view()
+ t.checkgraphs()
More information about the Pypy-commit
mailing list