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

arigo at codespeak.net arigo at codespeak.net
Mon Mar 27 13:50:10 CEST 2006


Author: arigo
Date: Mon Mar 27 13:50:07 2006
New Revision: 25025

Modified:
   pypy/dist/pypy/rpython/lltypesystem/llmemory.py
   pypy/dist/pypy/rpython/lltypesystem/rpbc.py
   pypy/dist/pypy/rpython/ootypesystem/rpbc.py
   pypy/dist/pypy/rpython/rmodel.py
   pypy/dist/pypy/rpython/rpbc.py
   pypy/dist/pypy/rpython/test/test_rpbc.py
Log:
Pass test_disjoint_pbcs.  The repr of SomePBC is a (breath
here) MultipleUnrelatedFrozenPBCRepr for frozen PBCs with no
common attribute access set.  This is an Address in the
lltypesystem, and an instance of the empty base PBCROOT class
in the ootypesystem.



Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llmemory.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py	Mon Mar 27 13:50:07 2006
@@ -130,6 +130,15 @@
         self.ob = ob
         self.offset = offset
 
+    def __repr__(self):
+        if self.ob is None:
+            s = 'NULL'
+        else:
+            s = str(self.ob)
+        if self.offset is not None:
+            s = '%s + %r' % (s, self.offset)
+        return '<fakeaddr %s>' % (s,)
+
     def __add__(self, other):
         if isinstance(other, AddressOffset):
             if self.offset is None:

Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rpbc.py	Mon Mar 27 13:50:07 2006
@@ -11,18 +11,24 @@
      commonbase, allattributenames, adjust_shape, \
      AbstractClassesPBCRepr, AbstractMethodsPBCRepr, OverriddenFunctionPBCRepr, \
      AbstractMultipleFrozenPBCRepr, MethodOfFrozenPBCRepr, \
-     AbstractFunctionsPBCRepr
-from pypy.rpython.lltypesystem import rclass
+     AbstractFunctionsPBCRepr, AbstractMultipleUnrelatedFrozenPBCRepr, \
+     SingleFrozenPBCRepr
+from pypy.rpython.lltypesystem import rclass, llmemory
 from pypy.tool.sourcetools import has_varargs
 
 from pypy.rpython import callparse
 
 def rtype_is_None(robj1, rnone2, hop, pos=0):
-    if not isinstance(robj1.lowleveltype, Ptr):
-        raise TyperError('is None of instance of the non-pointer: %r' % (robj1))           
-    v1 = hop.inputarg(robj1, pos)
-    return hop.genop('ptr_iszero', [v1], resulttype=Bool)
-    
+    if isinstance(robj1.lowleveltype, Ptr):
+        v1 = hop.inputarg(robj1, pos)
+        return hop.genop('ptr_iszero', [v1], resulttype=Bool)
+    elif robj1.lowleveltype == llmemory.Address:
+        v1 = hop.inputarg(robj1, pos)
+        cnull = hop.inputconst(llmemory.Address, robj1.null_instance())
+        return hop.genop('adr_eq', [v1, cnull], resulttype=Bool)
+    else:
+        raise TyperError('rtype_is_None of %r' % (robj1))
+
 # ____________________________________________________________
 
 class MultipleFrozenPBCRepr(AbstractMultipleFrozenPBCRepr):
@@ -50,6 +56,42 @@
         return llops.genop('getfield', [vpbc, cmangledname],
                            resulttype = r_value)
 
+
+class MultipleUnrelatedFrozenPBCRepr(AbstractMultipleUnrelatedFrozenPBCRepr):
+    """Representation selected for multiple non-callable pre-built constants
+    with no common access set."""
+
+    lowleveltype = llmemory.Address
+    EMPTY = Struct('pbc')
+
+    def convert_pbc(self, pbcptr):
+        return llmemory.fakeaddress(pbcptr)
+
+    def create_instance(self):
+        return malloc(self.EMPTY, immortal=True)
+
+    def null_instance(self):
+        return llmemory.Address._defl()
+
+class __extend__(pairtype(MultipleUnrelatedFrozenPBCRepr,
+                          MultipleUnrelatedFrozenPBCRepr),
+                 pairtype(MultipleUnrelatedFrozenPBCRepr,
+                          SingleFrozenPBCRepr),
+                 pairtype(SingleFrozenPBCRepr,
+                          MultipleUnrelatedFrozenPBCRepr)):
+    def rtype_is_((robj1, robj2), hop):
+        if isinstance(robj1, MultipleUnrelatedFrozenPBCRepr):
+            r = robj1
+        else:
+            r = robj2
+        vlist = hop.inputargs(r, r)
+        return hop.genop('adr_eq', vlist, resulttype=Bool)
+
+class __extend__(pairtype(MultipleFrozenPBCRepr,
+                          MultipleUnrelatedFrozenPBCRepr)):
+    def convert_from_to((robj1, robj2), v, llops):
+        return llops.genop('cast_ptr_to_adr', [v], resulttype=llmemory.Address)
+
 # ____________________________________________________________
 
 class FunctionsPBCRepr(AbstractFunctionsPBCRepr):

Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py	Mon Mar 27 13:50:07 2006
@@ -1,7 +1,7 @@
 from pypy.rpython.rmodel import CanBeNull, Repr, inputconst
 from pypy.rpython.rpbc import AbstractClassesPBCRepr, AbstractMethodsPBCRepr, \
         AbstractMultipleFrozenPBCRepr, MethodOfFrozenPBCRepr, \
-        AbstractFunctionsPBCRepr
+        AbstractFunctionsPBCRepr, AbstractMultipleUnrelatedFrozenPBCRepr
 from pypy.rpython.rclass import rtype_new_instance, getinstancerepr
 from pypy.rpython.rpbc import get_concrete_calltable
 from pypy.rpython import callparse
@@ -14,6 +14,13 @@
 import types
 
 
+def rtype_is_None(robj1, rnone2, hop, pos=0):
+    v1 = hop.inputarg(robj1, pos)
+    v2 = hop.genop('oononnull', [v1], resulttype=ootype.Bool)
+    v3 = hop.genop('bool_not', [v2], resulttype=ootype.Bool)
+    return v3
+
+
 class FunctionsPBCRepr(AbstractFunctionsPBCRepr):
     """Representation selected for a PBC of function(s)."""
 
@@ -160,12 +167,16 @@
     def convert_from_to(_, v, llops):
         return v
 
+# ____________________________________________________________
+
+PBCROOT = ootype.Instance('pbcroot', ootype.ROOT)
+
 class MultipleFrozenPBCRepr(AbstractMultipleFrozenPBCRepr):
     """Representation selected for multiple non-callable pre-built constants."""
     def __init__(self, rtyper, access_set):
         self.rtyper = rtyper
         self.access_set = access_set
-        self.lowleveltype = ootype.Instance('pbc', ootype.ROOT)
+        self.lowleveltype = ootype.Instance('pbc', PBCROOT)
         self.pbc_cache = {}
 
     def _setup_repr(self):
@@ -184,4 +195,24 @@
         return llops.genop('oogetfield', [vpbc, cmangledname],
                            resulttype = r_value)
 
+class MultipleUnrelatedFrozenPBCRepr(AbstractMultipleUnrelatedFrozenPBCRepr):
+    """Representation selected for multiple non-callable pre-built constants
+    with no common access set."""
+
+    lowleveltype = PBCROOT
+
+    def convert_pbc(self, pbc):
+        if ootype.typeOf(pbc) != PBCROOT:
+            pbc = ootype.ooupcast(PBCROOT, pbc)
+        return pbc
+
+    def create_instance(self):
+        return ootype.new(PBCROOT)
+
+    def null_instance(self):
+        return ootype.null(PBCROOT)
 
+class __extend__(pairtype(MultipleFrozenPBCRepr,
+                          MultipleUnrelatedFrozenPBCRepr)):
+    def convert_from_to((robj1, robj2), v, llops):
+        return llops.genop('ooupcast', [v], resulttype=PBCROOT)

Modified: pypy/dist/pypy/rpython/rmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/rmodel.py	(original)
+++ pypy/dist/pypy/rpython/rmodel.py	Mon Mar 27 13:50:07 2006
@@ -120,7 +120,7 @@
         if self.lowleveltype is not Void:
             try:
                 realtype = typeOf(value)
-            except (AssertionError, AttributeError):
+            except (AssertionError, AttributeError, TypeError):
                 realtype = '???'
             if realtype != self.lowleveltype:
                 raise TyperError("convert_const(self = %r, value = %r)" % (

Modified: pypy/dist/pypy/rpython/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/rpbc.py	Mon Mar 27 13:50:07 2006
@@ -349,7 +349,14 @@
         access = descs[0].queryattrfamily()
         for desc in descs[1:]:
             access1 = desc.queryattrfamily()
-            assert access1 is access       # XXX not implemented
+            if access1 is not access:
+                try:
+                    return rtyper.pbc_reprs['unrelated']
+                except KeyError:
+                    rpbc = rtyper.type_system.rpbc
+                    result = rpbc.MultipleUnrelatedFrozenPBCRepr(rtyper)
+                    rtyper.pbc_reprs['unrelated'] = result
+                    return result
         try:
             return rtyper.pbc_reprs[access]
         except KeyError:
@@ -377,7 +384,39 @@
         return object()  # lowleveltype is Void
 
 
-class AbstractMultipleFrozenPBCRepr(CanBeNull, Repr):
+class AbstractMultipleUnrelatedFrozenPBCRepr(CanBeNull, Repr):
+    """For a SomePBC of frozen PBCs that have no common access set.
+    The only possible operation on such a thing is comparison with 'is'."""
+
+    def __init__(self, rtyper):
+        self.rtyper = rtyper
+        self.converted_pbc_cache = {}
+
+    def convert_desc(self, frozendesc):
+        try:
+            return self.converted_pbc_cache[frozendesc]
+        except KeyError:
+            r = self.rtyper.getrepr(annmodel.SomePBC([frozendesc]))
+            if r.lowleveltype is Void:
+                # must create a new empty structure, as a placeholder
+                pbc = self.create_instance()
+            else:
+                pbc = r.convert_desc(frozendesc)
+            convpbc = self.convert_pbc(pbc)
+            self.converted_pbc_cache[frozendesc] = convpbc
+            return convpbc
+
+    def convert_const(self, pbc):
+        if pbc is None:
+            return self.null_instance() 
+        if isinstance(pbc, types.MethodType) and pbc.im_self is None:
+            value = pbc.im_func   # unbound method -> bare function
+        frozendesc = self.rtyper.annotator.bookkeeper.getdesc(pbc)
+        return self.convert_desc(frozendesc)
+
+
+class AbstractMultipleFrozenPBCRepr(AbstractMultipleUnrelatedFrozenPBCRepr):
+    """For a SomePBC of frozen PBCs with a common attribute access set."""
 
     def _setup_repr_fields(self):
         fields = []
@@ -415,14 +454,6 @@
                 setattr(result, mangled_name, llvalue)
             return result
 
-    def convert_const(self, pbc):
-        if pbc is None:
-            return self.null_instance() 
-        if isinstance(pbc, types.MethodType) and pbc.im_self is None:
-            value = pbc.im_func   # unbound method -> bare function
-        frozendesc = self.rtyper.annotator.bookkeeper.getdesc(pbc)
-        return self.convert_desc(frozendesc)
-    
     def rtype_getattr(self, hop):
         attr = hop.args_s[1].const
         vpbc, vattr = hop.inputargs(self, Void)

Modified: pypy/dist/pypy/rpython/test/test_rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rpbc.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rpbc.py	Mon Mar 27 13:50:07 2006
@@ -1094,6 +1094,62 @@
             res = interpret(f, [i, 1234], type_system=self.ts)
             assert res == f(i, 1234)
 
+    def test_disjoint_pbcs(self):
+        class Frozen(object):
+            def __init__(self, v):
+                self.v = v
+            def _freeze_(self):
+                return True
+
+        fr1 = Frozen(2)
+        fr2 = Frozen(3)
+
+        def g1(x):
+            return x.v
+        def g2(y):
+            return y.v
+        def h(x):
+            return x is not None
+        def h2(x):
+            return x is fr1
+
+        def f():
+            a = g1(fr1)
+            b = g2(fr2)
+            h(None)
+            return (h(fr1) + 10*h(fr2) + 100*a + 1000*b +
+                    10000*h2(fr1) + 100000*h2(fr2))
+
+        res = interpret(f, [], type_system=self.ts)
+        assert res == 13211
+
+    def test_disjoint_pbcs_2(self):
+        class Frozen(object):
+            def __init__(self, v):
+                self.v = v
+            def _freeze_(self):
+                return True
+        fr1 = Frozen(1)
+        fr2 = Frozen(2)
+        fr3 = Frozen(3)
+        def getv(x):
+            return x.v
+        def h(x):
+            return (x is not None) + 2*(x is fr2) + 3*(x is fr3)
+        def f(n):
+            if n == 1:
+                fr = fr1
+            else:
+                fr = fr2
+            total = getv(fr)
+            if n == 3:
+                fr = fr3
+            h(None)
+            return total + 10*h(fr)
+
+        res = interpret(f, [3], type_system=self.ts)
+        assert res == 42
+
 
 def test_call_from_list():
     # Don't test with ootype, since it doesn't support lists in a
@@ -1363,33 +1419,6 @@
     res = interp.eval_graph(ll_h_graph, [None, c_f, c_a])
     assert typeOf(res) == A_repr.lowleveltype
 
-def test_disjoint_pbcs():
-    py.test.skip("in-progress")
-    class Frozen(object):
-        def __init__(self, v):
-            self.v = 2
-        def _freeze_(self):
-            return True
-        
-    f1 = Frozen(2)
-    f2 = Frozen(3)
-
-    def g1(x):
-        return x.v
-    def g2(y):
-        return y.v
-    def h(x):
-        return x != None
-
-    def f():
-        a = g1(f1)
-        b = g2(f2)
-        return h(f1)+h(f2)+a+b
-        
-    res = interpret(f, [])
-
-    assert res == 7
-
 class TestLltype(BaseTestRPBC):
 
     ts = "lltype"



More information about the Pypy-commit mailing list