def test_closure_heap(self): ch = ClosureHeap() assert not ch.free_list a = ch.alloc() assert ch.free_list b = ch.alloc() chunks = [a, b] p = ch.free_list while p: chunks.append(p) p = rffi.cast(rffi.VOIDPP, p)[0] closure_size = rffi.sizeof(FFI_CLOSUREP.TO) assert len(chunks) == CHUNK//closure_size for i in range(len(chunks) -1 ): s = rffi.cast(rffi.UINT, chunks[i+1]) e = rffi.cast(rffi.UINT, chunks[i]) assert (e-s) >= rffi.sizeof(FFI_CLOSUREP.TO) ch.free(a) assert ch.free_list == rffi.cast(rffi.VOIDP, a) snd = rffi.cast(rffi.VOIDPP, a)[0] assert snd == chunks[2] ch.free(b) assert ch.free_list == rffi.cast(rffi.VOIDP, b) snd = rffi.cast(rffi.VOIDPP, b)[0] assert snd == rffi.cast(rffi.VOIDP, a)
def allocate(self, space, w_type, itemcount=0): # similar to PyType_GenericAlloc? # except that it's not related to any pypy object. # this returns a PyObject with ob_refcnt == 1. pytype = as_pyobj(space, w_type) pytype = rffi.cast(PyTypeObjectPtr, pytype) assert pytype # Don't increase refcount for non-heaptypes flags = rffi.cast(lltype.Signed, pytype.c_tp_flags) if flags & Py_TPFLAGS_HEAPTYPE: Py_IncRef(space, w_type) if pytype: size = pytype.c_tp_basicsize else: size = rffi.sizeof(self.basestruct) if pytype.c_tp_itemsize: size += itemcount * pytype.c_tp_itemsize assert size >= rffi.sizeof(PyObject.TO) buf = lltype.malloc(rffi.VOIDP.TO, size, flavor='raw', zero=True, add_memory_pressure=True) pyobj = rffi.cast(PyObject, buf) if pytype.c_tp_itemsize: pyvarobj = rffi.cast(PyVarObject, pyobj) pyvarobj.c_ob_size = itemcount pyobj.c_ob_refcnt = 1 #pyobj.c_ob_pypy_link should get assigned very quickly pyobj.c_ob_type = pytype return pyobj
def __init__(self, space, pto): bases_w = space.fixedview(from_ref(space, pto.c_tp_bases)) dict_w = {} add_operators(space, dict_w, pto) convert_method_defs(space, dict_w, pto.c_tp_methods, self) convert_getset_defs(space, dict_w, pto.c_tp_getset, self) convert_member_defs(space, dict_w, pto.c_tp_members, self) name = rffi.charp2str(pto.c_tp_name) flag_heaptype = pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE if flag_heaptype: minsize = rffi.sizeof(PyHeapTypeObject.TO) else: minsize = rffi.sizeof(PyObject.TO) new_layout = (pto.c_tp_basicsize > minsize or pto.c_tp_itemsize > 0) W_TypeObject.__init__(self, space, name, bases_w or [space.w_object], dict_w, force_new_layout=new_layout, is_heaptype=flag_heaptype) self.flag_cpytype = True # if a sequence or a mapping, then set the flag to force it if pto.c_tp_as_sequence and pto.c_tp_as_sequence.c_sq_item: self.flag_map_or_seq = 'S' elif (pto.c_tp_as_mapping and pto.c_tp_as_mapping.c_mp_subscript and not (pto.c_tp_as_sequence and pto.c_tp_as_sequence.c_sq_slice)): self.flag_map_or_seq = 'M' if pto.c_tp_doc: self.w_doc = space.wrap(rffi.charp2str(pto.c_tp_doc))
def _get_ffi2descr_dict(cpu): def entry(letter, TYPE): return (letter, cpu.arraydescrof(rffi.CArray(TYPE)), rffi.sizeof(TYPE)) # d = {('v', 0): ('v', None, 1)} if cpu.supports_floats: d[('f', 0)] = entry('f', lltype.Float) if cpu.supports_singlefloats: d[('S', 0)] = entry('i', lltype.SingleFloat) for SIGNED_TYPE in [rffi.SIGNEDCHAR, rffi.SHORT, rffi.INT, rffi.LONG, rffi.LONGLONG]: key = ('i', rffi.sizeof(SIGNED_TYPE)) kind = 'i' if key[1] > rffi.sizeof(lltype.Signed): if not cpu.supports_longlong: continue key = ('L', 0) kind = 'f' d[key] = entry(kind, SIGNED_TYPE) for UNSIGNED_TYPE in [rffi.UCHAR, rffi.USHORT, rffi.UINT, rffi.ULONG, rffi.ULONGLONG]: key = ('u', rffi.sizeof(UNSIGNED_TYPE)) if key[1] > rffi.sizeof(lltype.Signed): continue d[key] = entry('i', UNSIGNED_TYPE) return d
def inet_ntop(family, packed): "packed string -> human-readable string" if family == AF_INET: srcsize = sizeof(_c.in_addr) dstsize = _c.INET_ADDRSTRLEN elif AF_INET6 is not None and family == AF_INET6: srcsize = sizeof(_c.in6_addr) dstsize = _c.INET6_ADDRSTRLEN else: raise RSocketError("unknown address family") if len(packed) != srcsize: raise ValueError("packed IP wrong length for inet_ntop") srcbuf = rffi.get_nonmovingbuffer(packed) try: dstbuf = mallocbuf(dstsize) try: res = _c.inet_ntop(family, rffi.cast(rffi.VOIDP, srcbuf), dstbuf, dstsize) if not res: raise last_error() return rffi.charp2str(res) finally: lltype.free(dstbuf, flavor='raw') finally: rffi.free_nonmovingbuffer(packed, srcbuf)
def push_arg_as_ffiptr(ffitp, arg, ll_buf): # This is for primitive types. Note that the exact type of 'arg' may be # different from the expected 'c_size'. To cope with that, we fall back # to a byte-by-byte copy. TP = lltype.typeOf(arg) TP_P = lltype.Ptr(rffi.CArray(TP)) TP_size = rffi.sizeof(TP) c_size = intmask(ffitp.c_size) # if both types have the same size, we can directly write the # value to the buffer if c_size == TP_size: buf = rffi.cast(TP_P, ll_buf) buf[0] = arg else: # needs byte-by-byte copying. Make sure 'arg' is an integer type. # Note that this won't work for rffi.FLOAT/rffi.DOUBLE. assert TP is not rffi.FLOAT and TP is not rffi.DOUBLE if TP_size <= rffi.sizeof(lltype.Signed): arg = rffi.cast(lltype.Unsigned, arg) else: arg = rffi.cast(lltype.UnsignedLongLong, arg) if _LITTLE_ENDIAN: for i in range(c_size): ll_buf[i] = chr(arg & 0xFF) arg >>= 8 elif _BIG_ENDIAN: for i in range(c_size-1, -1, -1): ll_buf[i] = chr(arg & 0xFF) arg >>= 8 else: raise AssertionError
def f(d): bc = d * rffi.sizeof(rffi.SIGNED) va = alloc_raw_storage(bc, zero=True) vb = alloc_raw_storage(bc, zero=True) vc = alloc_raw_storage(bc, zero=True) x = 1 for i in range(d): j = i * rffi.sizeof(rffi.SIGNED) raw_storage_setitem(va, j, rffi.cast(rffi.SIGNED, i)) raw_storage_setitem(vb, j, rffi.cast(rffi.SIGNED, i)) i = 0 while i < bc: myjitdriver.jit_merge_point() a = raw_storage_getitem(rffi.SIGNED, va, i) b = raw_storage_getitem(rffi.SIGNED, vb, i) c = a + b raw_storage_setitem(vc, i, rffi.cast(rffi.SIGNED, c)) i += 1 * rffi.sizeof(rffi.SIGNED) res = 0 for i in range(d): res += raw_storage_getitem(rffi.SIGNED, vc, i * rffi.sizeof(rffi.SIGNED)) free_raw_storage(va) free_raw_storage(vb) free_raw_storage(vc) return res
def __init__(self, restype, argtypes): self.align = rffi.sizeof(rffi.VOIDP) self.argtypes = argtypes self.cif = lltype.nullptr(jit_libffi.CIF_DESCRIPTION) self.notready = True self.restype = restype self.size = rffi.sizeof(rffi.VOIDP)
def getkind(TYPE, supports_floats=True, supports_longlong=True, supports_singlefloats=True): if TYPE is lltype.Void: return "void" elif isinstance(TYPE, lltype.Primitive): if TYPE is lltype.Float and supports_floats: return 'float' if TYPE is lltype.SingleFloat and supports_singlefloats: return 'int' # singlefloats are stored in an int if TYPE in (lltype.Float, lltype.SingleFloat): raise NotImplementedError("type %s not supported" % TYPE) if (TYPE != llmemory.Address and rffi.sizeof(TYPE) > rffi.sizeof(lltype.Signed)): if supports_longlong and TYPE is not lltype.LongFloat: assert rffi.sizeof(TYPE) == 8 return 'float' raise NotImplementedError("type %s is too large" % TYPE) return "int" elif isinstance(TYPE, lltype.Ptr): if TYPE.TO._gckind == 'raw': return "int" else: return "ref" else: raise NotImplementedError("type %s not supported" % TYPE)
def convert_argument_libffi(self, space, w_obj, address, call_local): assert rffi.sizeof(self.c_type) <= 2*rffi.sizeof(rffi.VOIDP) # see interp_cppyy.py obj = self._unwrap_object(space, w_obj) typed_buf = rffi.cast(self.c_ptrtype, call_local) typed_buf[0] = obj x = rffi.cast(rffi.VOIDPP, address) x[0] = call_local
def test_get_call_descr_not_translated(): c0 = GcCache(False) descr1 = get_call_descr(c0, [lltype.Char, lltype.Signed], lltype.Char) assert descr1.get_result_size() == rffi.sizeof(lltype.Char) assert descr1.get_result_type() == history.INT assert descr1.arg_classes == "ii" # T = lltype.GcStruct('T') descr2 = get_call_descr(c0, [lltype.Ptr(T)], lltype.Ptr(T)) assert descr2.get_result_size() == rffi.sizeof(lltype.Ptr(T)) assert descr2.get_result_type() == history.REF assert descr2.arg_classes == "r" # U = lltype.GcStruct('U', ('x', lltype.Signed)) assert descr2 == get_call_descr(c0, [lltype.Ptr(U)], lltype.Ptr(U)) # V = lltype.Struct('V', ('x', lltype.Signed)) assert (get_call_descr(c0, [], lltype.Ptr(V)).get_result_type() == history.INT) # assert (get_call_descr(c0, [], lltype.Void).get_result_type() == history.VOID) # descr4 = get_call_descr(c0, [lltype.Float, lltype.Float], lltype.Float) assert descr4.get_result_size() == rffi.sizeof(lltype.Float) assert descr4.get_result_type() == history.FLOAT assert descr4.arg_classes == "ff" # descr5 = get_call_descr(c0, [lltype.SingleFloat], lltype.SingleFloat) assert descr5.get_result_size() == rffi.sizeof(lltype.SingleFloat) assert descr5.get_result_type() == "S" assert descr5.arg_classes == "S"
def _get_bind_info(self, space, numElements): # avoid bus errors on 64bit platforms numElements = numElements + (rffi.sizeof(roci.dvoidp) - numElements % rffi.sizeof(roci.dvoidp)) # initialize the buffers bindNames = lltype.malloc(roci.Ptr(roci.oratext).TO, numElements, flavor='raw') bindNameLengths = lltype.malloc(roci.Ptr(roci.ub1).TO, numElements, flavor='raw') indicatorNames = lltype.malloc(roci.Ptr(roci.oratext).TO, numElements, flavor='raw') indicatorNameLengths = lltype.malloc(roci.Ptr(roci.ub1).TO, numElements, flavor='raw') duplicate = lltype.malloc(roci.Ptr(roci.ub1).TO, numElements, flavor='raw') bindHandles = lltype.malloc(roci.Ptr(roci.OCIBind).TO, numElements, flavor='raw') foundElementsPtr = lltype.malloc(roci.Ptr(roci.sb4).TO, 1, flavor='raw') try: status = roci.OCIStmtGetBindInfo( self.handle, self.environment.errorHandle, numElements, 1, foundElementsPtr, bindNames, bindNameLengths, indicatorNames, indicatorNameLengths, duplicate, bindHandles) if status != roci.OCI_NO_DATA: self.environment.checkForError( status, "Cursor_GetBindNames()") # Too few elements allocated foundElements = rffi.cast(lltype.Signed, foundElementsPtr[0]) if foundElements < 0: return -foundElements, None names_w = [] # process the bind information returned for i in range(foundElements): if rffi.cast(lltype.Signed, duplicate[i]): continue names_w.append( w_string(space, bindNames[i], rffi.cast(lltype.Signed, bindNameLengths[i]))) return 0, names_w finally: lltype.free(bindNames, flavor='raw') lltype.free(bindNameLengths, flavor='raw') lltype.free(indicatorNames, flavor='raw') lltype.free(indicatorNameLengths, flavor='raw') lltype.free(duplicate, flavor='raw') lltype.free(bindHandles, flavor='raw') lltype.free(foundElementsPtr, flavor='raw')
def __init__(self, *args): W_CTypePrimitive.__init__(self, *args) self.value_fits_long = self.size <= rffi.sizeof(lltype.Signed) if self.size < rffi.sizeof(lltype.Signed): assert self.value_fits_long sh = self.size * 8 self.vmin = r_uint(-1) << (sh - 1) self.vrangemax = (r_uint(1) << sh) - 1
def __init__(self, *args): W_CTypePrimitive.__init__(self, *args) self.value_fits_long = self.size < rffi.sizeof(lltype.Signed) self.value_fits_ulong = self.size <= rffi.sizeof(lltype.Unsigned) if self.value_fits_long: self.vrangemax = self._compute_vrange_max() else: self.vrangemax = r_uint(sys.maxint)
def _fits_into_signed(TYPE): if isinstance(TYPE, lltype.Ptr): return True # pointers always fits into Signeds if not isinstance(TYPE, lltype.Primitive): return False if TYPE is lltype.Void or TYPE is rffi.FLOAT or TYPE is rffi.DOUBLE: return False sz = rffi.sizeof(TYPE) return sz <= rffi.sizeof(rffi.SIGNED)
def set_native_value(ptr, val, tp): if tp is Integer._type: pnt = rffi.cast(rffi.LONGP, ptr) pnt[0] = rffi.cast(rffi.LONG, val.int_val()) return rffi.cast(rffi.CCHARP, rffi.ptradd(pnt, rffi.sizeof(rffi.LONG))) if tp is String._type: pnt = rffi.cast(rffi.CCHARPP, ptr) pnt[0] = rffi.str2charp(str(rt.name(val))) return rffi.cast(rffi.CCHARP, rffi.ptradd(pnt, rffi.sizeof(rffi.CCHARP))) assert False
def inet_ntoa(packed): "packet 32-bits string -> IPv4 dotted string" if len(packed) != sizeof(_c.in_addr): raise RSocketError("packed IP wrong length for inet_ntoa") buf = rffi.make(_c.in_addr) try: for i in range(sizeof(_c.in_addr)): rffi.cast(rffi.CCHARP, buf)[i] = packed[i] return rffi.charp2str(_c.inet_ntoa(buf)) finally: lltype.free(buf, flavor='raw')
def signext(value, size): # 'value' is sign-extended from 'size' bytes to a full integer. # 'size' should be a constant smaller than a full integer size. if size == rffi.sizeof(rffi.SIGNEDCHAR): return rffi.cast(lltype.Signed, rffi.cast(rffi.SIGNEDCHAR, value)) elif size == rffi.sizeof(rffi.SHORT): return rffi.cast(lltype.Signed, rffi.cast(rffi.SHORT, value)) elif size == rffi.sizeof(rffi.INT): return rffi.cast(lltype.Signed, rffi.cast(rffi.INT, value)) else: raise AssertionError("unsupported size")
def unpack_list_of_float_items(self, ptr, length): if self.size == rffi.sizeof(rffi.DOUBLE): from rpython.rlib.rrawarray import populate_list_from_raw_array res = [] buf = rffi.cast(rffi.DOUBLEP, ptr) populate_list_from_raw_array(res, buf, length) return res elif self.size == rffi.sizeof(rffi.FLOAT): res = [0.0] * length misc.unpack_cfloat_list_from_raw_array(res, ptr) return res return None
def select_conversion_method(size, signed): if signed: if size <= rffi.sizeof(lltype.Signed): return "intmask_w" else: return "longlongmask_w" else: if size < rffi.sizeof(lltype.Signed): return "intmask_w" elif size == rffi.sizeof(lltype.Signed): return "uintmask_w" else: return "ulonglongmask_w"
def pack_list_of_items(self, cdata, w_ob): float_list = self.space.listview_float(w_ob) if float_list is not None: if self.size == rffi.sizeof(rffi.DOUBLE): # fastest path from rpython.rlib.rrawarray import copy_list_to_raw_array cdata = rffi.cast(rffi.DOUBLEP, cdata) copy_list_to_raw_array(float_list, cdata) return True elif self.size == rffi.sizeof(rffi.FLOAT): misc.pack_float_list_to_raw_array(float_list, cdata, rffi.FLOAT, rffi.FLOATP) return True return W_CTypePrimitive.pack_list_of_items(self, cdata, w_ob)
def unpack_list_of_float_items(self, w_cdata): if self.size == rffi.sizeof(rffi.DOUBLE): from rpython.rlib.rrawarray import populate_list_from_raw_array res = [] buf = rffi.cast(rffi.DOUBLEP, w_cdata._cdata) length = w_cdata.get_array_length() populate_list_from_raw_array(res, buf, length) return res elif self.size == rffi.sizeof(rffi.FLOAT): res = [0.0] * w_cdata.get_array_length() misc.unpack_cfloat_list_from_raw_array(res, w_cdata._cdata) return res return None
def test_get_field_descr(): U = lltype.Struct('U') T = lltype.GcStruct('T') S = lltype.GcStruct('S', ('x', lltype.Char), ('y', lltype.Ptr(T)), ('z', lltype.Ptr(U)), ('f', lltype.Float), ('s', lltype.SingleFloat)) # c0 = GcCache(False) c1 = GcCache(True) assert get_field_descr(c0, S, 'y') == get_field_descr(c0, S, 'y') assert get_field_descr(c0, S, 'y') != get_field_descr(c1, S, 'y') for tsc in [False, True]: c2 = GcCache(tsc) descr_x = get_field_descr(c2, S, 'x') descr_y = get_field_descr(c2, S, 'y') descr_z = get_field_descr(c2, S, 'z') descr_f = get_field_descr(c2, S, 'f') descr_s = get_field_descr(c2, S, 's') assert isinstance(descr_x, FieldDescr) assert descr_x.name == 'S.x' assert descr_y.name == 'S.y' assert descr_z.name == 'S.z' assert descr_f.name == 'S.f' assert descr_s.name == 'S.s' if not tsc: assert descr_x.offset < descr_y.offset < descr_z.offset assert descr_x.sort_key() < descr_y.sort_key() < descr_z.sort_key() assert descr_x.field_size == rffi.sizeof(lltype.Char) assert descr_y.field_size == rffi.sizeof(lltype.Ptr(T)) assert descr_z.field_size == rffi.sizeof(lltype.Ptr(U)) assert descr_f.field_size == rffi.sizeof(lltype.Float) assert descr_s.field_size == rffi.sizeof(lltype.SingleFloat) else: assert isinstance(descr_x.offset, Symbolic) assert isinstance(descr_y.offset, Symbolic) assert isinstance(descr_z.offset, Symbolic) assert isinstance(descr_f.offset, Symbolic) assert isinstance(descr_s.offset, Symbolic) assert isinstance(descr_x.field_size, Symbolic) assert isinstance(descr_y.field_size, Symbolic) assert isinstance(descr_z.field_size, Symbolic) assert isinstance(descr_f.field_size, Symbolic) assert isinstance(descr_s.field_size, Symbolic) assert descr_x.flag == FLAG_UNSIGNED assert descr_y.flag == FLAG_POINTER assert descr_z.flag == FLAG_UNSIGNED assert descr_f.flag == FLAG_FLOAT assert descr_s.flag == FLAG_UNSIGNED
def fb_build(self): # Build a CIF_DESCRIPTION. Actually this computes the size and # allocates a larger amount of data. It starts with a # CIF_DESCRIPTION and continues with data needed for the CIF: # # - the argument types, as an array of 'ffi_type *'. # # - optionally, the result's and the arguments' ffi type data # (this is used only for 'struct' ffi types; in other cases the # 'ffi_type *' just points to static data like 'ffi_type_sint32'). # nargs = len(self.fargs) # start with a cif_description (cif and exchange_* fields) self.fb_alloc(llmemory.sizeof(CIF_DESCRIPTION, nargs)) # next comes an array of 'ffi_type*', one per argument atypes = self.fb_alloc(rffi.sizeof(FFI_TYPE_P) * nargs) self.atypes = rffi.cast(FFI_TYPE_PP, atypes) # next comes the result type data self.rtype = self.fb_fill_type(self.fresult, True) # next comes each argument's type data for i, farg in enumerate(self.fargs): atype = self.fb_fill_type(farg, False) if self.atypes: self.atypes[i] = atype
def _vector_simple_int(self, func, type, la): oldfunc = func func = always_inline(func) size = rffi.sizeof(type) myjitdriver = JitDriver(greens = [], reds = 'auto', vectorize=True) def f(bytecount, va, vb, vc): i = 0 while i < bytecount: myjitdriver.jit_merge_point() a = raw_storage_getitem(type,va,i) b = raw_storage_getitem(type,vb,i) c = func(a,b) raw_storage_setitem(vc, i, rffi.cast(type,c)) i += size l = len(la) lb = list(reversed(la))[:] rawstorage = RawStorage() va = rawstorage.new(la, type) vb = rawstorage.new(lb, type) vc = rawstorage.new(None, type, size=l) self.meta_interp(f, [l*size, va, vb, vc], vec=True) for i in range(l): c = raw_storage_getitem(type,vc,i*size) assert rffi.cast(type, oldfunc(la[i], lb[i])) == c rawstorage.clear()
def _do_call(self, funcsym, ll_args, RESULT): # XXX: check len(args)? ll_result = lltype.nullptr(rffi.VOIDP.TO) if self.restype != types.void: size = adjust_return_size(intmask(self.restype.c_size)) ll_result = lltype.malloc(rffi.VOIDP.TO, size, flavor='raw') ffires = c_ffi_call(self.ll_cif, self.funcsym, rffi.cast(rffi.VOIDP, ll_result), rffi.cast(rffi.VOIDPP, ll_args)) if RESULT is not lltype.Void: TP = lltype.Ptr(rffi.CArray(RESULT)) if types.is_struct(self.restype): assert RESULT == rffi.SIGNED # for structs, we directly return the buffer and transfer the # ownership buf = rffi.cast(TP, ll_result) res = rffi.cast(RESULT, buf) else: if _BIG_ENDIAN and types.getkind(self.restype) in ('i','u'): ptr = ll_result n = rffi.sizeof(lltype.Signed) - self.restype.c_size ptr = rffi.ptradd(ptr, n) res = rffi.cast(TP, ptr)[0] else: res = rffi.cast(TP, ll_result)[0] else: res = None self._free_buffers(ll_result, ll_args) clibffi.check_fficall_result(ffires, self.flags) return res
def _vec_reduce(self, strat, func, type, data): func = always_inline(func) size = rffi.sizeof(type) myjitdriver = JitDriver(greens = [], reds = 'auto', vectorize=True) def f(accum, bytecount, v): i = 0 while i < bytecount: myjitdriver.jit_merge_point() e = raw_storage_getitem(type,v,i) accum = func(accum,e) i += size return accum la = data.draw(st.lists(strat, min_size=10, max_size=150)) #la = [1.0] * 10 l = len(la) accum = data.draw(strat) rawstorage = RawStorage() va = rawstorage.new(la, type) res = self.meta_interp(f, [accum, l*size, va], vec=True) assert isclose(rffi.cast(type, res), f(accum, l*size, va)) rawstorage.clear()
def fb_build_exchange(self, cif_descr): nargs = len(self.fargs) # first, enough room for an array of 'nargs' pointers exchange_offset = rffi.sizeof(rffi.CCHARP) * nargs exchange_offset = self.align_arg(exchange_offset) cif_descr.exchange_result = exchange_offset cif_descr.exchange_result_libffi = exchange_offset if BIG_ENDIAN and self.fresult.is_primitive_integer: # For results of precisely these types, libffi has a # strange rule that they will be returned as a whole # 'ffi_arg' if they are smaller. The difference # only matters on big-endian. if self.fresult.size < SIZE_OF_FFI_ARG: diff = SIZE_OF_FFI_ARG - self.fresult.size cif_descr.exchange_result += diff # then enough room for the result, rounded up to sizeof(ffi_arg) exchange_offset += max(rffi.getintfield(self.rtype, 'c_size'), SIZE_OF_FFI_ARG) # loop over args for i, farg in enumerate(self.fargs): if isinstance(farg, W_CTypePointer): exchange_offset += 1 # for the "must free" flag exchange_offset = self.align_arg(exchange_offset) cif_descr.exchange_args[i] = exchange_offset exchange_offset += rffi.getintfield(self.atypes[i], 'c_size') # store the exchange data size cif_descr.exchange_size = exchange_offset
def __init__(self, space, fargs, fresult, ellipsis): extra = self._compute_extra_text(fargs, fresult, ellipsis) size = rffi.sizeof(rffi.VOIDP) W_CTypePtrBase.__init__(self, space, size, extra, 2, fresult, could_cast_anything=False) self.fargs = fargs self.ellipsis = bool(ellipsis) # fresult is stored in self.ctitem if not ellipsis: # Functions with '...' varargs are stored without a cif_descr # at all. The cif is computed on every call from the actual # types passed in. For all other functions, the cif_descr # is computed here. builder = CifDescrBuilder(fargs, fresult) try: builder.rawallocate(self) except OperationError, e: if not e.match(space, space.w_NotImplementedError): raise # else, eat the NotImplementedError. We will get the # exception if we see an actual call if self.cif_descr: # should not be True, but you never know lltype.free(self.cif_descr, flavor='raw') self.cif_descr = lltype.nullptr(CIF_DESCRIPTION)
def _vector_float_unary(self, func, type, data): func = always_inline(func) size = rffi.sizeof(type) myjitdriver = JitDriver(greens = [], reds = 'auto', vectorize=True) def f(bytecount, va, vc): i = 0 while i < bytecount: myjitdriver.jit_merge_point() a = raw_storage_getitem(type,va,i) c = func(a) raw_storage_setitem(vc, i, rffi.cast(type,c)) i += size la = data.draw(st.lists(st.floats(), min_size=10, max_size=150)) l = len(la) rawstorage = RawStorage() va = rawstorage.new(la, type) vc = rawstorage.new(None, type, size=l) self.meta_interp(f, [l*size, va, vc], vec=True) for i in range(l): c = raw_storage_getitem(type,vc,i*size) r = func(la[i]) assert isclose(r, c) rawstorage.clear()
def pack_list_of_items(self, cdata, w_ob): int_list = self.space.listview_int(w_ob) if int_list is not None: if self.size == rffi.sizeof(rffi.LONG): # fastest path from rpython.rlib.rrawarray import copy_list_to_raw_array cdata = rffi.cast(rffi.LONGP, cdata) copy_list_to_raw_array(int_list, cdata) else: overflowed = misc.pack_list_to_raw_array_bounds_signed( int_list, cdata, self.size) if overflowed != 0: self._overflow(self.space.newint(overflowed)) return True return W_CTypePrimitive.pack_list_of_items(self, cdata, w_ob)
def _do_ffi_call_sint(cif_description, func_addr, exchange_buffer): result = jit_ffi_call_impl_int(cif_description, func_addr, exchange_buffer) size = types.getsize(cif_description.rtype) for TP in _short_sint_types: # short **signed** types if size == rffi.sizeof(TP): llop.raw_store(lltype.Void, llmemory.cast_ptr_to_adr(exchange_buffer), cif_description.exchange_result, rffi.cast(TP, result)) break else: # default case: expect a full signed number llop.raw_store(lltype.Void, llmemory.cast_ptr_to_adr(exchange_buffer), cif_description.exchange_result, result)
def setup_class(cls, space, w_cls): long_in_bits = 8 * rffi.sizeof(rffi.LONG) for orig, alias in [('int8', 'char'), ('uint8', 'uchar'), ('int16', 'short'), ('uint16', 'ushort'), ('int32', 'int'), ('uint32', 'uint'), ('int64', 'long_long'), ('uint64', 'ulong_long'), ('float32', 'float'), ('float64', 'double'), ('int' + str(long_in_bits), 'long'), ('uint' + str(long_in_bits), 'ulong')]: for prefix in ['put_', 'get_', 'write_', 'read_']: space.send(w_cls, 'alias_method', [ space.newsymbol(prefix + alias), space.newsymbol(prefix + orig) ])
def external(name, args, result, eci=CConfig._compilation_info_, **kwds): if _WIN and rffi.sizeof(rffi.TIME_T) == 8: # Recent Microsoft compilers use 64bit time_t and # the corresponding functions are named differently if (rffi.TIME_T in args or rffi.TIME_TP in args or result in (rffi.TIME_T, rffi.TIME_TP)): name = '_' + name + '64' return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv=calling_conv, releasegil=False, **kwds)
def locate_caller_based_on_retaddr(self, retaddr, ebp_in_caller): gcmapstart = llop.gc_asmgcroot_static(llmemory.Address, 0) gcmapend = llop.gc_asmgcroot_static(llmemory.Address, 1) item = search_in_gcmap(gcmapstart, gcmapend, retaddr) if item: self._shape_decompressor.setpos(item.signed[1]) return if not self._shape_decompressor.sorted: # the item may have been not found because the main array was # not sorted. Sort it and try again. win32_follow_gcmap_jmp(gcmapstart, gcmapend) sort_gcmap(gcmapstart, gcmapend) self._shape_decompressor.sorted = True item = search_in_gcmap(gcmapstart, gcmapend, retaddr) if item: self._shape_decompressor.setpos(item.signed[1]) return if self._with_jit: # item not found. We assume that it's a JIT-generated # location -- but we check for consistency that ebp points # to a JITFRAME object. from rpython.jit.backend.llsupport.jitframe import STACK_DEPTH_OFS tid = self.gc.get_possibly_forwarded_type_id(ebp_in_caller) if (rffi.cast(lltype.Signed, tid) == rffi.cast(lltype.Signed, self.frame_tid)): # fish the depth extra_stack_depth = (ebp_in_caller + STACK_DEPTH_OFS).signed[0] ll_assert((extra_stack_depth & (rffi.sizeof(lltype.Signed) - 1)) == 0, "asmgcc: misaligned extra_stack_depth") extra_stack_depth //= rffi.sizeof(lltype.Signed) self._shape_decompressor.setjitframe(extra_stack_depth) return llop.debug_fatalerror(lltype.Void, "cannot find gc roots!")
def __init__(self, space, pto): bases_w = space.fixedview(from_ref(space, pto.c_tp_bases)) dict_w = {} add_operators(space, dict_w, pto) convert_method_defs(space, dict_w, pto.c_tp_methods, self) convert_getset_defs(space, dict_w, pto.c_tp_getset, self) convert_member_defs(space, dict_w, pto.c_tp_members, self) w_dict = from_ref(space, pto.c_tp_dict) if w_dict is not None: dictkeys_w = space.listview(w_dict) for w_key in dictkeys_w: key = space.text_w(w_key) dict_w[key] = space.getitem(w_dict, w_key) name = rffi.charp2str(cts.cast('char*', pto.c_tp_name)) flag_heaptype = pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE if flag_heaptype: minsize = rffi.sizeof(PyHeapTypeObject.TO) else: minsize = rffi.sizeof(PyObject.TO) new_layout = (pto.c_tp_basicsize > minsize or pto.c_tp_itemsize > 0) W_TypeObject.__init__(self, space, name, bases_w or [space.w_object], dict_w, force_new_layout=new_layout, is_heaptype=flag_heaptype) self.flag_cpytype = True # if a sequence or a mapping, then set the flag to force it if pto.c_tp_as_sequence and pto.c_tp_as_sequence.c_sq_item: self.flag_map_or_seq = 'S' elif (pto.c_tp_as_mapping and pto.c_tp_as_mapping.c_mp_subscript and not (pto.c_tp_as_sequence and pto.c_tp_as_sequence.c_sq_slice)): self.flag_map_or_seq = 'M' if pto.c_tp_doc: self.w_doc = space.newtext( rffi.charp2str(cts.cast('char*', pto.c_tp_doc)))
def prepare_cif(self): argc = len(self.argtypes) # atypes points to an array of ffi_type pointers cif = lltype.malloc(jit_libffi.CIF_DESCRIPTION, argc, flavor='raw') cif.abi = clibffi.FFI_DEFAULT_ABI cif.atypes = lltype.malloc(clibffi.FFI_TYPE_PP.TO, argc, flavor='raw') for i in range(argc): cif.atypes[i] = self.argtypes[i].cast_to_ffitype() cif.nargs = argc restype = self.restype if restype is null: cif.rtype = clibffi.ffi_type_void # MSVC returns small structures in registers. Pretend int32 or # int64 return type. This is needed as a workaround for what # is really a bug of libffi_msvc seen as an independent library # (ctypes and pypy has a similar workaround). # Implementation of this workaround doesn't reach to elsewhere from here. elif USE_C_LIBFFI_MSVC and isinstance(restype, Struct) and restype.size <= 4: cif.rtype = clibffi.ffi_type_sint32 elif USE_C_LIBFFI_MSVC and isinstance(restype, Struct) and restype.size <= 8: cif.rtype = clibffi.ffi_type_sint64 else: cif.rtype = restype.cast_to_ffitype() exchange_size = argc * rffi.sizeof(rffi.VOIDPP) exchange_size = align(exchange_size, 8) for i in range(argc): argtype = self.argtypes[i] assert isinstance(argtype, Type) # checked prior that this holds. exchange_size = align(exchange_size, max(8, argtype.align)) cif.exchange_args[i] = int(exchange_size) exchange_size += sizeof(argtype) #cif.exchange_result_libffi = exchange_size if restype is null: exchange_size = align(exchange_size, 8) cif.exchange_result = int(exchange_size) exchange_size += jit_libffi.SIZE_OF_FFI_ARG elif isinstance(restype, Type): exchange_size = align(exchange_size, max(8, restype.align)) cif.exchange_result = int(exchange_size) exchange_size += max(sizeof(restype), jit_libffi.SIZE_OF_FFI_ARG) else: # SIZE_OF_FFI_ARG assert False # checked prior that this holds. cif.exchange_size = int(align(exchange_size, 8)) jit_libffi.jit_ffi_prep_cif(cif) self.cif = cif
def _PyDateTime_Import(space): state = space.fromcache(State) if len(state.datetimeAPI) > 0: return state.datetimeAPI[0] datetimeAPI = lltype.malloc(PyDateTime_CAPI, flavor='raw', track_allocation=False) w_datetime = PyImport_Import(space, space.newtext("datetime")) w_type = space.getattr(w_datetime, space.newtext("date")) datetimeAPI.c_DateType = rffi.cast(PyTypeObjectPtr, make_ref(space, w_type)) # convenient place to modify this, needed since the make_typedescr attach # links the "wrong" struct to W_DateTime_Date, which in turn is needed # because datetime, with a tzinfo entry, inherits from date, without one datetimeAPI.c_DateType.c_tp_basicsize = rffi.sizeof(PyObject.TO) w_type = space.getattr(w_datetime, space.newtext("datetime")) datetimeAPI.c_DateTimeType = rffi.cast(PyTypeObjectPtr, make_ref(space, w_type)) w_type = space.getattr(w_datetime, space.newtext("time")) datetimeAPI.c_TimeType = rffi.cast(PyTypeObjectPtr, make_ref(space, w_type)) w_type = space.getattr(w_datetime, space.newtext("timedelta")) datetimeAPI.c_DeltaType = rffi.cast(PyTypeObjectPtr, make_ref(space, w_type)) w_type = space.getattr(w_datetime, space.newtext("tzinfo")) datetimeAPI.c_TZInfoType = rffi.cast(PyTypeObjectPtr, make_ref(space, w_type)) datetimeAPI.c_Date_FromDate = llhelper( _PyDate_FromDate.api_func.functype, _PyDate_FromDate.api_func.get_wrapper(space)) datetimeAPI.c_Time_FromTime = llhelper( _PyTime_FromTime.api_func.functype, _PyTime_FromTime.api_func.get_wrapper(space)) datetimeAPI.c_DateTime_FromDateAndTime = llhelper( _PyDateTime_FromDateAndTime.api_func.functype, _PyDateTime_FromDateAndTime.api_func.get_wrapper(space)) datetimeAPI.c_Delta_FromDelta = llhelper( _PyDelta_FromDelta.api_func.functype, _PyDelta_FromDelta.api_func.get_wrapper(space)) state.datetimeAPI.append(datetimeAPI) return state.datetimeAPI[0]
def getaddrinfo(node, service): req = lltype.malloc(uv.getaddrinfo_ptr.TO, flavor='raw', zero=True) if node is None: node_string = lltype.nullptr(rffi.CCHARP.TO) else: node_string = rffi.str2charp(node.string.encode('utf-8')) if service is None: service_string = lltype.nullptr(rffi.CCHARP.TO) else: service_string = rffi.str2charp(service.string.encode('utf-8')) try: response = uv_callback.getaddrinfo(req) status, res = response.wait( uv.getaddrinfo(response.ec.uv_loop, req, uv_callback.getaddrinfo.cb, node_string, service_string, lltype.nullptr(uv.addrinfo_ptr.TO))) if rffi.r_long(status) < 0: raise uv_callback.to_error(status) this = res result = [] while this != lltype.nullptr(uv.addrinfo_ptr.TO): entry = Exnihilo() entry.setattr(u"flags", Integer(rffi.r_long(this.c_ai_flags))) entry.setattr(u"family", Integer(rffi.r_long(this.c_ai_family))) entry.setattr(u"socktype", Integer(rffi.r_long(this.c_ai_socktype))) entry.setattr(u"protocol", Integer(rffi.r_long(this.c_ai_protocol))) entry.setattr( u"addr", copy_to_uint8array(rffi.cast(rffi.VOIDP, this.c_ai_addr), this.c_ai_addrlen, rffi.sizeof(uv.sockaddr_storage))) if this.c_ai_canonname: entry.setattr( u"canonname", from_cstring(rffi.charp2str(this.c_ai_canonname))) else: entry.setattr(u"canonname", null) result.append(entry) this = rffi.cast(uv.addrinfo_ptr, this.c_ai_next) uv.freeaddrinfo(res) return List(result) finally: if node_string: lltype.free(node_string, flavor='raw') if service_string: lltype.free(service_string, flavor='raw') lltype.free(req, flavor='raw')
def test_it_offers_some_SIZE_constants(self, space): w_res = space.execute('FFI::Platform::INT8_SIZE') assert space.int_w(w_res) == rffi.sizeof(rffi.CHAR) w_res = space.execute('FFI::Platform::INT16_SIZE') assert space.int_w(w_res) == rffi.sizeof(rffi.SHORT) w_res = space.execute('FFI::Platform::INT32_SIZE') assert space.int_w(w_res) == rffi.sizeof(rffi.INT) w_res = space.execute('FFI::Platform::INT64_SIZE') assert space.int_w(w_res) == rffi.sizeof(rffi.LONGLONG) w_res = space.execute('FFI::Platform::LONG_SIZE') assert space.int_w(w_res) == rffi.sizeof(rffi.LONG) w_res = space.execute('FFI::Platform::FLOAT_SIZE') assert space.int_w(w_res) == rffi.sizeof(rffi.FLOAT) w_res = space.execute('FFI::Platform::DOUBLE_SIZE') assert space.int_w(w_res) == rffi.sizeof(rffi.DOUBLE) w_res = space.execute('FFI::Platform::ADDRESS_SIZE') assert space.int_w(w_res) == rffi.sizeof(rffi.VOIDP)
def test_gcreftracer(): a = lltype.malloc(rffi.CArray(lltype.Signed), 3, flavor='raw') a[0] = 123 a[1] = 456 a[2] = 789 tr = lltype.malloc(GCREFTRACER) tr.array_base_addr = base = rffi.cast(lltype.Signed, a) tr.array_length = 3 gc = FakeGC() gcrefs_trace(gc, llmemory.cast_ptr_to_adr(tr), "callback", "arg1", "arg2") assert len(gc.called) == 3 WORD = rffi.sizeof(lltype.Signed) for i in range(3): assert gc.called[i] == rffi.cast(llmemory.Address, base + i * WORD) lltype.free(a, flavor='raw')
def ClassPtrTypeID(classptr): """ASMJSValue representing the typeid for a class pointer. This is a special value for handling class comparisons when we're not using type pointers. It extracts an "expected type id" from the class pointer, which can be compared agaist the first half-word in the object pointer. Logic shamelessly cargo-culted from x86 backend. """ sizeof_ti = rffi.sizeof(GCData.TYPE_INFO) type_info_group = llop.gc_get_type_info_group(llmemory.Address) type_info_group = rffi.cast(lltype.Signed, type_info_group) typeid = Minus(classptr, ConstInt(sizeof_ti + type_info_group)) typeid = RShift(typeid, ConstInt(2)) typeid = And(typeid, ConstInt(0xFFFF)) return typeid
def __init__(self, itemtype, unwrap, canoverflow=False, signed=False, method='__int__'): self.itemtype = itemtype self.bytes = rffi.sizeof(itemtype) self.arraytype = lltype.Array(itemtype, hints={'nolength': True}) self.arrayptrtype = lltype.Ptr(self.arraytype) self.unwrap = unwrap self.signed = signed self.canoverflow = canoverflow self.w_class = None self.method = method
def unpack_list_of_int_items(self, w_cdata): if self.size == rffi.sizeof(rffi.LONG): from rpython.rlib.rrawarray import populate_list_from_raw_array res = [] length = w_cdata.get_array_length() with w_cdata as ptr: buf = rffi.cast(rffi.LONGP, ptr) populate_list_from_raw_array(res, buf, length) return res elif self.value_smaller_than_long: res = [0] * w_cdata.get_array_length() with w_cdata as ptr: misc.unpack_list_from_raw_array(res, ptr, self.size) return res return None
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 getaddrstring(self, w_obj): w_id = self.newint_or_bigint(compute_unique_id(w_obj)) w_4 = self.newint(4) w_0x0F = self.newint(0x0F) i = 2 * rffi.sizeof(llmemory.Address) addrstring = [" "] * i while True: n = self.int_w(self.send(w_id, "&", [w_0x0F])) n += ord("0") if n > ord("9"): n += (ord("a") - ord("9") - 1) i -= 1 addrstring[i] = chr(n) if i == 0: break w_id = self.send(w_id, ">>", [w_4]) return "".join(addrstring)
def timelib_time_modify(timelib_time, modifier, tzi): ll_s = rffi.str2charp(modifier) error_c = lltype.malloc(timelib_error_containerP.TO, 1, flavor='raw') tmp_timelib_time = timelib_strtotime(ll_s, len(modifier), error_c, timelib_builtin_db(), tzinfo_callback) lltype.free(error_c, flavor='raw') rffi.c_memcpy(rffi.cast(rffi.VOIDP, timelib_time.c_relative), rffi.cast(rffi.VOIDP, tmp_timelib_time.c_relative), rffi.sizeof(timelib_rel_time)) timelib_time.c_have_relative = tmp_timelib_time.c_have_relative timelib_time.c_sse_uptodate = rffi.cast(rffi.UINT, 0) if intmask(tmp_timelib_time.c_y) != -99999: timelib_time.c_y = tmp_timelib_time.c_y if intmask(tmp_timelib_time.c_m) != -99999: timelib_time.c_m = tmp_timelib_time.c_m if intmask(tmp_timelib_time.c_d) != -99999: timelib_time.c_d = tmp_timelib_time.c_d if intmask(tmp_timelib_time.c_h) != -99999: timelib_time.c_h = tmp_timelib_time.c_h if intmask(tmp_timelib_time.c_i) != -99999: timelib_time.c_i = tmp_timelib_time.c_i if intmask(tmp_timelib_time.c_s) != -99999: timelib_time.c_s = tmp_timelib_time.c_s else: timelib_time.c_s = rffi.cast(lltype.Signed, 0) else: timelib_time.c_i = rffi.cast(lltype.Signed, 0) timelib_time.c_s = rffi.cast(lltype.Signed, 0) timelib_time_dtor(tmp_timelib_time) timelib_update_ts(timelib_time, lltype.nullptr(timelib_tzinfo.TO)) timelib_update_from_sse(timelib_time) timelib_time.c_have_relative = rffi.cast(rffi.UINT, 0) return timelib_time
def raw_storage_getitem_unaligned(TP, storage, index): if misaligned_is_fine: if we_are_translated(): return raw_storage_getitem(TP, storage, index) else: return _raw_storage_getitem_unchecked(TP, storage, index) mask = _get_alignment_mask(TP) if (index & mask) == 0: if we_are_translated(): return raw_storage_getitem(TP, storage, index) else: return _raw_storage_getitem_unchecked(TP, storage, index) ptr = rffi.ptradd(storage, index) with lltype.scoped_alloc(rffi.CArray(TP), 1) as s_array: rffi.c_memcpy(rffi.cast(rffi.VOIDP, s_array), rffi.cast(rffi.VOIDP, ptr), rffi.sizeof(TP)) return rffi.cast(rffi.CArrayPtr(TP), s_array)[0]
def getsockopt_int(self, level, option): flag_p = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') try: flagsize_p = lltype.malloc(_c.socklen_t_ptr.TO, flavor='raw') try: flagsize_p[0] = rffi.cast(_c.socklen_t, rffi.sizeof(rffi.INT)) res = _c.socketgetsockopt(self.fd, level, option, rffi.cast(rffi.VOIDP, flag_p), flagsize_p) if res < 0: raise self.error_handler() result = rffi.cast(lltype.Signed, flag_p[0]) finally: lltype.free(flagsize_p, flavor='raw') finally: lltype.free(flag_p, flavor='raw') return result
class INETAddress(IPAddress): family = AF_INET struct = _c.sockaddr_in maxlen = minlen = sizeof(struct) def __init__(self, host, port): makeipaddr(host, self) a = self.lock(_c.sockaddr_in) rffi.setintfield(a, 'c_sin_port', htons(port)) self.unlock() def __repr__(self): try: return '<INETAddress %s:%d>' % (self.get_host(), self.get_port()) except SocketError: return '<INETAddress ?>' def get_port(self): a = self.lock(_c.sockaddr_in) port = ntohs(rffi.getintfield(a, 'c_sin_port')) self.unlock() return port def eq(self, other): # __eq__() is not called by RPython :-/ return (isinstance(other, INETAddress) and self.get_host() == other.get_host() and self.get_port() == other.get_port()) def from_in_addr(in_addr): result = instantiate(INETAddress) # store the malloc'ed data into 'result' as soon as possible # to avoid leaks if an exception occurs inbetween sin = lltype.malloc(_c.sockaddr_in, flavor='raw', zero=True, track_allocation=False) result.setdata(sin, sizeof(_c.sockaddr_in)) # PLAT sin_len rffi.setintfield(sin, 'c_sin_family', AF_INET) rffi.structcopy(sin.c_sin_addr, in_addr) return result from_in_addr = staticmethod(from_in_addr) def lock_in_addr(self): a = self.lock(_c.sockaddr_in) p = rffi.cast(rffi.VOIDP, a.c_sin_addr) return p, sizeof(_c.in_addr)
def do_unpack_fastpath(fmtiter): size = rffi.sizeof(TYPE) buf, pos = fmtiter.get_buffer_and_pos() if not USE_FASTPATH: raise CannotRead # if not ALLOW_FASTPATH: raise ValueError("fastpath not allowed :(") # typed_read does not do any bound check, so we must call it only if # we are sure there are at least "size" bytes to read if fmtiter.can_advance(size): result = buf.typed_read(TYPE, pos) fmtiter.advance(size) return result else: # this will raise StructError fmtiter.advance(size) assert False, 'fmtiter.advance should have raised!'
def call(self, RES_TP): self._check_args() ffires = c_ffi_call(self.ll_cif, self.funcsym, rffi.cast(rffi.VOIDP, self.ll_result), rffi.cast(VOIDPP, self.ll_args)) if RES_TP is not lltype.Void: TP = lltype.Ptr(rffi.CArray(RES_TP)) ptr = self.ll_result if _BIG_ENDIAN and RES_TP in TYPE_MAP_INT: # we get a 8 byte value in big endian n = rffi.sizeof(lltype.Signed) - self.restype_size ptr = rffi.ptradd(ptr, n) res = rffi.cast(TP, ptr)[0] else: res = None self._clean_args() check_fficall_result(ffires, self.flags) return res
def inflateInit(wbits=MAX_WBITS): """ Allocate and return an opaque 'stream' object that can be used to decompress data. """ stream = lltype.malloc(z_stream, flavor='raw', zero=True) rgc.add_memory_pressure(rffi.sizeof(z_stream)) err = _inflateInit2(stream, wbits) if err == Z_OK: return stream else: try: if err == Z_STREAM_ERROR: raise ValueError("Invalid initialization option") else: raise RZlibError.fromstream( stream, err, "while creating decompression object") finally: lltype.free(stream, flavor='raw')
def share_w(self, space, processid): from rpython.rtyper.lltypesystem import rffi, lltype from rpython.rlib import rwin32 from rpython.rlib.rsocket import _c info_ptr = lltype.malloc(_c.WSAPROTOCOL_INFOW, flavor='raw') try: winprocessid = rffi.cast(rwin32.DWORD, processid) res = _c.WSADuplicateSocketW(self.sock.fd, winprocessid, info_ptr) if res < 0: raise converted_error(space, rsocket.last_error()) bytes_ptr = rffi.cast(rffi.CCHARP, info_ptr) w_bytes = space.newbytes( rffi.charpsize2str(bytes_ptr, rffi.sizeof(_c.WSAPROTOCOL_INFOW))) finally: lltype.free(info_ptr, flavor='raw') return w_bytes
def make_float_packer(TYPE): size = rffi.sizeof(TYPE) def packer(fmtiter): fl = fmtiter.accept_float_arg() if TYPE is not rffi.FLOAT and pack_fastpath(TYPE)(fmtiter, fl): return # slow path try: result = ieee.pack_float(fmtiter.wbuf, fmtiter.pos, fl, size, fmtiter.bigendian) except OverflowError: assert size == 4 raise StructOverflowError("float too large for format 'f'") else: fmtiter.advance(size) return result return packer
def GetVersionEx(): info = lltype.malloc(OSVERSIONINFOEX, flavor='raw') rffi.setintfield(info, 'c_dwOSVersionInfoSize', rffi.sizeof(OSVERSIONINFOEX)) try: if not _GetVersionEx(info): raise lastSavedWindowsError() return (rffi.cast(lltype.Signed, info.c_dwMajorVersion), rffi.cast(lltype.Signed, info.c_dwMinorVersion), rffi.cast(lltype.Signed, info.c_dwBuildNumber), rffi.cast(lltype.Signed, info.c_dwPlatformId), rffi.charp2str(rffi.cast(rffi.CCHARP, info.c_szCSDVersion)), rffi.cast(lltype.Signed, info.c_wServicePackMajor), rffi.cast(lltype.Signed, info.c_wServicePackMinor), rffi.cast(lltype.Signed, info.c_wSuiteMask), rffi.cast(lltype.Signed, info.c_wProductType)) finally: lltype.free(info, flavor='raw')
def __init__(self, itemtype, unwrap, canoverflow=False, signed=False, method='__int__', errorname=None): if errorname is None: errorname = unwrap[:-2] self.itemtype = itemtype self.bytes = rffi.sizeof(itemtype) self.arraytype = lltype.Array(itemtype, hints={'nolength': True}) self.arrayptrtype = lltype.Ptr(self.arraytype) self.unwrap, _, self.convert = unwrap.partition('.') assert self.unwrap != 'str_w' self.signed = signed self.canoverflow = canoverflow self.w_class = None self.method = method self.errorname = errorname
def get_fixed_size(TYPE): if isinstance(TYPE, lltype.Primitive): if TYPE == lltype.Void: return 0 try: return struct.calcsize(primitive_to_fmt[TYPE]) except KeyError: from rpython.rtyper.lltypesystem import rffi return rffi.sizeof(TYPE) elif isinstance(TYPE, lltype.Ptr): return struct.calcsize("P") elif isinstance(TYPE, lltype.Struct): return get_layout(TYPE)["_size"] elif isinstance(TYPE, lltype.Array): return get_fixed_size(lltype.Unsigned) elif isinstance(TYPE, lltype.OpaqueType): return get_fixed_size(lltype.Unsigned) elif isinstance(TYPE, lltype.FuncType): return get_fixed_size(lltype.Unsigned) assert 0, "not yet implemented"
def test_force_virtual_str_storage(self): byteorder = sys.byteorder size = rffi.sizeof(lltype.Signed) def f(val): if byteorder == 'little': x = chr(val) + '\x00' * (size - 1) else: x = '\x00' * (size - 1) + chr(val) return str_gc_load(lltype.Signed, x, 0) res = self.interp_operations(f, [42], supports_singlefloats=True) assert res == 42 self.check_operations_history({ 'newstr': 1, # str forcing 'strsetitem': 1, # str forcing 'call_pure_r': 1, # str forcing (copystrcontent) 'guard_no_exception': 1, # str forcing 'gc_load_indexed_i': 1, # str_storage_getitem 'finish': 1 })
def fb_build_exchange(self, cif_descr): nargs = len(self.fargs) # first, enough room for an array of 'nargs' pointers exchange_offset = rffi.sizeof(rffi.VOIDP) * nargs exchange_offset = self.align_arg(exchange_offset) cif_descr.exchange_result = exchange_offset # then enough room for the result, rounded up to sizeof(ffi_arg) exchange_offset += max(rffi.getintfield(self.rtype, 'c_size'), SIZE_OF_FFI_ARG) # loop over args for i, farg in enumerate(self.fargs): #if isinstance(farg, W_CTypePointer): # exchange_offset += 1 # for the "must free" flag exchange_offset = self.align_arg(exchange_offset) cif_descr.exchange_args[i] = exchange_offset exchange_offset += rffi.getintfield(self.atypes[i], 'c_size') # store the exchange data size cif_descr.exchange_size = exchange_offset