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