[pypy-svn] r18768 - in pypy/dist/pypy: annotation rpython rpython/ootypesystem rpython/ootypesystem/test

arigo at codespeak.net arigo at codespeak.net
Wed Oct 19 19:57:39 CEST 2005


Author: arigo
Date: Wed Oct 19 19:57:37 2005
New Revision: 18768

Modified:
   pypy/dist/pypy/annotation/binaryop.py
   pypy/dist/pypy/annotation/bookkeeper.py
   pypy/dist/pypy/annotation/builtin.py
   pypy/dist/pypy/rpython/llinterp.py
   pypy/dist/pypy/rpython/ootypesystem/ootype.py
   pypy/dist/pypy/rpython/ootypesystem/rclass.py
   pypy/dist/pypy/rpython/ootypesystem/rootype.py
   pypy/dist/pypy/rpython/ootypesystem/rpbc.py
   pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py
   pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py
   pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py
   pypy/dist/pypy/rpython/rmodel.py
Log:
ootyper:

* more operations needed by ll helpers ("oo helpers"?) on OOInstanceReprs:
    'is' and truth-value testing.

* introduced a NULL run-time class reference, returned by type(x) if x is an
  instance that turns out to be None.  This supports the RPython style
  'if type(x) is W_SuchAndSuch:...'

* annotator support: SomeOOClass(None) for this NULL run-time class reference.

* more annotator support: prebuilt oo classes and instances.

* 'is' between classes.  Requires a new operation 'oosameclass' :-/

* fix extremely confusing error message in the base Repr.rtype_is_().

* test_type() passes.



Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py	(original)
+++ pypy/dist/pypy/annotation/binaryop.py	Wed Oct 19 19:57:37 2005
@@ -695,8 +695,14 @@
 
 class __extend__(pairtype(SomeOOClass, SomeOOClass)):
     def union((r1, r2)):
-        common = ootype.commonBaseclass(r1.ootype, r2.ootype)
-        assert common is not None, 'Mixing of incompatible classes %r, %r' %(r1.ootype, r2.ootype)
+        if r1.ootype is None:
+            common = r2.ootype
+        elif r2.ootype is None:
+            common = r1.ootype
+        else:
+            common = ootype.commonBaseclass(r1.ootype, r2.ootype)
+            assert common is not None, ('Mixing of incompatible classes %r, %r'
+                                        % (r1.ootype, r2.ootype))
         return SomeOOClass(common)
 
 class __extend__(pairtype(SomeOOInstance, SomeObject)):

Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py	(original)
+++ pypy/dist/pypy/annotation/bookkeeper.py	Wed Oct 19 19:57:37 2005
@@ -15,7 +15,8 @@
 from pypy.rpython.rarithmetic import r_uint
 from pypy.rpython.objectmodel import r_dict
 from pypy.tool.algo.unionfind import UnionFind
-from pypy.rpython import lltype
+from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.memory import lladdress
 
 from pypy.annotation.specialize import decide_callable
@@ -355,6 +356,10 @@
             result= SomeAddress(is_null=True)
         elif isinstance(x, ootype._static_meth):
             result = SomeOOStaticMeth(ootype.typeOf(x))
+        elif isinstance(x, ootype._class):
+            result = SomeOOClass(x._INSTANCE)   # NB. can be None
+        elif isinstance(x, ootype._instance):
+            result = SomeOOInstance(ootype.typeOf(x))
         elif callable(x) or isinstance(x, staticmethod): # XXX
             # maybe 'x' is a method bound to a not-yet-frozen cache?
             # fun fun fun.

Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py	(original)
+++ pypy/dist/pypy/annotation/builtin.py	Wed Oct 19 19:57:37 2005
@@ -391,7 +391,10 @@
 
 def runtimenew(c):
     assert isinstance(c, SomeOOClass)
-    return SomeOOInstance(c.ootype)
+    if c.ootype is None:
+        return SomeImpossibleValue()   # can't call runtimenew(NULL)
+    else:
+        return SomeOOInstance(c.ootype)
 
 def ooidentityhash(i):
     assert isinstance(i, SomeOOInstance)

Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py	(original)
+++ pypy/dist/pypy/rpython/llinterp.py	Wed Oct 19 19:57:37 2005
@@ -670,6 +670,11 @@
     def op_subclassof(self, class1, class2):
         return ootype.subclassof(class1, class2)
 
+    def op_oosameclass(self, class1, class2):
+        assert isinstance(class1, ootype._class)
+        assert isinstance(class2, ootype._class)
+        return class1 is class2
+
     def op_ooidentityhash(self, inst):
         return ootype.ooidentityhash(inst)
 

Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py	Wed Oct 19 19:57:37 2005
@@ -144,7 +144,8 @@
     _TYPE = Class
     def __init__(self, INSTANCE):
         self._INSTANCE = INSTANCE
-        
+nullruntimeclass = _class(None)
+
 class _instance(object):
     
     def __init__(self, INSTANCE):
@@ -256,6 +257,7 @@
 
 def runtimenew(class_):
     assert isinstance(class_, _class)
+    assert class_ is not nullruntimeclass
     return _instance(class_._INSTANCE)
 
 def static_meth(FUNCTION, name,  **attrs):
@@ -282,6 +284,8 @@
 def subclassof(class1, class2):
     assert isinstance(class1, _class)
     assert isinstance(class2, _class)
+    assert class1 is not nullruntimeclass
+    assert class2 is not nullruntimeclass
     return isSubclass(class1._INSTANCE, class2._INSTANCE)
 
 def addFields(INSTANCE, fields):

Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rclass.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rclass.py	Wed Oct 19 19:57:37 2005
@@ -38,6 +38,22 @@
         return hop.genop('subclassof', vlist, resulttype=ootype.Bool)
 
 
+    def rtype_is_((r_cls1, r_cls2), hop):
+        class_repr = get_type_repr(self.rtyper)
+        vlist = hop.inputargs(class_repr, class_repr)
+        return hop.genop('oosameclass', vlist, resulttype=ootype.Bool)
+
+
+def rtype_classes_is_(_, hop):
+    class_repr = get_type_repr(hop.rtyper)
+    vlist = hop.inputargs(class_repr, class_repr)
+    return hop.genop('oosameclass', vlist, resulttype=ootype.Bool)
+
+class __extend__(pairtype(ClassRepr, ClassRepr)):
+    rtype_is_ = rtype_classes_is_
+
+# ____________________________________________________________
+
 def mangle(name):
     # XXX temporary: for now it looks like a good idea to mangle names
     # systematically to trap bugs related to a confusion between mangled
@@ -213,7 +229,10 @@
 
     def rtype_type(self, hop):
         vinst, = hop.inputargs(self)
-        return hop.genop('classof', [vinst], resulttype=ootype.Class)
+        if hop.args_s[0].can_be_none():
+            return hop.gendirectcall(ll_inst_type, vinst)
+        else:
+            return hop.genop('classof', [vinst], resulttype=ootype.Class)
 
     def rtype_hash(self, hop):
         if self.classdef is None:
@@ -320,3 +339,10 @@
     if cached == 0:
         cached = ins._hash_cache_ = ootype.ooidentityhash(ins)
     return cached
+
+def ll_inst_type(obj):
+    if obj:
+        return ootype.classof(obj)
+    else:
+        # type(None) -> NULL  (for now)
+        return ootype.nullruntimeclass

Modified: pypy/dist/pypy/rpython/ootypesystem/rootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rootype.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rootype.py	Wed Oct 19 19:57:37 2005
@@ -1,5 +1,6 @@
 from pypy.annotation import model as annmodel
 from pypy.rpython.rmodel import Repr
+from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.ootypesystem.ootype import Void, Class
 from pypy.annotation.pairtype import pairtype
 
@@ -47,6 +48,18 @@
         vlist = hop.inputargs(self, Void, hop.args_r[2])
         return hop.genop('oosetfield', vlist)
 
+    def rtype_is_true(self, hop):
+        vlist = hop.inputargs(self)
+        return hop.genop('oononnull', vlist, resulttype=ootype.Bool)
+
+
+class __extend__(pairtype(OOInstanceRepr, OOInstanceRepr)):
+    def rtype_is_((r_ins1, r_ins2), hop):
+        # NB. this version performs no cast to the common base class
+        vlist = hop.inputargs(r_ins1, r_ins2)
+        return hop.genop('oois', vlist, resulttype=ootype.Bool)
+
+
 class OOBoundMethRepr(Repr):
     def __init__(self, ootype, name):
         self.lowleveltype = ootype

Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py	Wed Oct 19 19:57:37 2005
@@ -1,7 +1,8 @@
 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, mangle
+from pypy.rpython.ootypesystem.rclass import ClassRepr, InstanceRepr, mangle
+from pypy.rpython.ootypesystem.rclass import rtype_classes_is_
 from pypy.annotation.pairtype import pairtype
 
 class ClassesPBCRepr(AbstractClassesPBCRepr):
@@ -29,3 +30,10 @@
 
     def convert_from_to(_, v, llops):
         return v
+
+
+class __extend__(pairtype(ClassRepr, ClassesPBCRepr)):
+    rtype_is_ = rtype_classes_is_
+
+class __extend__(pairtype(ClassesPBCRepr, ClassRepr)):
+    rtype_is_ = rtype_classes_is_

Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py	Wed Oct 19 19:57:37 2005
@@ -146,3 +146,16 @@
 
     assert s.knowntype == int
 
+def test_truth_value():
+    C = Instance("C", None)
+    def oof(f):
+        if f:
+            c = new(C)
+        else:
+            c = null(C)
+        return not c
+
+    a = RPythonAnnotator()
+    s = a.build_types(oof, [bool])
+    assert isinstance(s, annmodel.SomeBool)
+    assert not s.is_constant()

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	Wed Oct 19 19:57:37 2005
@@ -461,7 +461,6 @@
     assert res == hash(d)
 
 def test_type():
-    py.test.skip('in progress')
     class A:
         pass
     class B(A):

Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py	Wed Oct 19 19:57:37 2005
@@ -3,6 +3,7 @@
 from pypy.annotation import model as annmodel
 from pypy.objspace.flow import FlowObjSpace
 from pypy.translator.translator import Translator
+from pypy.rpython.test.test_llinterp import interpret
 
 def gengraph(f, args=[], viewBefore=False, viewAfter=False):
     t = Translator(f)
@@ -52,3 +53,22 @@
     g = gengraph(f)
     rettype = g.getreturnvar().concretetype
     assert rettype == Signed
+
+def test_truth_value():
+    C = Instance("C", None)
+    NULL = null(C)
+    def oof(f):
+        if f:
+            c = new(C)
+        else:
+            c = NULL
+        return not c
+
+    g = gengraph(oof, [bool])
+    rettype = g.getreturnvar().concretetype
+    assert rettype == Bool
+
+    res = interpret(oof, [True], type_system='ootype')
+    assert res is False
+    res = interpret(oof, [False], type_system='ootype')
+    assert res is True

Modified: pypy/dist/pypy/rpython/rmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/rmodel.py	(original)
+++ pypy/dist/pypy/rpython/rmodel.py	Wed Oct 19 19:57:37 2005
@@ -199,6 +199,8 @@
     def rtype_is_((robj1, robj2), hop):
         if hop.s_result.is_constant():
             return inputconst(Bool, hop.s_result.const)
+        roriginal1 = robj1
+        roriginal2 = robj2
         if robj1.lowleveltype is Void:
             robj1 = robj2
         elif robj2.lowleveltype is Void:
@@ -206,10 +208,10 @@
         if (not isinstance(robj1.lowleveltype, Ptr) or
             not isinstance(robj2.lowleveltype, Ptr)):
             raise TyperError('is of instances of the non-pointers: %r, %r' % (
-                robj1, robj2))
+                roriginal1, roriginal2))
         if robj1.lowleveltype != robj2.lowleveltype:
             raise TyperError('is of instances of different pointer types: %r, %r' % (
-                robj1, robj2))
+                roriginal1, roriginal2))
             
         v_list = hop.inputargs(robj1, robj2)
         return hop.genop('ptr_eq', v_list, resulttype=Bool)



More information about the Pypy-commit mailing list