[pypy-svn] r12961 - in pypy/dist/pypy/rpython: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Jun 1 00:08:37 CEST 2005
Author: arigo
Date: Wed Jun 1 00:08:36 2005
New Revision: 12961
Added:
pypy/dist/pypy/rpython/rclass.py (contents, props changed)
pypy/dist/pypy/rpython/test/test_rclass.py (contents, props changed)
Modified:
pypy/dist/pypy/rpython/rpbc.py
pypy/dist/pypy/rpython/rtyper.py
pypy/dist/pypy/rpython/test/test_lltype.py
Log:
Starting the object model implementation. For now, we have classes and
instances with no attribute at all.
Added: pypy/dist/pypy/rpython/rclass.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/rclass.py Wed Jun 1 00:08:36 2005
@@ -0,0 +1,120 @@
+from pypy.annotation.pairtype import pair, pairtype
+from pypy.annotation.model import SomePBC, SomeInstance
+from pypy.rpython.lltype import *
+from pypy.rpython.rtyper import inputconst
+
+
+#
+# There is one "vtable" per user class, with the following structure:
+# A root class "object" has:
+#
+# struct object_vtable {
+# struct object_vtable* parenttypeptr;
+# }
+#
+# Every other class X, with parent Y, has the structure:
+#
+# struct vtable_X {
+# struct vtable_Y super; // inlined
+# ... // extra class attributes
+# }
+
+# The type of the instances is:
+#
+# struct object { // for the root class
+# struct object_vtable* typeptr;
+# }
+#
+# struct X {
+# struct Y super; // inlined
+# ... // extra instance attributes
+# }
+#
+
+OBJECT_VTABLE = ForwardReference()
+TYPEPTR = NonGcPtr(OBJECT_VTABLE)
+OBJECT_VTABLE.become(Struct('object_vtable', ('parenttypeptr', TYPEPTR)))
+
+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 getrclassdef(classdef):
+ try:
+ return classdef._rtype_rclassdef_
+ except AttributeError:
+ classdef._rtype_rclassdef_ = result = RClassDef(classdef)
+ return result
+
+
+def rtype_new_instance(s_cls, hop):
+ assert s_cls.is_constant()
+ cls = s_cls.const
+ classdef = hop.rtyper.annotator.getuserclasses()[cls]
+ rclassdef = getrclassdef(classdef)
+ return rclassdef.rtype_new_instance(hop.llops)
+
+
+# ____________________________________________________________
+
+class __extend__(SomeInstance):
+
+ def lowleveltype(s_ins):
+ rclassdef = getrclassdef(s_ins.classdef)
+ return GcPtr(rclassdef.object_type)
Modified: pypy/dist/pypy/rpython/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/rpbc.py (original)
+++ pypy/dist/pypy/rpython/rpbc.py Wed Jun 1 00:08:36 2005
@@ -2,6 +2,7 @@
from pypy.annotation.pairtype import pair, pairtype
from pypy.annotation.model import SomePBC
from pypy.rpython.lltype import typeOf
+from pypy.rpython import rclass
class __extend__(SomePBC):
@@ -18,12 +19,13 @@
if not s_func.is_constant():
NotImplementedYet
func = s_func.const
- if not isinstance(func, types.FunctionType):
- NotImplementedYet
- # XXX hackish
- f = hop.rtyper.getfunctionptr(func)
- FUNCPTR = typeOf(f)
- args_v = hop.inputargs(*FUNCPTR.TO.ARGS)
- c = hop.inputconst(FUNCPTR, f)
- return hop.genop('direct_call', [c] + args_v,
- resulttype = FUNCPTR.TO.RESULT)
+ if isinstance(func, types.FunctionType):
+ # XXX hackish
+ f = hop.rtyper.getfunctionptr(func)
+ FUNCPTR = typeOf(f)
+ args_v = hop.inputargs(*FUNCPTR.TO.ARGS)
+ c = hop.inputconst(FUNCPTR, f)
+ return hop.genop('direct_call', [c] + args_v,
+ resulttype = FUNCPTR.TO.RESULT)
+ elif isinstance(func, (types.ClassType, type)):
+ return rclass.rtype_new_instance(s_func, hop)
Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/dist/pypy/rpython/rtyper.py Wed Jun 1 00:08:36 2005
@@ -26,6 +26,7 @@
def __init__(self, annotator):
self.annotator = annotator
self.specialized_ll_functions = {}
+ self.rclassdefs = {}
self.typererror = None
def specialize(self):
Modified: pypy/dist/pypy/rpython/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_lltype.py (original)
+++ pypy/dist/pypy/rpython/test/test_lltype.py Wed Jun 1 00:08:36 2005
@@ -112,11 +112,15 @@
py.test.raises(TypeError, "Struct('invalid', ('x', S1))")
def test_substructure_ptr():
- S2 = Struct("s2", ('a', Signed))
+ S3 = Struct("s3", ('a', Signed))
+ S2 = Struct("s2", ('s3', S3))
S1 = GcStruct("s1", ('sub1', S2), ('sub2', S2))
p1 = malloc(S1)
assert typeOf(p1.sub1) == _TmpPtr(S2)
assert typeOf(p1.sub2) == _TmpPtr(S2)
+ assert typeOf(p1.sub1.s3) == _TmpPtr(S3)
+ p2 = cast_flags(NonGcPtr(S2), p1.sub1)
+ assert typeOf(p2.s3) == _TmpPtr(S3)
def test_gc_substructure_ptr():
S1 = GcStruct("s2", ('a', Signed))
Added: pypy/dist/pypy/rpython/test/test_rclass.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/test/test_rclass.py Wed Jun 1 00:08:36 2005
@@ -0,0 +1,21 @@
+from pypy.translator.translator import Translator
+from pypy.rpython.lltype import *
+from pypy.rpython.rtyper import RPythonTyper
+
+
+
+class EmptyBase(object):
+ pass
+
+
+def test_simple():
+ def dummyfn():
+ x = EmptyBase()
+ return x
+
+ t = Translator(dummyfn)
+ t.annotate([])
+ typer = RPythonTyper(t.annotator)
+ typer.specialize()
+ t.view()
+ t.checkgraphs()
More information about the Pypy-commit
mailing list