def add_operators(space, dict_w, pto): # XXX support PyObject_HashNotImplemented for method_name, slot_names, wrapper_func, wrapper_func_kwds, doc in slotdefs_for_wrappers: if method_name in dict_w: continue offset = [rffi.offsetof(lltype.typeOf(pto).TO, slot_names[0])] if len(slot_names) == 1: func = getattr(pto, slot_names[0]) else: assert len(slot_names) == 2 struct = getattr(pto, slot_names[0]) if not struct: continue offset.append(rffi.offsetof(lltype.typeOf(struct).TO, slot_names[1])) func = getattr(struct, slot_names[1]) func_voidp = rffi.cast(rffi.VOIDP, func) if not func: continue if wrapper_func is None and wrapper_func_kwds is None: continue w_obj = W_PyCWrapperObject(space, pto, method_name, wrapper_func, wrapper_func_kwds, doc, func_voidp, offset=offset) dict_w[method_name] = space.wrap(w_obj) if pto.c_tp_doc: dict_w['__doc__'] = space.newbytes(rffi.charp2str(pto.c_tp_doc)) if pto.c_tp_new: add_tp_new_wrapper(space, dict_w, pto)
def add_operators(space, dict_w, pto): from pypy.module.cpyext.object import PyObject_HashNotImplemented hash_not_impl = PyObject_HashNotImplemented.api_func.get_llhelper(space) for method_name, slot_names, wrapper_func, wrapper_func_kwds, doc in slotdefs_for_wrappers: if method_name in dict_w: continue offset = [rffi.offsetof(lltype.typeOf(pto).TO, slot_names[0])] if len(slot_names) == 1: func = getattr(pto, slot_names[0]) if slot_names[0] == 'c_tp_hash': if hash_not_impl == func: # special case for tp_hash == PyObject_HashNotImplemented dict_w[method_name] = space.w_None continue else: assert len(slot_names) == 2 struct = getattr(pto, slot_names[0]) if not struct: continue offset.append(rffi.offsetof(lltype.typeOf(struct).TO, slot_names[1])) func = getattr(struct, slot_names[1]) func_voidp = rffi.cast(rffi.VOIDP, func) if not func: continue if wrapper_func is None and wrapper_func_kwds is None: continue w_obj = W_PyCWrapperObject(space, pto, method_name, wrapper_func, wrapper_func_kwds, doc, func_voidp, offset=offset) dict_w[method_name] = w_obj if pto.c_tp_doc: dict_w['__doc__'] = space.newtext( rffi.charp2str(cts.cast('char*', pto.c_tp_doc))) if pto.c_tp_new: add_tp_new_wrapper(space, dict_w, pto)
def add_operators(space, dict_w, pto): # XXX support PyObject_HashNotImplemented for method_name, slot_names, wrapper_func, wrapper_func_kwds, doc in slotdefs_for_wrappers: if method_name in dict_w: continue offset = [rffi.offsetof(lltype.typeOf(pto).TO, slot_names[0])] if len(slot_names) == 1: func = getattr(pto, slot_names[0]) else: assert len(slot_names) == 2 struct = getattr(pto, slot_names[0]) if not struct: continue offset.append( rffi.offsetof(lltype.typeOf(struct).TO, slot_names[1])) func = getattr(struct, slot_names[1]) func_voidp = rffi.cast(rffi.VOIDP, func) if not func: continue if wrapper_func is None and wrapper_func_kwds is None: continue w_obj = W_PyCWrapperObject(space, pto, method_name, wrapper_func, wrapper_func_kwds, doc, func_voidp, offset=offset) dict_w[method_name] = w_obj if pto.c_tp_doc: dict_w['__doc__'] = space.newtext( rffi.charp2str(cts.cast('char*', pto.c_tp_doc))) if pto.c_tp_new: add_tp_new_wrapper(space, dict_w, pto)
def get_raw_address_of_string(space, w_x): """Special case for ffi.from_buffer(string). Returns a 'char *' that is valid as long as the string object is alive. Two calls to ffi.from_buffer(same_string) are guaranteed to return the same pointer. """ from rpython.rtyper.annlowlevel import llstr from rpython.rtyper.lltypesystem.rstr import STR from rpython.rtyper.lltypesystem import llmemory from rpython.rlib import rgc cache = space.fromcache(RawBytesCache) rawbytes = cache.wdict.get(w_x) if rawbytes is None: data = space.bytes_w(w_x) if (we_are_translated() and not rgc.can_move(data) and not rgc.must_split_gc_address_space()): lldata = llstr(data) data_start = (llmemory.cast_ptr_to_adr(lldata) + rffi.offsetof(STR, 'chars') + llmemory.itemoffsetof(STR.chars, 0)) data_start = rffi.cast(rffi.CCHARP, data_start) data_start[len(data)] = '\x00' # write the final extra null return data_start rawbytes = RawBytes(data) cache.wdict.set(w_x, rawbytes) return rawbytes.ptr
def _get_buffer_from_str(data): # Dangerous! The resulting pointer is only valid as long as there # is no GC! lldata = llstr(data) data_start = llmemory.cast_ptr_to_adr(lldata) + \ rffi.offsetof(rstr.STR, 'chars') + rffi.itemoffsetof(rstr.STR.chars, 0) return rffi.cast(rffi.CCHARP, data_start)
def get_raw_address_of_string(space, w_x): """Special case for ffi.from_buffer(string). Returns a 'char *' that is valid as long as the string object is alive. Two calls to ffi.from_buffer(same_string) are guaranteed to return the same pointer. """ from rpython.rtyper.annlowlevel import llstr from rpython.rtyper.lltypesystem.rstr import STR from rpython.rtyper.lltypesystem import llmemory from rpython.rlib import rgc cache = space.fromcache(RawBytesCache) rawbytes = cache.wdict.get(w_x) if rawbytes is None: data = space.str_w(w_x) if we_are_translated() and not rgc.can_move(data): lldata = llstr(data) data_start = (llmemory.cast_ptr_to_adr(lldata) + rffi.offsetof(STR, 'chars') + llmemory.itemoffsetof(STR.chars, 0)) data_start = rffi.cast(rffi.CCHARP, data_start) data_start[len(data)] = '\x00' # write the final extra null return data_start rawbytes = RawBytes(data) cache.wdict.set(w_x, rawbytes) return rawbytes.ptr
def add_operators(space, dict_w, pto): from pypy.module.cpyext.object import PyObject_HashNotImplemented hash_not_impl = llslot(space, PyObject_HashNotImplemented) for method_name, slot_names, wrapper_class, doc in slotdefs_for_wrappers: if method_name in dict_w: continue offset = [rffi.offsetof(lltype.typeOf(pto).TO, slot_names[0])] if len(slot_names) == 1: func = getattr(pto, slot_names[0]) if slot_names[0] == 'c_tp_hash': # two special cases where __hash__ is explicitly set to None # (which leads to an unhashable type): # 1) tp_hash == PyObject_HashNotImplemented # 2) tp_hash == NULL and either of tp_compare or tp_richcompare are not NULL if hash_not_impl == func or (not func and (pto.c_tp_compare or pto.c_tp_richcompare)): dict_w[method_name] = space.w_None continue else: assert len(slot_names) == 2 struct = getattr(pto, slot_names[0]) if not struct: continue offset.append( rffi.offsetof(lltype.typeOf(struct).TO, slot_names[1])) func = getattr(struct, slot_names[1]) func_voidp = rffi.cast(rffi.VOIDP, func) if not func: continue if wrapper_class is None: continue assert issubclass(wrapper_class, W_PyCWrapperObject) w_obj = wrapper_class(space, pto, method_name, doc, func_voidp, offset=offset[:]) dict_w[method_name] = w_obj if pto.c_tp_doc: dict_w['__doc__'] = space.newtext( rffi.charp2str(cts.cast('char*', pto.c_tp_doc))) if pto.c_tp_new: add_tp_new_wrapper(space, dict_w, pto)
def test_array_varsized_struct(): dirent = rffi_platform.getstruct("struct dirent", """ struct dirent /* for this example only, not the exact dirent */ { int d_off; char d_name[1]; }; """, [("d_name", rffi.CArray(rffi.CHAR))]) assert rffi.offsetof(dirent, 'c_d_name') == 4 assert dirent.c_d_name == rffi.CArray(rffi.CHAR)
def test_array_varsized_struct(): dirent = rffi_platform.getstruct( "struct dirent", """ struct dirent /* for this example only, not the exact dirent */ { int d_off; char d_name[1]; }; """, [("d_name", rffi.CArray(rffi.CHAR))]) assert rffi.offsetof(dirent, 'c_d_name') == 4 assert dirent.c_d_name == rffi.CArray(rffi.CHAR)
def get_path(self): a = self.lock(_c.sockaddr_un) maxlength = self.addrlen - offsetof(_c.sockaddr_un, 'c_sun_path') if _c.linux and maxlength > 0 and a.c_sun_path[0] == '\x00': # Linux abstract namespace length = maxlength else: # regular NULL-terminated string length = 0 while length < maxlength and a.c_sun_path[length] != '\x00': length += 1 result = ''.join([a.c_sun_path[i] for i in range(length)]) self.unlock() return result
class UNIXAddress(Address): family = AF_UNIX struct = _c.sockaddr_un minlen = offsetof(_c.sockaddr_un, 'c_sun_path') maxlen = sizeof(struct) def __init__(self, path): sun = lltype.malloc(_c.sockaddr_un, flavor='raw', zero=True, track_allocation=False) baseofs = offsetof(_c.sockaddr_un, 'c_sun_path') self.setdata(sun, baseofs + len(path)) rffi.setintfield(sun, 'c_sun_family', AF_UNIX) if _c.linux and path.startswith('\x00'): # Linux abstract namespace extension if len(path) > sizeof(_c.sockaddr_un.c_sun_path): raise RSocketError("AF_UNIX path too long") else: # regular NULL-terminated string if len(path) >= sizeof(_c.sockaddr_un.c_sun_path): raise RSocketError("AF_UNIX path too long") sun.c_sun_path[len(path)] = '\x00' for i in range(len(path)): sun.c_sun_path[i] = path[i] def __repr__(self): try: return '<UNIXAddress %r>' % (self.get_path(),) except SocketError: return '<UNIXAddress ?>' def get_path(self): a = self.lock(_c.sockaddr_un) maxlength = self.addrlen - offsetof(_c.sockaddr_un, 'c_sun_path') if _c.linux and maxlength > 0 and a.c_sun_path[0] == '\x00': # Linux abstract namespace length = maxlength else: # regular NULL-terminated string length = 0 while length < maxlength and a.c_sun_path[length] != '\x00': length += 1 result = ''.join([a.c_sun_path[i] for i in range(length)]) self.unlock() return result def eq(self, other): # __eq__() is not called by RPython :-/ return (isinstance(other, UNIXAddress) and self.get_path() == other.get_path())
def __init__(self, path): sun = lltype.malloc(_c.sockaddr_un, flavor="raw", zero=True, track_allocation=False) baseofs = offsetof(_c.sockaddr_un, "c_sun_path") self.setdata(sun, baseofs + len(path)) rffi.setintfield(sun, "c_sun_family", AF_UNIX) if _c.linux and path.startswith("\x00"): # Linux abstract namespace extension if len(path) > sizeof(_c.sockaddr_un.c_sun_path): raise RSocketError("AF_UNIX path too long") else: # regular NULL-terminated string if len(path) >= sizeof(_c.sockaddr_un.c_sun_path): raise RSocketError("AF_UNIX path too long") sun.c_sun_path[len(path)] = "\x00" for i in range(len(path)): sun.c_sun_path[i] = path[i]
def __init__(self, path): sun = lltype.malloc(_c.sockaddr_un, flavor='raw', zero=True, track_allocation=False) baseofs = offsetof(_c.sockaddr_un, 'c_sun_path') self.setdata(sun, baseofs + len(path)) rffi.setintfield(sun, 'c_sun_family', AF_UNIX) if _c.linux and path.startswith('\x00'): # Linux abstract namespace extension if len(path) > sizeof(_c.sockaddr_un.c_sun_path): raise RSocketError("AF_UNIX path too long") else: # regular NULL-terminated string if len(path) >= sizeof(_c.sockaddr_un.c_sun_path): raise RSocketError("AF_UNIX path too long") sun.c_sun_path[len(path)] = '\x00' for i in range(len(path)): sun.c_sun_path[i] = path[i]
def setup(): INSPECT = { 'b': 'signed char', 'h': 'signed short', 'i': 'signed int', 'l': 'signed long', 'q': 'signed long long', 'n': 'ssize_t', 'B': 'unsigned char', 'H': 'unsigned short', 'I': 'unsigned int', 'L': 'unsigned long', 'Q': 'unsigned long long', 'N': 'size_t', 'P': 'char *', 'f': 'float', 'd': 'double', '?': '_Bool', } pre_include_bits = [ """ #include <sys/types.h> #ifdef _MSC_VER #define _Bool char typedef int ssize_t; /* XXX fixme for 64 bit*/ typedef unsigned int size_t; /* XXX fixme for 64 bit*/ #endif""" ] field_names = dict.fromkeys(INSPECT) for fmtchar, ctype in INSPECT.iteritems(): field_name = ctype.replace(" ", "_").replace("*", "star") field_names[fmtchar] = field_name pre_include_bits.append(""" struct about_%s { char pad; %s field; }; """ % (field_name, ctype)) class CConfig: _compilation_info_ = ExternalCompilationInfo( pre_include_bits=pre_include_bits) for fmtchar, ctype in INSPECT.items(): setattr( CConfig, field_names[fmtchar], rffi_platform.Struct( "struct about_%s" % (field_names[fmtchar], ), [('field', lltype.FixedSizeArray(rffi.CHAR, 1))])) cConfig = rffi_platform.configure(CConfig) for fmtchar, ctype in INSPECT.items(): S = cConfig[field_names[fmtchar]] alignment = rffi.offsetof(S, 'c_field') size = rffi.sizeof(S.c_field) signed = 'a' <= fmtchar <= 'z' if fmtchar == 'f': pack = pack_float unpack = std.unpack_float elif fmtchar == 'd': pack = pack_double unpack = std.unpack_double elif fmtchar == '?': pack = std.pack_bool unpack = std.unpack_bool else: pack = std.make_int_packer(size, signed) unpack = std.make_int_unpacker(size, signed) native_fmttable[fmtchar] = { 'size': size, 'alignment': alignment, 'pack': pack, 'unpack': unpack }
def alignment(TYPE): S = lltype.Struct('aligncheck', ('x', lltype.Char), ('y', TYPE)) return rffi.offsetof(S, 'y')
def _memcpy_partial_hidden(self, from_): MEMCELLSIZE = rffi.offsetof(capi.MEM, 'zMalloc') rffi.c_memcpy(rffi.cast(rffi.VOIDP, self.pMem), rffi.cast(rffi.VOIDP, from_.pMem), MEMCELLSIZE)
def setup(): INSPECT = {'b': 'signed char', 'h': 'signed short', 'i': 'signed int', 'l': 'signed long', 'q': 'signed long long', 'B': 'unsigned char', 'H': 'unsigned short', 'I': 'unsigned int', 'L': 'unsigned long', 'Q': 'unsigned long long', 'P': 'char *', 'f': 'float', 'd': 'double', '?': '_Bool', } pre_include_bits = [""" #ifdef _MSC_VER #define _Bool char #endif"""] field_names = dict.fromkeys(INSPECT) for fmtchar, ctype in INSPECT.iteritems(): field_name = ctype.replace(" ", "_").replace("*", "star") field_names[fmtchar] = field_name pre_include_bits.append(""" struct about_%s { char pad; %s field; }; """ % (field_name, ctype)) class CConfig: _compilation_info_ = ExternalCompilationInfo( pre_include_bits = pre_include_bits ) for fmtchar, ctype in INSPECT.items(): setattr(CConfig, field_names[fmtchar], rffi_platform.Struct( "struct about_%s" % (field_names[fmtchar],), [('field', lltype.FixedSizeArray(rffi.CHAR, 1))])) cConfig = rffi_platform.configure(CConfig) for fmtchar, ctype in INSPECT.items(): S = cConfig[field_names[fmtchar]] alignment = rffi.offsetof(S, 'c_field') size = rffi.sizeof(S.c_field) signed = 'a' <= fmtchar <= 'z' if fmtchar == 'f': pack = pack_float unpack = unpack_float elif fmtchar == 'd': pack = pack_double unpack = unpack_double elif fmtchar == '?': pack = std.pack_bool unpack = std.unpack_bool else: pack = std.make_int_packer(size, signed, True) unpack = std.make_int_unpacker(size, signed) native_fmttable[fmtchar] = {'size': size, 'alignment': alignment, 'pack': pack, 'unpack': unpack}
def alignment(TYPE): S = lltype.Struct("aligncheck", ("x", lltype.Char), ("y", TYPE)) return rffi.offsetof(S, "y")