[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