def callback(ll_args, ll_res, ll_userdata): userdata = rffi.cast(USERDATA_P, ll_userdata) callback_ptr = global_counter.CallbackPtr_by_number[userdata.addarg] w_callable = callback_ptr.w_callable res = rffi.cast(rffi.VOIDPP, ll_res) argtypes = callback_ptr.args space = callback_ptr.space w_args = space.newlist([wrap_value(space, get_elem, ll_args[i], 0, letter2tp(space, argtypes[i])) for i in range(len(argtypes))]) w_res = space.call(w_callable, w_args) unwrap_value(space, push_elem, ll_res, 0, letter2tp(space, callback_ptr.result), w_res)
def from_memory(self, space, w_obj, offset): # read access, so no copy needed address_value = self._get_raw_address(space, w_obj, offset) address = rffi.cast(rffi.ULONGP, address_value) return lowlevelviews.W_LowLevelView(space, letter2tp(space, self.typecode), self.size, address[0])
def __init__(self, space, w_callable, w_args, w_result, flags=FUNCFLAG_CDECL): self.space = space self.w_callable = w_callable self.argtypes = unpack_argshapes(space, w_args) ffiargs = [tp.get_basic_ffi_type() for tp in self.argtypes] if not space.is_w(w_result, space.w_None): self.result = space.text_w(w_result) ffiresult = letter2tp(space, self.result).get_basic_ffi_type() else: self.result = None ffiresult = ffi_type_void self.number = global_counter.add(self) try: self.ll_callback = CallbackFuncPtr(ffiargs, ffiresult, callback, self.number, flags) except LibFFIError: raise got_libffi_error(space) self.ll_buffer = rffi.cast(rffi.VOIDP, self.ll_callback.get_closure()) if tracker.DO_TRACING: addr = rffi.cast(lltype.Signed, self.ll_callback.get_closure()) tracker.trace_allocation(addr, self) # # We must setup the GIL here, in case the callback is invoked in # some other non-Pythonic thread. This is the same as ctypes on # CPython (but only when creating a callback; on CPython it occurs # as soon as we import _ctypes) if space.config.translation.thread: from pypy.module.thread.os_thread import setup_threads setup_threads(space)
def __init__(self, space, w_callable, w_args, w_result, flags=FUNCFLAG_CDECL): self.space = space self.w_callable = w_callable self.argtypes = unpack_argshapes(space, w_args) ffiargs = [tp.get_basic_ffi_type() for tp in self.argtypes] if not space.is_w(w_result, space.w_None): self.result = space.str_w(w_result) ffiresult = letter2tp(space, self.result).get_basic_ffi_type() else: self.result = None ffiresult = ffi_type_void self.number = global_counter.add(self) try: self.ll_callback = CallbackFuncPtr(ffiargs, ffiresult, callback, self.number, flags) except LibFFIError: raise got_libffi_error(space) self.ll_buffer = rffi.cast(rffi.VOIDP, self.ll_callback.ll_closure) if tracker.DO_TRACING: addr = rffi.cast(lltype.Signed, self.ll_callback.ll_closure) tracker.trace_allocation(addr, self) # # We must setup the GIL here, in case the callback is invoked in # some other non-Pythonic thread. This is the same as ctypes on # CPython (but only when creating a callback; on CPython it occurs # as soon as we import _ctypes) if space.config.translation.thread: from pypy.module.thread.os_thread import setup_threads setup_threads(space)
def __getattr__(self, name): if name.startswith('array_'): typecode = name[len('array_'):] arr = self.space.interp_w(W_Array, letter2tp(self.space, typecode)) setattr(self, name, arr) return arr raise AttributeError(name)
def callback(ll_args, ll_res, ll_userdata): userdata = rffi.cast(USERDATA_P, ll_userdata) callback_ptr = global_counter.get(userdata.addarg) w_callable = callback_ptr.w_callable argtypes = callback_ptr.argtypes must_leave = False space = callback_ptr.space try: must_leave = space.threadlocals.try_enter_thread(space) args_w = [None] * len(argtypes) for i in range(len(argtypes)): argtype = argtypes[i] if isinstance(argtype, W_Structure): args_w[i] = argtype.fromaddress( space, rffi.cast(rffi.SIZE_T, ll_args[i])) else: # XXX other types? args_w[i] = space.wrap(rffi.cast(rffi.ULONG, ll_args[i])) w_res = space.call(w_callable, space.newtuple(args_w)) if callback_ptr.result is not None: # don't return void unwrap_value(space, write_ptr, ll_res, 0, callback_ptr.result, w_res) except OperationError, e: tbprint(space, space.wrap(e.get_traceback()), space.wrap(e.errorstr(space))) # force the result to be zero if callback_ptr.result is not None: resshape = letter2tp(space, callback_ptr.result) for i in range(resshape.size): ll_res[i] = '\x00'
def test_bitsizes(): fields = [("A", 'i', 1), ("B", 'i', 2), ("C", 'i', 3), ("D", 'i', 4), ("E", 'i', 5), ("F", 'i', 6), ("G", 'i', 7), ("H", 'i', 8), ("I", 'i', 9), ("M", 'h', 1), ("N", 'h', 2), ("O", 'h', 3), ("P", 'h', 4), ("Q", 'h', 5), ("R", 'h', 6), ("S", 'h', 7)] size, alignment, pos, bitsizes = size_alignment_pos( [(name, letter2tp('space', t), size) for (name, t, size) in fields]) assert size == 12 import ctypes class X(ctypes.Structure): _fields_ = [(name, {'i':ctypes.c_int, 'h': ctypes.c_short}[t], size) for (name, t, size) in fields] assert pos == [getattr(X, name).offset for (name, _, _) in fields] assert bitsizes == [getattr(X, name).size for (name, _, _) in fields]
def __init__(self, space, w_callable, w_args, w_result, flags=FUNCFLAG_CDECL): self.space = space self.w_callable = w_callable self.argtypes = unpack_argshapes(space, w_args) ffiargs = [tp.get_basic_ffi_type() for tp in self.argtypes] if not space.is_w(w_result, space.w_None): self.result = space.str_w(w_result) ffiresult = letter2tp(space, self.result).get_basic_ffi_type() else: self.result = None ffiresult = ffi_type_void self.number = global_counter.add(self) try: self.ll_callback = CallbackFuncPtr(ffiargs, ffiresult, callback, self.number, flags) except LibFFIError: raise got_libffi_error(space) self.ll_buffer = rffi.cast(rffi.VOIDP, self.ll_callback.ll_closure) if tracker.DO_TRACING: addr = rffi.cast(lltype.Signed, self.ll_callback.ll_closure) tracker.trace_allocation(addr, self)
def callback(ll_args, ll_res, ll_userdata): userdata = rffi.cast(USERDATA_P, ll_userdata) callback_ptr = global_counter.get(userdata.addarg) w_callable = callback_ptr.w_callable argtypes = callback_ptr.argtypes space = callback_ptr.space try: args_w = [None] * len(argtypes) for i in range(len(argtypes)): argtype = argtypes[i] if isinstance(argtype, W_Structure): args_w[i] = argtype.fromaddress( space, rffi.cast(rffi.SIZE_T, ll_args[i])) else: # XXX other types? args_w[i] = space.wrap(rffi.cast(rffi.ULONG, ll_args[i])) w_res = space.call(w_callable, space.newtuple(args_w)) if callback_ptr.result is not None: # don't return void unwrap_value(space, write_ptr, ll_res, 0, callback_ptr.result, w_res) except OperationError, e: tbprint(space, space.wrap(e.get_traceback()), space.wrap(e.errorstr(space))) # force the result to be zero if callback_ptr.result is not None: resshape = letter2tp(space, callback_ptr.result) for i in range(resshape.size): ll_res[i] = '\x00'
def test_bitsizes_longlong(): fields = [("a", "q", 1), ("b", "q", 62), ("c", "q", 1)] size, alignment, pos, bitsizes = size_alignment_pos( [(name, letter2tp("space", t), size) for (name, t, size) in fields] ) assert size == 8 assert pos == [0, 0, 0] assert bitsizes == [0x10000, 0x3E0001, 0x1003F]
def test_bitsizes_longlong(): fields = [("a", 'q', 1), ("b", 'q', 62), ("c", 'q', 1)] size, alignment, pos, bitsizes = size_alignment_pos([ (name, letter2tp('space', t), size) for (name, t, size) in fields ]) assert size == 8 assert pos == [0, 0, 0] assert bitsizes == [0x10000, 0x3e0001, 0x1003f]
def from_memory(self, space, w_obj, w_pycppclass, offset): # returned as a long value for the address (INTPTR_T is not proper # per se, but rffi does not come with a PTRDIFF_T) address = self._get_raw_address(space, w_obj, offset) ptrval = rffi.cast(rffi.ULONG, rffi.cast(rffi.VOIDPP, address)[0]) if ptrval == 0: from pypy.module.cppyy import interp_cppyy return interp_cppyy.get_nullptr(space) arr = space.interp_w(W_Array, letter2tp(space, 'P')) return arr.fromaddress(space, ptrval, sys.maxint)
def from_memory(self, space, w_obj, offset): # returned as a long value for the address (INTPTR_T is not proper # per se, but rffi does not come with a PTRDIFF_T) address = self._get_raw_address(space, w_obj, offset) ptrval = rffi.cast(rffi.ULONGP, address)[0] if ptrval == rffi.cast(rffi.ULONG, 0): from pypy.module._cppyy import interp_cppyy return interp_cppyy.get_nullptr(space) shape = letter2tp(space, 'P') return lowlevelviews.W_LowLevelView(space, shape, sys.maxint/shape.size, ptrval)
def from_memory(self, space, w_obj, w_pycppclass, offset): # returned as a long value for the address (INTPTR_T is not proper # per se, but rffi does not come with a PTRDIFF_T) address = self._get_raw_address(space, w_obj, offset) ptrval = rffi.cast(rffi.ULONG, rffi.cast(rffi.VOIDPP, address)[0]) if ptrval == 0: from pypy.module._cppyy import interp_cppyy return interp_cppyy.get_nullptr(space) arr = space.interp_w(W_Array, letter2tp(space, 'P')) return arr.fromaddress(space, ptrval, sys.maxint)
def execute(self, space, cppmethod, cppthis, num_args, args): if hasattr(space, "fake"): raise NotImplementedError address = capi.c_call_r(space, cppmethod, cppthis, num_args, args) ipv = rffi.cast(rffi.UINTPTR_T, address) if ipv == rffi.cast(rffi.UINTPTR_T, 0): from pypy.module._cppyy import interp_cppyy return interp_cppyy.get_nullptr(space) shape = letter2tp(space, self.typecode) return lowlevelviews.W_LowLevelView(space, shape, sys.maxint / shape.size, ipv)
def execute(self, space, cppmethod, cppthis, num_args, args): if hasattr(space, "fake"): raise NotImplementedError lresult = capi.c_call_l(space, cppmethod, cppthis, num_args, args) ptrval = rffi.cast(rffi.ULONG, lresult) if ptrval == rffi.cast(rffi.ULONG, 0): from pypy.module._cppyy import interp_cppyy return interp_cppyy.get_nullptr(space) shape = letter2tp(space, self.typecode) return lowlevelviews.W_LowLevelView(space, shape, sys.maxint / shape.size, ptrval)
def test_bitsizes_longlong(): fields = [("a", 'q', 1), ("b", 'q', 62), ("c", 'q', 1)] size, alignment, pos, bitsizes = size_alignment_pos( [(name, letter2tp('space', t), size) for (name, t, size) in fields]) assert size == 8 assert pos == [0, 0, 0] if sys.byteorder == 'little': assert bitsizes == [0x10000, 0x3e0001, 0x1003f] else: assert bitsizes == [0x1003f, 0x3e0001, 0x10000]
def callback(ll_args, ll_res, ll_userdata): userdata = rffi.cast(USERDATA_P, ll_userdata) callback_ptr = global_counter.CallbackPtr_by_number[userdata.addarg] w_callable = callback_ptr.w_callable res = rffi.cast(rffi.VOIDPP, ll_res) argtypes = callback_ptr.args space = callback_ptr.space try: w_args = space.newlist([space.wrap(rffi.cast(rffi.ULONG, ll_args[i])) for i in range(len(argtypes))]) w_res = space.call(w_callable, w_args) if callback_ptr.result != 'O': # don't return void unwrap_value(space, push_elem, ll_res, 0, letter2tp(space, callback_ptr.result), w_res) except OperationError, e: tbprint(space, space.wrap(e.application_traceback), space.wrap(e.errorstr(space)))
def __init__(self, space, w_callable, w_args, w_result, flags=FUNCFLAG_CDECL): self.space = space self.w_callable = w_callable self.argtypes = unpack_argshapes(space, w_args) ffiargs = [tp.get_basic_ffi_type() for tp in self.argtypes] if not space.is_w(w_result, space.w_None): self.result = space.str_w(w_result) ffiresult = letter2tp(space, self.result).get_basic_ffi_type() else: self.result = None ffiresult = ffi_type_void self.number = global_counter.add(self) self.ll_callback = CallbackFuncPtr(ffiargs, ffiresult, callback, self.number, flags) self.ll_buffer = rffi.cast(rffi.VOIDP, self.ll_callback.ll_closure) if tracker.DO_TRACING: addr = rffi.cast(lltype.Signed, self.ll_callback.ll_closure) tracker.trace_allocation(addr, self)
def callback(ll_args, ll_res, ll_userdata): userdata = rffi.cast(USERDATA_P, ll_userdata) callback_ptr = global_counter.get(userdata.addarg) w_callable = callback_ptr.w_callable argtypes = callback_ptr.argtypes must_leave = False space = callback_ptr.space try: must_leave = space.threadlocals.try_enter_thread(space) args_w = [None] * len(argtypes) for i in range(len(argtypes)): argtype = argtypes[i] if isinstance(argtype, W_Structure): args_w[i] = argtype.fromaddress( space, rffi.cast(rffi.SIZE_T, ll_args[i])) else: # XXX other types? args_w[i] = space.newint(rffi.cast(lltype.Unsigned, ll_args[i])) w_res = space.call(w_callable, space.newtuple(args_w)) if callback_ptr.result is not None: # don't return void ptr = ll_res letter = callback_ptr.result if BIGENDIAN: # take care of narrow integers! for int_type in unroll_narrow_integer_types: if int_type == letter: T = LL_TYPEMAP[int_type] n = rffi.sizeof(lltype.Signed) - rffi.sizeof(T) ptr = rffi.ptradd(ptr, n) break unwrap_value(space, write_ptr, ptr, 0, letter, w_res) except OperationError as e: tbprint(space, e.get_w_traceback(space), space.newtext(e.errorstr(space))) # force the result to be zero if callback_ptr.result is not None: resshape = letter2tp(space, callback_ptr.result) for i in range(resshape.size): ll_res[i] = '\x00' if must_leave: space.threadlocals.leave_thread(space)
def test_bitsizes(): fields = [("A", 'i', 1), ("B", 'i', 2), ("C", 'i', 3), ("D", 'i', 4), ("E", 'i', 5), ("F", 'i', 6), ("G", 'i', 7), ("H", 'i', 8), ("I", 'i', 9), ("M", 'h', 1), ("N", 'h', 2), ("O", 'h', 3), ("P", 'h', 4), ("Q", 'h', 5), ("R", 'h', 6), ("S", 'h', 7)] size, alignment, pos, bitsizes = size_alignment_pos([ (name, letter2tp('space', t), size) for (name, t, size) in fields ]) assert size == 12 import ctypes class X(ctypes.Structure): _fields_ = [(name, { 'i': ctypes.c_int, 'h': ctypes.c_short }[t], size) for (name, t, size) in fields] assert pos == [getattr(X, name).offset for (name, _, _) in fields] assert bitsizes == [getattr(X, name).size for (name, _, _) in fields]
def callback(ll_args, ll_res, ll_userdata): userdata = rffi.cast(USERDATA_P, ll_userdata) callback_ptr = global_counter.get(userdata.addarg) w_callable = callback_ptr.w_callable argtypes = callback_ptr.argtypes must_leave = False space = callback_ptr.space try: must_leave = space.threadlocals.try_enter_thread(space) args_w = [None] * len(argtypes) for i in range(len(argtypes)): argtype = argtypes[i] if isinstance(argtype, W_Structure): args_w[i] = argtype.fromaddress( space, rffi.cast(rffi.SIZE_T, ll_args[i])) else: # XXX other types? args_w[i] = space.wrap(rffi.cast(rffi.ULONG, ll_args[i])) w_res = space.call(w_callable, space.newtuple(args_w)) if callback_ptr.result is not None: # don't return void ptr = ll_res letter = callback_ptr.result if BIGENDIAN: # take care of narrow integers! for int_type in unroll_narrow_integer_types: if int_type == letter: T = LL_TYPEMAP[int_type] n = rffi.sizeof(lltype.Signed) - rffi.sizeof(T) ptr = rffi.ptradd(ptr, n) break unwrap_value(space, write_ptr, ptr, 0, letter, w_res) except OperationError as e: tbprint(space, space.wrap(e.get_traceback()), space.wrap(e.errorstr(space))) # force the result to be zero if callback_ptr.result is not None: resshape = letter2tp(space, callback_ptr.result) for i in range(resshape.size): ll_res[i] = '\x00' if must_leave: space.threadlocals.leave_thread(space)
def callback(ll_args, ll_res, ll_userdata): userdata = rffi.cast(USERDATA_P, ll_userdata) callback_ptr = global_counter.CallbackPtr_by_number[userdata.addarg] w_callable = callback_ptr.w_callable argtypes = callback_ptr.args space = callback_ptr.space try: w_args = space.newlist([space.wrap(rffi.cast(rffi.ULONG, ll_args[i])) for i in range(len(argtypes))]) w_res = space.call(w_callable, w_args) if callback_ptr.result != 'O': # don't return void unwrap_value(space, push_elem, ll_res, 0, callback_ptr.result, w_res) except OperationError, e: tbprint(space, space.wrap(e.application_traceback), space.wrap(e.errorstr(space))) # force the result to be zero if callback_ptr.result != 'O': _, size, _ = letter2tp(space, callback_ptr.result) for i in range(size): ll_res[i] = '\x00'
def unpack(desc): return [('x', letter2tp('space', i), 0) for i in desc]
def unpack(desc): return [("x", letter2tp("space", i), 0) for i in desc]
def __init__(self, space): self.space = space self.cache = {} self.array_of_ptr = self.get_array_type(letter2tp(space, 'P'))
def from_memory(self, space, w_obj, offset): # read access, so no copy needed address = self._get_raw_address(space, w_obj, offset) ipv = rffi.cast(rffi.UINTPTR_T, rffi.cast(rffi.VOIDPP, address)[0]) return lowlevelviews.W_LowLevelView( space, letter2tp(space, self.typecode), self.size, ipv)