[pypy-svn] r34494 - in pypy/dist/pypy/rlib: . test
arigo at codespeak.net
arigo at codespeak.net
Sat Nov 11 19:04:26 CET 2006
Author: arigo
Date: Sat Nov 11 19:04:25 2006
New Revision: 34494
Modified:
pypy/dist/pypy/rlib/rctypesobject.py
pypy/dist/pypy/rlib/test/test_rctypesobject.py
Log:
- some support for var-sized arrays.
- renamed makeRXxx() => RXxx().
Modified: pypy/dist/pypy/rlib/rctypesobject.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypesobject.py (original)
+++ pypy/dist/pypy/rlib/rctypesobject.py Sat Nov 11 19:04:25 2006
@@ -96,7 +96,7 @@
_primitive_cache = {}
-def makePrimitive(TYPE):
+def Primitive(TYPE):
"""Build a return a new RCTypesPrimitive class."""
try:
return _primitive_cache[TYPE]
@@ -118,18 +118,18 @@
return RCTypesPrimitive
# a few prebuilt primitive types
-rc_int = makePrimitive(lltype.Signed)
-rc_char = makePrimitive(lltype.Char)
+rc_int = Primitive(lltype.Signed)
+rc_char = Primitive(lltype.Char)
-def makeRPointer(contentscls):
+def RPointer(contentscls):
"""Build and return a new RCTypesPointer class."""
try:
return contentscls._ptrcls
except AttributeError:
assert issubclass(contentscls, RCTypesObject)
if contentscls is RCTypesObject:
- raise Exception("cannot call makeRPointer(RCTypesObject) or "
+ raise Exception("cannot call RPointer(RCTypesObject) or "
"pointer(x) if x degenerated to the base "
"RCTypesObject class")
@@ -155,17 +155,17 @@
contentscls._ptrcls = RCTypesPtr
return RCTypesPtr
-makeRPointer._annspecialcase_ = 'specialize:memo'
+RPointer._annspecialcase_ = 'specialize:memo'
def pointer(x):
- PTR = makeRPointer(x.__class__)
+ PTR = RPointer(x.__class__)
p = PTR.allocate()
p.set_contents(x)
return p
pointer._annspecialcase_ = 'specialize:argtype(0)'
-def makeRStruct(c_name, fields, c_external=False):
+def RStruct(c_name, fields, c_external=False):
"""Build and return a new RCTypesStruct class."""
def cmangle(name):
@@ -205,33 +205,88 @@
return RCTypesStruct
-def makeRArray(itemcls, fixedsize):
- """Build and return a new RCTypesArray class."""
+def RFixedArray(itemcls, fixedsize):
+ """Build and return a new RCTypesFixedArray class."""
- key = '_arraycls%d' % (fixedsize,)
+ key = '_fixedarraycls%d' % (fixedsize,)
try:
return getattr(itemcls, key)
except AttributeError:
assert issubclass(itemcls, RCTypesObject)
if itemcls is RCTypesObject:
- raise Exception("cannot call makeRArray(RCTypesObject)")
+ raise Exception("cannot call RFixedArray(RCTypesObject)")
ARRAYTYPE = lltype.FixedSizeArray(itemcls.LLTYPE, fixedsize)
FIRSTITEMOFS = llmemory.ArrayItemsOffset(ARRAYTYPE)
ITEMOFS = llmemory.sizeof(itemcls.LLTYPE)
- class RCTypesArray(RCTypesObject):
+ class RCTypesFixedArray(RCTypesObject):
+ ITEM = ARRAYTYPE.OF
LLTYPE = ARRAYTYPE
+ length = fixedsize
num_keepalives = itemcls.num_keepalives * fixedsize
def ref(self, n):
- subaddr = self.addr + FIRSTITEMOFS + ITEMOFS * n
+ subaddr = self.addr + (FIRSTITEMOFS + ITEMOFS * n)
subblock = self.memblock.addoffset(itemcls.num_keepalives * n)
return itemcls(subaddr, subblock)
- def length(self):
- return fixedsize
+ setattr(itemcls, key, RCTypesFixedArray)
+ return RCTypesFixedArray
+RFixedArray._annspecialcase_ = 'specialize:memo'
- setattr(itemcls, key, RCTypesArray)
- return RCTypesArray
-makeRArray._annspecialcase_ = 'specialize:memo'
+
+def RVarArray(itemcls):
+ """Build and return a new RCTypesVarArray class.
+ Note that this is *not* a subclass of RCTypesObject, so you cannot
+ take a pointer to it, use it as a field of a structure, etc.
+ """
+ try:
+ return itemcls._vararraycls
+ except AttributeError:
+ assert issubclass(itemcls, RCTypesObject)
+ if itemcls is RCTypesObject:
+ raise Exception("cannot call RVarArray(RCTypesObject)")
+
+ ARRAYTYPE = lltype.Array(itemcls.LLTYPE, hints={'nolength': True})
+ FIRSTITEMOFS = llmemory.ArrayItemsOffset(ARRAYTYPE)
+ ITEMOFS = llmemory.sizeof(itemcls.LLTYPE)
+
+ class RCTypesVarArray(object):
+ ITEM = ARRAYTYPE.OF
+
+ def __init__(self, addr, memblock, length):
+ self.addr = addr
+ self.memblock = memblock
+ self.length = length
+
+ def allocate(length):
+ rawsize = FIRSTITEMOFS + ITEMOFS * length
+ num_keepalives = itemcls.num_keepalives * length
+ memblock = AllocatedRawMemBlock(num_keepalives, rawsize)
+ addr = memblock.addr + FIRSTITEMOFS
+ return RCTypesVarArray(addr, memblock, length)
+ allocate = staticmethod(allocate)
+
+ def fromitem(itembox, length):
+ """Return a VarArray from a reference to its first element.
+ Note that if you use the VarArray to store pointer-ish data,
+ you have to keep the VarArray alive as long as you want
+ this new data to stay alive.
+ """
+ assert isinstance(itembox, itemcls)
+ num_keepalives = itemcls.num_keepalives * length
+ memblock = RawMemBlock(num_keepalives)
+ res = RCTypesVarArray(itembox.addr, memblock, length)
+ res._keepalive_memblock_fromitem = itembox.memblock
+ return res
+ fromitem = staticmethod(fromitem)
+
+ def ref(self, n):
+ subaddr = self.addr + ITEMOFS * n
+ subblock = self.memblock.addoffset(itemcls.num_keepalives * n)
+ return itemcls(subaddr, subblock)
+
+ itemcls._vararraycls = RCTypesVarArray
+ return RCTypesVarArray
+RVarArray._annspecialcase_ = 'specialize:memo'
Modified: pypy/dist/pypy/rlib/test/test_rctypesobject.py
==============================================================================
--- pypy/dist/pypy/rlib/test/test_rctypesobject.py (original)
+++ pypy/dist/pypy/rlib/test/test_rctypesobject.py Sat Nov 11 19:04:25 2006
@@ -32,8 +32,8 @@
assert res == 18
def test_struct(self):
- S1 = makeRStruct('S1', [('x', rc_int),
- ('y', makeRPointer(rc_int))])
+ S1 = RStruct('S1', [('x', rc_int),
+ ('y', RPointer(rc_int))])
def func():
x = rc_int.allocate()
x.set_value(42)
@@ -63,17 +63,44 @@
res = self.do(func)
assert res == 303
- def test_fixedsize_array(self):
+ def test_fixedarray(self):
def func():
- a = makeRArray(rc_int, 10).allocate()
+ a = RFixedArray(rc_int, 10).allocate()
for i in range(10):
a.ref(i).set_value(5 * i)
for i in range(10):
assert a.ref(i).get_value() == 5 * i
- return a.length()
+ return a.length
res = self.do(func)
assert res == 10
+ def test_vararray(self):
+ def func():
+ a = RVarArray(rc_int).allocate(10)
+ for i in range(10):
+ a.ref(i).set_value(5 * i)
+ for i in range(10):
+ assert a.ref(i).get_value() == 5 * i
+ return a.length
+ res = self.do(func)
+ assert res == 10
+
+ def test_vararray_cast(self):
+ def func():
+ a = RVarArray(rc_int).allocate(10)
+ for i in range(10):
+ a.ref(i).set_value(100 + 5 * i)
+ p = pointer(a.ref(0))
+ del a
+ assert p.get_contents().get_value() == 100
+ a1 = RVarArray(rc_int).fromitem(p.get_contents(), 8)
+ del p
+ for i in range(8):
+ a1.ref(i).get_value() == 100 + 5 * i
+ return a1.length
+ res = self.do(func)
+ assert res == 8
+
class TestLLInterpreted(TestBasic):
POLICY = AnnotatorPolicy()
More information about the Pypy-commit
mailing list