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

arigo at codespeak.net arigo at codespeak.net
Sun Apr 9 17:58:55 CEST 2006


Author: arigo
Date: Sun Apr  9 17:58:53 2006
New Revision: 25630

Modified:
   pypy/dist/pypy/rpython/lltypesystem/llmemory.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py
Log:
(arre, arigo)

More support for working with fakeaddresses:

  adr.signed[n]
  adr.char[n]
  adr.address[n]

now work as expected.  They also do some more type-checking.


Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llmemory.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py	Sun Apr  9 17:58:53 2006
@@ -36,13 +36,14 @@
             return NotImplemented
         return ItemOffset(self.TYPE, self.repeat * other)
 
-    def get(self, ob):
-        return ob[self.repeat]
+    def ref(self, firstitemref):
+        assert isinstance(firstitemref, _arrayitemref)
+        array = firstitemref.array
+        assert lltype.typeOf(array).TO.OF == self.TYPE
+        index = firstitemref.index + self.repeat
+        return _arrayitemref(array, index)
 
-    def set(self, ob, value):
-        ob[self.repeat] = value
 
-    
 class FieldOffset(AddressOffset):
 
     def __init__(self, TYPE, fldname):
@@ -52,11 +53,10 @@
     def __repr__(self):
         return "<FieldOffset %r %r>" % (self.TYPE, self.fldname)
 
-    def get(self, ob):
-        return getattr(ob, self.fldname)
-
-    def set(self, ob, value):
-        setattr(ob, self.fldname, value)
+    def ref(self, containerref):
+        struct = containerref.get()
+        assert lltype.typeOf(struct).TO == self.TYPE
+        return _structfieldref(struct, self.fldname)
 
 
 class CompositeOffset(AddressOffset):
@@ -68,11 +68,8 @@
     def __repr__(self):
         return '< %r + %r >'%(self.first, self.second)
 
-    def get(self, ob):
-        return self.second.get(self.first.get(ob))
-
-    def set(self, ob, value):
-        return self.second.set(self.first.get(ob), value)
+    def ref(self, containerref):
+        return self.second.ref(self.first.ref(containerref))
 
 
 class ArrayItemsOffset(AddressOffset):
@@ -83,11 +80,10 @@
     def __repr__(self):
         return '< ArrayItemsOffset >'
 
-    def get(self, ob):
-        return ob
-
-    def set(self, ob, value):
-        raise Exception("can't assign to an array's items")
+    def ref(self, arrayref):
+        array = arrayref.get()
+        assert lltype.typeOf(array).TO == self.TYPE
+        return _arrayitemref(array, index=0)
 
 class ArrayLengthOffset(AddressOffset):
 
@@ -97,12 +93,55 @@
     def __repr__(self):
         return '< ArrayLengthOffset >'
 
-    def get(self, ob):
-        return len(ob)
+    def ref(self, arrayref):
+        array = arrayref.get()
+        assert lltype.typeOf(array).TO == self.TYPE
+        return _arraylenref(array)
+
 
-    def set(self, ob, value):
+class _arrayitemref(object):
+    def __init__(self, array, index):
+        self.array = array
+        self.index = index
+    def get(self):
+        return self.array[self.index]
+    def set(self, value):
+        self.array[self.index] = value
+    def type(self):
+        return lltype.typeOf(self.array).TO.OF
+
+class _arraylenref(object):
+    def __init__(self, array):
+        self.array = array
+    def get(self):
+        return len(self.array)
+    def set(self, value):
         raise Exception("can't assign to an array's length")
+    def type(self):
+        return lltype.Signed
 
+class _structfieldref(object):
+    def __init__(self, struct, fieldname):
+        self.struct = struct
+        self.fieldname = fieldname
+    def get(self):
+        return getattr(self.struct, self.fieldname)
+    def set(self, value):
+        setattr(self.struct, self.fieldname, value)
+    def type(self):
+        return getattr(lltype.typeOf(self.struct), self.fieldname)
+
+class _obref(object):
+    def __init__(self, ob):
+        self.ob = ob
+    def get(self):
+        return self.ob
+    def set(self, value):
+        raise Exception("can't assign to whole object")
+    def type(self):
+        return lltype.typeOf(self.ob)
+
+# ____________________________________________________________
 
 def sizeof(TYPE, n=None):
     if n is None:
@@ -148,17 +187,17 @@
             return fakeaddress(self.ob, offset)
         return NotImplemented
 
+    def ref(self):
+        ref = _obref(self.ob)
+        if self.offset is not None:
+            ref = self.offset.ref(ref)
+        return ref
+
     def get(self):
-        if self.offset is None:
-            return self.ob
-        else:
-            return self.offset.get(self.ob)
+        return self.ref().get()
 
     def set(self, value):
-        if self.offset is None:
-            raise Exception("can't assign to whole object")
-        else:
-            self.offset.set(self.ob, value)
+        self.ref().set(value)
 
     def _cast_to_ptr(self, EXPECTED_TYPE):
         return lltype.cast_pointer(EXPECTED_TYPE, self.get())
@@ -166,43 +205,53 @@
     def _cast_to_int(self):
         return self.get()._cast_to_int()
 
-# XXX the indexing in code like
-#     addr.signed[0] = v
-#     is just silly.  remove it.
+# ____________________________________________________________
+
+NULL = fakeaddress(None) # XXX this should be the same as memory.lladdress.NULL
+Address = lltype.Primitive("Address", NULL)
+
 
 class _fakeaccessor(object):
     def __init__(self, addr):
         self.addr = addr
     def __getitem__(self, index):
-        assert index == 0
-        return self.convert(self.addr.get())
+        addr = self.addr
+        if index != 0:
+            addr += ItemOffset(addr.ref().type(), index)
+        return self.convert(addr.get())
 
     def __setitem__(self, index, value):
-        assert index == 0
-        self.addr.set(value)
-
-        
-class _signed_fakeaccessor(_fakeaccessor):
-    TYPE = lltype.Signed
+        addr = self.addr
+        if index != 0:
+            addr += ItemOffset(addr.ref().type(), index)
+        addr.set(value)
 
     def convert(self, value):
         assert lltype.typeOf(value) == self.TYPE
         return value
 
+
+class _signed_fakeaccessor(_fakeaccessor):
+    TYPE = lltype.Signed
+
+class _char_fakeaccessor(_fakeaccessor):
+    TYPE = lltype.Char
+
 class _address_fakeaccessor(_fakeaccessor):
-    TYPE = None
+    TYPE = Address
 
     def convert(self, value):
-        # XXX is this the right check for "Ptr-ness" ?
-        assert isinstance(value, lltype._ptr)
-        return fakeaddress(value)
+        if isinstance(value, lltype._ptr):
+            return fakeaddress(value)
+        elif isinstance(value, Address):
+            return value
+        else:
+            raise TypeError(value)
 
 
 fakeaddress.signed = property(_signed_fakeaccessor)
+fakeaddress.char = property(_char_fakeaccessor)
 fakeaddress.address = property(_address_fakeaccessor)
-
-Address = lltype.Primitive("Address", fakeaddress(None))
-
 fakeaddress._TYPE = Address
 
 # the obtained address will not keep the object alive. e.g. if the object is

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py	Sun Apr  9 17:58:53 2006
@@ -3,35 +3,39 @@
 import py
 
 def test_simple():
-    class C:
-        def __init__(self, x):
-            self.x = x
-    c = C(1)
-    a = fakeaddress(c)
-    assert a.get() is c
-    b = a + FieldOffset('dummy', 'x')
-    assert b.get() == 1
-    b.set(2)
-    assert c.x == 2
+    S = lltype.GcStruct("S", ("x", lltype.Signed), ("y", lltype.Signed))
+    s = lltype.malloc(S)
+    s.x = 123
+    s.y = 456
+    a = fakeaddress(s)
+    assert a.get() == s
+    b = a + FieldOffset(S, 'x')
+    assert b.get() == 123
+    b.set(234)
+    assert s.x == 234
 
 def test_composite():
-    class C:
-        def __init__(self, x):
-            self.x = x
-    c = C(C(3))
-    a = fakeaddress(c)
-    assert a.get() is c
-    b = a + FieldOffset('dummy', 'x') + FieldOffset('dummy', 'x')
-    assert b.get() == 3
-    b.set(2)
-    assert c.x.x == 2
+    S1 = lltype.GcStruct("S1", ("x", lltype.Signed), ("y", lltype.Signed))
+    S2 = lltype.GcStruct("S2", ("s", S1))
+    s2 = lltype.malloc(S2)
+    s2.s.x = 123
+    s2.s.y = 456
+    a = fakeaddress(s2)
+    assert a.get() == s2
+    b = a + FieldOffset(S2, 's') + FieldOffset(S1, 'x')
+    assert b.get() == 123
+    b.set(234)
+    assert s2.s.x == 234
     
 def test_array():
-    x = [2, 3, 5, 7, 11]
+    A = lltype.GcArray(lltype.Signed)
+    x = lltype.malloc(A, 5)
+    x[3] = 123
     a = fakeaddress(x)
-    # is there a way to ensure that we add the ArrayItemsOffset ?
-    b = a + ArrayItemsOffset('dummy') + ItemOffset('dummy')*3
-    assert b.get() == x[3]
+    b = a + ArrayItemsOffset(A)
+    b += ItemOffset(lltype.Signed)*2
+    b += ItemOffset(lltype.Signed)
+    assert b.get() == 123
     b.set(14)
     assert x[3] == 14
     
@@ -70,7 +74,6 @@
 
 def test_cast_adr_to_ptr():
     from pypy.rpython.memory.test.test_llinterpsim import interpret
-    from pypy.rpython.lltypesystem import lltype
     S = lltype.GcStruct("S", ("x", lltype.Signed))
     Sptr = lltype.Ptr(S)
     def f():
@@ -83,7 +86,6 @@
 
 def test_cast_adr_to_int():
     from pypy.rpython.memory.test.test_llinterpsim import interpret
-    from pypy.rpython.lltypesystem import lltype
     S = lltype.GcStruct("S", ("x", lltype.Signed))
     Sptr = lltype.Ptr(S)
     def f():
@@ -95,3 +97,36 @@
     assert f()
     res = interpret(f, [])
     assert res
+
+def test_fakeaccessor():
+    S = lltype.GcStruct("S", ("x", lltype.Signed), ("y", lltype.Signed))
+    s = lltype.malloc(S)
+    s.x = 123
+    s.y = 456
+    adr = cast_ptr_to_adr(s)
+    adr += FieldOffset(S, "y")
+    assert adr.signed[0] == 456
+    adr.signed[0] = 789
+    assert s.y == 789
+
+    A = lltype.GcArray(lltype.Signed)
+    a = lltype.malloc(A, 5)
+    a[3] = 123
+    adr = cast_ptr_to_adr(a)
+    assert (adr + ArrayLengthOffset(A)).signed[0] == 5
+    assert (adr + ArrayItemsOffset(A)).signed[3] == 123
+    (adr + ArrayItemsOffset(A)).signed[3] = 456
+    assert a[3] == 456
+    adr1000 = (adr + ArrayItemsOffset(A) + ItemOffset(lltype.Signed, 1000))
+    assert adr1000.signed[-997] == 456
+
+    A = lltype.GcArray(lltype.Char)
+    a = lltype.malloc(A, 5)
+    a[3] = '*'
+    adr = cast_ptr_to_adr(a)
+    assert (adr + ArrayLengthOffset(A)).signed[0] == 5
+    assert (adr + ArrayItemsOffset(A)).char[3] == '*'
+    (adr + ArrayItemsOffset(A)).char[3] = '+'
+    assert a[3] == '+'
+    adr1000 = (adr + ArrayItemsOffset(A) + ItemOffset(lltype.Char, 1000))
+    assert adr1000.char[-997] == '+'



More information about the Pypy-commit mailing list