[pypy-svn] r44310 - in pypy/dist/pypy: annotation annotation/test rpython rpython/ootypesystem rpython/ootypesystem/test translator/js

pedronis at codespeak.net pedronis at codespeak.net
Sat Jun 16 19:27:42 CEST 2007


Author: pedronis
Date: Sat Jun 16 19:27:42 2007
New Revision: 44310

Added:
   pypy/dist/pypy/rpython/ootypesystem/rbltregistry.py
      - copied, changed from r44307, pypy/dist/pypy/rpython/rexternalobj.py
Modified:
   pypy/dist/pypy/annotation/binaryop.py
   pypy/dist/pypy/annotation/bookkeeper.py
   pypy/dist/pypy/annotation/model.py
   pypy/dist/pypy/annotation/test/test_annrpython.py
   pypy/dist/pypy/annotation/unaryop.py
   pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
   pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py
   pypy/dist/pypy/rpython/rexternalobj.py
   pypy/dist/pypy/translator/js/database.py
Log:
sanitize a bit the ExternalType mess:

unify SomeExternalObject and SomeExternalBuiltin, introduce SomeExternalInstance which has just different union behavior.

use getrepr and introduce rbltnregistry for rtyping logic for BasicExternal whose annotation now is a special case
of SomeExternalInstance

split ExternalType into a thin OOType and a desc that is cached on the bookkeeper. No more mutable ootype containing
annotations ...

the js test are passing, as well as the annotation and rtyping tests for BasicExternal for what is worth.



Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py	(original)
+++ pypy/dist/pypy/annotation/binaryop.py	Sat Jun 16 19:27:42 2007
@@ -20,7 +20,7 @@
 from pypy.annotation.model import add_knowntypedata, merge_knowntypedata
 from pypy.annotation.model import lltype_to_annotation
 from pypy.annotation.model import SomeGenericCallable
-from pypy.annotation.model import SomeExternalBuiltin
+from pypy.annotation.model import SomeExternalInstance
 from pypy.annotation.bookkeeper import getbookkeeper
 from pypy.objspace.flow.model import Variable
 from pypy.annotation.listdef import ListDef
@@ -759,7 +759,7 @@
             return SomeExternalObject(ext1.knowntype)
         return SomeObject()
 
-class __extend__(pairtype(SomeExternalBuiltin, SomeExternalBuiltin)):
+class __extend__(pairtype(SomeExternalInstance, SomeExternalInstance)):
     def union((ext1, ext2)):
         def commonsuperclass(cls1, cls2):
             cls = cls2
@@ -767,11 +767,11 @@
                 cls = cls.__bases__[0]
             return cls
         
-        from pypy.rpython.ootypesystem.bltregistry import BasicExternal, ExternalType
-        cls = commonsuperclass(ext1.knowntype._class_, ext2.knowntype._class_)
+        from pypy.rpython.ootypesystem.bltregistry import BasicExternal
+        cls = commonsuperclass(ext1.knowntype, ext2.knowntype)
         if cls is BasicExternal:
             return SomeObject()
-        return SomeExternalBuiltin(ExternalType(cls))
+        return SomeExternalInstance(cls)
 
 # ____________________________________________________________
 # annotation of low-level types

Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py	(original)
+++ pypy/dist/pypy/annotation/bookkeeper.py	Sat Jun 16 19:27:42 2007
@@ -558,9 +558,10 @@
         try:
             return self.external_class_cache[class_]
         except KeyError:
-            from pypy.rpython.ootypesystem.bltregistry import ExternalType
-            next = ExternalType(class_)
+            from  pypy.rpython.ootypesystem import bltregistry
+            next = bltregistry.ExternalInstanceDesc(class_)
             self.external_class_cache[class_] = next
+            next.setup()
             return next
 
     def pbc_getattr(self, pbc, s_attr):

Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py	(original)
+++ pypy/dist/pypy/annotation/model.py	Sat Jun 16 19:27:42 2007
@@ -445,12 +445,10 @@
     def can_be_none(self):
         return True
 
-class SomeExternalBuiltin(SomeExternalObject):
+class SomeExternalInstance(SomeExternalObject):
     """Stands for an object of 'external' type, but with custom access to
     attributes as well as methods
     """
-    def can_be_none(self):
-        return True
 
 class SomeCTypesObject(SomeExternalObject):
     """Stands for an object of the ctypes module."""
@@ -614,7 +612,7 @@
         elif T == ootype.Class:
             return SomeOOClass(ootype.ROOT)
         elif isinstance(T, ExternalType):
-            return SomeExternalBuiltin(T)
+            return SomeExternalInstance(T._class_)
         else:
             return SomePtr(T)
     else:

Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py	(original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py	Sat Jun 16 19:27:42 2007
@@ -2712,7 +2712,7 @@
         P.allow_someobjects = False
         a = self.RPythonAnnotator(policy=P)
         s = a.build_types(f, [bool])
-        assert isinstance(s, annmodel.SomeExternalBuiltin)        
+        assert isinstance(s, annmodel.SomeExternalInstance)        
 
     def test_instance_with_flags(self):
         from pypy.rlib.jit import hint

Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py	(original)
+++ pypy/dist/pypy/annotation/unaryop.py	Sat Jun 16 19:27:42 2007
@@ -615,6 +615,7 @@
         return self.s_result
 
 class __extend__(SomeExternalObject):
+    # XXX kill with extfunctable.py
     def find_method(obj, name):
         "Look for a special-case implementation for the named method."
         type_analyser = builtin.EXTERNAL_TYPE_ANALYZERS[obj.knowntype]
@@ -623,9 +624,31 @@
             return SomeBuiltin(analyser, obj, name)
         return SomeObject.find_method(obj, name)
 
+    def getattr(p, s_attr):
+        if s_attr.is_constant() and isinstance(s_attr.const, str):
+            # XXX kill with extfunctable.py
+            if p.knowntype in builtin.EXTERNAL_TYPE_ANALYZERS:
+                return SomeObject.getattr(p, s_attr)
+            
+            attr = s_attr.const
+            entry = extregistry.lookup_type(p.knowntype)
+            s_value = entry.get_field_annotation(p.knowntype, attr)
+            return s_value
+        else:
+            return SomeObject()
+    getattr.can_only_throw = []
+    
+    def setattr(p, s_attr, s_value):
+        assert s_attr.is_constant()
+        attr = s_attr.const
+        entry = extregistry.lookup_type(p.knowntype)
+        entry.set_field_annotation(p.knowntype, attr, s_value)
+    
+    def is_true(p):
+        return s_Bool
 
 # annotation of low-level types
-from pypy.annotation.model import SomePtr, SomeLLADTMeth, SomeExternalBuiltin
+from pypy.annotation.model import SomePtr, SomeLLADTMeth
 from pypy.annotation.model import SomeOOInstance, SomeOOBoundMeth, SomeOOStaticMeth
 from pypy.annotation.model import ll_to_annotation, lltype_to_annotation, annotation_to_lltype
 
@@ -663,29 +686,6 @@
     def is_true(p):
         return s_Bool
 
-class __extend__(SomeExternalBuiltin):
-    def getattr(p, s_attr):
-        if s_attr.is_constant() and isinstance(s_attr.const, str):
-            attr = s_attr.const
-            entry = extregistry.lookup_type(p.knowntype._class_)
-            s_value = entry.get_field_annotation(p.knowntype, attr)
-            return s_value
-        else:
-            return SomeObject()
-    getattr.can_only_throw = []
-    
-    def setattr(p, s_attr, s_value):
-        assert s_attr.is_constant()
-        attr = s_attr.const
-        entry = extregistry.lookup_type(p.knowntype._class_)
-        entry.set_field_annotation(p.knowntype, attr, s_value)
-    
-    def find_method(obj, name):
-        return obj.knowntype.get_field(name)
-    
-    def is_true(p):
-        return s_Bool
-
 class __extend__(SomeLLADTMeth):
 
     def call(adtmeth, args):

Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/bltregistry.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py	Sat Jun 16 19:27:42 2007
@@ -119,117 +119,104 @@
             assert expected.contains(res)
         return self.s_retval
 
-class ExternalType(ootype.OOType):
-    class_dict = {}
-    __name__ = "ExternalType"
 
-    def __init__(self, _class):
-        self._class_ = _class
-        self._name = str(_class)
-        self._superclass = None
-        self._root = True
-        self.updated = False
-        self._data = frozendict(_class._fields), frozendict(_class._methods)
-    
-    def update_fields(self, _fields):
-        for i, val in _fields.iteritems():
-            self._fields[i] = annotation(val)
-    
-    def _is_compatible(type2):
-        return type(type2) is ExternalType
-    
+class ExternalInstanceDesc(object):
 
-    def __eq__(self, other):
-        return self.__class__ is other.__class__ and \
-               self._class_ is other._class_
+    def __init__(self, class_):
+        self._class_ = class_
 
-    _is_compatible = staticmethod(_is_compatible)
-    
-    def update_methods(self, _methods):
-        _signs = {}
+    def setup(self):
+        _signs = self._methods = {}
         self._fields = {}
-        for i, val in _methods.iteritems():
+        for i, val in self._class_._methods.iteritems():
             retval = annotation(val.retval._type)
             values = [annotation(arg._type) for arg in val.args]
             s_args = [j for j in values]
             _signs[i] = MethodDesc(tuple(s_args), retval)
-            next = annmodel.SomeBuiltin(Analyzer(i, val, retval, s_args), s_self = annmodel.SomeExternalBuiltin(self), methodname = i)
+            next = annmodel.SomeBuiltin(Analyzer(i, val, retval, s_args),
+                       s_self = annmodel.SomeExternalInstance(self._class_),
+                       methodname = i)
             next.const = True
             self._fields[i] = next
-        self._methods = frozendict(_signs)
 
-    def __hash__(self):
-        return hash(self._name)
-    
+        for i, val in self._class_._fields.iteritems():
+            self._fields[i] = annotation(val)
+
     def set_field(self, attr, knowntype):
-        self.check_update()
         assert attr in self._fields
         field_ann = self._fields[attr]
         res = unionof(knowntype, field_ann)
         assert res.contains(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()
         try:
             return self._fields[attr]
         except KeyError:
             from pypy.tool.error import NoSuchAttrError
             raise NoSuchAttrError("Basic external %s has no attribute %s" %
                                   (self._class_, attr))
-
-    def find_method(self, meth):
-        raise NotImplementedError()
     
     def __repr__(self):
-        return "%s %s" % (self.__name__, self._name)
-    
-    def _defl(self):
-        return _external_type(self, None)
-
-class _external_type(object):
-    
-    def __init__(self, et, value):
-        self._TYPE = et
-        self.value = value
+        return "<%s %s>" % (self.__class__.__name__, self._name)
 
 class Entry_basicexternalmeta(ExtRegistryEntry):
     _metatype_ = BasicMetaExternal
     
     def compute_annotation(self):
-        return annmodel.SomeExternalBuiltin(self.bookkeeper.getexternaldesc\
-            (self.type))
-    
-    def get_field_annotation(self, ext_obj, attr):
-        return ext_obj.get_field(attr)
-    
-    #def get_arg_annotation(self, ext_obj, attr, s_pbc):
-    #    s_field = ext_obj.get_field(attr)
-    #    res = unionof(s_field, s_pbc)
-    #    assert s_field.contains(res)
-    #    return s_field.args_s
+        return annmodel.SomeExternalInstance(self.type)
     
-    def set_field_annotation(self, ext_obj, attr, s_val):
-        ext_obj.set_field(attr, s_val)
+    def get_field_annotation(self, _, attr):
+        bk = getbookkeeper()
+        ext_desc = bk.getexternaldesc(self.type)
+        return ext_desc.get_field(attr)
+    
+    def set_field_annotation(self, _, attr, s_val):
+        bk = getbookkeeper()
+        ext_desc = bk.getexternaldesc(self.type)        
+        ext_desc.set_field(attr, s_val)
+
+    def get_repr(self, rtyper, s_extinst):
+        from pypy.rpython.ootypesystem import rbltregistry
+        return rbltregistry.ExternalInstanceRepr(rtyper, s_extinst.knowntype)
 
 class Entry_basicexternal(ExtRegistryEntry):
     _type_ = BasicExternal.__metaclass__
     
     def compute_result_annotation(self):
-        if self.bookkeeper is None:
-            # XXX diverges from the cache
-            return annmodel.SomeExternalBuiltin(ExternalType(self.instance))
-        return annmodel.SomeExternalBuiltin(self.bookkeeper.getexternaldesc(self.instance))
+        return annmodel.SomeExternalInstance(self.instance)
     
     def specialize_call(self, hop):
         value = hop.r_result.lowleveltype
         return hop.genop('new', [Constant(value, concretetype=ootype.Void)], \
             resulttype = value)
+
+class ExternalType(ootype.OOType):
+
+    def __init__(self, class_):
+        self._class_ = class_
+        self._name = str(class_) # xxx fragile
+        self._superclass = None
+        self._root = True
+
+    def _is_compatible(type2):
+        return type(type2) is ExternalType    
+    _is_compatible = staticmethod(_is_compatible)
+    
+    def __eq__(self, other):
+        return (self.__class__ is other.__class__ and
+               self._class_ is other._class_)
+
+    def __hash__(self):
+        return hash(self._name)
+    
+    def _defl(self):
+        return _external_inst(self, None)
+
+    def __str__(self):
+        return "%s(%s)" % (self.__class__.__name__, self._name)
+
+class _external_inst(object):
+    
+    def __init__(self, et, value):
+        self._TYPE = et
+        self.value = value

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	Sat Jun 16 19:27:42 2007
@@ -22,8 +22,7 @@
     
     a = RPythonAnnotator()
     s = a.build_types(new, [])
-    assert isinstance(s.knowntype, ExternalType)
-    assert s.knowntype._class_ is C
+    assert s.knowntype is C
 
 class A(BasicExternal):
     _fields = {

Modified: pypy/dist/pypy/rpython/rexternalobj.py
==============================================================================
--- pypy/dist/pypy/rpython/rexternalobj.py	(original)
+++ pypy/dist/pypy/rpython/rexternalobj.py	Sat Jun 16 19:27:42 2007
@@ -15,6 +15,7 @@
 class __extend__(annmodel.SomeExternalObject):
 
     def rtyper_makerepr(self, rtyper):
+        # XXX kill with extfunctable.py
         if self.knowntype in typetable:
             return ExternalObjRepr(self.knowntype)
         else:
@@ -68,87 +69,3 @@
     def rtype_is_true(self, hop):
         vlist = hop.inputargs(self)
         return hop.genop('ptr_nonzero', vlist, resulttype=lltype.Bool)
-
-# ExternalBuiltins
-
-class __extend__(annmodel.SomeExternalBuiltin):
-    
-    def rtyper_makerepr(self, rtyper):
-        return ExternalBuiltinRepr(self.knowntype)
-    
-    def rtyper_makekey(self):
-        return self.__class__, self.knowntype
-    
-class ExternalBuiltinRepr(Repr):
-    def __init__(self, knowntype):
-        self.knowntype = knowntype
-        self.lowleveltype = knowntype
-        self.name = "<class '%s'>" % self.knowntype._class_.__name__
-    
-    def convert_const(self, value):
-        from pypy.rpython.ootypesystem.bltregistry import ExternalType,_external_type
-        return _external_type(self.knowntype, value)
-    
-    def rtype_getattr(self, hop):
-        self.knowntype.check_update()
-        attr = hop.args_s[1].const
-        s_inst = hop.args_s[0]
-        if self.knowntype._methods.has_key(attr):
-            # just return instance - will be handled by simple_call
-            return hop.inputarg(hop.args_r[0], arg=0)
-        vlist = hop.inputargs(self, ootype.Void)
-        return hop.genop("oogetfield", vlist,
-                         resulttype = hop.r_result.lowleveltype)
-
-    def rtype_setattr(self, hop):
-        if self.lowleveltype is ootype.Void:
-            return
-        vlist = [hop.inputarg(self, arg=0), hop.inputarg(ootype.Void, arg=1)]
-        field_name = hop.args_s[1].const
-        obj = self.knowntype._class_._fields[field_name]
-        bookkeeper = hop.rtyper.annotator.bookkeeper
-        # XXX WARNING XXX
-        # annotation() here should not be called, but we somehow
-        # have overwritten _fields. This will do no harm, but may hide some
-        # errors
-        r = hop.rtyper.getrepr(annotation(obj, bookkeeper))
-        r.setup()
-        v = hop.inputarg(r, arg=2)
-        vlist.append(v)
-        return hop.genop('oosetfield', vlist)
-    
-    def call_method(self, name, hop):
-        bookkeeper = hop.rtyper.annotator.bookkeeper
-        args_r = []
-        for s_arg in self.knowntype._fields[name].analyser.s_args:
-            r = hop.rtyper.getrepr(s_arg)
-            r.setup()
-            args_r.append(r)
-        vlist = hop.inputargs(self, *args_r)
-        c_name = hop.inputconst(ootype.Void, name)
-        hop.exception_is_here()
-        return hop.genop('oosend', [c_name] + vlist, resulttype=hop.r_result)
-    
-    def rtype_is_true(self, hop):
-        vlist = hop.inputargs(self)
-        return hop.genop('is_true', vlist, resulttype=lltype.Bool)
-    
-    def ll_str(self, val):
-        return ootype.oostring(self.name, -1)
-    
-    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__(pairtype(ExternalBuiltinRepr, ExternalBuiltinRepr)):
-    def convert_from_to((from_, to), v, llops):
-        type_from = from_.knowntype._class_
-        type_to = to.knowntype._class_
-        if issubclass(type_from, type_to):
-            v.concretetype=to.knowntype
-            return v
-        return NotImplemented

Modified: pypy/dist/pypy/translator/js/database.py
==============================================================================
--- pypy/dist/pypy/translator/js/database.py	(original)
+++ pypy/dist/pypy/translator/js/database.py	Sat Jun 16 19:27:42 2007
@@ -232,7 +232,7 @@
             return StringConst(db, const)
         elif isinstance(const, ootype._dict):
             return DictConst(db, const)
-        elif isinstance(const, bltregistry._external_type):
+        elif isinstance(const, bltregistry._external_inst):
             return ExtObject(db, const)
         elif isinstance(const, ootype._class):
             if const._INSTANCE:



More information about the Pypy-commit mailing list