Author: Maciej Fijalkowski <[email protected]>
Branch:
Changeset: r59779:99da6b4f5a3f
Date: 2013-01-05 22:25 +0200
http://bitbucket.org/pypy/pypy/changeset/99da6b4f5a3f/
Log: merge
diff --git a/pypy/rlib/rgc.py b/pypy/rlib/rgc.py
--- a/pypy/rlib/rgc.py
+++ b/pypy/rlib/rgc.py
@@ -139,6 +139,40 @@
hop.exception_cannot_occur()
return hop.genop(opname, vlist, resulttype = hop.r_result.lowleveltype)
+def copy_struct_item(source, dest, si, di):
+ TP = lltype.typeOf(source)
+ i = 0
+ while i < len(TP._names):
+ setattr(dest[di], TP._names[i], getattr(source[si], TP._names[i]))
+
+class CopyStructEntry(ExtRegistryEntry):
+ _about_ = copy_struct_item
+
+ def compute_result_annotation(self, s_source, s_dest, si, di):
+ pass
+
+ def specialize_call(self, hop):
+ v_source, v_dest, v_si, v_di = hop.inputargs(hop.args_r[0],
+ hop.args_r[1],
+ lltype.Signed,
+ lltype.Signed)
+ hop.exception_cannot_occur()
+ TP = v_source.concretetype.TO.OF
+ for name, TP in TP._flds.iteritems():
+ c_name = hop.inputconst(lltype.Void, name)
+ v_fld = hop.genop('getinteriorfield', [v_source, v_si, c_name],
+ resulttype=TP)
+ hop.genop('setinteriorfield', [v_dest, v_di, c_name, v_fld])
+
+
[email protected]()
+def copy_item(source, dest, si, di):
+ TP = lltype.typeOf(source)
+ if isinstance(TP.TO.OF, lltype.Struct):
+ copy_struct_item(source, dest, si, di)
+ else:
+ dest[di] = source[si]
+
@jit.oopspec('list.ll_arraycopy(source, dest, source_start, dest_start,
length)')
@enforceargs(None, None, int, int, int)
@specialize.ll()
@@ -150,7 +184,7 @@
# and also, maybe, speed up very small cases
if length <= 1:
if length == 1:
- dest[dest_start] = source[source_start]
+ copy_item(source, dest, source_start, dest_start)
return
# supports non-overlapping copies only
@@ -170,7 +204,7 @@
# if the write barrier is not supported, copy by hand
i = 0
while i < length:
- dest[i + dest_start] = source[i + source_start]
+ copy_item(source, dest, i + source_start, i + dest_start)
i += 1
return
source_addr = llmemory.cast_ptr_to_adr(source)
diff --git a/pypy/rlib/test/test_rgc.py b/pypy/rlib/test/test_rgc.py
--- a/pypy/rlib/test/test_rgc.py
+++ b/pypy/rlib/test/test_rgc.py
@@ -134,6 +134,24 @@
assert check.called
+def test_ll_arraycopy_array_of_structs():
+ TP = lltype.GcArray(lltype.Struct('x', ('x', lltype.Signed),
+ ('y', lltype.Signed)))
+ def f():
+ a1 = lltype.malloc(TP, 3)
+ a2 = lltype.malloc(TP, 3)
+ for i in range(3):
+ a1[i].x = 2 * i
+ a1[i].y = 2 * i + 1
+ rgc.ll_arraycopy(a1, a2, 0, 0, 3)
+ for i in range(3):
+ assert a2[i].x == 2 * i
+ assert a2[i].y == 2 * i + 1
+
+
+ interpret(f, [])
+ f()
+
def test_ll_arraycopy_small():
TYPE = lltype.GcArray(lltype.Signed)
for length in range(5):
diff --git a/pypy/rpython/lltypesystem/test/test_lltype.py
b/pypy/rpython/lltypesystem/test/test_lltype.py
--- a/pypy/rpython/lltypesystem/test/test_lltype.py
+++ b/pypy/rpython/lltypesystem/test/test_lltype.py
@@ -808,7 +808,6 @@
assert F.RESULT == Signed
assert F.ARGS == (Signed,)
-
class TestTrackAllocation:
def test_automatic_tracking(self):
# calls to start_tracking_allocations/stop_tracking_allocations
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit