[pypy-svn] r25804 - in pypy/dist/pypy/rpython/rctypes: . test
arigo at codespeak.net
arigo at codespeak.net
Thu Apr 13 17:25:09 CEST 2006
Author: arigo
Date: Thu Apr 13 17:25:07 2006
New Revision: 25804
Modified:
pypy/dist/pypy/rpython/rctypes/rarray.py
pypy/dist/pypy/rpython/rctypes/rstruct.py
pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py
pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py
Log:
Implemented structures in rctypes, almost exactly copied from rarray.
Modified: pypy/dist/pypy/rpython/rctypes/rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rarray.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rarray.py Thu Apr 13 17:25:07 2006
@@ -65,6 +65,15 @@
class __extend__(pairtype(ArrayRepr, IntegerRepr)):
+ def rtype_getitem((r_array, r_int), hop):
+ v_array, v_index = hop.inputargs(r_array, lltype.Signed)
+ if isinstance(r_array.r_item, PrimitiveRepr):
+ # primitive case (optimization only)
+ return r_array.get_item_value(hop.llops, v_array, v_index)
+ # normal case
+ v_c_data = r_array.get_c_data_of_item(hop.llops, v_array, v_index)
+ return r_array.r_item.return_c_data(hop.llops, v_c_data)
+
def rtype_setitem((r_array, r_int), hop):
v_array, v_index, v_item = hop.inputargs(r_array, lltype.Signed,
r_array.r_item)
@@ -79,15 +88,6 @@
v_newvalue = r_array.r_item.getvalue(hop.llops, v_item)
r_array.set_item_value(hop.llops, v_array, v_index, v_newvalue)
- def rtype_getitem((r_array, r_int), hop):
- v_array, v_index = hop.inputargs(r_array, lltype.Signed)
- if isinstance(r_array.r_item, PrimitiveRepr):
- # primitive case (optimization only)
- return r_array.get_item_value(hop.llops, v_array, v_index)
- # normal case
- v_c_data = r_array.get_c_data_of_item(hop.llops, v_array, v_index)
- return r_array.r_item.return_c_data(hop.llops, v_c_data)
-
# ____________________________________________________________
def arraytype_specialize_call(hop):
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 17:25:07 2006
@@ -1,12 +1,95 @@
from ctypes import Structure
from pypy.annotation.model import SomeCTypesObject, SomeBuiltin
from pypy.rpython import extregistry
+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
+from pypy.rpython.rctypes.rprimitive import PrimitiveRepr
StructType = type(Structure)
+class StructRepr(CTypesRefRepr):
+ def __init__(self, rtyper, s_struct):
+ struct_ctype = s_struct.knowntype
+
+ # Find the repr and low-level type of the fields from their ctype
+ self.r_fields = {}
+ llfields = []
+ for name, field_ctype in struct_ctype._fields_:
+ r_field = rtyper.getrepr(SomeCTypesObject(field_ctype,
+ SomeCTypesObject.MEMORYALIAS))
+ self.r_fields[name] = r_field
+ llfields.append((name, r_field.ll_type))
+
+ # Here, self.c_data_type == self.ll_type
+ c_data_type = lltype.Struct(struct_ctype.__name__, *llfields)
+
+ super(StructRepr, self).__init__(rtyper, s_struct, c_data_type)
+
+ 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]
+ 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)
+
+ def get_field_value(self, llops, v_struct, fieldname):
+ # ByValue case only
+ r_field = self.r_fields[fieldname]
+ assert isinstance(r_field, CTypesValueRepr)
+ v_c_struct = self.get_c_data(llops, v_struct)
+ c_fieldname = inputconst(lltype.Void, fieldname)
+ return llops.genop('getfield', [v_c_struct, c_fieldname],
+ resulttype = r_field.ll_type)
+
+ def set_field_value(self, llops, v_struct, fieldname, v_newvalue):
+ # ByValue case only
+ r_field = self.r_fields[fieldname]
+ assert isinstance(r_field, CTypesValueRepr)
+ v_c_struct = self.get_c_data(llops, v_struct)
+ c_fieldname = inputconst(lltype.Void, fieldname)
+ llops.genop('setfield', [v_c_struct, c_fieldname, v_newvalue])
+
+ def rtype_getattr(self, hop):
+ s_attr = hop.args_s[1]
+ assert s_attr.is_constant()
+ name = s_attr.const
+ r_field = self.r_fields[name]
+ v_struct, v_attr = hop.inputargs(self, lltype.Void)
+ if isinstance(r_field, PrimitiveRepr):
+ # 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)
+ return r_field.return_c_data(hop.llops, v_c_data)
+
+ def rtype_setattr(self, hop):
+ s_attr = hop.args_s[1]
+ assert s_attr.is_constant()
+ name = s_attr.const
+ r_field = self.r_fields[name]
+ v_struct, v_attr, v_item = hop.inputargs(self, lltype.Void, r_field)
+ 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)
+ # copy the whole structure's content over
+ genreccopy(hop.llops, v_new_c_data, v_c_data)
+ else:
+ # ByValue case (optimization; the above also works in this case)
+ v_newvalue = r_field.getvalue(hop.llops, v_item)
+ self.set_field_value(hop.llops, v_struct, name, v_newvalue)
-
+# ____________________________________________________________
def structtype_specialize_call(hop):
r_struct = hop.r_result
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 17:25:07 2006
@@ -63,3 +63,18 @@
assert p[0] == x.value == "world"
p[0] = "other"
assert x.value == p.contents.value == p[0] == "other"
+
+def test_struct():
+ class tagpoint(Structure):
+ _fields_ = [('x', c_int),
+ ('p', POINTER(c_short))]
+
+ y = c_short(123)
+ z = c_short(-33)
+ s = tagpoint()
+ s.p.contents = z
+ assert s.p.contents.value == -33
+ s.p = pointer(y)
+ assert s.p.contents.value == 123
+ s.p.contents.value = 124
+ assert y.value == 124
Modified: pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py Thu Apr 13 17:25:07 2006
@@ -50,3 +50,42 @@
if conftest.option.view:
t.view()
+
+ def test_annotate_prebuilt(self):
+ my_struct_2 = tagpoint(5, 7)
+ my_struct_3 = tagpoint(x=6, y=11)
+ def func(i):
+ if i == 2:
+ struct = my_struct_2
+ else:
+ struct = my_struct_3
+ return struct.y
+
+ t = TranslationContext()
+ a = t.buildannotator()
+ s = a.build_types(func, [int])
+ if conftest.option.view:
+ a.translator.view()
+ assert s.knowntype == int
+
+class Test_specialization:
+ def test_specialize_struct(self):
+ def create_struct():
+ return tagpoint()
+
+ res = interpret(create_struct, [])
+ c_data = res.c_data
+ assert c_data.x == 0
+ assert c_data.y == 0
+
+ def test_specialize_struct_access(self):
+ def access_struct(n):
+ my_struct = tagpoint()
+ my_struct.x = c_int(1)
+ my_struct.y = 2
+ my_struct.x += n
+
+ return my_struct.x * my_struct.y
+
+ res = interpret(access_struct, [44])
+ assert res == 90
More information about the Pypy-commit
mailing list