def ctypes2lltype(T, cobj): """Convert the ctypes object 'cobj' to its lltype equivalent. 'T' is the expected lltype type. """ if isinstance(T, lltype.Ptr): if not cobj: # NULL pointer return lltype.nullptr(T.TO) if isinstance(T.TO, lltype.Struct): if T.TO._arrayfld is not None: lgt = getattr(cobj.contents, T.TO._arrayfld).length container = lltype._struct(T.TO, lgt) else: container = lltype._struct(T.TO) struct_use_ctypes_storage(container, cobj.contents) elif isinstance(T.TO, lltype.Array): if T.TO._hints.get('nolength', False): container = _array_of_unknown_length(T.TO) container._storage = cobj.contents else: raise NotImplementedError("array with an explicit length") elif isinstance(T.TO, lltype.FuncType): _callable = get_ctypes_trampoline(T.TO, cobj) return lltype.functionptr(T.TO, getattr(cobj, '__name__', '?'), _callable=_callable) elif isinstance(T.TO, lltype.OpaqueType): container = lltype._opaque(T.TO) else: raise NotImplementedError(T) llobj = lltype._ptr(T, container, solid=True) elif T is lltype.Char: llobj = chr(cobj) elif T is lltype.UniChar: llobj = unichr(cobj) elif T is lltype.Signed: llobj = cobj elif T is lltype.SingleFloat: if isinstance(cobj, ctypes.c_float): cobj = cobj.value llobj = r_singlefloat(cobj) else: from pypy.rpython.lltypesystem import rffi try: inttype = rffi.platform.numbertype_to_rclass[T] except KeyError: llobj = cobj else: llobj = inttype(cobj) assert lltype.typeOf(llobj) == T return llobj
def ctypes2lltype(T, cobj): """Convert the ctypes object 'cobj' to its lltype equivalent. 'T' is the expected lltype type. """ if isinstance(T, lltype.Ptr): if not cobj: # NULL pointer return lltype.nullptr(T.TO) if isinstance(T.TO, lltype.Struct): if T.TO._arrayfld is not None: raise NotImplementedError("XXX var-sized structs") container = lltype._struct(T.TO) struct_use_ctypes_storage(container, cobj.contents) elif isinstance(T.TO, lltype.Array): if T.TO._hints.get('nolength', False): container = _array_of_unknown_length(T.TO) container._storage = cobj.contents else: raise NotImplementedError("array with an explicit length") elif isinstance(T.TO, lltype.FuncType): _callable = get_ctypes_trampoline(T.TO, cobj) return lltype.functionptr(T.TO, getattr(cobj, '__name__', '?'), _callable=_callable) elif isinstance(T.TO, lltype.OpaqueType): container = lltype._opaque(T.TO) else: raise NotImplementedError(T) llobj = lltype._ptr(T, container, solid=True) elif T is lltype.Char: llobj = chr(cobj) elif T is lltype.UniChar: llobj = unichr(cobj) elif T is lltype.Signed: llobj = cobj elif T is lltype.SingleFloat: if isinstance(cobj, ctypes.c_float): cobj = cobj.value llobj = r_singlefloat(cobj) else: from pypy.rpython.lltypesystem import rffi try: inttype = rffi.platform.numbertype_to_rclass[T] except KeyError: llobj = cobj else: llobj = inttype(cobj) assert lltype.typeOf(llobj) == T return llobj
def ctypes2lltype(T, cobj): """Convert the ctypes object 'cobj' to its lltype equivalent. 'T' is the expected lltype type. """ if T is lltype.Void: return None if isinstance(T, lltype.Typedef): T = T.OF if isinstance(T, lltype.Ptr): ptrval = ctypes.cast(cobj, ctypes.c_void_p).value if not cobj or not ptrval: # NULL pointer # CFunctionType.__nonzero__ is broken before Python 2.6 return lltype.nullptr(T.TO) if isinstance(T.TO, lltype.Struct): if T.TO._gckind == 'gc' and ptrval & 1: # a tagged pointer gcref = _opaque_objs[ptrval // 2].hide() return lltype.cast_opaque_ptr(T, gcref) REAL_TYPE = T.TO if T.TO._arrayfld is not None: carray = getattr(cobj.contents, T.TO._arrayfld) container = lltype._struct(T.TO, carray.length) else: # special treatment of 'OBJECT' subclasses if get_rtyper() and lltype._castdepth(REAL_TYPE, OBJECT) >= 0: # figure out the real type of the object containerheader = lltype._struct(OBJECT) cobjheader = ctypes.cast(cobj, get_ctypes_type(lltype.Ptr(OBJECT))) struct_use_ctypes_storage(containerheader, cobjheader) REAL_TYPE = get_rtyper().get_type_for_typeptr( containerheader.typeptr) REAL_T = lltype.Ptr(REAL_TYPE) cobj = ctypes.cast(cobj, get_ctypes_type(REAL_T)) container = lltype._struct(REAL_TYPE) struct_use_ctypes_storage(container, cobj) if REAL_TYPE != T.TO: p = container._as_ptr() container = lltype.cast_pointer(T, p)._as_obj() # special treatment of 'OBJECT_VTABLE' subclasses if get_rtyper() and lltype._castdepth(REAL_TYPE, OBJECT_VTABLE) >= 0: # figure out the real object that this vtable points to, # and just return that p = get_rtyper().get_real_typeptr_for_typeptr( container._as_ptr()) container = lltype.cast_pointer(T, p)._as_obj() elif isinstance(T.TO, lltype.Array): if T.TO._hints.get('nolength', False): container = _array_of_unknown_length(T.TO) container._storage = type(cobj)(cobj.contents) else: container = _array_of_known_length(T.TO) container._storage = type(cobj)(cobj.contents) elif isinstance(T.TO, lltype.FuncType): cobjkey = intmask(ctypes.cast(cobj, ctypes.c_void_p).value) if cobjkey in _int2obj: container = _int2obj[cobjkey] else: _callable = get_ctypes_trampoline(T.TO, cobj) return lltype.functionptr(T.TO, getattr(cobj, '__name__', '?'), _callable=_callable) elif isinstance(T.TO, lltype.OpaqueType): if T == llmemory.GCREF: container = _llgcopaque(cobj) else: container = lltype._opaque(T.TO) cbuf = ctypes.cast(cobj, ctypes.c_void_p) add_storage(container, _parentable_mixin, cbuf) else: raise NotImplementedError(T) llobj = lltype._ptr(T, container, solid=True) elif T is llmemory.Address: if cobj is None: llobj = llmemory.NULL else: llobj = _lladdress(cobj) elif T is lltype.Char: llobj = chr(cobj) elif T is lltype.UniChar: try: llobj = unichr(cobj) except (ValueError, OverflowError): for tc in 'HIL': if array(tc).itemsize == array('u').itemsize: import struct cobj &= 256 ** struct.calcsize(tc) - 1 llobj = array('u', array(tc, (cobj,)).tostring())[0] break else: raise elif T is lltype.Signed: llobj = cobj elif T is lltype.Bool: assert cobj == True or cobj == False # 0 and 1 work too llobj = bool(cobj) elif T is lltype.SingleFloat: if isinstance(cobj, ctypes.c_float): cobj = cobj.value llobj = r_singlefloat(cobj) elif T is lltype.LongFloat: if isinstance(cobj, ctypes.c_longdouble): cobj = cobj.value llobj = r_longfloat(cobj) elif T is lltype.Void: llobj = cobj else: from pypy.rpython.lltypesystem import rffi try: inttype = rffi.platform.numbertype_to_rclass[T] except KeyError: llobj = cobj else: llobj = inttype(cobj) assert lltype.typeOf(llobj) == T return llobj
def ctypes2lltype(T, cobj): """Convert the ctypes object 'cobj' to its lltype equivalent. 'T' is the expected lltype type. """ if T is lltype.Void: return None if isinstance(T, lltype.Ptr): if not cobj: # NULL pointer return lltype.nullptr(T.TO) if T is base_ptr_lltype(): return _opaque_list[ctypes.cast(cobj, ctypes.c_void_p).value] if isinstance(T.TO, lltype.Struct): if T.TO._arrayfld is not None: carray = getattr(cobj.contents, T.TO._arrayfld) container = lltype._struct(T.TO, carray.length) else: # special treatment of 'OBJECT' subclasses if get_rtyper() and lltype._castdepth(T.TO, OBJECT) > 0: ctypes_object = get_ctypes_type(lltype.Ptr(OBJECT)) as_obj = ctypes2lltype(lltype.Ptr(OBJECT), ctypes.cast(cobj, ctypes_object)) TObj = get_rtyper().get_type_for_typeptr(as_obj.typeptr) if TObj != T.TO: ctypes_instance = get_ctypes_type(lltype.Ptr(TObj)) return lltype.cast_pointer(T, ctypes2lltype(lltype.Ptr(TObj), ctypes.cast(cobj, ctypes_instance))) container = lltype._struct(T.TO) struct_use_ctypes_storage(container, cobj.contents) elif isinstance(T.TO, lltype.Array): if T.TO._hints.get('nolength', False): container = _array_of_unknown_length(T.TO) container._storage = cobj.contents else: container = _array_of_known_length(T.TO) container._storage = cobj.contents elif isinstance(T.TO, lltype.FuncType): cobjkey = ctypes.cast(cobj, ctypes.c_void_p).value if cobjkey in _callback2obj: container = _callback2obj[cobjkey] else: _callable = get_ctypes_trampoline(T.TO, cobj) return lltype.functionptr(T.TO, getattr(cobj, '__name__', '?'), _callable=_callable) elif isinstance(T.TO, lltype.OpaqueType): if T == llmemory.GCREF: # XXX obscure hack return _llgcref(cobj) else: container = lltype._opaque(T.TO) else: raise NotImplementedError(T) llobj = lltype._ptr(T, container, solid=True) elif T is llmemory.Address: if cobj is None: llobj = llmemory.NULL else: llobj = _lladdress(cobj) elif T is lltype.Char: llobj = chr(cobj) elif T is lltype.UniChar: llobj = unichr(cobj) elif T is lltype.Signed: llobj = cobj elif T is lltype.SingleFloat: if isinstance(cobj, ctypes.c_float): cobj = cobj.value llobj = r_singlefloat(cobj) elif T is lltype.Void: llobj = cobj else: from pypy.rpython.lltypesystem import rffi try: inttype = rffi.platform.numbertype_to_rclass[T] except KeyError: llobj = cobj else: llobj = inttype(cobj) assert lltype.typeOf(llobj) == T return llobj
def ctypes2lltype(T, cobj): """Convert the ctypes object 'cobj' to its lltype equivalent. 'T' is the expected lltype type. """ if T is lltype.Void: return None if isinstance(T, lltype.Ptr): if not cobj: # NULL pointer return lltype.nullptr(T.TO) if isinstance(T.TO, lltype.Struct): REAL_TYPE = T.TO if T.TO._arrayfld is not None: carray = getattr(cobj.contents, T.TO._arrayfld) container = lltype._struct(T.TO, carray.length) else: # special treatment of 'OBJECT' subclasses if get_rtyper() and lltype._castdepth(REAL_TYPE, OBJECT) >= 0: # figure out the real type of the object containerheader = lltype._struct(OBJECT) cobjheader = ctypes.cast( cobj, get_ctypes_type(lltype.Ptr(OBJECT))) struct_use_ctypes_storage(containerheader, cobjheader.contents) REAL_TYPE = get_rtyper().get_type_for_typeptr( containerheader.typeptr) REAL_T = lltype.Ptr(REAL_TYPE) cobj = ctypes.cast(cobj, get_ctypes_type(REAL_T)) container = lltype._struct(REAL_TYPE) struct_use_ctypes_storage(container, cobj.contents) if REAL_TYPE != T.TO: p = container._as_ptr() container = lltype.cast_pointer(T, p)._as_obj() # special treatment of 'OBJECT_VTABLE' subclasses if get_rtyper() and lltype._castdepth(REAL_TYPE, OBJECT_VTABLE) >= 0: # figure out the real object that this vtable points to, # and just return that p = get_rtyper().get_real_typeptr_for_typeptr( container._as_ptr()) container = lltype.cast_pointer(T, p)._as_obj() elif isinstance(T.TO, lltype.Array): if T.TO._hints.get('nolength', False): container = _array_of_unknown_length(T.TO) container._storage = cobj.contents else: container = _array_of_known_length(T.TO) container._storage = cobj.contents elif isinstance(T.TO, lltype.FuncType): cobjkey = ctypes.cast(cobj, ctypes.c_void_p).value if cobjkey in _callback2obj: container = _callback2obj[cobjkey] else: _callable = get_ctypes_trampoline(T.TO, cobj) return lltype.functionptr(T.TO, getattr(cobj, '__name__', '?'), _callable=_callable) elif isinstance(T.TO, lltype.OpaqueType): if T == llmemory.GCREF: container = _llgcopaque(cobj) else: container = lltype._opaque(T.TO) else: raise NotImplementedError(T) llobj = lltype._ptr(T, container, solid=True) elif T is llmemory.Address: if cobj is None: llobj = llmemory.NULL else: llobj = _lladdress(cobj) elif T is lltype.Char: llobj = chr(cobj) elif T is lltype.UniChar: llobj = unichr(cobj) elif T is lltype.Signed: llobj = cobj elif T is lltype.Bool: assert cobj == True or cobj == False # 0 and 1 work too llobj = bool(cobj) elif T is lltype.SingleFloat: if isinstance(cobj, ctypes.c_float): cobj = cobj.value llobj = r_singlefloat(cobj) elif T is lltype.Void: llobj = cobj else: from pypy.rpython.lltypesystem import rffi try: inttype = rffi.platform.numbertype_to_rclass[T] except KeyError: llobj = cobj else: llobj = inttype(cobj) assert lltype.typeOf(llobj) == T return llobj
def ctypes2lltype(T, cobj): """Convert the ctypes object 'cobj' to its lltype equivalent. 'T' is the expected lltype type. """ if T is lltype.Void: return None if isinstance(T, lltype.Ptr): if not cobj: # NULL pointer return lltype.nullptr(T.TO) if isinstance(T.TO, lltype.Struct): REAL_TYPE = T.TO if T.TO._arrayfld is not None: carray = getattr(cobj.contents, T.TO._arrayfld) container = lltype._struct(T.TO, carray.length) else: # special treatment of 'OBJECT' subclasses if get_rtyper() and lltype._castdepth(REAL_TYPE, OBJECT) >= 0: # figure out the real type of the object containerheader = lltype._struct(OBJECT) cobjheader = ctypes.cast(cobj, get_ctypes_type(lltype.Ptr(OBJECT))) struct_use_ctypes_storage(containerheader, cobjheader.contents) REAL_TYPE = get_rtyper().get_type_for_typeptr( containerheader.typeptr) REAL_T = lltype.Ptr(REAL_TYPE) cobj = ctypes.cast(cobj, get_ctypes_type(REAL_T)) container = lltype._struct(REAL_TYPE) struct_use_ctypes_storage(container, cobj.contents) if REAL_TYPE != T.TO: p = container._as_ptr() container = lltype.cast_pointer(T, p)._as_obj() # special treatment of 'OBJECT_VTABLE' subclasses if get_rtyper() and lltype._castdepth(REAL_TYPE, OBJECT_VTABLE) >= 0: # figure out the real object that this vtable points to, # and just return that p = get_rtyper().get_real_typeptr_for_typeptr( container._as_ptr()) container = lltype.cast_pointer(T, p)._as_obj() elif isinstance(T.TO, lltype.Array): if T.TO._hints.get('nolength', False): container = _array_of_unknown_length(T.TO) container._storage = cobj.contents else: container = _array_of_known_length(T.TO) container._storage = cobj.contents elif isinstance(T.TO, lltype.FuncType): cobjkey = ctypes.cast(cobj, ctypes.c_void_p).value if cobjkey in _callback2obj: container = _callback2obj[cobjkey] else: _callable = get_ctypes_trampoline(T.TO, cobj) return lltype.functionptr(T.TO, getattr(cobj, '__name__', '?'), _callable=_callable) elif isinstance(T.TO, lltype.OpaqueType): if T == llmemory.GCREF: container = _llgcopaque(cobj) else: container = lltype._opaque(T.TO) else: raise NotImplementedError(T) llobj = lltype._ptr(T, container, solid=True) elif T is llmemory.Address: if cobj is None: llobj = llmemory.NULL else: llobj = _lladdress(cobj) elif T is lltype.Char: llobj = chr(cobj) elif T is lltype.UniChar: llobj = unichr(cobj) elif T is lltype.Signed: llobj = cobj elif T is lltype.Bool: assert cobj == True or cobj == False # 0 and 1 work too llobj = bool(cobj) elif T is lltype.SingleFloat: if isinstance(cobj, ctypes.c_float): cobj = cobj.value llobj = r_singlefloat(cobj) elif T is lltype.Void: llobj = cobj else: from pypy.rpython.lltypesystem import rffi try: inttype = rffi.platform.numbertype_to_rclass[T] except KeyError: llobj = cobj else: llobj = inttype(cobj) assert lltype.typeOf(llobj) == T return llobj
def ctypes2lltype(T, cobj): """Convert the ctypes object 'cobj' to its lltype equivalent. 'T' is the expected lltype type. """ if T is lltype.Void: return None if isinstance(T, lltype.Ptr): if not cobj: # NULL pointer return lltype.nullptr(T.TO) if T is base_ptr_lltype(): return _opaque_list[ctypes.cast(cobj, ctypes.c_void_p).value] if isinstance(T.TO, lltype.Struct): if T.TO._arrayfld is not None: carray = getattr(cobj.contents, T.TO._arrayfld) container = lltype._struct(T.TO, carray.length) else: # special treatment of 'OBJECT' subclasses if get_rtyper() and lltype._castdepth(T.TO, OBJECT) > 0: ctypes_object = get_ctypes_type(lltype.Ptr(OBJECT)) as_obj = ctypes2lltype(lltype.Ptr(OBJECT), ctypes.cast(cobj, ctypes_object)) TObj = get_rtyper().get_type_for_typeptr(as_obj.typeptr) if TObj != T.TO: ctypes_instance = get_ctypes_type(lltype.Ptr(TObj)) return lltype.cast_pointer( T, ctypes2lltype(lltype.Ptr(TObj), ctypes.cast(cobj, ctypes_instance))) container = lltype._struct(T.TO) struct_use_ctypes_storage(container, cobj.contents) addr = ctypes.addressof(cobj.contents) if addr in _parent_cache: setparentstructure(container, _parent_cache[addr]) elif isinstance(T.TO, lltype.Array): if T.TO._hints.get('nolength', False): container = _array_of_unknown_length(T.TO) container._storage = cobj.contents else: container = _array_of_known_length(T.TO) container._storage = cobj.contents elif isinstance(T.TO, lltype.FuncType): cobjkey = ctypes.cast(cobj, ctypes.c_void_p).value if cobjkey in _callback2obj: container = _callback2obj[cobjkey] else: _callable = get_ctypes_trampoline(T.TO, cobj) return lltype.functionptr(T.TO, getattr(cobj, '__name__', '?'), _callable=_callable) elif isinstance(T.TO, lltype.OpaqueType): if T == llmemory.GCREF: container = _llgcopaque(cobj) else: container = lltype._opaque(T.TO) else: raise NotImplementedError(T) llobj = lltype._ptr(T, container, solid=True) elif T is llmemory.Address: if cobj is None: llobj = llmemory.NULL else: llobj = _lladdress(cobj) elif T is lltype.Char: llobj = chr(cobj) elif T is lltype.UniChar: llobj = unichr(cobj) elif T is lltype.Signed: llobj = cobj elif T is lltype.Bool: assert cobj == True or cobj == False # 0 and 1 work too llobj = bool(cobj) elif T is lltype.SingleFloat: if isinstance(cobj, ctypes.c_float): cobj = cobj.value llobj = r_singlefloat(cobj) elif T is lltype.Void: llobj = cobj else: from pypy.rpython.lltypesystem import rffi try: inttype = rffi.platform.numbertype_to_rclass[T] except KeyError: llobj = cobj else: llobj = inttype(cobj) assert lltype.typeOf(llobj) == T return llobj