Author: Antonio Cuni <[email protected]>
Branch: fast_cffi_list_init
Changeset: r67250:a8d55ebf78ea
Date: 2013-10-09 18:20 +0200
http://bitbucket.org/pypy/pypy/changeset/a8d55ebf78ea/

Log:    implement the fast-path for intstrategy and long[] only

diff --git a/pypy/module/_cffi_backend/ctypeprim.py 
b/pypy/module/_cffi_backend/ctypeprim.py
--- a/pypy/module/_cffi_backend/ctypeprim.py
+++ b/pypy/module/_cffi_backend/ctypeprim.py
@@ -85,6 +85,11 @@
             return self.space.wrap(s)
         return W_CType.string(self, cdataobj, maxlen)
 
+    def is_long(self):
+        return False
+
+    def is_double(self):
+        return False
 
 class W_CTypePrimitiveCharOrUniChar(W_CTypePrimitive):
     _attrs_ = []
@@ -171,6 +176,9 @@
             self.vmin = r_uint(-1) << (sh - 1)
             self.vrangemax = (r_uint(1) << sh) - 1
 
+    def is_long(self):
+        return self.size == rffi.sizeof(lltype.Signed)
+
     def cast_to_int(self, cdata):
         return self.convert_to_object(cdata)
 
@@ -274,6 +282,9 @@
 class W_CTypePrimitiveFloat(W_CTypePrimitive):
     _attrs_ = []
 
+    def is_double(self):
+        return self.size == rffi.sizeof(lltype.Float)
+
     def cast(self, w_ob):
         space = self.space
         if isinstance(w_ob, cdataobj.W_CData):
diff --git a/pypy/module/_cffi_backend/ctypeptr.py 
b/pypy/module/_cffi_backend/ctypeptr.py
--- a/pypy/module/_cffi_backend/ctypeptr.py
+++ b/pypy/module/_cffi_backend/ctypeptr.py
@@ -58,19 +58,44 @@
             value = rffi.cast(rffi.CCHARP, value)
         return cdataobj.W_CData(space, value, self)
 
+    def _convert_array_from_list_strategy_maybe(self, cdata, w_ob):
+        from rpython.rlib.rarray import copy_list_to_raw_array
+        from pypy.objspace.std.listobject import W_ListObject, 
IntegerListStrategy
+        if not isinstance(w_ob, W_ListObject):
+            return False
+        #
+        int_stragegy = self.space.fromcache(IntegerListStrategy)
+
+        if w_ob.strategy is int_stragegy and self.ctitem.is_long():
+            int_list = w_ob.strategy.unerase(w_ob.lstorage)
+            cdata = rffi.cast(rffi.LONGP, cdata)
+            copy_list_to_raw_array(int_list, cdata)
+            return True
+
+        return False
+
+    def _convert_array_from_listview(self, cdata, w_ob):
+        space = self.space
+        lst_w = space.listview(w_ob)
+        if self.length >= 0 and len(lst_w) > self.length:
+            raise operationerrfmt(space.w_IndexError,
+                "too many initializers for '%s' (got %d)",
+                                  self.name, len(lst_w))
+        ctitem = self.ctitem
+        for i in range(len(lst_w)):
+            ctitem.convert_from_object(cdata, lst_w[i])
+            cdata = rffi.ptradd(cdata, ctitem.size)
+
     def convert_array_from_object(self, cdata, w_ob):
         space = self.space
+        if self._convert_array_from_list_strategy_maybe(cdata, w_ob):
+            # the fast path worked, we are done now
+            return
+        #
+        # continue with the slow path
         if (space.isinstance_w(w_ob, space.w_list) or
             space.isinstance_w(w_ob, space.w_tuple)):
-            lst_w = space.listview(w_ob)
-            if self.length >= 0 and len(lst_w) > self.length:
-                raise operationerrfmt(space.w_IndexError,
-                    "too many initializers for '%s' (got %d)",
-                                      self.name, len(lst_w))
-            ctitem = self.ctitem
-            for i in range(len(lst_w)):
-                ctitem.convert_from_object(cdata, lst_w[i])
-                cdata = rffi.ptradd(cdata, ctitem.size)
+            self._convert_array_from_listview(cdata, w_ob)
         elif (self.can_cast_anything or
               (self.ctitem.is_primitive_integer and
                self.ctitem.size == rffi.sizeof(lltype.Char))):
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -139,6 +139,8 @@
 
 class W_ListObject(W_Root):
 
+    strategy = None
+
     def __init__(self, space, wrappeditems, sizehint=-1):
         assert isinstance(wrappeditems, list)
         self.space = space
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to