[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