[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