def realize_global_int(ffi, g, gindex): fetch_fnptr = rffi.cast(FUNCPTR_FETCH_LONGLONG, g.c_address) with lltype.scoped_alloc(parse_c_type.GETCONST_S) as p_value: p_value.c_ctx = ffi.ctxobj.ctx rffi.setintfield(p_value, 'c_gindex', gindex) neg = fetch_fnptr(p_value) value = p_value.c_value neg = rffi.cast(lltype.Signed, neg) if neg == 0: # positive if value <= rffi.cast(rffi.ULONGLONG, sys.maxint): return ffi.space.wrap(intmask(value)) else: return ffi.space.wrap(value) elif neg == 1: # negative value = rffi.cast(rffi.LONGLONG, value) if value >= -sys.maxint-1: return ffi.space.wrap(intmask(value)) else: return ffi.space.wrap(value) if neg == 2: got = "%d (0x%x)" % (value, value) else: got = "%d" % (rffi.cast(rffi.LONGLONG, value),) raise oefmt(ffi.w_FFIError, "the C compiler says '%s' is equal to %s, " "but the cdef disagrees", rffi.charp2str(g.c_name), got)
def parse(input): OUTPUT_SIZE = 100 out = lltype.malloc(rffi.VOIDPP.TO, OUTPUT_SIZE, flavor='raw', track_allocation=False) info = lltype.malloc(parse_c_type.PINFO.TO, flavor='raw', zero=True, track_allocation=False) info.c_ctx = ctx info.c_output = out rffi.setintfield(info, 'c_output_size', OUTPUT_SIZE) for j in range(OUTPUT_SIZE): out[j] = rffi.cast(rffi.VOIDP, -424242) res = parse_c_type.parse_c_type(info, input.encode('ascii')) if res < 0: raise ParseError( rffi.charp2str(info.c_error_message).decode('ascii'), rffi.getintfield(info, 'c_error_location')) assert 0 <= res < OUTPUT_SIZE result = [] for j in range(OUTPUT_SIZE): if out[j] == rffi.cast(rffi.VOIDP, -424242): assert res < j break i = rffi.cast(rffi.SIGNED, out[j]) if j == res: result.append('->') result.append(i) return result
def decompress(stream, data, flush=Z_SYNC_FLUSH, max_length=sys.maxint): """ Feed more data into an inflate stream. Returns a tuple (string, finished, unused_data_length). The string contains (a part of) the decompressed data. If flush != Z_NO_FLUSH, this also flushes the output data; see zlib.h or the documentation of the zlib module for the possible values of 'flush'. The 'string' is never longer than 'max_length'. The 'unused_data_length' is the number of unprocessed input characters, either because they are after the end of the compressed stream or because processing it would cause the 'max_length' to be exceeded. """ # Warning, reentrant calls to the zlib with a given stream can cause it # to crash. The caller of rpython.rlib.rzlib should use locks if needed. # _operate() does not support the Z_FINISH method of decompressing. # We can use Z_SYNC_FLUSH instead and manually check that we got to # the end of the data. if flush == Z_FINISH: flush = Z_SYNC_FLUSH should_finish = True else: should_finish = False while_doing = "while decompressing data" data, err, avail_in = _operate(stream, data, flush, max_length, _inflate, while_doing) if should_finish: # detect incomplete input rffi.setintfield(stream, 'c_avail_in', 0) err = _inflate(stream, Z_FINISH) if err < 0: raise RZlibError.fromstream(stream, err, while_doing) finished = (err == Z_STREAM_END) return data, finished, avail_in
def PyBuffer_FillInfo(space, view, obj, buf, length, readonly, flags): """ Fills in a buffer-info structure correctly for an exporter that can only share a contiguous chunk of memory of "unsigned bytes" of the given length. Returns 0 on success and -1 (with raising an error) on error. This is not a complete re-implementation of the CPython API; it only provides a subset of CPython's behavior. """ if flags & PyBUF_WRITABLE and readonly: raise OperationError(space.w_ValueError, space.wrap("Object is not writable")) view.c_buf = buf view.c_len = length view.c_obj = obj Py_IncRef(space, obj) view.c_itemsize = 1 rffi.setintfield(view, 'c_readonly', readonly) rffi.setintfield(view, 'c_ndim', 0) view.c_format = lltype.nullptr(rffi.CCHARP.TO) view.c_shape = lltype.nullptr(Py_ssize_tP.TO) view.c_strides = lltype.nullptr(Py_ssize_tP.TO) view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO) view.c_internal = lltype.nullptr(rffi.VOIDP.TO) return 0
def _select(self, for_writing): """Returns 0 when reading/writing is possible, 1 when timing out and -1 on error.""" timeout = self.timeout if timeout <= 0.0 or self.fd == _c.INVALID_SOCKET: # blocking I/O or no socket. return 0 tv = rffi.make(_c.timeval) rffi.setintfield(tv, 'c_tv_sec', int(timeout)) rffi.setintfield(tv, 'c_tv_usec', int((timeout-int(timeout)) * 1000000)) fds = lltype.malloc(_c.fd_set.TO, flavor='raw') _c.FD_ZERO(fds) _c.FD_SET(self.fd, fds) null = lltype.nullptr(_c.fd_set.TO) if for_writing: n = _c.select(self.fd + 1, null, fds, null, tv) else: n = _c.select(self.fd + 1, fds, null, null, tv) lltype.free(fds, flavor='raw') lltype.free(tv, flavor='raw') if n < 0: return -1 if n == 0: return 1 return 0
def poll(fddict, timeout=-1): """'fddict' maps file descriptors to interesting events. 'timeout' is an integer in milliseconds, and NOT a float number of seconds, but it's the same in CPython. Use -1 for infinite. Returns a list [(fd, events)]. """ numfd = len(fddict) pollfds = lltype.malloc(_c.pollfdarray, numfd, flavor='raw') try: i = 0 for fd, events in fddict.iteritems(): rffi.setintfield(pollfds[i], 'c_fd', fd) rffi.setintfield(pollfds[i], 'c_events', events) i += 1 assert i == numfd ret = _c.poll(pollfds, numfd, timeout) if ret < 0: raise PollError(_c.geterrno()) retval = [] for i in range(numfd): pollfd = pollfds[i] fd = rffi.cast(lltype.Signed, pollfd.c_fd) revents = rffi.cast(lltype.Signed, pollfd.c_revents) if revents: retval.append((fd, revents)) finally: lltype.free(pollfds, flavor='raw') return retval
def test_deflate_set_dictionary(): text = 'abcabc' zdict = 'abc' stream = rzlib.deflateInit() rzlib.deflateSetDictionary(stream, zdict) bytes = rzlib.compress(stream, text, rzlib.Z_FINISH) rzlib.deflateEnd(stream) stream2 = rzlib.inflateInit() from rpython.rtyper.lltypesystem import lltype, rffi, rstr from rpython.rtyper.annlowlevel import llstr from rpython.rlib.rstring import StringBuilder with lltype.scoped_alloc(rffi.CCHARP.TO, len(bytes)) as inbuf: rstr.copy_string_to_raw(llstr(bytes), inbuf, 0, len(bytes)) stream2.c_next_in = rffi.cast(rzlib.Bytefp, inbuf) rffi.setintfield(stream2, 'c_avail_in', len(bytes)) with lltype.scoped_alloc(rffi.CCHARP.TO, 100) as outbuf: stream2.c_next_out = rffi.cast(rzlib.Bytefp, outbuf) bufsize = 100 rffi.setintfield(stream2, 'c_avail_out', bufsize) err = rzlib._inflate(stream2, rzlib.Z_SYNC_FLUSH) assert err == rzlib.Z_NEED_DICT rzlib.inflateSetDictionary(stream2, zdict) rzlib._inflate(stream2, rzlib.Z_SYNC_FLUSH) avail_out = rffi.cast(lltype.Signed, stream2.c_avail_out) result = StringBuilder() result.append_charpsize(outbuf, bufsize - avail_out) rzlib.inflateEnd(stream2) assert result.build() == text
def frame_attach(space, py_obj, w_obj): "Fills a newly allocated PyFrameObject with a frame object" frame = space.interp_w(PyFrame, w_obj) py_frame = rffi.cast(PyFrameObject, py_obj) py_frame.c_f_code = rffi.cast(PyCodeObject, make_ref(space, frame.pycode)) py_frame.c_f_globals = make_ref(space, frame.w_globals) rffi.setintfield(py_frame, 'c_f_lineno', frame.f_lineno)
def _decompress_buf(self, data, max_length): total_in = len(data) in_bufsize = min(total_in, MAX_BUFSIZE) total_in -= in_bufsize with rffi.scoped_nonmovingbuffer(data) as in_buf: # setup the input and the size it can consume self.bzs.c_next_in = in_buf rffi.setintfield(self.bzs, 'c_avail_in', in_bufsize) self.left_to_process = in_bufsize with OutBuffer(self.bzs, max_length=max_length) as out: while True: bzreturn = BZ2_bzDecompress(self.bzs) # add up the size that has not been processed avail_in = rffi.getintfield(self.bzs, 'c_avail_in') self.left_to_process = avail_in if bzreturn == BZ_STREAM_END: self.running = False break if bzreturn != BZ_OK: _catch_bz2_error(self.space, bzreturn) if self.left_to_process == 0: break elif rffi.getintfield(self.bzs, 'c_avail_out') == 0: if out.get_data_size() == max_length: break out.prepare_next_chunk() self.left_to_process += total_in res = out.make_result_string() return self.space.newbytes(res)
def _sem_timedwait_save(sem, deadline): delay = 0 void = lltype.nullptr(rffi.VOIDP.TO) with lltype.scoped_alloc(TIMEVALP.TO, 1) as tvdeadline: while True: # poll if _sem_trywait(sem) == 0: return 0 elif rposix.get_saved_errno() != errno.EAGAIN: return -1 now = gettimeofday() c_tv_sec = rffi.getintfield(deadline[0], 'c_tv_sec') c_tv_nsec = rffi.getintfield(deadline[0], 'c_tv_nsec') if (c_tv_sec < now[0] or (c_tv_sec == now[0] and c_tv_nsec <= now[1])): rposix.set_saved_errno(errno.ETIMEDOUT) return -1 # calculate how much time is left difference = ((c_tv_sec - now[0]) * 1000000 + (c_tv_nsec - now[1])) # check delay not too long -- maximum is 20 msecs if delay > 20000: delay = 20000 if delay > difference: delay = difference delay += 1000 # sleep rffi.setintfield(tvdeadline[0], 'c_tv_sec', delay / 1000000) rffi.setintfield(tvdeadline[0], 'c_tv_usec', delay % 1000000) if _select(0, void, void, void, tvdeadline) < 0: return -1
def buffer_attach(space, py_obj, w_obj): """ Fills a newly allocated PyBufferObject with the given (str) buffer object. """ py_buf = rffi.cast(PyBufferObject, py_obj) py_buf.c_b_offset = 0 rffi.setintfield(py_buf, 'c_b_readonly', 1) rffi.setintfield(py_buf, 'c_b_hash', -1) assert isinstance(w_obj, W_Buffer) buf = w_obj.buf if isinstance(buf, SubBuffer): py_buf.c_b_offset = buf.offset buf = buf.buffer # If buf already allocated a fixed buffer, use it, and keep a # reference to buf. # Otherwise, b_base stays NULL, and we own the b_ptr. if isinstance(buf, StringBuffer): py_buf.c_b_base = lltype.nullptr(PyObject.TO) py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, rffi.str2charp(buf.value)) py_buf.c_b_size = buf.getlength() elif isinstance(buf, ArrayBuffer): w_base = buf.array py_buf.c_b_base = make_ref(space, w_base) py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, buf.array._charbuf_start()) py_buf.c_b_size = buf.getlength() else: raise OperationError(space.w_NotImplementedError, space.wrap( "buffer flavor not supported"))
def fill_Py_buffer(space, buf, view): # c_buf, c_obj have been filled in ndim = buf.getndim() view.c_len = buf.getlength() view.c_itemsize = buf.getitemsize() rffi.setintfield(view, 'c_ndim', ndim) fmt = buf.getformat() n = len(fmt) view.c_format = lltype.malloc(rffi.CCHARP.TO, n + 1, flavor='raw', add_memory_pressure=True) flags = widen(view.c_flags) flags |= FORMAT_ALLOCATED view.c_flags = rffi.cast(rffi.INT_real, flags) for i in range(n): view.c_format[i] = fmt[i] view.c_format[n] = '\x00' if ndim > 0: view.c_shape = rffi.cast(Py_ssize_tP, view.c__shape) view.c_strides = rffi.cast(Py_ssize_tP, view.c__strides) shape = buf.getshape() strides = buf.getstrides() for i in range(ndim): view.c_shape[i] = shape[i] view.c_strides[i] = strides[i] else: view.c_shape = lltype.nullptr(Py_ssize_tP.TO) view.c_strides = lltype.nullptr(Py_ssize_tP.TO) view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO) view.c_internal = lltype.nullptr(rffi.VOIDP.TO) return 0
def assert_updated_metrics(width, height): rffi.setintfield(stub_videoresize_event, 'c_w', width) rffi.setintfield(stub_videoresize_event, 'c_h', height) result = sut.get_next_event() # TODO: decide whether no events or windowmetric events should be raised assert sut.width == width assert sut.height == height
def _operate(stream, data, flush, max_length, cfunc, while_doing): """Common code for compress() and decompress(). """ # Prepare the input buffer for the stream with lltype.scoped_alloc(rffi.CCHARP.TO, len(data)) as inbuf: for i in xrange(len(data)): inbuf[i] = data[i] stream.c_next_in = rffi.cast(Bytefp, inbuf) rffi.setintfield(stream, 'c_avail_in', len(data)) # Prepare the output buffer with lltype.scoped_alloc(rffi.CCHARP.TO, OUTPUT_BUFFER_SIZE) as outbuf: # Strategy: we call deflate() to get as much output data as fits in # the buffer, then accumulate all output into a StringBuffer # 'result'. result = StringBuilder() while True: stream.c_next_out = rffi.cast(Bytefp, outbuf) bufsize = OUTPUT_BUFFER_SIZE if max_length < bufsize: if max_length <= 0: err = Z_OK break bufsize = max_length max_length -= bufsize rffi.setintfield(stream, 'c_avail_out', bufsize) err = cfunc(stream, flush) if err == Z_OK or err == Z_STREAM_END: # accumulate data into 'result' avail_out = rffi.cast(lltype.Signed, stream.c_avail_out) result.append_charpsize(outbuf, bufsize - avail_out) # if the output buffer is full, there might be more data # so we need to try again. Otherwise, we're done. if avail_out > 0: break # We're also done if we got a Z_STREAM_END (which should # only occur when flush == Z_FINISH). if err == Z_STREAM_END: break else: continue elif err == Z_BUF_ERROR: avail_out = rffi.cast(lltype.Signed, stream.c_avail_out) # When compressing, we will only get Z_BUF_ERROR if # the output buffer was full but there wasn't more # output when we tried again, so it is not an error # condition. if avail_out == bufsize: break # fallback case: report this error raise RZlibError.fromstream(stream, err, while_doing) # When decompressing, if the compressed stream of data was truncated, # then the zlib simply returns Z_OK and waits for more. If it is # complete it returns Z_STREAM_END. return (result.build(), err, rffi.cast(lltype.Signed, stream.c_avail_in))
def PyBuffer_FillInfo(space, view, obj, buf, length, readonly, flags): """ Fills in a buffer-info structure correctly for an exporter that can only share a contiguous chunk of memory of "unsigned bytes" of the given length. Returns 0 on success and -1 (with raising an error) on error. This is not a complete re-implementation of the CPython API; it only provides a subset of CPython's behavior. """ if flags & PyBUF_WRITABLE and readonly: raise OperationError(space.w_ValueError, space.wrap("Object is not writable")) view.c_buf = buf view.c_len = length view.c_obj = obj Py_IncRef(space, obj) view.c_itemsize = 1 rffi.setintfield(view, "c_readonly", readonly) rffi.setintfield(view, "c_ndim", 0) view.c_format = lltype.nullptr(rffi.CCHARP.TO) view.c_shape = lltype.nullptr(Py_ssize_tP.TO) view.c_strides = lltype.nullptr(Py_ssize_tP.TO) view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO) view.c_internal = lltype.nullptr(rffi.VOIDP.TO) return 0
def realize_global_int(ffi, g, gindex): fetch_fnptr = rffi.cast(FUNCPTR_FETCH_LONGLONG, g.c_address) with lltype.scoped_alloc(parse_c_type.GETCONST_S) as p_value: p_value.c_ctx = ffi.ctxobj.ctx rffi.setintfield(p_value, 'c_gindex', gindex) neg = fetch_fnptr(p_value) value = p_value.c_value neg = rffi.cast(lltype.Signed, neg) if neg == 0: # positive if value <= rffi.cast(rffi.ULONGLONG, sys.maxint): return ffi.space.newint(intmask(value)) else: return ffi.space.newint(value) elif neg == 1: # negative value = rffi.cast(rffi.LONGLONG, value) if value >= -sys.maxint - 1: return ffi.space.newint(intmask(value)) else: return ffi.space.newint(value) if neg == 2: got = "%d (0x%x)" % (value, value) else: got = "%d" % (rffi.cast(rffi.LONGLONG, value), ) raise oefmt( ffi.w_FFIError, "the C compiler says '%s' is equal to %s, " "but the cdef disagrees", rffi.charp2str(g.c_name), got)
def parse(input): OUTPUT_SIZE = 100 out = lltype.malloc(rffi.VOIDPP.TO, OUTPUT_SIZE, flavor='raw', track_allocation=False) info = lltype.malloc(parse_c_type.PINFO.TO, flavor='raw', zero=True, track_allocation=False) info.c_ctx = ctx info.c_output = out rffi.setintfield(info, 'c_output_size', OUTPUT_SIZE) for j in range(OUTPUT_SIZE): out[j] = rffi.cast(rffi.VOIDP, -424242) res = parse_c_type.parse_c_type(info, input.encode('ascii')) if res < 0: raise ParseError(rffi.charp2str(info.c_error_message).decode('ascii'), rffi.getintfield(info, 'c_error_location')) assert 0 <= res < OUTPUT_SIZE result = [] for j in range(OUTPUT_SIZE): if out[j] == rffi.cast(rffi.VOIDP, -424242): assert res < j break i = rffi.cast(rffi.SIGNED, out[j]) if j == res: result.append('->') result.append(i) return result
def buffer_attach(space, py_obj, w_obj, w_userdata=None): """ Fills a newly allocated PyBufferObject with the given (str) buffer object. """ py_buf = rffi.cast(PyBufferObject, py_obj) py_buf.c_b_offset = 0 rffi.setintfield(py_buf, 'c_b_readonly', 1) rffi.setintfield(py_buf, 'c_b_hash', -1) assert isinstance(w_obj, W_Buffer) buf = w_obj.buf if isinstance(buf, SubBuffer): py_buf.c_b_offset = buf.offset buf = buf.buffer # If buf already allocated a fixed buffer, use it, and keep a # reference to buf. # Otherwise, b_base stays NULL, and we own the b_ptr. if isinstance(buf, StringBuffer): py_buf.c_b_base = lltype.nullptr(PyObject.TO) py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, rffi.str2charp(buf.value)) py_buf.c_b_size = buf.getlength() elif isinstance(buf, ArrayBuffer): w_base = buf.w_array py_buf.c_b_base = make_ref(space, w_base) py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, buf.w_array._charbuf_start()) py_buf.c_b_size = buf.getlength() else: raise oefmt(space.w_NotImplementedError, "buffer flavor not supported")
def memory_attach(space, py_obj, w_obj, w_userdata=None): """ Fills a newly allocated PyMemoryViewObject with the given W_MemoryView object. """ assert isinstance(w_obj, W_MemoryView) py_obj = rffi.cast(PyMemoryViewObject, py_obj) view = py_obj.c_view ndim = w_obj.getndim() if ndim >= Py_MAX_NDIMS: # XXX warn? return fill_Py_buffer(space, w_obj.view, view) try: view.c_buf = rffi.cast(rffi.VOIDP, w_obj.view.get_raw_address()) # not used in PyPy to keep something alive, # but some c-extensions check the type without checking for NULL view.c_obj = make_ref(space, space.w_None) rffi.setintfield(view, 'c_readonly', rffi.cast(rffi.INT_real, w_obj.view.readonly)) except ValueError: w_s = w_obj.descr_tobytes(space) view.c_obj = make_ref(space, w_s) view.c_buf = rffi.cast( rffi.VOIDP, rffi.str2charp(space.bytes_w(w_s), track_allocation=False)) rffi.setintfield(view, 'c_readonly', 1)
def _operate(stream, data, flush, max_length, cfunc, while_doing): """Common code for compress() and decompress(). """ # Prepare the input buffer for the stream with lltype.scoped_alloc(rffi.CCHARP.TO, len(data)) as inbuf: # XXX (groggi) should be possible to improve this with pinning by # not performing the 'copy_string_to_raw' if non-movable/pinned copy_string_to_raw(llstr(data), inbuf, 0, len(data)) stream.c_next_in = rffi.cast(Bytefp, inbuf) rffi.setintfield(stream, 'c_avail_in', len(data)) # Prepare the output buffer with lltype.scoped_alloc(rffi.CCHARP.TO, OUTPUT_BUFFER_SIZE) as outbuf: # Strategy: we call deflate() to get as much output data as fits in # the buffer, then accumulate all output into a StringBuffer # 'result'. result = StringBuilder() while True: stream.c_next_out = rffi.cast(Bytefp, outbuf) bufsize = OUTPUT_BUFFER_SIZE if max_length < bufsize: if max_length <= 0: err = Z_OK break bufsize = max_length max_length -= bufsize rffi.setintfield(stream, 'c_avail_out', bufsize) err = cfunc(stream, flush) if err == Z_OK or err == Z_STREAM_END: # accumulate data into 'result' avail_out = rffi.cast(lltype.Signed, stream.c_avail_out) result.append_charpsize(outbuf, bufsize - avail_out) # if the output buffer is full, there might be more data # so we need to try again. Otherwise, we're done. if avail_out > 0: break # We're also done if we got a Z_STREAM_END (which should # only occur when flush == Z_FINISH). if err == Z_STREAM_END: break else: continue elif err == Z_BUF_ERROR: avail_out = rffi.cast(lltype.Signed, stream.c_avail_out) # When compressing, we will only get Z_BUF_ERROR if # the output buffer was full but there wasn't more # output when we tried again, so it is not an error # condition. if avail_out == bufsize: break # fallback case: report this error raise RZlibError.fromstream(stream, err, while_doing) # When decompressing, if the compressed stream of data was truncated, # then the zlib simply returns Z_OK and waits for more. If it is # complete it returns Z_STREAM_END. return (result.build(), err, rffi.cast(lltype.Signed, stream.c_avail_in))
def select(space, w_iwtd, w_owtd, w_ewtd, w_timeout): """Wait until one or more file descriptors are ready for some kind of I/O. The first three arguments are sequences of file descriptors to be waited for: rlist -- wait until ready for reading wlist -- wait until ready for writing xlist -- wait for an ``exceptional condition'' If only one kind of condition is required, pass [] for the other lists. A file descriptor is either a socket or file object, or a small integer gotten from a fileno() method call on one of those. The optional 4th argument specifies a timeout in seconds; it may be a floating point number to specify fractions of seconds. If it is absent or None, the call will never time out. The return value is a tuple of three lists corresponding to the first three arguments; each contains the subset of the corresponding file descriptors that are ready. *** IMPORTANT NOTICE *** On Windows, only sockets are supported; on Unix, all file descriptors. """ iwtd_w = space.listview(w_iwtd) owtd_w = space.listview(w_owtd) ewtd_w = space.listview(w_ewtd) if space.is_w(w_timeout, space.w_None): timeout = -1.0 else: timeout = space.float_w(w_timeout) ll_inl = lltype.nullptr(_c.fd_set.TO) ll_outl = lltype.nullptr(_c.fd_set.TO) ll_errl = lltype.nullptr(_c.fd_set.TO) ll_timeval = lltype.nullptr(_c.timeval) try: if len(iwtd_w) > 0: ll_inl = lltype.malloc(_c.fd_set.TO, flavor='raw') if len(owtd_w) > 0: ll_outl = lltype.malloc(_c.fd_set.TO, flavor='raw') if len(ewtd_w) > 0: ll_errl = lltype.malloc(_c.fd_set.TO, flavor='raw') if timeout >= 0.0: ll_timeval = rffi.make(_c.timeval) i = int(timeout) rffi.setintfield(ll_timeval, 'c_tv_sec', i) rffi.setintfield(ll_timeval, 'c_tv_usec', int((timeout-i)*1000000)) # Call this as a separate helper to avoid a large piece of code # in try:finally:. Needed for calling further _always_inline_ # helpers like _build_fd_set(). return _call_select(space, iwtd_w, owtd_w, ewtd_w, ll_inl, ll_outl, ll_errl, ll_timeval) finally: if ll_timeval: lltype.free(ll_timeval, flavor='raw') if ll_errl: lltype.free(ll_errl, flavor='raw') if ll_outl: lltype.free(ll_outl, flavor='raw') if ll_inl: lltype.free(ll_inl, flavor='raw')
def draw_pixel(self, x, y, color): color = self.colors[color] start_x = x * self.scale start_y = y * self.scale dstrect = self.blit_rect rffi.setintfield(dstrect, 'c_x', start_x) rffi.setintfield(dstrect, 'c_y', start_y) RSDL.FillRect(self.screen, dstrect, color)
def frame_attach(space, py_obj, w_obj, w_userdata=None): "Fills a newly allocated PyFrameObject with a frame object" frame = space.interp_w(PyFrame, w_obj) py_frame = rffi.cast(PyFrameObject, py_obj) py_frame.c_f_code = rffi.cast(PyCodeObject, make_ref(space, frame.pycode)) py_frame.c_f_globals = make_ref(space, frame.get_w_globals()) py_frame.c_f_locals = make_ref(space, frame.get_w_locals()) rffi.setintfield(py_frame, 'c_f_lineno', frame.getorcreatedebug().f_lineno)
def timeval_from_double(d, timeval): c_tv_sec = int(d) c_tv_usec = int((d - int(d)) * 1000000) # Don't disable the timer if the computation above rounds down to zero. if d > 0.0 and c_tv_sec == 0 and c_tv_usec == 0: c_tv_usec = 1 rffi.setintfield(timeval, 'c_tv_sec', c_tv_sec) rffi.setintfield(timeval, 'c_tv_usec', c_tv_usec)
def mktime(tup): buf = _gettmarg(tup) rffi.setintfield(buf, "c_tm_wday", -1) tt = c_mktime(buf) if tt == -1 and rffi.getintfield(buf, "c_tm_wday") == -1: raise Exception('mktime argument out of range') return float(tt)
def unregister_sock(self, sock): assert isinstance(sock, s.Socket) del self.sockets[sock.fd] with lltype.scoped_alloc(epoll_event) as ev: ev.c_events = rffi.cast(rffi.UINT, 0) rffi.setintfield(ev.c_data, 'c_fd', sock.fd) if epoll_ctl(self.fd, EPOLL_CTL_DEL, sock.fd, ev) < 0: raise rsocket.last_error()
def clock_settime(space, clk_id, secs): with lltype.scoped_alloc(TIMESPEC) as timespec: integer_secs = rffi.cast(TIMESPEC.c_tv_sec, secs) frac = secs - widen(integer_secs) rffi.setintfield(timespec, 'c_tv_sec', integer_secs) rffi.setintfield(timespec, 'c_tv_nsec', int(frac * 1e9)) ret = c_clock_settime(clk_id, timespec) if ret != 0: raise exception_from_saved_errno(space, space.w_OSError)
def from_in6_addr(in6_addr): result = instantiate(INET6Address) # store the malloc'ed data into 'result' as soon as possible # to avoid leaks if an exception occurs inbetween sin = lltype.malloc(_c.sockaddr_in6, flavor="raw", zero=True, track_allocation=False) result.setdata(sin, sizeof(_c.sockaddr_in6)) rffi.setintfield(sin, "c_sin6_family", AF_INET6) rffi.structcopy(sin.c_sin6_addr, in6_addr) return result
def register_sock(self, sock, flags): assert isinstance(sock, s.Socket) assert isinstance(flags, data.UInt) self.sockets[sock.fd] = sock with lltype.scoped_alloc(epoll_event) as ev: ev.c_events = rffi.cast(rffi.UINT, flags.n) rffi.setintfield(ev.c_data, 'c_fd', sock.fd) if epoll_ctl(self.fd, EPOLL_CTL_ADD, sock.fd, ev) < 0: raise rsocket.last_error()
def test_dont_do_superfluous_flag_writes(): with lltype.scoped_alloc(capi.MEM) as pMem: rffi.setintfield(pMem, 'flags', CConfig.MEM_Int) pMem.u.i = 17 pMem.u.r = 2.3 mem = Mem(FakeHLQuery(), pMem, 0) assert mem.get_flags() == CConfig.MEM_Int mem.pMem = None mem.set_flags(CConfig.MEM_Int) # works, because unnecessary
def _call_select(space, iwtd_w, owtd_w, ewtd_w, ll_inl, ll_outl, ll_errl, ll_timeval, timeout): fdlistin = fdlistout = fdlisterr = None nfds = -1 if ll_inl: fdlistin, nfds = _build_fd_set(space, iwtd_w, ll_inl, nfds) if ll_outl: fdlistout, nfds = _build_fd_set(space, owtd_w, ll_outl, nfds) if ll_errl: fdlisterr, nfds = _build_fd_set(space, ewtd_w, ll_errl, nfds) if ll_timeval: end_time = timeutils.monotonic(space) + timeout else: end_time = 0.0 while True: if ll_timeval: i = int(timeout) rffi.setintfield(ll_timeval, 'c_tv_sec', i) rffi.setintfield(ll_timeval, 'c_tv_usec', int((timeout - i) * 1000000)) res = _c.select(nfds + 1, ll_inl, ll_outl, ll_errl, ll_timeval) if res >= 0: break # normal path err = _c.geterrno() if err != errno.EINTR: msg = _c.socket_strerror_unicode(err) raise OperationError( space.w_OSError, space.newtuple([space.newint(err), space.newunicode(msg)])) # got EINTR, automatic retry space.getexecutioncontext().checksignals() if timeout > 0.0: timeout = end_time - timeutils.monotonic(space) if timeout < 0.0: timeout = 0.0 resin_w = [] resout_w = [] reserr_w = [] if res > 0: if fdlistin is not None: _unbuild_fd_set(space, iwtd_w, fdlistin, ll_inl, resin_w) if fdlistout is not None: _unbuild_fd_set(space, owtd_w, fdlistout, ll_outl, resout_w) if fdlisterr is not None: _unbuild_fd_set(space, ewtd_w, fdlisterr, ll_errl, reserr_w) return space.newtuple([ space.newlist(resin_w), space.newlist(resout_w), space.newlist(reserr_w) ])
def select(inl, outl, excl, timeout=-1.0): nfds = 0 if inl: ll_inl = lltype.malloc(_c.fd_set.TO, flavor='raw') _c.FD_ZERO(ll_inl) for i in inl: _c.FD_SET(i, ll_inl) if i > nfds: nfds = i else: ll_inl = lltype.nullptr(_c.fd_set.TO) if outl: ll_outl = lltype.malloc(_c.fd_set.TO, flavor='raw') _c.FD_ZERO(ll_outl) for i in outl: _c.FD_SET(i, ll_outl) if i > nfds: nfds = i else: ll_outl = lltype.nullptr(_c.fd_set.TO) if excl: ll_excl = lltype.malloc(_c.fd_set.TO, flavor='raw') _c.FD_ZERO(ll_excl) for i in excl: _c.FD_SET(i, ll_excl) if i > nfds: nfds = i else: ll_excl = lltype.nullptr(_c.fd_set.TO) if timeout != -1.0: ll_timeval = rffi.make(_c.timeval) rffi.setintfield(ll_timeval, 'c_tv_sec', int(timeout)) rffi.setintfield(ll_timeval, 'c_tv_usec', int((timeout-int(timeout)) * 1000000)) else: ll_timeval = lltype.nullptr(_c.timeval) try: res = _c.select(nfds + 1, ll_inl, ll_outl, ll_excl, ll_timeval) if res == -1: raise SelectError(_c.geterrno()) if res == 0: return ([], [], []) else: return ( [i for i in inl if _c.FD_ISSET(i, ll_inl)], [i for i in outl if _c.FD_ISSET(i, ll_outl)], [i for i in excl if _c.FD_ISSET(i, ll_excl)]) finally: if ll_inl: lltype.free(ll_inl, flavor='raw') if ll_outl: lltype.free(ll_outl, flavor='raw') if ll_excl: lltype.free(ll_excl, flavor='raw') if ll_timeval: lltype.free(ll_timeval, flavor='raw')
def makeipv4addr(s_addr, result=None): if result is None: result = instantiate(INETAddress) elif result.family != AF_INET: raise RSocketError("address family mismatched") sin = lltype.malloc(_c.sockaddr_in, flavor="raw", zero=True, track_allocation=False) result.setdata(sin, sizeof(_c.sockaddr_in)) rffi.setintfield(sin, "c_sin_family", AF_INET) # PLAT sin_len rffi.setintfield(sin.c_sin_addr, "c_s_addr", s_addr) return result
def make_null_address(family): klass = familyclass(family) result = instantiate(klass) buf = lltype.malloc(rffi.CCHARP.TO, klass.maxlen, flavor="raw", zero=True, track_allocation=False) # Initialize the family to the correct value. Avoids surprizes on # Windows when calling a function that unexpectedly does not set # the output address (e.g. recvfrom() on a connected IPv4 socket). rffi.setintfield(rffi.cast(_c.sockaddr_ptr, buf), "c_sa_family", family) result.setdata(buf, 0) return result, klass.maxlen
def code_attach(space, py_obj, w_obj): py_code = rffi.cast(PyCodeObject, py_obj) assert isinstance(w_obj, PyCode) py_code.c_co_name = make_ref(space, space.wrap(w_obj.co_name)) co_flags = 0 for name, value in ALL_CODE_FLAGS: if w_obj.co_flags & getattr(pycode, name): co_flags |= value rffi.setintfield(py_code, 'c_co_flags', co_flags) rffi.setintfield(py_code, 'c_co_argcount', w_obj.co_argcount)
def tcpConnect(stream, address, port, callback): connect = alloc_connect() rffi.setintfield(sin, "c_sin_family", s.AF_INET) rffi.setintfield(sin, "c_sin_port", s.htons(port)) if inet_pton(s.AF_INET, address, sin.c_sin_addr): print "tcpConnect: inet_pton failed!?" assert False rv = check("tcp_connect", tcp_connect(connect, stream, sin, callback)) return rv
def from_in6_addr(in6_addr): result = instantiate(INET6Address) # store the malloc'ed data into 'result' as soon as possible # to avoid leaks if an exception occurs inbetween sin = lltype.malloc(_c.sockaddr_in6, flavor='raw', zero=True, track_allocation=False) result.setdata(sin, sizeof(_c.sockaddr_in6)) rffi.setintfield(sin, 'c_sin6_family', AF_INET6) rffi.structcopy(sin.c_sin6_addr, in6_addr) return result
def tcpBind(stream, address, port): rffi.setintfield(sin, "c_sin_family", s.AF_INET) rffi.setintfield(sin, "c_sin_port", s.htons(port)) if inet_pton(s.AF_INET, address, sin.c_sin_addr): print "tcpBind: inet_pton failed!?" assert False # No flags. rv = check("tcp_bind", tcp_bind(stream, sin, 0)) return rv
def allocate_ctxobj(src_ctx): p = lltype.malloc(PCTXOBJ.TO, flavor='raw', zero=True) if src_ctx: rffi.c_memcpy(rffi.cast(rffi.VOIDP, p.ctx), rffi.cast(rffi.VOIDP, src_ctx), rffi.cast(rffi.SIZE_T, rffi.sizeof(PCTX.TO))) p.info.c_ctx = p.ctx p.info.c_output = internal_output rffi.setintfield(p.info, 'c_output_size', FFI_COMPLEXITY_OUTPUT) return p
def epoll_ctl(self, space, ctl, w_fd, eventmask, ignore_ebadf=False): fd = space.c_filedescriptor_w(w_fd) with lltype.scoped_alloc(epoll_event) as ev: ev.c_events = rffi.cast(rffi.UINT, eventmask) rffi.setintfield(ev.c_data, 'c_fd', fd) result = epoll_ctl(self.epfd, ctl, fd, ev) if ignore_ebadf and get_errno() == errno.EBADF: result = 0 if result < 0: raise exception_from_errno(space, space.w_IOError)
def posix_fakeimpl(arg): if s_arg == traits.str0: arg = hlstr(arg) st = getattr(os, name)(arg) fields = [TYPE for fieldname, TYPE in STATVFS_FIELDS] TP = TUPLE_TYPE(fields) ll_tup = lltype.malloc(TP.TO) for i, (fieldname, TYPE) in enumerate(STATVFS_FIELDS): val = getattr(st, fieldname) rffi.setintfield(ll_tup, 'item%d' % i, int(val)) return ll_tup
def make_null_address(family): klass = familyclass(family) result = instantiate(klass) buf = lltype.malloc(rffi.CCHARP.TO, klass.maxlen, flavor='raw', zero=True, track_allocation=False) # Initialize the family to the correct value. Avoids surprizes on # Windows when calling a function that unexpectedly does not set # the output address (e.g. recvfrom() on a connected IPv4 socket). rffi.setintfield(rffi.cast(_c.sockaddr_ptr, buf), 'c_sa_family', family) result.setdata(buf, 0) return result, klass.maxlen
def traceback_attach(space, py_obj, w_obj): py_traceback = rffi.cast(PyTracebackObject, py_obj) traceback = space.interp_w(PyTraceback, w_obj) if traceback.next is None: w_next_traceback = None else: w_next_traceback = space.wrap(traceback.next) py_traceback.c_tb_next = rffi.cast(PyTracebackObject, make_ref(space, w_next_traceback)) py_traceback.c_tb_frame = rffi.cast(PyFrameObject, make_ref(space, space.wrap(traceback.frame))) rffi.setintfield(py_traceback, 'c_tb_lasti', traceback.lasti) rffi.setintfield(py_traceback, 'c_tb_lineno',traceback.get_lineno())
def stub_videoresize_event(stub_event, monkeypatch): p_test_resize_event = rffi.cast(RSDL.ResizeEventPtr, stub_event) rffi.setintfield(p_test_resize_event, 'c_type', RSDL.VIDEORESIZE) def PollEvent_stub(p_event): p_event.c_type = p_test_resize_event.c_type p_resizeevent = rffi.cast(RSDL.ResizeEventPtr, p_event) p_resizeevent.c_w = p_test_resize_event.c_w p_resizeevent.c_h = p_test_resize_event.c_h return 1 monkeypatch.setattr(RSDL, "PollEvent", PollEvent_stub) return p_test_resize_event
def makeipv4addr(s_addr, result=None): if result is None: result = instantiate(INETAddress) elif result.family != AF_INET: raise RSocketError("address family mismatched") sin = lltype.malloc(_c.sockaddr_in, flavor='raw', zero=True, track_allocation=False) result.setdata(sin, sizeof(_c.sockaddr_in)) rffi.setintfield(sin, 'c_sin_family', AF_INET) # PLAT sin_len rffi.setintfield(sin.c_sin_addr, 'c_s_addr', s_addr) return result
def epoll_ctl(self, space, ctl, w_fd, eventmask, ignore_ebadf=False): fd = space.c_filedescriptor_w(w_fd) with lltype.scoped_alloc(epoll_event) as ev: ev.c_events = rffi.cast(rffi.UINT, eventmask) rffi.setintfield(ev.c_data, 'c_fd', fd) result = epoll_ctl(self.epfd, ctl, fd, ev) if ignore_ebadf and get_saved_errno() == errno.EBADF: result = 0 if result < 0: raise exception_from_saved_errno(space, space.w_IOError)
def tcp6Connect(stream, address, port, callback): inet, sin, s_addr, s_fam, s_port = af6 connect = alloc_connect() rffi.setintfield(sin, s_fam, inet) rffi.setintfield(sin, s_port, s.htons(port)) if inet_pton(inet, address, getattr(sin, s_addr)): print "tcp6Connect: inet_pton failed!?" assert False rv = check("tcp_connect", tcp_connect(connect, stream, sin, callback)) return rv
def test_unknown_addr_as_object(): from pypy.module._socket.interp_socket import addr_as_object c_addr = lltype.malloc(rsocket._c.sockaddr, flavor='raw', track_allocation=False) c_addr.c_sa_data[0] = 'c' rffi.setintfield(c_addr, 'c_sa_family', 15) # XXX what size to pass here? for the purpose of this test it has # to be short enough so we have some data, 1 sounds good enough # + sizeof USHORT w_obj = addr_as_object(rsocket.Address(c_addr, 1 + 2), -1, space) assert space.isinstance_w(w_obj, space.w_tuple) assert space.int_w(space.getitem(w_obj, space.wrap(0))) == 15 assert space.str_w(space.getitem(w_obj, space.wrap(1))) == 'c'
def tcp6Bind(stream, address, port): inet, sin, s_addr, s_fam, s_port = af6 rffi.setintfield(sin, s_fam, inet) rffi.setintfield(sin, s_port, s.htons(port)) if inet_pton(inet, address, getattr(sin, s_addr)): print "tcp6Bind: inet_pton failed!?" assert False # No flags. rv = check("tcp_bind", tcp_bind(stream, sin, 0)) return rv