[pypy-svn] r12715 - in pypy/dist/pypy: annotation annotation/test rpython rpython/test translator/genc translator/genc/test
arigo at codespeak.net
arigo at codespeak.net
Sat May 21 19:06:16 CEST 2005
Author: arigo
Date: Sat May 21 19:06:16 2005
New Revision: 12715
Modified:
pypy/dist/pypy/annotation/builtin.py
pypy/dist/pypy/annotation/test/test_model.py
pypy/dist/pypy/rpython/lltypes.py
pypy/dist/pypy/rpython/rlist.py
pypy/dist/pypy/rpython/test/test_llann.py
pypy/dist/pypy/rpython/test/test_lltypes.py
pypy/dist/pypy/translator/genc/lltype.py
pypy/dist/pypy/translator/genc/test/test_lltyped.py
Log:
Added a distinction between Struct and GcStruct, as well as Array and GcArray.
The Gc version are the ones that come with a reference counter (or other GC
supporting memory), and can be malloc'ed. The non-Gc versions are the ones
that can be inlined inside other structures.
Lots of other small changes triggered by this...
Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py (original)
+++ pypy/dist/pypy/annotation/builtin.py Sat May 21 19:06:16 2005
@@ -265,12 +265,9 @@
assert isinstance(s_p, SomePtr), "casting of non-pointer: %r" % s_p
assert PtrT.is_constant()
PtrT = PtrT.const
- parent_example_p = PtrT._example()
- first_p = parent_example_p._first()
- if s_p.ll_ptrtype == lltypes.typeOf(first_p):
- candidate_p = first_p
- else:
- candidate_p = s_p.ll_ptrtype._example()
+ parent_p = PtrT._example()
+ candidate_p = s_p.ll_ptrtype._example()
+ parent_p._setfirst(candidate_p)
return SomePtr(ll_ptrtype=lltypes.typeOf(lltypes.cast_parent(PtrT, candidate_p)))
BUILTIN_ANALYZERS[lltypes.malloc] = malloc
Modified: pypy/dist/pypy/annotation/test/test_model.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_model.py (original)
+++ pypy/dist/pypy/annotation/test/test_model.py Sat May 21 19:06:16 2005
@@ -112,8 +112,8 @@
assert s_uz.contains(s_u)
assert ll_to_annotation(lltypes.Bool._defl()).contains(SomeBool())
assert ll_to_annotation(lltypes.Char._defl()).contains(SomeChar())
- S = lltypes.Struct('s')
- A = lltypes.Array()
+ S = lltypes.GcStruct('s')
+ A = lltypes.GcArray()
s_p = ll_to_annotation(lltypes.malloc(S))
assert isinstance(s_p, SomePtr) and s_p.ll_ptrtype == lltypes.GcPtr(S)
s_p = ll_to_annotation(lltypes.malloc(A, 0))
@@ -136,17 +136,17 @@
assert annotation_to_lltype(s_u1) == lltypes.Unsigned
assert annotation_to_lltype(SomeBool()) == lltypes.Bool
assert annotation_to_lltype(SomeChar()) == lltypes.Char
- PS = lltypes.GcPtr(lltypes.Struct('s'))
+ PS = lltypes.GcPtr(lltypes.GcStruct('s'))
s_p = SomePtr(ll_ptrtype=PS)
assert annotation_to_lltype(s_p) == PS
py.test.raises(ValueError, "annotation_to_lltype(si0)")
def test_ll_union():
- PS1 = lltypes.GcPtr(lltypes.Struct('s'))
- PS2 = lltypes.GcPtr(lltypes.Struct('s'))
- PS3 = lltypes.GcPtr(lltypes.Struct('s3'))
- PA1 = lltypes.GcPtr(lltypes.Array())
- PA2 = lltypes.GcPtr(lltypes.Array())
+ PS1 = lltypes.GcPtr(lltypes.GcStruct('s'))
+ PS2 = lltypes.GcPtr(lltypes.GcStruct('s'))
+ PS3 = lltypes.GcPtr(lltypes.GcStruct('s3'))
+ PA1 = lltypes.GcPtr(lltypes.GcArray())
+ PA2 = lltypes.GcPtr(lltypes.GcArray())
assert unionof(SomePtr(PS1),SomePtr(PS1)) == SomePtr(PS1)
assert unionof(SomePtr(PS1),SomePtr(PS2)) == SomePtr(PS2)
Modified: pypy/dist/pypy/rpython/lltypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypes.py (original)
+++ pypy/dist/pypy/rpython/lltypes.py Sat May 21 19:06:16 2005
@@ -56,11 +56,18 @@
if name in flds:
raise TypeError("%s: repeated field name" % self._name)
flds[name] = typ
-
+ if isinstance(typ, GC_CONTAINER):
+ if name == fields[0][0] and isinstance(self, GC_CONTAINER):
+ pass # can inline a GC_CONTAINER as 1st field of GcStruct
+ else:
+ raise TypeError("%s: cannot inline GC container %r" % (
+ self._name, typ))
+
# look if we have an inlined variable-sized array as the last field
if fields:
for name, typ in fields[:-1]:
typ._inline_is_varsize(False)
+ first = False
name, typ = fields[-1]
if typ._inline_is_varsize(True):
self._arrayfld = name
@@ -85,7 +92,8 @@
for name in self._names])
def __str__(self):
- return "Struct %s { %s }" % (self._name, self._str_fields())
+ return "%s %s { %s }" % (self.__class__.__name__,
+ self._name, self._str_fields())
def _defl(self, parent=None):
return _struct(self, parent=parent)
@@ -97,6 +105,9 @@
n = 1
return _struct(self, n)
+class GcStruct(Struct):
+ pass
+
class Array(ContainerType):
def __init__(self, *fields):
self.OF = Struct("<arrayitem>", *fields)
@@ -109,11 +120,16 @@
return True
def __str__(self):
- return "Array of { %s }" % (self.OF._str_fields(),)
+ return "%s of { %s }" % (self.__class__.__name__,
+ self.OF._str_fields(),)
def _container_example(self):
return _array(self, 1)
+class GcArray(Array):
+ def _inline_is_varsize(self, last):
+ raise TypeError("cannot inline a GC array inside a structure")
+
class FuncType(ContainerType):
def __init__(self, args, result):
for arg in args:
@@ -140,9 +156,14 @@
class ForwardReference(ContainerType):
def become(self, realcontainertype):
+ if not isinstance(realcontainertype, GC_CONTAINER):
+ raise TypeError("ForwardReference can only be to GcStruct or "
+ "GcArray, not %r" % (realcontainertype,))
self.__class__ = realcontainertype.__class__
self.__dict__ = realcontainertype.__dict__
+GC_CONTAINER = (GcStruct, GcArray, PyObjectType, ForwardReference)
+
class Primitive(LowLevelType):
def __init__(self, name, default):
@@ -170,10 +191,12 @@
if not isinstance(TO, ContainerType):
raise TypeError, ("can only point to a Struct or an Array or a FuncType, "
"not to %s" % (TO,))
+ if 'gc' in flags:
+ if not isinstance(TO, GC_CONTAINER):
+ raise TypeError, ("GcPtr can only point to GcStruct, GcArray or"
+ " PyObject, not to %s" % (TO,))
self.TO = TO
self.flags = frozendict(flags)
- if isinstance(TO, FuncType) and 'gc' in self.flags:
- raise TypeError, "function pointers are not gc-able"
def _str_flags(self):
flags = self.flags.keys()
@@ -261,7 +284,9 @@
# * converting from TO-structure to a parent TO-structure whose first
# field is the original structure
if (not isinstance(CURTYPE.TO, Struct) or
- not isinstance(PTRTYPE.TO, Struct)):
+ not isinstance(PTRTYPE.TO, Struct) or
+ len(PTRTYPE.TO._names) == 0 or
+ PTRTYPE.TO._flds[PTRTYPE.TO._names[0]] != CURTYPE.TO):
raise InvalidCast(CURTYPE, PTRTYPE)
ptr._check()
parent = ptr._obj._wrparent()
@@ -279,7 +304,7 @@
T = typeOf(val)
if isinstance(T, ContainerType):
assert not isinstance(T, FuncType), "functions cannot be substructures"
- if can_have_gc and isinstance(T, Struct):
+ if can_have_gc and isinstance(T, GcStruct):
val = _ptr(GcPtr(T), val)
else:
val = _ptr(_TmpPtr(T), val)
@@ -323,10 +348,21 @@
raise AttributeError("%r instance has no field %r" % (self._T,
field_name))
- def _first(self):
+ def _setfirst(self, p):
if isinstance(self._T, Struct) and self._T._names:
- return self.__getattr__(self._T._names[0])
- raise AttributeError("%r instance has no first field" % (self._T,))
+ if not isinstance(p, _ptr) or not isinstance(p._obj, _struct):
+ raise InvalidCast(typeOf(p), typeOf(self))
+ field_name = self._T._names[0]
+ T1 = self._T._flds[field_name]
+ T2 = typeOf(p._obj)
+ if T1 != T2:
+ raise InvalidCast(typeOf(p), typeOf(self))
+ self._check()
+ setattr(self._obj, field_name, p._obj)
+ p._obj._wrparent = weakref.ref(self._obj)
+ p._obj._wrparent_type = typeOf(self._obj)
+ return
+ raise TypeError("%r instance has no first field" % (self._T,))
def __setattr__(self, field_name, val):
if isinstance(self._T, Struct):
Modified: pypy/dist/pypy/rpython/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/rlist.py (original)
+++ pypy/dist/pypy/rpython/rlist.py Sat May 21 19:06:16 2005
@@ -19,8 +19,8 @@
LISTPTR = self.LISTPTR
LIST = self.LIST
ITEM = self.ITEM
- LIST.become(Struct("list",
- ("items", GcPtr(Array(('item', ITEM))))))
+ LIST.become(GcStruct("list",
+ ("items", GcPtr(GcArray(('item', ITEM))))))
def getitem(l, i):
return l.items[i].item
Modified: pypy/dist/pypy/rpython/test/test_llann.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_llann.py (original)
+++ pypy/dist/pypy/rpython/test/test_llann.py Sat May 21 19:06:16 2005
@@ -8,7 +8,7 @@
from pypy.translator.annrpython import RPythonAnnotator
def test_simple(self):
- S = Struct("s", ('v', Signed))
+ S = GcStruct("s", ('v', Signed))
def llf():
s = malloc(S)
return s.v
@@ -18,7 +18,7 @@
def test_simple2(self):
S = Struct("s", ('v', Signed))
- S2 = Struct("s2", ('a',S), ('b',S))
+ S2 = GcStruct("s2", ('a',S), ('b',S))
def llf():
s = malloc(S2)
return s.a.v+s.b.v
@@ -27,7 +27,7 @@
assert s.knowntype == int
def test_array(self):
- A = Array(('v', Signed))
+ A = GcArray(('v', Signed))
def llf():
a = malloc(A, 1)
return a[0].v
@@ -36,7 +36,7 @@
assert s.knowntype == int
def test_cast_flags(self):
- S1 = Struct("s1", ('a', Signed), ('b', Unsigned))
+ S1 = GcStruct("s1", ('a', Signed), ('b', Unsigned))
NGCPS1 = NonGcPtr(S1)
def llf():
p1 = malloc(S1)
@@ -49,7 +49,25 @@
def test_cast_parent(self):
S2 = Struct("s2", ('a', Signed))
- S1 = Struct("s1", ('sub1', S2), ('sub2', S2))
+ S1 = GcStruct("s1", ('sub1', S2), ('sub2', S2))
+ GCPS1 = GcPtr(S1)
+ NGCPS1 = NonGcPtr(S1)
+ NGCPS2 = NonGcPtr(S2)
+ def llf():
+ p1 = malloc(S1)
+ p2 = p1.sub1
+ p3 = cast_flags(NGCPS2, p2)
+ p4 = cast_parent(NGCPS1, p3)
+ p5 = cast_flags(GCPS1, p4)
+ return p5
+ a = self.RPythonAnnotator()
+ s = a.build_types(llf, [])
+ assert isinstance(s, annmodel.SomePtr)
+ assert s.ll_ptrtype == GCPS1
+
+ def test_cast_parent_from_gc(self):
+ S2 = GcStruct("s2", ('a', Signed))
+ S1 = GcStruct("s1", ('sub1', S2), ('x', Signed))
GCPS1 = GcPtr(S1)
def llf():
p1 = malloc(S1)
@@ -62,7 +80,7 @@
assert s.ll_ptrtype == GCPS1
def test_array_length(self):
- A = Array(('v', Signed))
+ A = GcArray(('v', Signed))
def llf():
a = malloc(A, 1)
return len(a)
Modified: pypy/dist/pypy/rpython/test/test_lltypes.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_lltypes.py (original)
+++ pypy/dist/pypy/rpython/test/test_lltypes.py Sat May 21 19:06:16 2005
@@ -2,7 +2,7 @@
from pypy.rpython.lltypes import _TmpPtr
def test_basics():
- S0 = Struct("s0", ('a', Signed), ('b', Signed))
+ S0 = GcStruct("s0", ('a', Signed), ('b', Signed))
assert S0.a == Signed
assert S0.b == Signed
s0 = malloc(S0)
@@ -16,7 +16,7 @@
assert s0.a == 1
assert s0.b == 1
# simple array
- Ar = Array(('v', Signed))
+ Ar = GcArray(('v', Signed))
x = malloc(Ar,0)
print x
assert len(x) == 0
@@ -32,8 +32,8 @@
assert [x[z].v for z in range(3)] == [1, 2, 3]
#
def define_list(T):
- List_typ = Struct("list",
- ("items", GcPtr(Array(('item',T)))))
+ List_typ = GcStruct("list",
+ ("items", GcPtr(GcArray(('item',T)))))
def newlist():
l = malloc(List_typ)
items = malloc(List_typ.items.TO, 0)
@@ -65,7 +65,7 @@
assert iitem(l, 0) == 2
assert iitem(l, 1) == 3
- IWrap = Struct("iwrap", ('v', Signed))
+ IWrap = GcStruct("iwrap", ('v', Signed))
List_typ, iwnewlist, iwappend, iwitem = define_list(GcPtr(IWrap))
l = iwnewlist()
@@ -82,12 +82,14 @@
assert iwitem(l, 1).v == 3
# not allowed
- List_typ, iwnewlistzzz, iwappendzzz, iwitemzzz = define_list(IWrap) # works but
+ S = Struct("s", ('v', Signed))
+ List_typ, iwnewlistzzz, iwappendzzz, iwitemzzz = define_list(S) # works but
l = iwnewlistzzz()
- py.test.raises(TypeError, "iwappendzzz(l, malloc(IWrap))")
+ S1 = GcStruct("strange", ('s', S))
+ py.test.raises(TypeError, "iwappendzzz(l, malloc(S1).s)")
def test_varsizestruct():
- S1 = Struct("s1", ('a', Signed), ('rest', Array(('v', Signed))))
+ S1 = GcStruct("s1", ('a', Signed), ('rest', Array(('v', Signed))))
py.test.raises(TypeError, "malloc(S1)")
s1 = malloc(S1, 4)
assert s1.a == 0
@@ -105,17 +107,27 @@
assert s1.rest[3].v == 5
py.test.raises(TypeError, "Struct('invalid', ('rest', Array(('v', Signed))), ('a', Signed))")
+ py.test.raises(TypeError, "Struct('invalid', ('rest', GcArray(('v', Signed))), ('a', Signed))")
+ py.test.raises(TypeError, "Struct('invalid', ('x', Struct('s1', ('a', Signed), ('rest', Array(('v', Signed))))))")
py.test.raises(TypeError, "Struct('invalid', ('x', S1))")
def test_substructure_ptr():
S2 = Struct("s2", ('a', Signed))
- S1 = Struct("s1", ('sub1', S2), ('sub2', S2))
+ S1 = GcStruct("s1", ('sub1', S2), ('sub2', S2))
p1 = malloc(S1)
- assert typeOf(p1.sub1) == GcPtr(S2)
+ assert typeOf(p1.sub1) == _TmpPtr(S2)
+ assert typeOf(p1.sub2) == _TmpPtr(S2)
+
+def test_gc_substructure_ptr():
+ S1 = GcStruct("s2", ('a', Signed))
+ S2 = Struct("s3", ('a', Signed))
+ S0 = GcStruct("s1", ('sub1', S1), ('sub2', S2))
+ p1 = malloc(S0)
+ assert typeOf(p1.sub1) == GcPtr(S1)
assert typeOf(p1.sub2) == _TmpPtr(S2)
def test_tagged_pointer():
- S1 = Struct("s1", ('a', Signed), ('b', Unsigned))
+ S1 = GcStruct("s1", ('a', Signed), ('b', Unsigned))
PList = [
GcPtr(S1),
NonGcPtr(S1),
@@ -129,7 +141,7 @@
assert PList[2] == GcPtr(S1, mytag=True)
def test_cast_flags():
- S1 = Struct("s1", ('a', Signed), ('b', Unsigned))
+ S1 = GcStruct("s1", ('a', Signed), ('b', Unsigned))
p1 = malloc(S1)
p2 = cast_flags(NonGcPtr(S1), p1)
assert typeOf(p2) == NonGcPtr(S1)
@@ -150,19 +162,27 @@
def test_cast_parent():
S2 = Struct("s2", ('a', Signed))
- S1 = Struct("s1", ('sub1', S2), ('sub2', S2))
+ S1 = GcStruct("s1", ('sub1', S2), ('sub2', S2))
p1 = malloc(S1)
p2 = p1.sub1
- assert typeOf(p2) == GcPtr(S2)
- p3 = cast_parent(GcPtr(S1), p2)
- assert typeOf(p3) == GcPtr(S1)
- assert p3 == p1
+ assert typeOf(p2) == _TmpPtr(S2)
+ p3 = cast_flags(NonGcPtr(S2), p2)
+ assert typeOf(p3) == NonGcPtr(S2)
+ p4 = cast_parent(NonGcPtr(S1), p3)
+ assert typeOf(p4) == NonGcPtr(S1)
+ p5 = cast_flags(GcPtr(S1), p4)
+ assert typeOf(p5) == GcPtr(S1)
+ assert p5 == p1
+ py.test.raises(TypeError, "cast_parent(GcPtr(S1), p1.sub1)")
py.test.raises(TypeError, "cast_parent(GcPtr(S1), p1.sub2)")
py.test.raises(TypeError, "cast_parent(_TmpPtr(S1), p1.sub2)")
+ py.test.raises(TypeError, "cast_parent(NonGcPtr(S2), p3)")
+ SUnrelated = Struct("unrelated")
+ py.test.raises(TypeError, "cast_parent(NonGcPtr(SUnrelated), p3)")
def test_best_effort_gced_parent_detection():
S2 = Struct("s2", ('a', Signed))
- S1 = Struct("s1", ('sub1', S2), ('sub2', S2), ('tail', Array(('e', Signed))))
+ S1 = GcStruct("s1", ('sub1', S2), ('sub2', S2), ('tail', Array(('e', Signed))))
p1 = malloc(S1, 1)
p2 = p1.sub2
assert p2.a == 0
@@ -176,7 +196,7 @@
py.test.raises(RuntimeError, "p3[0]")
def test_best_effort_gced_parent_for_arrays():
- A1 = Array(('v', Signed))
+ A1 = GcArray(('v', Signed))
p1 = malloc(A1, 10)
p1[5].v=3
assert p1[0].v == 0
@@ -189,9 +209,9 @@
py.test.raises(RuntimeError, "p1_5.v")
def test_examples():
- A1 = Array(('v', Signed))
- S = Struct("s", ('v', Signed))
- St = Struct("st", ('v', Signed),('trail', A1))
+ A1 = GcArray(('v', Signed))
+ S = GcStruct("s", ('v', Signed))
+ St = GcStruct("st", ('v', Signed),('trail', Array(('v', Signed))))
PA1 = GcPtr(A1)
PS = GcPtr(S)
@@ -220,3 +240,20 @@
py.test.raises(TypeError, pf, 0, 0)
py.test.raises(TypeError, pf, 'a')
+def test_inconsistent_gc_containers():
+ A = GcArray(('y', Signed))
+ S = GcStruct('b', ('y', Signed))
+ py.test.raises(TypeError, "GcPtr(Struct('a', ('x', Signed)))")
+ py.test.raises(TypeError, "Struct('a', ('x', S))")
+ py.test.raises(TypeError, "GcStruct('a', ('x', Signed), ('y', S))")
+ py.test.raises(TypeError, "Array(('x', S))")
+ py.test.raises(TypeError, "GcArray(('x', S))")
+ py.test.raises(TypeError, "Struct('a', ('x', A))")
+ py.test.raises(TypeError, "GcStruct('a', ('x', A))")
+
+def test_forward_reference():
+ F = ForwardReference()
+ S = GcStruct('abc', ('x', GcPtr(F)))
+ F.become(S)
+ assert S.x == GcPtr(S)
+ py.test.raises(TypeError, "ForwardReference().become(Struct('abc'))")
Modified: pypy/dist/pypy/translator/genc/lltype.py
==============================================================================
--- pypy/dist/pypy/translator/genc/lltype.py (original)
+++ pypy/dist/pypy/translator/genc/lltype.py Sat May 21 19:06:16 2005
@@ -203,7 +203,9 @@
ll2concretetypemap = {
lltypes.Struct: CStructType,
+ lltypes.GcStruct: CStructType,
lltypes.Array: CArrayType,
+ lltypes.GcArray: CArrayType,
lltypes._PtrType: CPtrType,
lltypes.Primitive: get_primitive_type,
}
Modified: pypy/dist/pypy/translator/genc/test/test_lltyped.py
==============================================================================
--- pypy/dist/pypy/translator/genc/test/test_lltyped.py (original)
+++ pypy/dist/pypy/translator/genc/test/test_lltyped.py Sat May 21 19:06:16 2005
@@ -18,7 +18,7 @@
return skip_missing_compiler(t.ccompile)
def test_simple(self):
- S = Struct("s", ('v', Signed))
+ S = GcStruct("s", ('v', Signed))
def llf():
s = malloc(S)
return s.v
@@ -27,7 +27,7 @@
def test_simple2(self):
S = Struct("s", ('v', Signed))
- S2 = Struct("s2", ('a',S), ('b',S))
+ S2 = GcStruct("s2", ('a',S), ('b',S))
def llf():
s = malloc(S2)
s.a.v = 6
More information about the Pypy-commit
mailing list