[pypy-svn] r25951 - in pypy/dist/pypy/rpython/rctypes: . test
arigo at codespeak.net
arigo at codespeak.net
Tue Apr 18 16:18:52 CEST 2006
Author: arigo
Date: Tue Apr 18 16:18:50 2006
New Revision: 25951
Modified:
pypy/dist/pypy/rpython/rctypes/rstruct.py
pypy/dist/pypy/rpython/rctypes/test/test_overhead.py
pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py
Log:
Keepalives for rctypes structs.
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 16:18:50 2006
@@ -2,7 +2,7 @@
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, reccopy
+from pypy.rpython.rctypes.rmodel import genreccopy_structfield, reccopy
from pypy.rpython.rctypes.rprimitive import PrimitiveRepr
from pypy.annotation.model import SomeCTypesObject
@@ -28,6 +28,19 @@
super(StructRepr, self).__init__(rtyper, s_struct, c_data_type)
+ def get_content_keepalive_type(self):
+ "An extra struct of keepalives, one per field."
+ keepalives = []
+ for name in self.c_data_type._names:
+ r_field = self.r_fields[name]
+ field_keepalive_type = r_field.get_content_keepalive_type()
+ if field_keepalive_type:
+ keepalives.append((name, field_keepalive_type))
+ if not keepalives:
+ return None
+ else:
+ return lltype.Struct('keepalives', *keepalives)
+
def initialize_const(self, p, value):
for name, r_field in self.r_fields.items():
llitem = r_field.convert_const(getattr(value, name))
@@ -61,13 +74,13 @@
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 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]
@@ -93,13 +106,13 @@
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_field(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)
+ v_newvalue = r_field.get_c_data_or_value(hop.llops, v_item)
+ # copy the new value (which might be a whole substructure)
+ v_c_struct = self.get_c_data(hop.llops, v_struct)
+ genreccopy_structfield(hop.llops, v_newvalue, v_c_struct, name)
+ # copy the keepalive information too
+ v_newkeepalive = r_field.getkeepalive(hop.llops, v_item)
+ if v_newkeepalive is not None:
+ v_keepalive_struct = self.getkeepalive(hop.llops, v_struct)
+ genreccopy_structfield(hop.llops, v_newkeepalive,
+ v_keepalive_struct, name)
Modified: pypy/dist/pypy/rpython/rctypes/test/test_overhead.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_overhead.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_overhead.py Tue Apr 18 16:18:50 2006
@@ -3,6 +3,7 @@
by the rctypes rtyping.
"""
+import py
import pypy.rpython.rctypes.implementation
from pypy import conftest
from pypy.rpython.test.test_llinterp import gengraph
@@ -18,7 +19,7 @@
def find_mallocs(func, argtypes):
t, typer, graph = gengraph(func, argtypes)
- backend_optimizations(t)
+ backend_optimizations(t, inline_threshold=10)
if conftest.option.view:
t.view()
@@ -78,3 +79,22 @@
mallocs = find_mallocs(func, [A, S, int])
assert not mallocs
+
+def test_struct_setitem():
+ py.test.skip("not working yet")
+ class S(Structure):
+ _fields_ = [('x', c_int)]
+ class T(Structure):
+ _fields_ = [('s', POINTER(S))]
+ def make_t(i):
+ t = T()
+ s = S()
+ s.x = i*i
+ t.s = pointer(s)
+ return t
+ def func():
+ t = make_t(17)
+ return t.s.contents.x
+
+ mallocs = find_mallocs(func, [])
+ assert not mallocs # depends on inlining
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 Tue Apr 18 16:18:50 2006
@@ -154,6 +154,24 @@
res = interpret(func, [])
assert res == 121
+ def test_specialize_keepalive(self):
+ class S(Structure):
+ _fields_ = [('x', c_int)]
+ class T(Structure):
+ _fields_ = [('s', POINTER(S))]
+ def make_t(i):
+ t = T()
+ s = S()
+ s.x = i*i
+ t.s = pointer(s)
+ return t
+ def func():
+ t = make_t(17)
+ return t.s.contents.x
+
+ res = interpret(func, [])
+ assert res == 289
+
class Test_compilation:
def test_compile_struct_access(self):
def access_struct(n):
More information about the Pypy-commit
mailing list