[pypy-svn] r32256 - in pypy/dist/pypy/rpython/rctypes: . test

arigo at codespeak.net arigo at codespeak.net
Wed Sep 13 14:10:57 CEST 2006


Author: arigo
Date: Wed Sep 13 14:10:52 2006
New Revision: 32256

Modified:
   pypy/dist/pypy/rpython/rctypes/rarray.py
   pypy/dist/pypy/rpython/rctypes/test/test_rarray.py
Log:
Support for slicing char arrays, as it's the only way to get an RPython
string from a slice without doing multiple copies.



Modified: pypy/dist/pypy/rpython/rctypes/rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rarray.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rarray.py	Wed Sep 13 14:10:52 2006
@@ -1,6 +1,7 @@
 from ctypes import ARRAY, c_int
 from pypy.rpython.lltypesystem.rstr import string_repr
 from pypy.rpython.rmodel import IntegerRepr, inputconst
+from pypy.rpython.rslice import AbstractSliceRepr
 from pypy.rpython.lltypesystem import lltype
 from pypy.annotation.pairtype import pairtype
 from pypy.rpython.rctypes.rmodel import CTypesRefRepr, CTypesValueRepr
@@ -140,6 +141,17 @@
         r_array.setitem(hop.llops, v_array, v_index, v_item)
 
 
+class __extend__(pairtype(ArrayRepr, AbstractSliceRepr)):
+    def rtype_getitem((r_array, r_slic), hop):
+        rs = hop.rtyper.type_system.rslice
+        if r_slic == rs.startstop_slice_repr:
+            # slicing: char array only
+            assert r_array.r_item.ll_type == lltype.Char
+            v_array, v_slice = hop.inputargs(r_array, rs.startstop_slice_repr)
+            return hop.gendirectcall(ll_chararrayslice, v_array, v_slice)
+        raise TyperError('getitem does not support slices with %r' % (r_slic,))
+
+
 class __extend__(pairtype(ArrayRepr, PointerRepr)):
     def convert_from_to((r_from, r_to), v, llops):
         # XXX keepalives
@@ -159,3 +171,16 @@
     for i in range(length):
         newstr.chars[i] = p[i]
     return newstr
+
+def ll_chararrayslice(box, slice):
+    from pypy.rpython.rctypes import rchar_p
+    p = box.c_data
+    start = slice.start
+    stop = slice.stop
+    length = stop - start
+    assert length >= 0
+    newstr = lltype.malloc(string_repr.lowleveltype.TO, length)
+    newstr.hash = 0
+    for i in range(length):
+        newstr.chars[i] = p[start+i]
+    return newstr

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rarray.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rarray.py	Wed Sep 13 14:10:52 2006
@@ -163,6 +163,21 @@
             a.translator.view()
         assert s == annmodel.SomeString()
 
+    def test_annotate_char_array_slice(self):
+        A = c_char * 3
+        def func():
+            a = A()
+            a[0] = 'x'
+            a[1] = 'y'
+            a[2] = 'z'
+            return a[0:2]
+        t = TranslationContext()
+        a = t.buildannotator()
+        s = a.build_types(func, [])
+        if conftest.option.view:
+            a.translator.view()
+        assert s == annmodel.SomeString()
+
     def test_annotate_varsize_array(self):
         def func(n):
             a = (c_int * n)()
@@ -229,6 +244,20 @@
         res = interpret(func, [])
         assert ''.join(res.chars) == "xy"
 
+    def test_specialize_char_array_slice(self):
+        A = c_char * 3
+        def func(n):
+            a = A()
+            a[0] = 'x'
+            a[1] = 'y'
+            a[2] = 'z'
+            assert n >= 0
+            return a[0:n]
+        res = interpret(func, [1])
+        assert ''.join(res.chars) == "x"
+        res = interpret(func, [3])
+        assert ''.join(res.chars) == "xyz"
+
     def test_automatic_cast_array_to_pointer(self):
         A = c_int * 10
         class S(Structure):



More information about the Pypy-commit mailing list