[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