[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