Commits

Maciej Fijalkowski  committed 45bee24 Merge

merge default

  • Participants
  • Parent commits 195cfa2, 99da6b4
  • Branches rdict-experiments

Comments (0)

Files changed (3)

File pypy/rlib/rgc.py

         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])
+
+
+@specialize.ll()
+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()
     # 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
             # 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)

File pypy/rlib/test/test_rgc.py

 
     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):

File pypy/rpython/lltypesystem/test/test_lltype.py

     assert F.RESULT == Signed
     assert F.ARGS == (Signed,)
 
-
 class TestTrackAllocation:
     def test_automatic_tracking(self):
         # calls to start_tracking_allocations/stop_tracking_allocations