[pypy-svn] r26918 - in pypy/dist/pypy: annotation rpython rpython/lltypesystem rpython/lltypesystem/test rpython/test

arigo at codespeak.net arigo at codespeak.net
Sun May 7 10:25:17 CEST 2006


Author: arigo
Date: Sun May  7 10:25:14 2006
New Revision: 26918

Modified:
   pypy/dist/pypy/annotation/builtin.py
   pypy/dist/pypy/rpython/llinterp.py
   pypy/dist/pypy/rpython/lltypesystem/lloperation.py
   pypy/dist/pypy/rpython/lltypesystem/lltype.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
   pypy/dist/pypy/rpython/rbuiltin.py
   pypy/dist/pypy/rpython/test/test_rptr.py
Log:
(pedronis, arigo)

* added GcOpaqueType.
* added cast_opaque_ptr to cast between ptr-to-opaque and
  ptr-to-something-normal.


Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py	(original)
+++ pypy/dist/pypy/annotation/builtin.py	Sun May  7 10:25:14 2006
@@ -423,6 +423,15 @@
     cast_p = lltype.cast_pointer(PtrT.const, s_p.ll_ptrtype._defl())
     return SomePtr(ll_ptrtype=lltype.typeOf(cast_p))
 
+def cast_opaque_ptr(PtrT, s_p):
+    assert isinstance(s_p, SomePtr), "casting of non-pointer: %r" % s_p
+    assert PtrT.is_constant()
+    try:
+        lltype.cast_opaque_ptr(PtrT.const, s_p.ll_ptrtype._defl())
+    except RuntimeError:
+        pass    # the type checks passed, but the _defl opaque cannot be cast
+    return SomePtr(ll_ptrtype=PtrT.const)
+
 def direct_fieldptr(s_p, s_fieldname):
     assert isinstance(s_p, SomePtr), "direct_* of non-pointer: %r" % s_p
     assert s_fieldname.is_constant()
@@ -464,6 +473,7 @@
 BUILTIN_ANALYZERS[lltype.cast_primitive] = cast_primitive
 BUILTIN_ANALYZERS[lltype.nullptr] = nullptr
 BUILTIN_ANALYZERS[lltype.cast_pointer] = cast_pointer
+BUILTIN_ANALYZERS[lltype.cast_opaque_ptr] = cast_opaque_ptr
 BUILTIN_ANALYZERS[lltype.direct_fieldptr] = direct_fieldptr
 BUILTIN_ANALYZERS[lltype.direct_arrayitems] = direct_arrayitems
 BUILTIN_ANALYZERS[lltype.direct_ptradd] = direct_ptradd

Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py	(original)
+++ pypy/dist/pypy/rpython/llinterp.py	Sun May  7 10:25:14 2006
@@ -335,7 +335,8 @@
         vals = [self.getval(x) for x in operation.args]
         # if these special cases pile up, do something better here
         if operation.opname in ['cast_pointer', 'ooupcast', 'oodowncast',
-                                'cast_adr_to_ptr', 'cast_int_to_ptr']:
+                                'cast_adr_to_ptr', 'cast_int_to_ptr',
+                                'cast_opaque_ptr']:
             vals.insert(0, operation.result.concretetype)
         try:
             retval = ophandler(*vals)
@@ -556,9 +557,11 @@
         return len(array)
 
     def op_cast_pointer(self, tp, obj):
-        # well, actually this is what's now in the globals.
         return lltype.cast_pointer(tp, obj)
 
+    def op_cast_opaque_ptr(self, tp, obj):
+        return lltype.cast_opaque_ptr(tp, obj)
+
     def op_ptr_eq(self, ptr1, ptr2):
         assert checkptr(ptr1)
         assert checkptr(ptr2)

Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py	Sun May  7 10:25:14 2006
@@ -270,6 +270,7 @@
     'direct_fieldptr':      LLOp(canfold=True),
     'direct_arrayitems':    LLOp(canfold=True),
     'direct_ptradd':        LLOp(canfold=True),
+    'cast_opaque_ptr':      LLOp(canfold=True),
 
     # _________ XXX l3interp hacks ___________
 

Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py	Sun May  7 10:25:14 2006
@@ -427,6 +427,14 @@
 
 RuntimeTypeInfo = OpaqueType("RuntimeTypeInfo")
 
+class GcOpaqueType(OpaqueType):
+
+    def __str__(self):
+        return "%s (gcopaque)" % self.tag
+
+    def _inline_is_varsize(self, last):
+        raise TypeError, "%r cannot be inlined in structure" % self
+
 class PyObjectType(ContainerType):
     __name__ = 'PyObject'
     def __str__(self):
@@ -452,7 +460,8 @@
         self.__class__ = realcontainertype.__class__
         self.__dict__ = realcontainertype.__dict__
 
-GC_CONTAINER = (GcStruct, GcArray, PyObjectType, GcForwardReference)
+GC_CONTAINER = (GcStruct, GcArray, PyObjectType, GcForwardReference,
+                GcOpaqueType)
 
 
 class Primitive(LowLevelType):
@@ -614,6 +623,33 @@
         raise TypeError, "can only cast pointers to other pointers"
     return ptr._cast_to(PTRTYPE)
 
+def cast_opaque_ptr(PTRTYPE, ptr):
+    CURTYPE = typeOf(ptr)
+    if not isinstance(CURTYPE, Ptr) or not isinstance(PTRTYPE, Ptr):
+        raise TypeError, "can only cast pointers to other pointers"
+    if CURTYPE._needsgc() != PTRTYPE._needsgc():
+        raise TypeError("cast_opaque_ptr() cannot change the gc status: "
+                        "%s to %s" % (CURTYPE, PTRTYPE))
+    if (isinstance(CURTYPE.TO, OpaqueType)
+        and not isinstance(PTRTYPE.TO, OpaqueType)):
+        try:
+            container = ptr._obj.container
+        except AttributeError:
+            raise RuntimeError("%r does not come from a container" % (ptr,))
+        if typeOf(container) != PTRTYPE.TO:
+            raise RuntimeError("%r contains a container of the wrong type:\n"
+                               "%r instead of %r" % (ptr, typeOf(container),
+                                                     PTRTYPE.TO))
+        solid = getattr(ptr._obj, 'solid', False)
+        return _ptr(PTRTYPE, container, solid)
+    elif (not isinstance(CURTYPE.TO, OpaqueType)
+          and isinstance(PTRTYPE.TO, OpaqueType)):
+        return opaqueptr(PTRTYPE.TO, 'hidden', container = ptr._obj,
+                                               solid     = ptr._solid)
+    else:
+        raise TypeError("cast_opaque_ptr(): only between Opaque and "
+                        "non-Opaque")
+
 def direct_fieldptr(structptr, fieldname):
     """Get a pointer to a field in the struct.  The resulting
     pointer is actually of type Ptr(FixedSizeArray(FIELD, 1)).
@@ -1264,7 +1300,7 @@
     if not isinstance(TYPE, OpaqueType):
         raise TypeError, "opaqueptr() for OpaqueTypes only"
     o = _opaque(TYPE, _name=name, **attrs)
-    return _ptr(Ptr(TYPE), o, solid=attrs.get('immortal', True))
+    return _ptr(Ptr(TYPE), o, solid=True)
 
 def pyobjectptr(obj):
     o = _pyobject(obj)

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py	Sun May  7 10:25:14 2006
@@ -430,6 +430,28 @@
     assert typeOf(p2.stuff) == Ptr(O)
     assert parentlink(p2.stuff._obj) == (p2._obj, 'stuff')
 
+def test_cast_opaque_ptr():
+    O = GcOpaqueType('O')
+    S = GcStruct('S', ('x', Signed))
+    s = malloc(S)
+    o = cast_opaque_ptr(Ptr(O), s)
+    assert typeOf(o).TO == O
+    p = cast_opaque_ptr(Ptr(S), o)
+    assert typeOf(p).TO == S
+    assert p == s
+    O1 = OpaqueType('O')
+    S1 = Struct('S1', ('x', Signed))
+    s1 = malloc(S1, immortal=True)
+    o1 = cast_opaque_ptr(Ptr(O1), s1)
+    assert typeOf(o1).TO == O1
+    p1 = cast_opaque_ptr(Ptr(S1), o1)
+    assert typeOf(p1).TO == S1
+    assert p1 == s1
+    py.test.raises(TypeError, "cast_opaque_ptr(Ptr(S), o1)")
+    py.test.raises(TypeError, "cast_opaque_ptr(Ptr(O1), s)")
+    S2 = Struct('S2', ('z', Signed))
+    py.test.raises(TypeError, "cast_opaque_ptr(Ptr(S2), o1)")
+
 def test_is_atomic():
     U = Struct('inlined', ('z', Signed))
     A = Ptr(RuntimeTypeInfo)

Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Sun May  7 10:25:14 2006
@@ -332,6 +332,14 @@
     return hop.genop('cast_pointer', [v_input],    # v_type implicit in r_result
                      resulttype = hop.r_result.lowleveltype)
 
+def rtype_cast_opaque_ptr(hop):
+    assert hop.args_s[0].is_constant()
+    assert isinstance(hop.args_r[1], rptr.PtrRepr)
+    v_type, v_input = hop.inputargs(lltype.Void, hop.args_r[1])
+    hop.exception_cannot_occur()
+    return hop.genop('cast_opaque_ptr', [v_input], # v_type implicit in r_result
+                     resulttype = hop.r_result.lowleveltype)
+
 def rtype_direct_fieldptr(hop):
     assert isinstance(hop.args_r[0], rptr.PtrRepr)
     assert hop.args_s[1].is_constant()
@@ -421,6 +429,7 @@
 BUILTIN_TYPER[lltype.malloc] = rtype_malloc
 BUILTIN_TYPER[lltype.cast_primitive] = rtype_cast_primitive
 BUILTIN_TYPER[lltype.cast_pointer] = rtype_cast_pointer
+BUILTIN_TYPER[lltype.cast_opaque_ptr] = rtype_cast_opaque_ptr
 BUILTIN_TYPER[lltype.direct_fieldptr] = rtype_direct_fieldptr
 BUILTIN_TYPER[lltype.direct_arrayitems] = rtype_direct_arrayitems
 BUILTIN_TYPER[lltype.direct_ptradd] = rtype_direct_ptradd

Modified: pypy/dist/pypy/rpython/test/test_rptr.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rptr.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rptr.py	Sun May  7 10:25:14 2006
@@ -118,3 +118,24 @@
     
     p = interpret(ll_example, [])
     assert typeOf(p) == Ptr(S)
+
+def test_cast_opaque_ptr():
+    O = GcOpaqueType('O')
+    S = GcStruct('S', ('x', Signed))
+    def fn():
+        s = malloc(S)
+        o = cast_opaque_ptr(Ptr(O), s)
+        p = cast_opaque_ptr(Ptr(S), o)
+        return p == s
+    res = interpret(fn, [])
+    assert res is True
+
+    O1 = OpaqueType('O')
+    S1 = Struct('S1', ('x', Signed))
+    s1 = malloc(S1, immortal=True)
+    def fn1():
+        o1 = cast_opaque_ptr(Ptr(O1), s1)
+        p1 = cast_opaque_ptr(Ptr(S1), o1)
+        return p1 == s1
+    res = interpret(fn1, [])
+    assert res is True



More information about the Pypy-commit mailing list