[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