[pypy-svn] r25894 - in pypy/dist/pypy/rpython: . lltypesystem rctypes rctypes/test
arigo at codespeak.net
arigo at codespeak.net
Mon Apr 17 15:06:43 CEST 2006
Author: arigo
Date: Mon Apr 17 15:06:42 2006
New Revision: 25894
Modified:
pypy/dist/pypy/rpython/lltypesystem/lltype.py
pypy/dist/pypy/rpython/rbuiltin.py
pypy/dist/pypy/rpython/rctypes/rpointer.py
pypy/dist/pypy/rpython/rctypes/test/test_rpointer.py
Log:
Some support for pointer[non-zero-index].
Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Mon Apr 17 15:06:42 2006
@@ -908,7 +908,16 @@
def _cast_to_adr(self):
from pypy.rpython.lltypesystem import llmemory
- return llmemory.fakeaddress(self)
+ if isinstance(self._obj, _subarray):
+ # return an address built as an offset in the whole array
+ parent, parentindex = parentlink(self._obj)
+ T = typeOf(parent)
+ addr = llmemory.fakeaddress(_ptr(Ptr(T), parent))
+ addr += llmemory.itemoffsetof(T, parentindex)
+ return addr
+ else:
+ # normal case
+ return llmemory.fakeaddress(self)
assert not '__dict__' in dir(_ptr)
Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py (original)
+++ pypy/dist/pypy/rpython/rbuiltin.py Mon Apr 17 15:06:42 2006
@@ -335,6 +335,19 @@
return llops.genop('cast_adr_to_ptr', [v_base_adr],
resulttype = ARRAYPTRTYPE)
+def gen_add_itemoffset_to_pointer(llops, ITEMTYPE, v_ptr, v_index):
+ "Generates address manipulations equivalent to the C expression ptr+index."
+ from pypy.rpython.lltypesystem import llmemory
+ v_adr = llops.genop('cast_ptr_to_adr', [v_ptr],
+ resulttype = llmemory.Address)
+ c_ofs = inputconst(lltype.Signed, llmemory.ItemOffset(ITEMTYPE))
+ v_ofs = llops.genop('int_mul', [c_ofs, v_index],
+ resulttype = lltype.Signed)
+ v_newadr = llops.genop('adr_add', [v_adr, v_ofs],
+ resulttype = llmemory.Address)
+ return llops.genop('cast_adr_to_ptr', [v_newadr],
+ resulttype = v_ptr.concretetype)
+
def rtype_cast_structfield_pointer(hop):
assert hop.args_s[0].is_constant()
assert hop.args_s[2].is_constant()
Modified: pypy/dist/pypy/rpython/rctypes/rpointer.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rpointer.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rpointer.py Mon Apr 17 15:06:42 2006
@@ -1,3 +1,4 @@
+from pypy.rpython.rbuiltin import gen_add_itemoffset_to_pointer
from pypy.rpython.rmodel import IntegerRepr, inputconst
from pypy.rpython.error import TyperError
from pypy.rpython.lltypesystem import lltype
@@ -64,11 +65,14 @@
def rtype_getitem((r_ptr, _), hop):
self = r_ptr
v_ptr, v_index = hop.inputargs(self, lltype.Signed)
+ v_c_ptr = self.getvalue(hop.llops, v_ptr)
if hop.args_s[1].is_constant() and hop.args_s[1].const == 0:
- v_c_ptr = self.getvalue(hop. llops, v_ptr)
- return self.r_contents.return_c_data(hop.llops, v_c_ptr)
+ pass # skip adding the offset
else:
- raise NotImplementedError("XXX: pointer[non-zero-index]")
+ v_c_ptr = gen_add_itemoffset_to_pointer(hop.llops,
+ r_ptr.r_contents.ll_type,
+ v_c_ptr, v_index)
+ return self.r_contents.return_c_data(hop.llops, v_c_ptr)
def rtype_setitem((r_ptr, _), hop):
# p[0] = x is not the same as p.contents.value = x
Modified: pypy/dist/pypy/rpython/rctypes/test/test_rpointer.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rpointer.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rpointer.py Mon Apr 17 15:06:42 2006
@@ -2,13 +2,14 @@
Test the rctypes pointer implementation
"""
-import py.test
+import py
import pypy.rpython.rctypes.implementation
from pypy.translator.translator import TranslationContext
from pypy import conftest
from pypy.rpython.test.test_llinterp import interpret
+from pypy.translator.c.test.test_genc import compile
-from ctypes import c_int, c_float, POINTER, pointer
+from ctypes import c_int, c_float, POINTER, pointer, Structure
class Test_annotation:
def test_simple(self):
@@ -251,3 +252,32 @@
res = interpret(fn, [])
float_c_data = res.c_data[0]
assert float_c_data[0] == 6.25
+
+ def test_specialize_getitem_nonzero_index(self):
+ A = c_int * 10
+ class S(Structure):
+ _fields_ = [('x', POINTER(c_int))]
+ def fn():
+ a = A()
+ a[3] = 5
+ s = S()
+ s.x = a
+ return s.x[3]
+ assert fn() == 5
+ res = interpret(fn, [])
+ assert res == 5
+
+class Test_compilation:
+ def test_compile_getitem_nonzero_index(self):
+ A = c_int * 10
+ class S(Structure):
+ _fields_ = [('x', POINTER(c_int))]
+ def func():
+ a = A()
+ a[3] = 5
+ s = S()
+ s.x = a
+ return s.x[3]
+ fn = compile(func, [])
+ res = fn()
+ assert res == 5
More information about the Pypy-commit
mailing list