[pypy-svn] r13050 - pypy/branch/rpython-refactoring
arigo at codespeak.net
arigo at codespeak.net
Sat Jun 4 12:10:50 CEST 2005
Author: arigo
Date: Sat Jun 4 12:10:50 2005
New Revision: 13050
Modified:
pypy/branch/rpython-refactoring/rclass.py
pypy/branch/rpython-refactoring/rpbc.py
Log:
A nice and clean -- if still quite strange -- version of rclass.py.
Modified: pypy/branch/rpython-refactoring/rclass.py
==============================================================================
--- pypy/branch/rpython-refactoring/rclass.py (original)
+++ pypy/branch/rpython-refactoring/rclass.py Sat Jun 4 12:10:50 2005
@@ -37,99 +37,153 @@
OBJECT = GcStruct('object', ('typeptr', TYPEPTR))
-class RClassDef:
-
- def __init__(self, classdef):
- self.classdef = classdef
- if classdef.basedef is None:
- self.depth = 1
- parent_vtable_type = OBJECT_VTABLE
- parent_typeptr = nullptr(OBJECT_VTABLE)
- parent_object_type = OBJECT
- else:
- rbasedef = getrclassdef(classdef.basedef)
- self.depth = rbasedef.depth + 1
- parent_vtable_type = rbasedef.vtable_type
- parent_typeptr = rbasedef.typeptr
- parent_object_type = rbasedef.object_type
- self.vtable_type = Struct('%s_vtable' % classdef.cls.__name__,
- ('super', parent_vtable_type),
- # XXX class attributes
- )
- self.vtable = malloc(self.vtable_type, immortal=True)
- # cast the vtable pointer from "vtable_type" to "parent_vtable_type"
- # to "parent_parent_vtable_type" to .... to OBJECT_VTABLE
- p = self.vtable
- for i in range(self.depth):
- p = p.super
- self.typeptr = cast_flags(TYPEPTR, p)
- p.parenttypeptr = parent_typeptr
- #
- self.parent_object_type = parent_object_type
- self.object_type = GcStruct(classdef.cls.__name__,
- ('super', parent_object_type),
- # XXX instance attributes
- )
-
- def parent_cast(self, targetclassdef, v, llops):
- classdef = self.classdef
- super_name = inputconst(Void, "super")
- while classdef is not targetclassdef:
- rclassdef = getrclassdef(classdef)
- parent_object_type = rclassdef.parent_object_type
- v = llops.genop('getsubstruct', [v, super_name],
- resulttype = GcPtr(parent_object_type))
- classdef = classdef.basedef
- return v
-
- def rtype_new_instance(self, llops):
- ctype = inputconst(Void, self.object_type)
- vptr = llops.genop('malloc', [ctype],
- resulttype = GcPtr(self.object_type))
- vptr_as_object = self.parent_cast(None, vptr, llops)
- typeptr_name = inputconst(Void, "typeptr")
- ctypeptr = inputconst(TYPEPTR, self.typeptr)
- llops.genop('setfield', [vptr_as_object, typeptr_name, ctypeptr])
- # XXX call __init__ somewhere
- return vptr
-
+def getclassrepr(classdef):
+ if classdef is None:
+ return root_class_repr
+ try:
+ return classdef._rtype_classrepr_
+ except AttributeError:
+ classdef._rtype_classrepr_ = result = ClassRepr(classdef)
+ return result
-def getrclassdef(classdef):
+def getinstancerepr(classdef):
+ if classdef is None:
+ return root_instance_repr
try:
- return classdef._rtype_rclassdef_
+ return classdef._rtype_instancerepr_
except AttributeError:
- classdef._rtype_rclassdef_ = result = RClassDef(classdef)
+ classdef._rtype_instancerepr_ = result = InstanceRepr(classdef)
return result
-def rtype_new_instance(cls, hop):
- classdef = hop.rtyper.annotator.getuserclasses()[cls]
- rclassdef = getrclassdef(classdef)
- return rclassdef.rtype_new_instance(hop.llops)
+class ClassRepr(Repr):
+
+ def __init__(self, classdef):
+ self.classdef = classdef
+ if classdef is None:
+ # 'object' root type
+ self.vtable_type = OBJECT_VTABLE
+ self.typeptr = nullptr(OBJECT_VTABLE)
+ else:
+ self.rbase = getclassrepr(classdef.basedef)
+ self.vtable_type = Struct('%s_vtable' % classdef.cls.__name__,
+ ('super', self.rbase.vtable_type),
+ # XXX class attributes
+ )
+ self.lowleveltype = NonGcPtr(self.vtable_type)
+ self.vtable = None
+
+ def getvtable(self, cast_to_typeptr=True):
+ """Return a ptr to the vtable of this type."""
+ if self.vtable is None:
+ self.vtable = malloc(self.vtable_type, immortal=True)
+ if self.classdef is not None:
+ self.setup_vtable(self.vtable, self.classdef)
+ #
+ vtable = self.vtable
+ if cast_to_typeptr:
+ r = self
+ while r is not root_class_repr:
+ r = r.rbase
+ vtable = cast_flags(r.lowleveltype, vtable.super)
+ return vtable
+
+ def setup_vtable(self, vtable, subclsdef):
+ """Initialize the 'self' portion of the 'vtable' belonging to the
+ 'subclsdef'."""
+ if self.classdef is None:
+ # initialize the 'parenttypeptr' field
+ rbase = getclassrepr(subclsdef.basedef)
+ vtable.parenttypeptr = rbase.getvtable()
+ else:
+ # XXX setup class attributes
+ # then initialize the 'super' portion of the vtable
+ self.rbase.setup_vtable(vtable.super, subclsdef)
+root_class_repr = ClassRepr(None)
+type_repr = root_class_repr
+
# ____________________________________________________________
+
class __extend__(annmodel.SomeInstance):
def rtyper_makerepr(self, rtyper):
- return InstanceRepr(self.classdef)
+ return getinstancerepr(self.classdef)
class InstanceRepr(Repr):
def __init__(self, classdef):
- self.rclassdef = getrclassdef(classdef)
- self.lowleveltype = GcPtr(self.rclassdef.object_type)
+ self.classdef = classdef
+ self.rclass = getclassrepr(classdef)
+ if self.classdef is None:
+ self.object_type = OBJECT
+ else:
+ self.rbase = getinstancerepr(classdef.basedef)
+ self.object_type = GcStruct(classdef.cls.__name__,
+ ('super', self.rbase.object_type),
+ # XXX instance attributes
+ )
+ self.lowleveltype = GcPtr(self.object_type)
+
+ 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]
+
+ def getfield(self, vinst, attr, llops):
+ """Read the given attribute (or __class__ for the type) of 'vinst'."""
+ if self.classdef is None:
+ if attr != '__class__':
+ raise TyperError("attribute error: %s" % attr)
+ cname = inputconst(Void, 'typeptr')
+ return llops.genop('getfield', [vinst, cname], resulttype=TYPEPTR)
+ else:
+ # XXX instance attributes
+ vsuper = self.parentpart(vinst, llops)
+ return self.rbase.getfield(vsuper, attr, llops)
+
+ def setfield(self, vinst, attr, vvalue, llops):
+ """Write the given attribute (or __class__ for the type) of 'vinst'."""
+ if self.classdef is None:
+ if attr != '__class__':
+ raise TyperError("attribute error: %s" % attr)
+ cname = inputconst(Void, 'typeptr')
+ llops.genop('setfield', [vinst, cname, vvalue])
+ else:
+ # XXX instance attributes
+ vsuper = self.parentpart(vinst, llops)
+ self.rbase.getfield(vsuper, attr, llops)
+
+ def new_instance(self, llops):
+ """Build a new instance, without calling __init__."""
+ ctype = inputconst(Void, self.object_type)
+ vptr = llops.genop('malloc', [ctype],
+ resulttype = GcPtr(self.object_type))
+ ctypeptr = inputconst(TYPEPTR, self.rclass.getvtable())
+ self.setfield(vptr, '__class__', ctypeptr, llops)
+ # XXX instance attributes
+ return vptr
def rtype_type(self, hop):
- vptr, = hop.inputargs(self)
- vptr_as_object = self.rclassdef.parent_cast(None, vptr, hop.llops)
- typeptr_name = hop.inputconst(Void, "typeptr")
- return hop.genop('getfield', [vptr_as_object, typeptr_name],
- resulttype=TYPEPTR)
+ vinst, = hop.inputargs(self)
+ return self.getfield(vinst, '__class__', hop.llops)
-class TypeRepr(Repr):
- lowleveltype = TYPEPTR
+root_instance_repr = InstanceRepr(None)
-type_repr = TypeRepr()
+# ____________________________________________________________
+
+def rtype_new_instance(cls, hop):
+ classdef = hop.rtyper.annotator.getuserclasses()[cls]
+ rinstance = getinstancerepr(classdef)
+ return rinstance.new_instance(hop.llops)
Modified: pypy/branch/rpython-refactoring/rpbc.py
==============================================================================
--- pypy/branch/rpython-refactoring/rpbc.py (original)
+++ pypy/branch/rpython-refactoring/rpbc.py Sat Jun 4 12:10:50 2005
@@ -45,3 +45,4 @@
resulttype = rresult)
elif isinstance(func, (types.ClassType, type)):
return rclass.rtype_new_instance(s_func.const, hop)
+ # XXX call __init__ somewhere
More information about the Pypy-commit
mailing list