[pypy-svn] r25809 - in pypy/dist/pypy: annotation rpython/rctypes rpython/rctypes/test
arigo at codespeak.net
arigo at codespeak.net
Thu Apr 13 18:43:56 CEST 2006
Author: arigo
Date: Thu Apr 13 18:43:54 2006
New Revision: 25809
Modified:
pypy/dist/pypy/annotation/model.py
pypy/dist/pypy/rpython/rctypes/rchar_p.py
pypy/dist/pypy/rpython/rctypes/rprimitive.py
pypy/dist/pypy/rpython/rctypes/rstruct.py
pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py
pypy/dist/pypy/rpython/rctypes/test/test_rarray.py
pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py
Log:
Automatic c_char_p-to-str conversion when reads fields of a struct
or getting a function's result. Typos, tests.
Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py (original)
+++ pypy/dist/pypy/annotation/model.py Thu Apr 13 18:43:54 2006
@@ -451,11 +451,8 @@
from pypy.rpython import extregistry
assert extregistry.is_registered_type(self.knowntype)
entry = extregistry.lookup_type(self.knowntype)
- if hasattr(entry, 'lowleveltype'):
- # special case for returning primitives
- return lltype_to_annotation(entry.lowleveltype)
- else:
- return self
+ # special case for returning primitives or c_char_p
+ return getattr(entry, 's_return_trick', self)
class SomeImpossibleValue(SomeObject):
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 Thu Apr 13 18:43:54 2006
@@ -12,6 +12,13 @@
class CCharPRepr(CTypesValueRepr):
+ def return_c_data(self, llops, v_c_data):
+ """Read out the RPython string from a raw C pointer.
+ Used when the data is returned from an operation or C function call.
+ """
+ v_char_p = self.getvalue_from_c_data(llops, v_c_data)
+ return llops.gendirectcall(ll_charp2str, v_char_p)
+
def get_content_keepalives(self):
"Return an extra keepalive field used for the RPython string."
return [('keepalive_str', string_repr.lowleveltype)]
@@ -83,6 +90,13 @@
def ll_str2charp(s):
return lltype.cast_subarray_pointer(CCHARP, s.chars, 0)
+def ll_charp2str(p):
+ length = ll_strlen(p)
+ newstr = lltype.malloc(string_repr.lowleveltype.TO, length)
+ for i in range(length):
+ newstr.chars[i] = p[i]
+ return newstr
+
def ll_getstring(box):
p = box.c_data[0]
if p:
@@ -137,7 +151,9 @@
compute_annotation = c_char_compute_annotation,
get_repr = c_char_p_get_repr,
)
+s_value_annotation = annmodel.SomeString(can_be_None=True)
def c_char_p_get_field_annotation(s_char_p, fieldname):
assert fieldname == 'value'
- return annmodel.SomeString(can_be_None=True)
+ return s_value_annotation
entry.get_field_annotation = c_char_p_get_field_annotation
+entry.s_return_trick = s_value_annotation
Modified: pypy/dist/pypy/rpython/rctypes/rprimitive.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rprimitive.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rprimitive.py Thu Apr 13 18:43:54 2006
@@ -95,11 +95,12 @@
compute_annotation=compute_prebuilt_instance_annotation,
get_repr=primitive_get_repr,
)
+ s_value_annotation = annmodel.lltype_to_annotation(ll_type)
def primitive_get_field_annotation(s_primitive, fieldname):
assert fieldname == 'value'
- return annmodel.lltype_to_annotation(ll_type)
+ return s_value_annotation
entry.get_field_annotation = primitive_get_field_annotation
- entry.lowleveltype = ll_type
+ entry.s_return_trick = s_value_annotation
for the_type, ll_type in ctypes_annotation_list:
do_register(the_type, ll_type)
Modified: pypy/dist/pypy/rpython/rctypes/rstruct.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rstruct.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rstruct.py Thu Apr 13 18:43:54 2006
@@ -79,7 +79,7 @@
# primitive case (optimization only)
return self.get_field_value(hop.llops, v_struct, name)
# normal case
- v_c_data = self.get_c_data_of_item(hop.llops, v_struct, name)
+ v_c_data = self.get_c_data_of_field(hop.llops, v_struct, name)
return r_field.return_c_data(hop.llops, v_c_data)
def rtype_setattr(self, hop):
@@ -91,7 +91,7 @@
if isinstance(r_field, CTypesRefRepr):
# ByRef case
v_new_c_data = r_field.get_c_data(hop.llops, v_item)
- v_c_data = self.get_c_data_of_item(hop.llops, v_struct, name)
+ v_c_data = self.get_c_data_of_field(hop.llops, v_struct, name)
# copy the whole structure's content over
genreccopy(hop.llops, v_new_c_data, v_c_data)
else:
Modified: pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py Thu Apr 13 18:43:54 2006
@@ -64,6 +64,11 @@
p[0] = "other"
assert x.value == p.contents.value == p[0] == "other"
+ myarray = (c_char_p * 10)()
+ myarray[7] = "hello"
+ assert isinstance(myarray[7], str)
+ assert myarray[7] == "hello"
+
def test_struct():
class tagpoint(Structure):
_fields_ = [('x', c_int),
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 Thu Apr 13 18:43:54 2006
@@ -16,7 +16,7 @@
except ImportError:
py.test.skip("this test needs ctypes installed")
-from ctypes import c_int, c_short, ARRAY, POINTER, pointer
+from ctypes import c_int, c_short, ARRAY, POINTER, pointer, c_char_p
c_int_10 = ARRAY(c_int,10)
@@ -118,6 +118,30 @@
a.translator.view()
assert s.knowntype == int
+ def test_annotate_variants(self):
+ A1 = c_int * 10
+ A2 = POINTER(c_int) * 10
+ A3 = A1 * 10
+ A4 = POINTER(A1) * 10
+ A5 = c_char_p * 10
+ def func():
+ a1 = A1(); a1[4] = 1000
+ a2 = A2(); a2[5] = pointer(c_int(200))
+ a3 = A3(); a3[2][9] = 30
+ a4 = A4(); a4[3] = pointer(a1); a1[1] = 4
+ a5 = A5(); a5[7] = "hello"
+ res = a1[4] + a2[5].contents.value + a3[2][9] + a4[3].contents[1]
+ res *= ord(a5[7][1])
+ return res
+ assert func() == 1234 * ord('e')
+
+ t = TranslationContext()
+ a = t.buildannotator()
+ s = a.build_types(func, [])
+ if conftest.option.view:
+ a.translator.view()
+ assert s.knowntype == int
+
class Test_specialization:
def test_specialize_array(self):
def create_array():
Modified: pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py Thu Apr 13 18:43:54 2006
@@ -17,7 +17,7 @@
except ImportError:
py.test.skip("this test needs ctypes installed")
-from ctypes import c_char_p, pointer
+from ctypes import c_char_p, pointer, Structure
class Test_annotation:
def test_annotate_c_char_p(self):
@@ -44,6 +44,21 @@
if conftest.option.view:
t.view()
+ def test_annotate_return(self):
+ class S(Structure):
+ _fields_ = [('string', c_char_p)]
+ def func():
+ s = S()
+ s.string = "hello"
+ return s.string
+
+ t = TranslationContext()
+ a = t.buildannotator()
+ s = a.build_types(func, [])
+ assert s.knowntype == str
+ if conftest.option.view:
+ t.view()
+
class Test_specialization:
def test_specialize_c_char_p(self):
def func():
@@ -82,6 +97,18 @@
res = interpret(func, [])
assert ''.join(res.chars) == 'ka'
+ def test_specialize_return(self):
+ class S(Structure):
+ _fields_ = [('string', c_char_p)]
+ def func():
+ s = S()
+ s.string = "hello"
+ return s.string
+
+ assert func() == "hello"
+ res = interpret(func, [])
+ assert ''.join(res.chars) == "hello"
+
class Test_compilation:
def test_compile_c_char_p(self):
More information about the Pypy-commit
mailing list