[pypy-svn] r28714 - in pypy/dist/pypy/rpython: . ootypesystem ootypesystem/test rctypes

fijal at codespeak.net fijal at codespeak.net
Mon Jun 12 17:56:51 CEST 2006


Author: fijal
Date: Mon Jun 12 17:56:49 2006
New Revision: 28714

Modified:
   pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
   pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py
   pypy/dist/pypy/rpython/rbuiltin.py
   pypy/dist/pypy/rpython/rctypes/implementation.py
   pypy/dist/pypy/rpython/rexternalobj.py
Log:
RTyper level of External Builtin Object support.


Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/bltregistry.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py	Mon Jun 12 17:56:49 2006
@@ -7,9 +7,15 @@
 from pypy.annotation import model as annmodel
 from pypy.objspace.flow.model import Variable, Constant
 from pypy.rpython.ootypesystem import ootype
+from pypy.annotation.bookkeeper import getbookkeeper
+from pypy.rpython.lltypesystem.lltype import frozendict, isCompatibleType
+from types import MethodType
 
 class BasicMetaExternal(type):
-    pass
+    def _is_compatible(type2):
+        return type(type2) is BasicMetaExternal
+    
+    _is_compatible = staticmethod(_is_compatible)
 
 class BasicExternal(object):
     __metaclass__ = BasicMetaExternal
@@ -20,19 +26,54 @@
 from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.rpython.rmodel import Repr
 
+class Analyzer(object):
+    def __init__(self, name, value):
+        self.name = name
+        self.args, self.retval = value
+    
+    def __call__(self, *args):
+        #for i in xrange(len(args)):
+        #    assert getbookkeeper().valueoftype(self.args[i]).contains(args[i])
+        if self.retval is None:
+            return None
+        return getbookkeeper().valueoftype(self.retval)
 
 class ExternalType(ootype.Instance):
     class_dict = {}
+    __name__ = "ExternalType"
+    _TYPE = BasicMetaExternal
     
     def __init__(self, _class):
         # FIXME: We want to support inheritance at some point
         self._class_ = _class
-        _methods = dict([(i,ootype._meth(ootype.Meth(*val))) for i,val in _class._methods.iteritems()])
-        ootype.Instance.__init__(self, str(_class), None, _class._fields, _methods, True)
+        self._name = str(_class)
+        self._superclass = None
+        self._root = True
+        self._fields = {}
+        self.updated = False
+        self._data = _class._fields, _class._methods
+        #self._methods = _class._methods
+        #_methods = dict([(i,ootype._meth(ootype.Meth(*val))) for i,val in _class._methods.iteritems()])
+        #ootype.Instance.__init__(self, str(_class), None, _class._fields, _methods, True)
+        #self.attr = {}
+    
+    def update_fields(self, _fields):
+        for i, val in _fields.iteritems():
+            self._fields[i] = getbookkeeper().valueoftype(val)
+    
+    def update_methods(self, _methods):
+        _signs = {}
+        for i, val in _methods.iteritems():
+            if val[1] is None:
+                retval = None
+            else:
+                retval = getbookkeeper().valueoftype(val[1])
+            _signs[i] = tuple([getbookkeeper().valueoftype(j) for j in val[0]]), retval
+            next = annmodel.SomeBuiltin(Analyzer(i, val), s_self = annmodel.SomeExternalBuiltin(self), methodname = i)
+            next.const = True
+            self._fields[i] = next
+        self._methods = frozendict(_signs)
     
-##    def _example(self):
-##        return ootype._instance(self)
-
     def get(class_):
         try:
             return ExternalType.class_dict[class_]
@@ -40,57 +81,57 @@
             next = ExternalType(class_)
             ExternalType.class_dict[class_] = next
             return next
-
-    get = staticmethod(get)
     
-##    def _init_instance(self, inst):
-##        for i,val in self._fields.iteritems():
-##            inst.__dict__[i] = val
-##    
-##    def _lookup(self, name):
-##        return self, None
-##    
-##    def _lookup_field(self, name):
-##        return self, self.fields.get(name)
-##    
-##    def _has_field(self, name):
-##        return self._fields.get(name) is not None
-##    
-##    def _field_type(self, name):
-##        return self._fields[name]
-##    
-##    def _check_field(self, name):
-##        return True
-##    
-##    def __repr__(self):
-##        return "<Externaltype%r>" % self._class
-##    
-##    def __str__(self):
-##        return "ExternalType(%s)" % self._class
-
-##class ExternalInstance(ootype.OOType):
-##    pass
-##
-##ExternalInstanceSingleton = ExternalInstance()
+    def set_field(self, attr, knowntype):
+        self.check_update()
+        self._fields[attr] = knowntype
+        
+    def check_update(self):
+        if not self.updated:
+            _fields, _methods = self._data
+            self.update_methods(_methods)
+            self.update_fields(_fields)
+            self.updated = True
+            self._fields = frozendict(self._fields)
+            del self._data
+    
+    def get_field(self, attr):
+        self.check_update()
+        return self._fields[attr]
+    
+    def find_method(self, meth):
+        raise NotImplementedError()
+    
+    def __repr__(self):
+        return "%s %s" % (self.__name__, self._name)
+    
+    get = staticmethod(get)
 
 class Entry_basicexternalmeta(ExtRegistryEntry):
-    _metatype_ = BasicMetaExternal    
+    _metatype_ = BasicMetaExternal
     
     def compute_annotation(self):
-        return annmodel.SomeOOInstance(ootype=ExternalType.get(self.instance))
+        return annmodel.SomeExternalBuiltin(ExternalType.get(self.instance.__class__))
+    
+    def get_field_annotation(self, ext_obj, attr):
+        return ext_obj.get_field(attr)
+    
+    def set_field_annotation(self, ext_obj, attr, s_val):
+        ext_obj.set_field(attr, s_val)
 
 class Entry_basicexternal(ExtRegistryEntry):
     _type_ = BasicExternal.__metaclass__
     
     #def compute_annotation(self, *args):
     #    return annmodel.SomeOOInstance(ootype=BasicExternal)
+    
     def compute_result_annotation(self):
-        return annmodel.SomeOOInstance(ootype=ExternalType.get(self.instance))
+        return annmodel.SomeExternalBuiltin(ExternalType.get(self.instance))
+        #Ereturn annmodel.SomeOOInstance(ExternalType.get(self.instance))
     
     def specialize_call(self, hop):
         #assert isinstance(hop.args_s[0], annmodel.SomeOOInstance)\
         #       and hop.args_s[0].ootype is Externaltype
-        #import pdb; pdb.set_trace()
         _class = hop.r_result.lowleveltype._class_
         return hop.genop('new', [Constant(ExternalType.get(_class), concretetype=ootype.Void)], \
             resulttype = ExternalType.get(_class))

Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py	Mon Jun 12 17:56:49 2006
@@ -2,12 +2,14 @@
 """ Builtin annotation test
 """
 
+import autopath
+
 from pypy.annotation import model as annmodel
 from pypy.objspace.flow import FlowObjSpace
 from pypy.annotation.annrpython import RPythonAnnotator
 import exceptions
 from pypy.rpython.ootypesystem.bltregistry import BasicExternal, ExternalType
-from pypy.rpython.ootypesystem.ootype import Signed
+from pypy.rpython.ootypesystem.ootype import Signed, _static_meth, StaticMethod, Void
 from pypy.rpython.test.test_llinterp import interpret
 
 class C(BasicExternal):
@@ -19,31 +21,43 @@
     
     a = RPythonAnnotator()
     s = a.build_types(new, [])
-    assert isinstance(s.ootype, ExternalType)
-    assert s.ootype._class_ is C
+    assert isinstance(s.knowntype, ExternalType)
+    assert s.knowntype._class_ is C
 
 class A(BasicExternal):
     _fields = {
-        'b' : Signed,
+        'b' : int,
     }
 
 def test_bltn_attrs():
     def access_attr():
         a = A()
-        a.b = 3
         return a.b
     
     a = RPythonAnnotator()
     s = a.build_types(access_attr, [])
     assert s.knowntype is int
 
+class AA(BasicExternal):
+    pass
+
+def test_bltn_set_attr():
+    def add_attr():
+        a = AA()
+        a.b = 3
+        return a.b
+    
+    a = RPythonAnnotator()
+    s = a.build_types(add_attr, [])
+    assert s.knowntype is int
+
 class B(BasicExternal):
     _fields = {
-        'a' : Signed,
+        'a' : int,
     }
     
     _methods = {
-        'm' : ([Signed],Signed),
+        'm' : ([int],int),
     }
 
 def test_bltn_method():
@@ -64,3 +78,21 @@
     a = RPythonAnnotator()
     s = a.build_types(access_global, [])
     assert s.knowntype is int
+
+class CB(BasicExternal):
+    pass
+
+def some_int():
+    return 3
+    
+def test_flowin():
+    #py.test.skip("Can we assume that it might work?")
+    def set_callback():
+        a = CB()
+        a.m = some_int
+        return a.m()
+    
+    a = RPythonAnnotator()
+    s = a.build_types(set_callback, [])
+    assert s.knowntype is int
+

Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Mon Jun 12 17:56:49 2006
@@ -49,7 +49,6 @@
             # to it.
             return (self.__class__, self.methodname, id(self.s_self))
 
-
 class BuiltinFunctionRepr(Repr):
     lowleveltype = lltype.Void
 

Modified: pypy/dist/pypy/rpython/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/implementation.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/implementation.py	Mon Jun 12 17:56:49 2006
@@ -91,7 +91,6 @@
 ##        """To be overriden for ctypes objects whose mere presence influences
 ##        annotation, e.g. callback functions."""
 
-
 class CTypesCallEntry(CTypesEntry):
     "Annotation and rtyping of calls to ctypes types."
 

Modified: pypy/dist/pypy/rpython/rexternalobj.py
==============================================================================
--- pypy/dist/pypy/rpython/rexternalobj.py	(original)
+++ pypy/dist/pypy/rpython/rexternalobj.py	Mon Jun 12 17:56:49 2006
@@ -1,5 +1,6 @@
 from pypy.annotation import model as annmodel
 from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.rmodel import Repr
 from pypy.rpython.extfunctable import typetable
 from pypy.rpython import rbuiltin
@@ -27,7 +28,54 @@
             del attrs['const_box']
         return self.__class__, attrs
 
+class ExternalBuiltinRepr(Repr):
+    def __init__(self, knowntype):
+        self.knowntype = knowntype
+        self.lowleveltype = knowntype
+    
+    def convert_const(self, value):
+        from pypy.rpython.ootypesystem.bltregistry import ExternalType
+        if value is None:
+            return lltype.Void
+        return ExternalType.get(value)
+    
+    def rtype_getattr(self, hop):
+        s_attr = hop.args_s[1]
+        if s_attr.is_constant() and isinstance(s_attr.const, str):
+            field = self.knowntype.get_field(s_attr.const)
+            if isinstance(field, annmodel.SomeBuiltin):
+                # we need to type it as static method
+                args, retval = self.knowntype._methods[s_attr.const]
+                ll_args = [i.rtyper_makerepr(hop.rtyper).lowleveltype for i in args]
+                if retval is None:
+                    ll_retval = ootype.Void
+                else:
+                    ll_retval = retval.rtyper_makerepr(hop.rtyper).lowleveltype
+                return Constant(hop.args_v[0], concretetype=self.lowleveltype)
+                #return Constant(ootype.StaticMethod(ll_args, ll_retval), concretetype=self.lowleveltype)
+                #return Constant(ootype.StaticMethod(ll_args, ll_retval), concretetype = lltype.Void)
+            return self.knowntype.get_field(s_attr.const).rtyper_makerepr(hop.repr).lowleveltype
+        else:
+            raise TyperError("getattr() with a non-constant attribute name")
+    
+    def call_method(self, name, hop):
+        return hop.genop('oosend', [Constant(name)] + hop.args_v, resulttype=hop.r_result)
+    
+    def __getattr__(self, attr):
+        if attr.startswith("rtype_method_"):
+            name = attr[len("rtype_method_"):]
+            return lambda hop: self.call_method(name, hop)
+        else:
+            raise AttributeError(attr)
 
+class __extend__(annmodel.SomeExternalBuiltin):
+    
+    def rtyper_makerepr(self, rtyper):
+        return ExternalBuiltinRepr(self.knowntype)
+    
+    def rtyper_makekey(self):
+        return self.__class__, self.knowntype
+    
 class ExternalObjRepr(Repr):
     """Repr for the (obsolecent) extfunctable.declaretype() case.
     If you use the extregistry instead you get to pick your own Repr.



More information about the Pypy-commit mailing list