[pypy-svn] r18674 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem ootypesystem/test

mwh at codespeak.net mwh at codespeak.net
Sun Oct 16 11:53:02 CEST 2005


Author: mwh
Date: Sun Oct 16 11:52:59 2005
New Revision: 18674

Modified:
   pypy/dist/pypy/rpython/lltypesystem/rpbc.py
   pypy/dist/pypy/rpython/ootypesystem/rclass.py
   pypy/dist/pypy/rpython/ootypesystem/rpbc.py
   pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py
   pypy/dist/pypy/rpython/rpbc.py
Log:
(boria, mwh, bert, samuele, arigo, anyone else who wants some credit/blame :)
* move a large part of lltypesystem.rpbc.MethodsPBCRepr back into rpbc
  as AbstractMethodsPBCRepr and have what's left inherit from this.
* implement ootypesystem.rpbc.MethodsPBCRepr.
* extend ootypesystem.rclass.InstanceRepr to have some support for 
  methods (no support for overriding yet).
* enable a simple test that calls a method.



Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rpbc.py	Sun Oct 16 11:52:59 2005
@@ -12,7 +12,7 @@
 from pypy.rpython.rpbc import SingleFrozenPBCRepr, getsignature, samesig,\
                                 commonbase, allattributenames, get_access_set,\
                                 MultiplePBCRepr, FunctionsPBCRepr, \
-                                AbstractClassesPBCRepr
+                                AbstractClassesPBCRepr, AbstractMethodsPBCRepr
 from pypy.rpython.lltypesystem import rclass
 from pypy.tool.sourcetools import has_varargs
 
@@ -174,59 +174,11 @@
     
 # ____________________________________________________________
 
-class MethodsPBCRepr(Repr):
+class MethodsPBCRepr(AbstractMethodsPBCRepr):
     """Representation selected for a PBC of the form {func: classdef...}.
     It assumes that all the methods come from the same name in a base
     classdef."""
 
-    def __init__(self, rtyper, s_pbc):
-        self.rtyper = rtyper
-        self.s_pbc = s_pbc
-        if None in s_pbc.prebuiltinstances:
-            raise TyperError("unsupported: variable of type "
-                             "bound-method-object or None")
-        basedef = commonbase(s_pbc.prebuiltinstances.values())
-        for classdef1, name in allattributenames(basedef):
-            # don't trust the func.func_names and see if this 'name' would be
-            # the one under which we can find all these methods
-            for func, classdef in s_pbc.prebuiltinstances.items():
-                try:
-                    if func != getattr(classdef.cls, name).im_func:
-                        break
-                except AttributeError:
-                    break
-            else:
-                # yes!
-                self.methodname = name
-                self.classdef = classdef1   # where the Attribute is defined
-                break
-        else:
-            raise TyperError("cannot find a unique name under which the "
-                             "methods can be found: %r" % (
-                s_pbc.prebuiltinstances,))
-        # the low-level representation is just the bound 'self' argument.
-        self.s_im_self = annmodel.SomeInstance(self.classdef)
-        self.r_im_self = rclass.getinstancerepr(rtyper, self.classdef)
-        self.lowleveltype = self.r_im_self.lowleveltype
-
-    def convert_const(self, method):
-        if getattr(method, 'im_func', None) is None:
-            raise TyperError("not a bound method: %r" % method)
-        return self.r_im_self.convert_const(method.im_self)
-
-    def get_r_implfunc(self):
-        r_class = self.r_im_self.rclass
-        mangled_name, r_func = r_class.clsfields[self.methodname]
-        return r_func, 1
-
-    def get_s_callable(self):
-        return self.s_pbc
-
-    def get_method_from_instance(self, r_inst, v_inst, llops):
-        # The 'self' might have to be cast to a parent class
-        # (as shown for example in test_rclass/test_method_both_A_and_B)
-        return llops.convertvar(v_inst, r_inst, self.r_im_self)
-
     def rtype_hardwired_simple_call(self, hop):
         return self.redispatch_call(hop, call_args=False, hardwired=True)
 

Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rclass.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rclass.py	Sun Oct 16 11:52:59 2005
@@ -1,6 +1,7 @@
 from pypy.rpython.rmodel import inputconst
 from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr, \
                                 getinstancerepr
+from pypy.rpython.rpbc import getsignature
 from pypy.rpython.ootypesystem import ootype
 
 CLASSTYPE = ootype.Class
@@ -28,6 +29,7 @@
 
         self.lowleveltype = ootype.Instance(classdef.cls.__name__, b, {}, {})
         self.prebuiltinstances = {}   # { id(x): (x, _ptr) }
+        self.allmethods = {}
 
     def _setup_repr(self):
         # FIXME methods
@@ -41,6 +43,23 @@
                 fields[name] = oot
 
         ootype.addFields(self.lowleveltype, fields)
+
+        methods = {}
+        baseInstance = self.lowleveltype._superclass
+
+        for name, attrdef in attrs:
+            if attrdef.readonly:
+                assert len(attrdef.s_value.prebuiltinstances) == 1, 'no support for overridden methods yet'
+                # XXX following might not always succeed
+                impl = self.classdef.cls.__dict__[name]
+
+                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)
+                
+                methods[name] = m
+
+        ootype.addMethods(self.lowleveltype, methods)
             
     def rtype_getattr(self, hop):
         attr = hop.args_s[1].const

Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py	Sun Oct 16 11:52:59 2005
@@ -1,6 +1,8 @@
-from pypy.rpython.rpbc import AbstractClassesPBCRepr
+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.annotation.pairtype import pairtype
 
 class ClassesPBCRepr(AbstractClassesPBCRepr):
     def rtype_simple_call(self, hop):
@@ -10,3 +12,19 @@
         klass = self.s_pbc.const
         v_instance = rtype_new_instance(hop.rtyper, klass, hop.llops)
         return v_instance
+
+
+class MethodsPBCRepr(AbstractMethodsPBCRepr):
+
+    def rtype_simple_call(self, hop):
+        vlist = hop.inputargs(self, *hop.args_r[1:])
+        cname = hop.inputconst(ootype.Void, self.methodname)
+        return hop.genop("oosend", [cname]+vlist,
+                         resulttype = hop.r_result.lowleveltype)
+
+        
+
+class __extend__(pairtype(InstanceRepr, MethodsPBCRepr)):
+
+    def convert_from_to(_, v, llops):
+        return v

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	Sun Oct 16 11:52:59 2005
@@ -81,8 +81,8 @@
         return 1
         
 def test_method():
-    py.test.skip('in progress')
     def dummyfn():
         inst = HasAMethod()
         return inst.f()
-    specialize(dummyfn, [])#, viewBefore=True)
+    result = interpret(dummyfn, [], type_system='ootype')
+    assert result == 1

Modified: pypy/dist/pypy/rpython/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/rpbc.py	Sun Oct 16 11:52:59 2005
@@ -361,6 +361,59 @@
             return inputconst(r_clspbc2, r_clspbc1.s_pbc.const)
         return NotImplemented
 
+class AbstractMethodsPBCRepr(Repr):
+    """Representation selected for a PBC of the form {func: classdef...}.
+    It assumes that all the methods come from the same name in a base
+    classdef."""
+
+    def __init__(self, rtyper, s_pbc):
+        self.rtyper = rtyper
+        self.s_pbc = s_pbc
+        if None in s_pbc.prebuiltinstances:
+            raise TyperError("unsupported: variable of type "
+                             "bound-method-object or None")
+        basedef = commonbase(s_pbc.prebuiltinstances.values())
+        for classdef1, name in allattributenames(basedef):
+            # don't trust the func.func_names and see if this 'name' would be
+            # the one under which we can find all these methods
+            for func, classdef in s_pbc.prebuiltinstances.items():
+                try:
+                    if func != getattr(classdef.cls, name).im_func:
+                        break
+                except AttributeError:
+                    break
+            else:
+                # yes!
+                self.methodname = name
+                self.classdef = classdef1   # where the Attribute is defined
+                break
+        else:
+            raise TyperError("cannot find a unique name under which the "
+                             "methods can be found: %r" % (
+                s_pbc.prebuiltinstances,))
+        # the low-level representation is just the bound 'self' argument.
+        self.s_im_self = annmodel.SomeInstance(self.classdef)
+        self.r_im_self = rclass.getinstancerepr(rtyper, self.classdef)
+        self.lowleveltype = self.r_im_self.lowleveltype
+
+    def convert_const(self, method):
+        if getattr(method, 'im_func', None) is None:
+            raise TyperError("not a bound method: %r" % method)
+        return self.r_im_self.convert_const(method.im_self)
+
+    def get_r_implfunc(self):
+        r_class = self.r_im_self.rclass
+        mangled_name, r_func = r_class.clsfields[self.methodname]
+        return r_func, 1
+
+    def get_s_callable(self):
+        return self.s_pbc
+
+    def get_method_from_instance(self, r_inst, v_inst, llops):
+        # The 'self' might have to be cast to a parent class
+        # (as shown for example in test_rclass/test_method_both_A_and_B)
+        return llops.convertvar(v_inst, r_inst, self.r_im_self)
+
 # ____________________________________________________________
 
 def getsignature(rtyper, func):



More information about the Pypy-commit mailing list