Author: Antonio Cuni <[email protected]>
Branch: fast_cffi_list_init
Changeset: r67237:2bbec1d6d9cc
Date: 2013-10-09 15:14 +0200
http://bitbucket.org/pypy/pypy/changeset/2bbec1d6d9cc/

Log:    add a function to memcpy the content of a raw array into an rpython
        list

diff --git a/rpython/rlib/rarray.py b/rpython/rlib/rarray.py
--- a/rpython/rlib/rarray.py
+++ b/rpython/rlib/rarray.py
@@ -1,5 +1,8 @@
+from rpython.annotator import model as annmodel
+from rpython.annotator.listdef import ListDef
 from rpython.rtyper.lltypesystem import lltype, llmemory
 from rpython.rtyper.extregistry import ExtRegistryEntry
+from rpython.tool.pairtype import pair
 
 def copy_list_to_raw_array(lst, array):
     for i, item in enumerate(lst):
@@ -19,6 +22,10 @@
 
 
 def ll_copy_list_to_raw_array(ll_list, dst_ptr):
+    # this code is delicate: we must ensure that there are no GC operations
+    # between here and the call to raw_memcopy
+    #
+    # start of no-GC section
     src_ptr = ll_list.ll_items()
     src_adr = llmemory.cast_ptr_to_adr(src_ptr)
     src_adr += llmemory.itemoffsetof(lltype.typeOf(src_ptr).TO, 0) # skip the 
GC header
@@ -29,3 +36,41 @@
     ITEM = lltype.typeOf(dst_ptr).TO.OF
     size = llmemory.sizeof(ITEM) * ll_list.ll_length()
     llmemory.raw_memcopy(src_adr, dst_adr, size)
+    # end of no-GC section
+
+
+def populate_list_from_raw_array(lst, array, length):
+    lst[:] = [array[i] for i in range(length)]
+
+class Entry(ExtRegistryEntry):
+    _about_ = populate_list_from_raw_array
+
+    def compute_result_annotation(self, s_list, s_array, s_length):
+        s_item = annmodel.lltype_to_annotation(s_array.ll_ptrtype.TO.OF)
+        s_newlist = self.bookkeeper.newlist(s_item)
+        s_newlist.listdef.resize()
+        pair(s_list, s_newlist).union()
+
+    def specialize_call(self, hop):
+        v_list, v_buf, v_length = hop.inputargs(*hop.args_r)
+        hop.exception_is_here()
+        return hop.gendirectcall(ll_populate_list_from_raw_array, v_list, 
v_buf, v_length)
+
+
+def ll_populate_list_from_raw_array(ll_list, src_ptr, length):
+    PTR_ITEMS = lltype.typeOf(ll_list.items)
+    new_items = lltype.malloc(PTR_ITEMS.TO, length)
+    #
+    # start of no-GC section
+    src_adr = llmemory.cast_ptr_to_adr(src_ptr)
+    src_adr += llmemory.itemoffsetof(lltype.typeOf(src_ptr).TO, 0)
+    dst_adr = llmemory.cast_ptr_to_adr(new_items)
+    dst_adr += llmemory.itemoffsetof(lltype.typeOf(new_items).TO, 0) # skip 
the GC header
+    #
+    ITEM = lltype.typeOf(src_ptr).TO.OF
+    size = llmemory.sizeof(ITEM) * length
+    llmemory.raw_memcopy(src_adr, dst_adr, size)
+    # end of no-GC section
+    #
+    ll_list.items = new_items
+    ll_list.length = length
diff --git a/rpython/rlib/test/test_rarray.py b/rpython/rlib/test/test_rarray.py
--- a/rpython/rlib/test/test_rarray.py
+++ b/rpython/rlib/test/test_rarray.py
@@ -1,4 +1,4 @@
-from rpython.rlib.rarray import copy_list_to_raw_array
+from rpython.rlib.rarray import copy_list_to_raw_array, 
populate_list_from_raw_array
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rtyper.test.tool import BaseRtypingTest
 
@@ -35,4 +35,30 @@
             lltype.free(buf, flavor='raw')
             lltype.free(buf2, flavor='raw')
         self.interpret(fn, [])
-    
+
+    def test_new_list_from_raw_array(self):
+        INTARRAY = rffi.CArray(lltype.Signed)
+        buf = lltype.malloc(INTARRAY, 4, flavor='raw')
+        buf[0] = 1
+        buf[1] = 2
+        buf[2] = 3
+        buf[3] = 4
+        lst = []
+        populate_list_from_raw_array(lst, buf, 4)
+        assert lst == [1, 2, 3, 4]
+        lltype.free(buf, flavor='raw')
+
+    def test_new_list_from_raw_array_rtyped(self):
+        INTARRAY = rffi.CArray(lltype.Signed)
+        def fn():
+            buf = lltype.malloc(INTARRAY, 4, flavor='raw')
+            buf[0] = 1
+            buf[1] = 2
+            buf[2] = 3
+            buf[3] = 4
+            lst = []
+            populate_list_from_raw_array(lst, buf, 4)
+            assert lst == [1, 2, 3, 4]
+            lltype.free(buf, flavor='raw')
+        #
+        self.interpret(fn, [])
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to