Author: Armin Rigo <[email protected]>
Branch: ffi-backend
Changeset: r55757:f49e20cfb0b1
Date: 2012-06-22 19:02 +0200
http://bitbucket.org/pypy/pypy/changeset/f49e20cfb0b1/
Log: (arigo, fijal around) General progress.
diff --git a/pypy/module/_ffi_backend/cdataobj.py
b/pypy/module/_ffi_backend/cdataobj.py
--- a/pypy/module/_ffi_backend/cdataobj.py
+++ b/pypy/module/_ffi_backend/cdataobj.py
@@ -1,10 +1,11 @@
+import operator
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.baseobjspace import Wrappable
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.typedef import TypeDef
from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.rlib.objectmodel import keepalive_until_here
-from pypy.rlib import rgc
+from pypy.rlib.objectmodel import keepalive_until_here, specialize
+from pypy.rlib import objectmodel, rgc
from pypy.module._ffi_backend import misc
@@ -18,7 +19,7 @@
assert lltype.typeOf(cdata) == rffi.CCHARP
assert isinstance(ctype, ctypeobj.W_CType)
self.space = space
- self.cdata = cdata
+ self._cdata = cdata # don't forget keepalive_until_here!
self.ctype = ctype
def repr(self):
@@ -29,10 +30,10 @@
return ''
def nonzero(self):
- return self.space.wrap(bool(self.cdata))
+ return self.space.wrap(bool(self._cdata))
def int(self):
- w_result = self.ctype.int(self.cdata)
+ w_result = self.ctype.int(self._cdata)
keepalive_until_here(self)
return w_result
@@ -44,40 +45,71 @@
return w_result
def float(self):
- w_result = self.ctype.float(self.cdata)
+ w_result = self.ctype.float(self._cdata)
keepalive_until_here(self)
return w_result
def str(self):
- w_result = self.ctype.try_str(self.cdata)
+ w_result = self.ctype.try_str(self._cdata)
keepalive_until_here(self)
return w_result or self.repr()
+ @specialize.arg(2)
+ def _cmp(self, w_other, cmp):
+ space = self.space
+ cdata1 = self._cdata
+ other = space.interpclass_w(w_other)
+ if isinstance(other, W_CData):
+ cdata2 = other._cdata
+ elif space.is_w(w_other, space.w_None):
+ cdata2 = lltype.nullptr(rffi.CCHARP.TO)
+ else:
+ return space.w_NotImplemented
+ return space.newbool(cmp(cdata1, cdata2))
+
+ def eq(self, w_other): return self._cmp(w_other, operator.eq)
+ def ne(self, w_other): return self._cmp(w_other, operator.ne)
+
+ def hash(self):
+ h = (objectmodel.compute_identity_hash(self.ctype) ^
+ rffi.cast(lltype.Signed, self._cdata))
+ return self.space.wrap(h)
+
+ def getitem(self, w_index):
+ from pypy.module._ffi_backend import ctypeobj
+ space = self.space
+ i = space.getindex_w(w_index, space.w_IndexError)
+ self.ctype._check_subscript_index(self, i)
+ citem = self.ctype.ctypeitem
+ w_o = citem.convert_to_object(rffi.ptradd(self._cdata, i * citem.size))
+ keepalive_until_here(self)
+ return w_o
+
def read_raw_signed_data(self):
- result = misc.read_raw_signed_data(self.cdata, self.ctype.size)
+ result = misc.read_raw_signed_data(self._cdata, self.ctype.size)
keepalive_until_here(self)
return result
def read_raw_unsigned_data(self):
- result = misc.read_raw_unsigned_data(self.cdata, self.ctype.size)
+ result = misc.read_raw_unsigned_data(self._cdata, self.ctype.size)
keepalive_until_here(self)
return result
def write_raw_integer_data(self, source):
- misc.write_raw_integer_data(self.cdata, source, self.ctype.size)
+ misc.write_raw_integer_data(self._cdata, source, self.ctype.size)
keepalive_until_here(self)
def read_raw_float_data(self):
- result = misc.read_raw_float_data(self.cdata, self.ctype.size)
+ result = misc.read_raw_float_data(self._cdata, self.ctype.size)
keepalive_until_here(self)
return result
def write_raw_float_data(self, source):
- misc.write_raw_float_data(self.cdata, source, self.ctype.size)
+ misc.write_raw_float_data(self._cdata, source, self.ctype.size)
keepalive_until_here(self)
def convert_to_object(self):
- w_obj = self.ctype.convert_to_object(self.cdata)
+ w_obj = self.ctype.convert_to_object(self._cdata)
keepalive_until_here(self)
return w_obj
@@ -90,7 +122,7 @@
@rgc.must_be_light_finalizer
def __del__(self):
- lltype.free(self.cdata, flavor='raw')
+ lltype.free(self._cdata, flavor='raw')
class W_CDataOwn(W_CDataOwnFromCasted):
@@ -108,9 +140,9 @@
__long__ = interp2app(W_CData.long),
__float__ = interp2app(W_CData.float),
__str__ = interp2app(W_CData.str),
+ __eq__ = interp2app(W_CData.eq),
+ __ne__ = interp2app(W_CData.ne),
+ __hash__ = interp2app(W_CData.hash),
+ __getitem__ = interp2app(W_CData.getitem),
)
W_CData.acceptable_as_base_class = False
-
-
-def check_cdata(space, w_obj):
- return space.is_w(space.type(w_obj), space.gettypefor(W_CData))
diff --git a/pypy/module/_ffi_backend/ctypeobj.py
b/pypy/module/_ffi_backend/ctypeobj.py
--- a/pypy/module/_ffi_backend/ctypeobj.py
+++ b/pypy/module/_ffi_backend/ctypeobj.py
@@ -4,6 +4,7 @@
from pypy.interpreter.typedef import TypeDef
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.objectmodel import keepalive_until_here
from pypy.module._ffi_backend import cdataobj, misc
@@ -44,6 +45,13 @@
def convert_to_object(self, cdata):
raise NotImplementedError
+ def convert_from_object(self, cdata, w_ob):
+ raise NotImplementedError
+
+ def _check_subscript_index(self, w_cdata, i):
+ space = self.space
+ raise OperationError(xxx)
+
def try_str(self, cdata):
return None
@@ -55,7 +63,11 @@
return name, name_position
-class W_CTypePointer(W_CType):
+class W_CTypePtrOrArray(W_CType):
+ pass
+
+
+class W_CTypePointer(W_CTypePtrOrArray):
def __init__(self, space, ctypeitem):
name, name_position = ctypeitem.insert_name(' *', 2)
@@ -64,7 +76,18 @@
self.ctypeitem = ctypeitem
def cast(self, w_ob):
- xxx
+ space = self.space
+ ob = space.interpclass_w(w_ob)
+ if (isinstance(ob, cdataobj.W_CData) and
+ isinstance(ob.ctype, W_CTypePtrOrArray)):
+ value = ob._cdata
+ elif space.is_w(w_ob, space.w_None):
+ value = lltype.nullptr(rffi.CCHARP.TO)
+ else:
+ xxx
+ value = misc.as_unsigned_long_long(space, w_ob, strict=False)
+ value = rffi.cast(rffi.CCHARP, value)
+ return cdataobj.W_CData(space, value, self)
def newp(self, w_init):
space = self.space
@@ -73,8 +96,18 @@
xxx
if isinstance(citem, W_CTypePrimitiveChar):
xxx
- w_cdata = cdataobj.W_CDataOwn(space, citem.size, self)
- return w_cdata
+ cdata = cdataobj.W_CDataOwn(space, citem.size, self)
+ if not space.is_w(w_init, space.w_None):
+ citem.convert_from_object(cdata._cdata, w_init)
+ keepalive_until_here(cdata)
+ return cdata
+
+ def _check_subscript_index(self, w_cdata, i):
+ if isinstance(w_cdata, cdataobj.W_CDataOwn) and i != 0:
+ space = self.space
+ raise operationerrfmt(space.w_IndexError,
+ "cdata '%s' can only be indexed by 0",
+ self.name)
class W_CTypePrimitive(W_CType):
@@ -90,7 +123,8 @@
def cast(self, w_ob):
space = self.space
- if cdataobj.check_cdata(space, w_ob):
+ ob = space.interpclass_w(w_ob)
+ if isinstance(ob, cdataobj.W_CData):
xxx
elif space.isinstance_w(w_ob, space.w_str):
value = self.cast_single_char(w_ob)
@@ -135,6 +169,12 @@
else:
return self.space.wrap(value) # r_longlong => on 32-bit, 'long'
+ def convert_from_object(self, cdata, w_ob):
+ value = misc.as_long_long(self.space, w_ob)
+ # xxx enums
+ misc.write_raw_integer_data(cdata, value, self.size)
+ # xxx overflow
+
class W_CTypePrimitiveUnsigned(W_CTypePrimitive):
@@ -157,7 +197,8 @@
def cast(self, w_ob):
space = self.space
- if cdataobj.check_cdata(space, w_ob):
+ ob = space.interpclass_w(w_ob)
+ if isinstance(ob, cdataobj.W_CData):
xxx
elif space.isinstance_w(w_ob, space.w_str):
value = self.cast_single_char(w_ob)
@@ -186,7 +227,3 @@
__repr__ = interp2app(W_CType.repr),
)
W_CType.acceptable_as_base_class = False
-
-
-def check_ctype(space, w_obj):
- return space.is_w(space.type(w_obj), space.gettypefor(W_CType))
diff --git a/pypy/module/_ffi_backend/func.py b/pypy/module/_ffi_backend/func.py
--- a/pypy/module/_ffi_backend/func.py
+++ b/pypy/module/_ffi_backend/func.py
@@ -21,13 +21,12 @@
# ____________________________________________________________
def sizeof(space, w_obj):
- if cdataobj.check_cdata(space, w_obj):
+ ob = space.interpclass_w(w_obj)
+ if isinstance(ob, cdataobj.W_CData):
# xxx CT_ARRAY
- w_cdata = space.interp_w(cdataobj.W_CData, w_obj)
- size = w_cdata.ctype.size
- elif ctypeobj.check_ctype(space, w_obj):
- w_ctype = space.interp_w(ctypeobj.W_CType, w_obj)
- size = w_ctype.size
+ size = ob.ctype.size
+ elif isinstance(ob, ctypeobj.W_CType):
+ size = ob.size
if size < 0:
raise operationerrfmt(space.w_ValueError,
"ctype '%s' is of unknown size",
diff --git a/pypy/module/_ffi_backend/misc.py b/pypy/module/_ffi_backend/misc.py
--- a/pypy/module/_ffi_backend/misc.py
+++ b/pypy/module/_ffi_backend/misc.py
@@ -86,7 +86,7 @@
# ____________________________________________________________
-def as_long_long(space, w_ob, strict):
+def as_long_long(space, w_ob):
# (possibly) convert and cast a Python object to a long long.
# This version accepts a Python int too, and does convertions from
# other types of objects. It refuses floats.
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit