[pypy-svn] r25955 - in pypy/dist/pypy: annotation rpython rpython/lltypesystem rpython/lltypesystem/test rpython/rctypes rpython/rctypes/test translator/c translator/c/test
arigo at codespeak.net
arigo at codespeak.net
Tue Apr 18 17:18:05 CEST 2006
Author: arigo
Date: Tue Apr 18 17:18:01 2006
New Revision: 25955
Modified:
pypy/dist/pypy/annotation/builtin.py
pypy/dist/pypy/rpython/llinterp.py
pypy/dist/pypy/rpython/lltypesystem/llmemory.py
pypy/dist/pypy/rpython/lltypesystem/lloperation.py
pypy/dist/pypy/rpython/lltypesystem/lltype.py
pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
pypy/dist/pypy/rpython/rbuiltin.py
pypy/dist/pypy/rpython/rctypes/rarray.py
pypy/dist/pypy/rpython/rctypes/rchar_p.py
pypy/dist/pypy/rpython/rctypes/rpointer.py
pypy/dist/pypy/rpython/rctypes/rstringbuf.py
pypy/dist/pypy/rpython/rctypes/rstruct.py
pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py
pypy/dist/pypy/translator/c/funcgen.py
pypy/dist/pypy/translator/c/test/test_lltyped.py
Log:
Major cleanup to get rid of the obscure address manipulation routines
cast_subarray_pointer() & co. Instead, we have three new ll operations
that each have a very straightforward C equivalent:
* direct_fieldptr(struct, name) -> get a ptr to the field
* direct_arrayitems(array) -> get a ptr to the first item
* direct_ptradd(ptr, n) -> shift a ptr by n items
They manipulate a kind of "pointer to primitives" represented as
a Ptr(FixedSizeArray(T, 1)). See test_lltype.py for examples.
(This is all for rctypes.)
Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py (original)
+++ pypy/dist/pypy/annotation/builtin.py Tue Apr 18 17:18:01 2006
@@ -421,23 +421,23 @@
cast_p = lltype.cast_pointer(PtrT.const, s_p.ll_ptrtype._defl())
return SomePtr(ll_ptrtype=lltype.typeOf(cast_p))
-def cast_subarray_pointer(PtrT, s_p, s_offset):
- assert isinstance(s_p, SomePtr), "casting of non-pointer: %r" % s_p
- assert PtrT.is_constant()
- cast_p = lltype.cast_subarray_pointer(PtrT.const,
- s_p.ll_ptrtype._example(),
- 0)
+def direct_fieldptr(s_p, s_fieldname):
+ assert isinstance(s_p, SomePtr), "direct_* of non-pointer: %r" % s_p
+ assert s_fieldname.is_constant()
+ cast_p = lltype.direct_fieldptr(s_p.ll_ptrtype._example(),
+ s_fieldname.const)
return SomePtr(ll_ptrtype=lltype.typeOf(cast_p))
-def cast_structfield_pointer(PtrT, s_p, s_fieldname):
- assert isinstance(s_p, SomePtr), "casting of non-pointer: %r" % s_p
- assert PtrT.is_constant()
- assert s_fieldname.is_constant()
- cast_p = lltype.cast_structfield_pointer(PtrT.const,
- s_p.ll_ptrtype._example(),
- s_fieldname.const)
+def direct_arrayitems(s_p):
+ assert isinstance(s_p, SomePtr), "direct_* of non-pointer: %r" % s_p
+ cast_p = lltype.direct_arrayitems(s_p.ll_ptrtype._example())
return SomePtr(ll_ptrtype=lltype.typeOf(cast_p))
+def direct_ptradd(s_p, s_n):
+ assert isinstance(s_p, SomePtr), "direct_* of non-pointer: %r" % s_p
+ # don't bother with an example here: the resulting pointer is the same
+ return s_p
+
def cast_ptr_to_int(s_ptr): # xxx
return SomeInteger()
@@ -454,8 +454,9 @@
BUILTIN_ANALYZERS[lltype.cast_primitive] = cast_primitive
BUILTIN_ANALYZERS[lltype.nullptr] = nullptr
BUILTIN_ANALYZERS[lltype.cast_pointer] = cast_pointer
-BUILTIN_ANALYZERS[lltype.cast_subarray_pointer] = cast_subarray_pointer
-BUILTIN_ANALYZERS[lltype.cast_structfield_pointer] = cast_structfield_pointer
+BUILTIN_ANALYZERS[lltype.direct_fieldptr] = direct_fieldptr
+BUILTIN_ANALYZERS[lltype.direct_arrayitems] = direct_arrayitems
+BUILTIN_ANALYZERS[lltype.direct_ptradd] = direct_ptradd
BUILTIN_ANALYZERS[lltype.cast_ptr_to_int] = cast_ptr_to_int
BUILTIN_ANALYZERS[lltype.getRuntimeTypeInfo] = getRuntimeTypeInfo
BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info
Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py (original)
+++ pypy/dist/pypy/rpython/llinterp.py Tue Apr 18 17:18:01 2006
@@ -536,6 +536,20 @@
assert checkptr(ptr1)
return not bool(ptr1)
+ def op_direct_fieldptr(self, obj, field):
+ assert checkptr(obj)
+ assert isinstance(field, str)
+ return lltype.direct_fieldptr(obj, field)
+
+ def op_direct_arrayitems(self, obj):
+ assert checkptr(obj)
+ return lltype.direct_arrayitems(obj)
+
+ def op_direct_ptradd(self, obj, index):
+ assert checkptr(obj)
+ assert isinstance(index, int)
+ return lltype.direct_ptradd(obj, index)
+
def op_cast_ptr_to_int(self, ptr1):
assert checkptr(ptr1)
assert isinstance(lltype.typeOf(ptr1).TO, (lltype.Array, lltype.Struct))
Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llmemory.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py Tue Apr 18 17:18:01 2006
@@ -219,17 +219,15 @@
if (isinstance(ref, _arrayitemref) and
isinstance(EXPECTED_TYPE.TO, lltype.FixedSizeArray) and
ref.type() == EXPECTED_TYPE.TO.OF):
- # special case that requires cast_subarray_pointer
- return lltype.cast_subarray_pointer(EXPECTED_TYPE,
- ref.array,
- ref.index)
+ # special case that requires direct_arrayitems
+ p_items = lltype.direct_arrayitems(ref.array)
+ return lltype.direct_ptradd(p_items, ref.index)
elif (isinstance(ref, _structfieldref) and
isinstance(EXPECTED_TYPE.TO, lltype.FixedSizeArray) and
ref.type() == EXPECTED_TYPE.TO.OF):
- # special case that requires cast_structfield_pointer
- return lltype.cast_structfield_pointer(EXPECTED_TYPE,
- ref.struct,
- ref.fieldname)
+ # special case that requires direct_fieldptr
+ return lltype.direct_fieldptr(ref.struct,
+ ref.fieldname)
else:
# regular case
return lltype.cast_pointer(EXPECTED_TYPE, ref.get())
Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Tue Apr 18 17:18:01 2006
@@ -265,6 +265,9 @@
'ptr_nonzero': LLOp(canfold=True),
'ptr_iszero': LLOp(canfold=True),
'cast_ptr_to_int': LLOp(sideeffects=False),
+ 'direct_fieldptr': LLOp(canfold=True),
+ 'direct_arrayitems': LLOp(canfold=True),
+ 'direct_ptradd': LLOp(canfold=True),
# _________ XXX l3interp hacks ___________
Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Tue Apr 18 17:18:01 2006
@@ -614,53 +614,44 @@
raise TypeError, "can only cast pointers to other pointers"
return ptr._cast_to(PTRTYPE)
-def cast_subarray_pointer(ARRAYPTRTYPE, arrayptr, baseoffset):
- CURPTRTYPE = typeOf(arrayptr)
- if not isinstance(CURPTRTYPE, Ptr) or not isinstance(ARRAYPTRTYPE, Ptr):
- raise TypeError, "can only cast pointers to other pointers"
- ARRAYTYPE = ARRAYPTRTYPE.TO
- if (not isinstance(CURPTRTYPE.TO, (Array, FixedSizeArray)) or
- not isinstance(ARRAYTYPE, FixedSizeArray)):
- raise TypeError, "can only cast from arrays to FixedSizeArray"
- if CURPTRTYPE.TO.OF != ARRAYTYPE.OF:
- raise TypeError, "mismatching array item types"
+def direct_fieldptr(structptr, fieldname):
+ """Get a pointer to a field in the struct. The resulting
+ pointer is actually of type Ptr(FixedSizeArray(FIELD, 1)).
+ It can be used in a regular getarrayitem(0) or setarrayitem(0)
+ to read or write to the field.
+ """
+ CURTYPE = typeOf(structptr).TO
+ if not isinstance(CURTYPE, Struct):
+ raise TypeError, "direct_fieldptr: not a struct"
+ if fieldname not in CURTYPE._flds:
+ raise TypeError, "%s has no field %r" % (CURTYPE, fieldname)
+ if not structptr:
+ raise RuntimeError("direct_fieldptr: NULL argument")
+ return _subarray._makeptr(structptr._obj, fieldname)
+
+def direct_arrayitems(arrayptr):
+ """Get a pointer to the first item of the array. The resulting
+ pointer is actually of type Ptr(FixedSizeArray(ITEM, 1)) but can
+ be used in a regular getarrayitem(n) or direct_ptradd(n) to access
+ further elements.
+ """
+ CURTYPE = typeOf(arrayptr).TO
+ if not isinstance(CURTYPE, (Array, FixedSizeArray)):
+ raise TypeError, "direct_arrayitems: not an array"
if not arrayptr:
- raise RuntimeError("cast_subarray_pointer: NULL argument")
- try:
- cache = _subarray._cache[arrayptr._obj]
- except KeyError:
- cache = _subarray._cache[arrayptr._obj] = {}
- key = (ARRAYTYPE, baseoffset)
- try:
- subarray = cache[key]
- except KeyError:
- subarray = cache[key] = _subarray(ARRAYTYPE, arrayptr._obj, baseoffset)
- return _ptr(ARRAYPTRTYPE, subarray)
+ raise RuntimeError("direct_arrayitems: NULL argument")
+ return _subarray._makeptr(arrayptr._obj, 0)
-def cast_structfield_pointer(ARRAYPTRTYPE, structptr, fieldname):
- CURPTRTYPE = typeOf(structptr)
- if not isinstance(CURPTRTYPE, Ptr) or not isinstance(ARRAYPTRTYPE, Ptr):
- raise TypeError, "can only cast pointers to other pointers"
- ARRAYTYPE = ARRAYPTRTYPE.TO
- if (not isinstance(CURPTRTYPE.TO, Struct) or
- not isinstance(ARRAYTYPE, FixedSizeArray)):
- raise TypeError, "can only cast from (Gc)Struct to FixedSizeArray"
- if ARRAYTYPE.length != 1:
- raise TypeError, "can only cast to FixedSizeArray of length 1"
- if getattr(CURPTRTYPE.TO, fieldname) != ARRAYTYPE.OF:
- raise TypeError, "mismatching array item type"
- if not structptr:
- raise RuntimeError("cast_structfield_pointer: NULL argument")
- try:
- cache = _subarray._cache[structptr._obj]
- except KeyError:
- cache = _subarray._cache[structptr._obj] = {}
- try:
- subarray = cache[fieldname]
- except KeyError:
- subarray = cache[fieldname] = _subarray(ARRAYTYPE, structptr._obj,
- fieldname)
- return _ptr(ARRAYPTRTYPE, subarray)
+def direct_ptradd(ptr, n):
+ """Shift a pointer forward or backward by n items. The pointer must
+ have been built by direct_arrayitems().
+ """
+ if not ptr:
+ raise RuntimeError("direct_ptradd: NULL argument")
+ if not isinstance(ptr._obj, _subarray):
+ raise TypeError("direct_ptradd: only for direct_arrayitems() ptrs")
+ parent, base = parentlink(ptr._obj)
+ return _subarray._makeptr(parent, base + n)
def _expose(val, solid=False):
"""XXX A nice docstring here"""
@@ -1138,6 +1129,24 @@
else:
self._parentstructure().setitem(baseoffset + index, value)
+ def _makeptr(parent, baseoffset_or_fieldname):
+ cache = _subarray._cache.setdefault(parent, {})
+ try:
+ subarray = cache[baseoffset_or_fieldname]
+ except KeyError:
+ PARENTTYPE = typeOf(parent)
+ if isinstance(baseoffset_or_fieldname, str):
+ # for direct_fieldptr
+ ITEMTYPE = getattr(PARENTTYPE, baseoffset_or_fieldname)
+ else:
+ # for direct_arrayitems
+ ITEMTYPE = PARENTTYPE.OF
+ ARRAYTYPE = FixedSizeArray(ITEMTYPE, 1)
+ subarray = _subarray(ARRAYTYPE, parent, baseoffset_or_fieldname)
+ cache[baseoffset_or_fieldname] = subarray
+ return _ptr(Ptr(subarray._TYPE), subarray)
+ _makeptr = staticmethod(_makeptr)
+
class _func(object):
def __init__(self, TYPE, **attrs):
Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py Tue Apr 18 17:18:01 2006
@@ -578,7 +578,7 @@
assert len(s.a) == 5
py.test.raises(TypeError, "s.a = a")
-def test_cast_subarray_pointer():
+def test_direct_arrayitems():
for a in [malloc(GcArray(Signed), 5),
malloc(FixedSizeArray(Signed, 5), immortal=True)]:
a[0] = 0
@@ -586,36 +586,34 @@
a[2] = 20
a[3] = 30
a[4] = 40
- BOX = Ptr(FixedSizeArray(Signed, 2))
- b01 = cast_subarray_pointer(BOX, a, 0)
- b12 = cast_subarray_pointer(BOX, a, 1)
- b23 = cast_subarray_pointer(BOX, a, 2)
- b34 = cast_subarray_pointer(BOX, a, 3)
- assert b01[0] == 0
- assert b01[1] == 10
- assert b12[0] == 10
- assert b12[1] == 20
- assert b23[0] == 20
- assert b23[1] == 30
- assert b34[0] == 30
- assert b34[1] == 40
- b23[0] = 23
+ b0 = direct_arrayitems(a)
+ b1 = direct_ptradd(b0, 1)
+ b2 = direct_ptradd(b1, 1)
+ b3 = direct_ptradd(b0, 3)
+ assert b0[0] == 0
+ assert b0[1] == 10
+ assert b0[4] == 40
+ assert b1[0] == 10
+ assert b1[1] == 20
+ assert b2[0] == 20
+ assert b2[1] == 30
+ assert b3[-2] == 10
+ assert b3[0] == 30
+ assert b3[1] == 40
+ assert b2[-2] == 0
+ assert b1[3] == 40
+ b2[0] = 23
assert a[2] == 23
- b12[1] += 1
+ b1[1] += 1
assert a[2] == 24
- # out-of-bound access is allowed, if it's within the parent's bounds
- assert len(b23) == 2
- assert b23[-1] == 10
- assert b12[3] == 40
- py.test.raises(IndexError, "b01[-1]")
- py.test.raises(IndexError, "b34[2]")
- py.test.raises(IndexError, "b12[4]")
+ py.test.raises(IndexError, "b0[-1]")
+ py.test.raises(IndexError, "b3[2]")
+ py.test.raises(IndexError, "b1[4]")
-def test_cast_structfield_pointer():
+def test_direct_fieldptr():
S = GcStruct('S', ('x', Signed), ('y', Signed))
- A = FixedSizeArray(Signed, 1)
s = malloc(S)
- a = cast_structfield_pointer(Ptr(A), s, 'y')
+ a = direct_fieldptr(s, 'y')
a[0] = 34
assert s.y == 34
py.test.raises(IndexError, "a[1]")
Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py (original)
+++ pypy/dist/pypy/rpython/rbuiltin.py Tue Apr 18 17:18:01 2006
@@ -307,77 +307,27 @@
return hop.genop('cast_pointer', [v_input], # v_type implicit in r_result
resulttype = hop.r_result.lowleveltype)
-def rtype_cast_subarray_pointer(hop):
- assert hop.args_s[0].is_constant()
- assert isinstance(hop.args_r[1], rptr.PtrRepr)
- v_type, v_input, v_baseoffset = hop.inputargs(lltype.Void, hop.args_r[1],
- lltype.Signed)
+def rtype_direct_fieldptr(hop):
+ assert isinstance(hop.args_r[0], rptr.PtrRepr)
+ assert hop.args_s[1].is_constant()
+ vlist = hop.inputargs(hop.args_r[0], lltype.Void)
hop.exception_cannot_occur()
- # instead of adding a 'cast_subarray_pointer' ll operation,
- # we do it with address manipulations
- return gen_cast_subarray_pointer(hop.llops, hop.r_result.lowleveltype,
- v_input, v_baseoffset)
-
-def gen_cast_subarray_pointer(llops, ARRAYPTRTYPE, v_array, v_baseoffset):
- "Helper to generate the equivalent of a 'cast_subarray_pointer' operation."
- from pypy.rpython.lltypesystem import llmemory
- SRCTYPE = v_array.concretetype.TO
- v_array_adr = llops.genop('cast_ptr_to_adr', [v_array],
- resulttype = llmemory.Address)
- c_ofs1 = inputconst(lltype.Signed, llmemory.ArrayItemsOffset(SRCTYPE))
- v_array_items_adr = llops.genop('adr_add', [v_array_adr, c_ofs1],
- resulttype = llmemory.Address)
- if isinstance(v_baseoffset, Constant) and v_baseoffset.value == 0:
- v_base_adr = v_array_items_adr
- else:
- c_ofs2 = inputconst(lltype.Signed, llmemory.ItemOffset(SRCTYPE.OF))
- v_ofs3 = llops.genop('int_mul', [c_ofs2, v_baseoffset],
- resulttype = lltype.Signed)
- v_base_adr = llops.genop('adr_add', [v_array_items_adr, v_ofs3],
- resulttype = llmemory.Address)
- 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."
- if isinstance(v_index, Constant) and v_index.value == 0:
- return v_ptr
- 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)
+ return hop.genop('direct_fieldptr', vlist,
+ resulttype=hop.r_result.lowleveltype)
-def rtype_cast_structfield_pointer(hop):
- assert hop.args_s[0].is_constant()
- assert hop.args_s[2].is_constant()
- fieldname = hop.args_s[2].const
- assert isinstance(hop.args_r[1], rptr.PtrRepr)
- v_type, v_input, v_fieldname = hop.inputargs(lltype.Void, hop.args_r[1],
- lltype.Void)
+def rtype_direct_arrayitems(hop):
+ assert isinstance(hop.args_r[0], rptr.PtrRepr)
+ vlist = hop.inputargs(hop.args_r[0])
+ hop.exception_cannot_occur()
+ return hop.genop('direct_arrayitems', vlist,
+ resulttype=hop.r_result.lowleveltype)
+
+def rtype_direct_ptradd(hop):
+ assert isinstance(hop.args_r[0], rptr.PtrRepr)
+ vlist = hop.inputargs(hop.args_r[0], lltype.Signed)
hop.exception_cannot_occur()
- # instead of adding a 'cast_structfield_pointer' ll operation,
- # we do it with address manipulations
- return gen_cast_structfield_pointer(hop.llops, hop.r_result.lowleveltype,
- v_input, fieldname)
-
-def gen_cast_structfield_pointer(llops, ARRAYPTRTYPE, v_struct, fieldname):
- "Helper to generate the equivalent of a 'cast_structfield_pointer' op."
- from pypy.rpython.lltypesystem import llmemory
- SRCTYPE = v_struct.concretetype.TO
- v_struct_adr = llops.genop('cast_ptr_to_adr', [v_struct],
- resulttype = llmemory.Address)
- c_ofs1 = inputconst(lltype.Signed,
- llmemory.FieldOffset(SRCTYPE, fieldname))
- v_base_adr = llops.genop('adr_add', [v_struct_adr, c_ofs1],
- resulttype = llmemory.Address)
- return llops.genop('cast_adr_to_ptr', [v_base_adr],
- resulttype = ARRAYPTRTYPE)
+ return hop.genop('direct_ptradd', vlist,
+ resulttype=hop.r_result.lowleveltype)
def rtype_cast_primitive(hop):
assert hop.args_s[0].is_constant()
@@ -413,8 +363,9 @@
BUILTIN_TYPER[lltype.malloc] = rtype_malloc
BUILTIN_TYPER[lltype.cast_primitive] = rtype_cast_primitive
BUILTIN_TYPER[lltype.cast_pointer] = rtype_cast_pointer
-BUILTIN_TYPER[lltype.cast_subarray_pointer] = rtype_cast_subarray_pointer
-BUILTIN_TYPER[lltype.cast_structfield_pointer] = rtype_cast_structfield_pointer
+BUILTIN_TYPER[lltype.direct_fieldptr] = rtype_direct_fieldptr
+BUILTIN_TYPER[lltype.direct_arrayitems] = rtype_direct_arrayitems
+BUILTIN_TYPER[lltype.direct_ptradd] = rtype_direct_ptradd
BUILTIN_TYPER[lltype.cast_ptr_to_int] = rtype_cast_ptr_to_int
BUILTIN_TYPER[lltype.typeOf] = rtype_const_result
BUILTIN_TYPER[lltype.nullptr] = rtype_const_result
Modified: pypy/dist/pypy/rpython/rctypes/rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rarray.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rarray.py Tue Apr 18 17:18:01 2006
@@ -1,5 +1,4 @@
from ctypes import ARRAY, c_int
-from pypy.rpython.rbuiltin import gen_cast_subarray_pointer
from pypy.rpython.rstr import string_repr
from pypy.rpython.rmodel import IntegerRepr, inputconst
from pypy.rpython.lltypesystem import lltype
@@ -9,6 +8,7 @@
from pypy.rpython.rctypes.rprimitive import PrimitiveRepr
from pypy.rpython.rctypes.rpointer import PointerRepr
from pypy.annotation.model import SomeCTypesObject
+from pypy.objspace.flow.model import Constant
ArrayType = type(ARRAY(c_int, 10))
@@ -64,9 +64,15 @@
lltype.Ptr(self.r_item.c_data_type))
else:
# ByValue case
- A = lltype.FixedSizeArray(self.r_item.ll_type, 1)
- return gen_cast_subarray_pointer(llops, lltype.Ptr(A),
- v_c_array, v_index)
+ P = lltype.Ptr(lltype.FixedSizeArray(self.r_item.ll_type, 1))
+ v_items = llops.genop('direct_arrayitems', [v_c_array],
+ resulttype = P)
+ if isinstance(v_index, Constant) and v_index.value == 0:
+ pass # skip direct_ptradd
+ else:
+ v_items = llops.genop('direct_ptradd', [v_items, v_index],
+ resulttype = P)
+ return v_items
def get_item_value(self, llops, v_array, v_index):
# ByValue case only
@@ -125,8 +131,7 @@
def ll_chararrayvalue(box):
from pypy.rpython.rctypes import rchar_p
p = box.c_data
- p1 = lltype.cast_subarray_pointer(rchar_p.CCHARP, p, 0)
- length = rchar_p.ll_strnlen(p1, len(p))
+ length = rchar_p.ll_strnlen(lltype.direct_arrayitems(p), len(p))
newstr = lltype.malloc(string_repr.lowleveltype.TO, length)
for i in range(length):
newstr.chars[i] = p[i]
Modified: pypy/dist/pypy/rpython/rctypes/rchar_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rchar_p.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rchar_p.py Tue Apr 18 17:18:01 2006
@@ -103,7 +103,7 @@
return i
def ll_str2charp(s):
- return lltype.cast_subarray_pointer(CCHARP, s.chars, 0)
+ return lltype.direct_arrayitems(s.chars)
def ll_charp2str(p):
length = ll_strlen(p)
Modified: pypy/dist/pypy/rpython/rctypes/rpointer.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rpointer.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rpointer.py Tue Apr 18 17:18:01 2006
@@ -1,10 +1,10 @@
-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
from pypy.annotation.pairtype import pairtype
from pypy.rpython.rctypes.rmodel import CTypesValueRepr, genreccopy
from pypy.annotation.model import SomeCTypesObject
+from pypy.objspace.flow.model import Constant
class PointerRepr(CTypesValueRepr):
@@ -65,9 +65,11 @@
self = r_ptr
v_ptr, v_index = hop.inputargs(self, lltype.Signed)
v_c_ptr = self.getvalue(hop.llops, v_ptr)
- v_c_ptr = gen_add_itemoffset_to_pointer(hop.llops,
- r_ptr.r_contents.ll_type,
- v_c_ptr, v_index)
+ if isinstance(v_index, Constant) and v_index.value == 0:
+ pass # skip direct_ptradd
+ else:
+ v_c_ptr = hop.genop('direct_ptradd', [v_c_ptr, v_index],
+ resulttype = r_ptr.ll_type)
return self.r_contents.return_c_data(hop.llops, v_c_ptr)
def rtype_setitem((r_ptr, _), hop):
Modified: pypy/dist/pypy/rpython/rctypes/rstringbuf.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rstringbuf.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rstringbuf.py Tue Apr 18 17:18:01 2006
@@ -1,8 +1,8 @@
from pypy.rpython.lltypesystem import lltype
from pypy.annotation.pairtype import pairtype
-from pypy.rpython.rbuiltin import gen_cast_subarray_pointer
from pypy.rpython.rmodel import IntegerRepr, inputconst
from pypy.rpython.rctypes.rmodel import CTypesRefRepr
+from pypy.objspace.flow.model import Constant
class StringBufRepr(CTypesRefRepr):
@@ -23,8 +23,14 @@
def get_c_data_of_item(self, llops, v_stringbuf, v_index):
v_array = self.get_c_data(llops, v_stringbuf)
- return gen_cast_subarray_pointer(llops, ONE_CHAR_PTR,
- v_array, v_index)
+ v_char_p = llops.genop('direct_arrayitems', [v_array],
+ resulttype = ONE_CHAR_PTR)
+ if isinstance(v_index, Constant) and v_index.value == 0:
+ pass # skip direct_ptradd
+ else:
+ v_char_p = llops.genop('direct_ptradd', [v_char_p, v_index],
+ resulttype = ONE_CHAR_PTR)
+ return v_char_p
ONE_CHAR_PTR = lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1))
Modified: pypy/dist/pypy/rpython/rctypes/rstruct.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rstruct.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rstruct.py Tue Apr 18 17:18:01 2006
@@ -1,5 +1,4 @@
from pypy.rpython.rmodel import inputconst
-from pypy.rpython.rbuiltin import gen_cast_structfield_pointer
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.rctypes.rmodel import CTypesRefRepr, CTypesValueRepr
from pypy.rpython.rctypes.rmodel import genreccopy_structfield, reccopy
@@ -54,16 +53,16 @@
def get_c_data_of_field(self, llops, v_struct, fieldname):
v_c_struct = self.get_c_data(llops, v_struct)
r_field = self.r_fields[fieldname]
+ c_fieldname = inputconst(lltype.Void, fieldname)
if isinstance(r_field, CTypesRefRepr):
# ByRef case
- c_fieldname = inputconst(lltype.Void, fieldname)
return llops.genop('getsubstruct', [v_c_struct, c_fieldname],
lltype.Ptr(r_field.c_data_type))
else:
# ByValue case
- A = lltype.FixedSizeArray(r_field.ll_type, 1)
- return gen_cast_structfield_pointer(llops, lltype.Ptr(A),
- v_c_struct, fieldname)
+ P = lltype.Ptr(lltype.FixedSizeArray(r_field.ll_type, 1))
+ return llops.genop('direct_fieldptr', [v_c_struct, c_fieldname],
+ resulttype = P)
def get_field_value(self, llops, v_struct, fieldname):
# ByValue case only
Modified: pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py Tue Apr 18 17:18:01 2006
@@ -72,8 +72,7 @@
def str2subarray(string):
llstring = string_repr.convert_const(string)
keepalive.append(llstring)
- A = lltype.FixedSizeArray(lltype.Char, 1)
- return lltype.cast_subarray_pointer(lltype.Ptr(A), llstring.chars, 0)
+ return lltype.direct_arrayitems(llstring.chars)
assert ll_atoi(str2subarray("")) == 0
assert ll_atoi(str2subarray("42z7")) == 42
assert ll_atoi(str2subarray("blah")) == 0
Modified: pypy/dist/pypy/translator/c/funcgen.py
==============================================================================
--- pypy/dist/pypy/translator/c/funcgen.py (original)
+++ pypy/dist/pypy/translator/c/funcgen.py Tue Apr 18 17:18:01 2006
@@ -564,6 +564,21 @@
else:
raise NotImplementedError
+ def OP_DIRECT_FIELDPTR(self, op):
+ return self.OP_GETFIELD(op, ampersand='&')
+
+ def OP_DIRECT_ARRAYITEMS(self, op):
+ ARRAY = self.lltypemap(op.args[0]).TO
+ items = self.expr(op.args[0])
+ if not isinstance(ARRAY, FixedSizeArray):
+ items += '->items'
+ return '%s = %s;' % (self.expr(op.result), items)
+
+ def OP_DIRECT_PTRADD(self, op):
+ return '%s = %s + %s;' % (self.expr(op.result),
+ self.expr(op.args[0]),
+ self.expr(op.args[1]))
+
def OP_CAST_POINTER(self, op):
TYPE = self.lltypemap(op.result)
typename = self.db.gettype(TYPE)
Modified: pypy/dist/pypy/translator/c/test/test_lltyped.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_lltyped.py (original)
+++ pypy/dist/pypy/translator/c/test/test_lltyped.py Tue Apr 18 17:18:01 2006
@@ -129,7 +129,7 @@
res = fn(4)
assert res == -1
- def test_cast_subarray_pointer(self):
+ def test_direct_arrayitems(self):
for a in [malloc(GcArray(Signed), 5),
malloc(FixedSizeArray(Signed, 5), immortal=True)]:
a[0] = 0
@@ -137,16 +137,16 @@
a[2] = 20
a[3] = 30
a[4] = 40
- BOX = Ptr(FixedSizeArray(Signed, 2))
- b01 = cast_subarray_pointer(BOX, a, 0)
- b12 = cast_subarray_pointer(BOX, a, 1)
- b23 = cast_subarray_pointer(BOX, a, 2)
- b34 = cast_subarray_pointer(BOX, a, 3)
+ b0 = direct_arrayitems(a)
+ b1 = direct_ptradd(b0, 1)
+ b2 = direct_ptradd(b1, 1)
def llf(n=int):
+ b0 = direct_arrayitems(a)
+ b3 = direct_ptradd(direct_ptradd(b0, 5), -2)
saved = a[n]
a[n] = 1000
try:
- return b01[0] + b12[0] + b23[1] + b34[1]
+ return b0[0] + b3[-2] + b2[1] + b1[3]
finally:
a[n] = saved
fn = self.getcompiled(llf)
@@ -161,13 +161,11 @@
res = fn(4)
assert res == 0 + 10 + 30 + 1000
- def test_cast_structfield_pointer(self):
+ def test_direct_fieldptr(self):
S = GcStruct('S', ('x', Signed), ('y', Signed))
- SUBARRAY = FixedSizeArray(Signed, 1)
- P = Ptr(SUBARRAY)
def llf(n=int):
s = malloc(S)
- a = cast_structfield_pointer(P, s, 'y')
+ a = direct_fieldptr(s, 'y')
a[0] = n
return s.y
@@ -183,11 +181,10 @@
a2[1] = 600
s.x = 50
s.y = 4
- P = Ptr(FixedSizeArray(Signed, 1))
- p1 = cast_subarray_pointer(P, a1, 3)
- p2 = cast_subarray_pointer(P, a2, 1)
- p3 = cast_structfield_pointer(P, s, 'x')
- p4 = cast_structfield_pointer(P, s, 'y')
+ p1 = direct_ptradd(direct_arrayitems(a1), 3)
+ p2 = direct_ptradd(direct_arrayitems(a2), 1)
+ p3 = direct_fieldptr(s, 'x')
+ p4 = direct_fieldptr(s, 'y')
def llf():
a1[3] += 1000
a2[1] += 100
More information about the Pypy-commit
mailing list