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 # then enough room for the result --- which means at least # sizeof(ffi_arg), according to the ffi docs, but we also # align according to the result type, for cffi issue #531 exchange_offset = self.align_to(exchange_offset, self.rtype) exchange_offset = self.align_arg(exchange_offset) cif_descr.exchange_result = exchange_offset 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 atype = self.atypes[i] exchange_offset = self.align_to(exchange_offset, atype) exchange_offset = self.align_arg(exchange_offset) cif_descr.exchange_args[i] = exchange_offset exchange_offset += rffi.getintfield(atype, 'c_size') # store the exchange data size # we also align it to the next multiple of 8, in an attempt to # work around bugs(?) of libffi (see cffi issue #241) cif_descr.exchange_size = self.align_arg(exchange_offset)
def do_realize_lazy_struct(w_ctype): """This is called by W_CTypeStructOrUnion.force_lazy_struct(). """ assert isinstance(w_ctype, ctypestruct.W_CTypeStructOrUnion) space = w_ctype.space ffi = w_ctype._lazy_ffi s = w_ctype._lazy_s assert w_ctype.size != -1 # not an opaque (but may be -2) assert ffi is not None # still lazy first_field = rffi.getintfield(s, 'c_first_field_index') num_fields = rffi.getintfield(s, 'c_num_fields') fields_w = [None] * num_fields for i in range(num_fields): fld = ffi.ctxobj.ctx.c_fields[first_field + i] field_name = rffi.charp2str(fld.c_name) field_size = rffi.getintfield(fld, 'c_field_size') field_offset = rffi.getintfield(fld, 'c_field_offset') op = rffi.getintfield(fld, 'c_field_type_op') case = getop(op) if case == cffi_opcode.OP_NOOP: fbitsize = -1 # standard field elif case == cffi_opcode.OP_BITFIELD: assert field_size >= 0 fbitsize = field_size
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 __init__(self, ai): self.flags = getintfield(ai, "c_ai_flags") self.socktype = socktypes.get(getintfield(ai, "c_ai_socktype"), u"unknown") # XXX getprotoent(3) self.protocol = getintfield(ai, "c_ai_protocol") self.addr = ruv.IP6Name(ai.c_ai_addr)
def descr_list_types(self): """\ Returns the user type names known to this FFI instance. This returns a tuple containing three lists of names: (typedef_names, names_of_structs, names_of_unions)""" # space = self.space ctx = self.ctxobj.ctx lst1_w = [] for i in range(rffi.getintfield(ctx, 'c_num_typenames')): s = rffi.charp2str(ctx.c_typenames[i].c_name) lst1_w.append(space.newtext(s)) lst2_w = [] lst3_w = [] for i in range(rffi.getintfield(ctx, 'c_num_struct_unions')): su = ctx.c_struct_unions[i] if su.c_name[0] == '$': continue s = rffi.charp2str(su.c_name) if rffi.getintfield(su, 'c_flags') & cffi_opcode.F_UNION: lst_w = lst3_w else: lst_w = lst2_w lst_w.append(space.newtext(s)) return space.newtuple([space.newlist(lst1_w), space.newlist(lst2_w), space.newlist(lst3_w)])
def clock_getres(space, clk_id): with lltype.scoped_alloc(rtime.TIMESPEC) as tp: ret = rtime.c_clock_getres(clk_id, tp) if ret != 0: raise exception_from_saved_errno(space, space.w_IOError) t = float(rffi.getintfield(tp, "c_tv_sec")) + float(rffi.getintfield(tp, "c_tv_nsec")) * 0.000000001 return space.wrap(t)
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 _tm_to_tuple(space, t): time_tuple = [ space.newint(rffi.getintfield(t, 'c_tm_year') + 1900), space.newint(rffi.getintfield(t, 'c_tm_mon') + 1), # want january == 1 space.newint(rffi.getintfield(t, 'c_tm_mday')), space.newint(rffi.getintfield(t, 'c_tm_hour')), space.newint(rffi.getintfield(t, 'c_tm_min')), space.newint(rffi.getintfield(t, 'c_tm_sec')), space.newint( (rffi.getintfield(t, 'c_tm_wday') + 6) % 7), # want monday == 0 space.newint(rffi.getintfield(t, 'c_tm_yday') + 1), # want january, 1 == 1 space.newint(rffi.getintfield(t, 'c_tm_isdst')) ] if HAS_TM_ZONE: # CPython calls PyUnicode_DecodeLocale here should we do the same? tm_zone = decode_utf8(space, rffi.charp2str(t.c_tm_zone), allow_surrogates=True) extra = [ space.newunicode(tm_zone), space.newint(rffi.getintfield(t, 'c_tm_gmtoff')) ] w_time_tuple = space.newtuple(time_tuple + extra) else: w_time_tuple = space.newtuple(time_tuple) w_struct_time = _get_module_object(space, 'struct_time') w_obj = space.call_function(w_struct_time, w_time_tuple) return w_obj
def time_clock_llimpl(): a = lltype.malloc(TIMESPEC, flavor='raw') c_clock_gettime(CLOCK_PROCESS_CPUTIME_ID, a) result = (float(rffi.getintfield(a, 'c_tv_sec')) + float(rffi.getintfield(a, 'c_tv_nsec')) * 0.000000001) lltype.free(a, flavor='raw') return result
def vdbeUnbind(self, i): """ ** Unbind the value bound to variable i in virtual machine p. This is the ** the same as binding a NULL value to the column. If the "i" parameter is ** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK. ** ** A successful evaluation of this routine acquires the mutex on p. ** the mutex is released if any kind of error occurs. ** ** The error code stored in database p->db is overwritten with the return ** value in any case. """ p = self.p if rffi.getintfield(p, 'magic') != CConfig.VDBE_MAGIC_RUN or rffi.getintfield(p, 'pc') >= 0: raise SQPyteException("bind on a busy prepared statement") #: [%s]", p.zSql i -= 1 pVar = self.var_with_index(i) pVar.sqlite3VdbeMemRelease() pVar.set_flags(CConfig.MEM_Null) # sqlite3Error(p->db, SQLITE_OK); # XXX # If the bit corresponding to this variable in Vdbe.expmask is set, then # binding a new value to this variable invalidates the current query plan. # IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host # parameter in the WHERE clause might influence the choice of query plan # for a statement, then the statement will be automatically recompiled, # as if there had been a schema change, on the first sqlite3_step() call # following any change to the bindings of that parameter. if self.get_isPrepareV2() and i < 32: expmask = rffi.getintfield(p, 'expmask') if expmask & (1 << i) or expmask == 0xffffffff: raise SQPyteException("XXX expiry not supported :-(")
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 descr_list_types(self): """\ Returns the user type names known to this FFI instance. This returns a tuple containing three lists of names: (typedef_names, names_of_structs, names_of_unions)""" # space = self.space ctx = self.ctxobj.ctx lst1_w = [] for i in range(rffi.getintfield(ctx, "c_num_typenames")): s = rffi.charp2str(ctx.c_typenames[i].c_name) lst1_w.append(space.wrap(s)) lst2_w = [] lst3_w = [] for i in range(rffi.getintfield(ctx, "c_num_struct_unions")): su = ctx.c_struct_unions[i] if su.c_name[0] == "$": continue s = rffi.charp2str(su.c_name) if rffi.getintfield(su, "c_flags") & cffi_opcode.F_UNION: lst_w = lst3_w else: lst_w = lst2_w lst_w.append(space.wrap(s)) return space.newtuple([space.newlist(lst1_w), space.newlist(lst2_w), space.newlist(lst3_w)])
def handle_keypress(self, c_type, event): self.key = 0 p = rffi.cast(RSDL.KeyboardEventPtr, event) sym = rffi.getintfield(p.c_keysym, 'c_sym') char = rffi.getintfield(p.c_keysym, 'c_unicode') if sym == RSDL.K_DOWN: self.key = 31 elif sym == RSDL.K_LEFT: self.key = 28 elif sym == RSDL.K_RIGHT: self.key = 29 elif sym == RSDL.K_UP: self.key = 30 elif char != 0: chars = unicode_encode_utf_8(unichr(char), 1, "ignore") if len(chars) == 1: asciivalue = ord(chars[0]) if asciivalue >= 32: self.key = asciivalue if self.key == 0 and sym <= 255: self.key = sym interrupt = self.interrupt_key if (interrupt & 0xFF == self.key and interrupt >> 8 == self.get_modifier_mask(0)): raise KeyboardInterrupt
def clock_getres(space, clk_id): with lltype.scoped_alloc(rtime.TIMESPEC) as tp: ret = rtime.c_clock_getres(clk_id, tp) if ret != 0: raise exception_from_saved_errno(space, space.w_IOError) t = (float(rffi.getintfield(tp, 'c_tv_sec')) + float(rffi.getintfield(tp, 'c_tv_nsec')) * 0.000000001) return space.newfloat(t)
def test_clock_getres(self): if not rtime.HAS_CLOCK_GETTIME: py.test.skip("no clock_gettime()") lst = [] with lltype.scoped_alloc(rtime.TIMESPEC) as a1: res = rtime.c_clock_getres(rtime.CLOCK_MONOTONIC, a1) assert res == 0 t = (float(rffi.getintfield(a1, 'c_tv_sec')) + float(rffi.getintfield(a1, 'c_tv_nsec')) * 0.000000001) assert 0.0 < t <= 1.0
def gettimeofday(): now = lltype.malloc(TIMEVALP.TO, 1, flavor='raw') try: res = _gettimeofday(now, None) if res < 0: raise OSError(rposix.get_saved_errno(), "gettimeofday failed") return (rffi.getintfield(now[0], 'c_tv_sec'), rffi.getintfield(now[0], 'c_tv_usec')) finally: lltype.free(now, flavor='raw')
def test_clock_gettime(self): if not rtime.HAS_CLOCK_GETTIME: py.test.skip("no clock_gettime()") lst = [] for i in range(50): with lltype.scoped_alloc(rtime.TIMESPEC) as a1: res = rtime.c_clock_gettime(rtime.CLOCK_MONOTONIC, a1) assert res == 0 t = (float(rffi.getintfield(a1, 'c_tv_sec')) + float(rffi.getintfield(a1, 'c_tv_nsec')) * 0.000000001) lst.append(t) assert lst == sorted(lst)
def _init_python_data(self, use_flag_cache): from sqpyte.mem import Mem nMem = rffi.getintfield(self.p, 'nMem') self._llmem_as_python_list = [self.p.aMem[i] for i in range(nMem + 1)] self._mem_as_python_list = [Mem(self, self.p.aMem[i], i) for i in range(nMem + 1)] nVar = rffi.getintfield(self.p, 'nVar') self._var_as_python_list = [Mem(self, self.p.aVar[i], i + nMem + 1) for i in range(nVar)] self._hlops = [Op(self, self.p.aOp[i], i) for i in range(self.p.nOp)] self.init_mem_cache(use_flag_cache) self.use_translated = opcode.OpcodeStatus(use_flag_cache)
def clock(): if _WIN32: return win_perf_counter() elif HAS_CLOCK_GETTIME and CLOCK_PROCESS_CPUTIME_ID is not None: with lltype.scoped_alloc(TIMESPEC) as a: if c_clock_gettime(CLOCK_PROCESS_CPUTIME_ID, a) == 0: return (float(rffi.getintfield(a, 'c_tv_sec')) + float(rffi.getintfield(a, 'c_tv_nsec')) * 0.000000001) with lltype.scoped_alloc(RUSAGE) as a: c_getrusage(RUSAGE_SELF, a) result = (decode_timeval(a.c_ru_utime) + decode_timeval(a.c_ru_stime)) return result
def get(self): rv = [] event = lltype.malloc(RSDL.Event, flavor='raw') ok = RSDL.PollEvent(event) if ok: c_type = rffi.getintfield(event, 'c_type') if c_type in (RSDL.KEYDOWN, RSDL.KEYUP): p = rffi.cast(RSDL.KeyboardEventPtr, event) c_sym = rffi.getintfield(p.c_keysym, 'c_sym') pyevent = Event(etype=c_type, key=c_sym) rv.append(pyevent) lltype.free(event, flavor='raw') return rv
def monotonic(space, w_info=None): if rffi.getintfield(timebase_info, 'c_denom') == 0: c_mach_timebase_info(timebase_info) time = rffi.cast(lltype.Signed, c_mach_absolute_time()) numer = rffi.getintfield(timebase_info, 'c_numer') denom = rffi.getintfield(timebase_info, 'c_denom') nanosecs = time * numer / denom if w_info is not None: res = (numer / denom) * 1e-9 _setinfo(space, w_info, "mach_absolute_time()", res, True, False) secs = nanosecs / 10**9 rest = nanosecs % 10**9 return space.newfloat(float(secs) + float(rest) * 1e-9)
def strftime(space, format, w_tup=None): """strftime(format[, tuple]) -> string Convert a time tuple to a string according to a format specification. See the library reference manual for formatting codes. When the time tuple is not present, current time as returned by localtime() is used.""" buf_value = _gettmarg(space, w_tup) _checktm(space, buf_value) # Normalize tm_isdst just in case someone foolishly implements %Z # based on the assumption that tm_isdst falls within the range of # [-1, 1] if rffi.getintfield(buf_value, 'c_tm_isdst') < -1: rffi.setintfield(buf_value, 'c_tm_isdst', -1) elif rffi.getintfield(buf_value, 'c_tm_isdst') > 1: rffi.setintfield(buf_value, 'c_tm_isdst', 1) rffi.setintfield(buf_value, "c_tm_year", rffi.getintfield(buf_value, "c_tm_year") - 1900) if _WIN: # check that the format string contains only valid directives length = len(format) i = 0 while i < length: if format[i] == '%': i += 1 if i < length and format[i] == '#': # not documented by python i += 1 if i >= length or format[i] not in "aAbBcdHIjmMpSUwWxXyYzZ%": raise oefmt(space.w_ValueError, "invalid format string") i += 1 i = 1024 while True: outbuf = lltype.malloc(rffi.CCHARP.TO, i, flavor='raw') try: buflen = c_strftime(outbuf, i, format, buf_value) if buflen > 0 or i >= 256 * len(format): # if the buffer is 256 times as long as the format, # it's probably not failing for lack of room! # More likely, the format yields an empty result, # e.g. an empty format, or %Z when the timezone # is unknown. result = rffi.charp2strn(outbuf, intmask(buflen)) return space.newtext(result) finally: lltype.free(outbuf, flavor='raw') i += i
def _gettmarg(tup): if len(tup) != 9: raise Exception("argument must be sequence of length 9, not %d", len(tup)) y = tup[0] tm_mon = tup[1] if tm_mon == 0: tm_mon = 1 tm_mday = tup[2] if tm_mday == 0: tm_mday = 1 tm_yday = tup[7] if tm_yday == 0: tm_yday = 1 rffi.setintfield(glob_buf, 'c_tm_mon', tm_mon) rffi.setintfield(glob_buf, 'c_tm_mday', tm_mday) rffi.setintfield(glob_buf, 'c_tm_hour', tup[3]) rffi.setintfield(glob_buf, 'c_tm_min', tup[4]) rffi.setintfield(glob_buf, 'c_tm_sec', tup[5]) rffi.setintfield(glob_buf, 'c_tm_wday', tup[6]) rffi.setintfield(glob_buf, 'c_tm_yday', tm_yday) rffi.setintfield(glob_buf, 'c_tm_isdst', tup[8]) if _POSIX: if _CYGWIN: pass else: # actually never happens, but makes annotator happy glob_buf.c_tm_zone = lltype.nullptr(rffi.CCHARP.TO) rffi.setintfield(glob_buf, 'c_tm_gmtoff', 0) if y < 1900: if 69 <= y <= 99: y += 1900 elif 0 <= y <= 68: y += 2000 else: raise Exception("year out of range") # tm_wday does not need checking of its upper-bound since taking "% # 7" in gettmarg() automatically restricts the range. if rffi.getintfield(glob_buf, 'c_tm_wday') < -1: raise Exception("day of week out of range") rffi.setintfield(glob_buf, 'c_tm_year', y - 1900) rffi.setintfield(glob_buf, 'c_tm_mon', rffi.getintfield(glob_buf, 'c_tm_mon') - 1) rffi.setintfield(glob_buf, 'c_tm_wday', (rffi.getintfield(glob_buf, 'c_tm_wday') + 1) % 7) rffi.setintfield(glob_buf, 'c_tm_yday', rffi.getintfield(glob_buf, 'c_tm_yday') - 1) return glob_buf
def strftime(space, format, w_tup=None): """strftime(format[, tuple]) -> string Convert a time tuple to a string according to a format specification. See the library reference manual for formatting codes. When the time tuple is not present, current time as returned by localtime() is used.""" buf_value = _gettmarg(space, w_tup) _checktm(space, buf_value) # Normalize tm_isdst just in case someone foolishly implements %Z # based on the assumption that tm_isdst falls within the range of # [-1, 1] if rffi.getintfield(buf_value, 'c_tm_isdst') < -1: rffi.setintfield(buf_value, 'c_tm_isdst', -1) elif rffi.getintfield(buf_value, 'c_tm_isdst') > 1: rffi.setintfield(buf_value, 'c_tm_isdst', 1) if _WIN: # check that the format string contains only valid directives length = len(format) i = 0 while i < length: if format[i] == '%': i += 1 if i < length and format[i] == '#': # not documented by python i += 1 if i >= length or format[i] not in "aAbBcdHIjmMpSUwWxXyYzZ%": raise OperationError(space.w_ValueError, space.wrap("invalid format string")) i += 1 i = 1024 while True: outbuf = lltype.malloc(rffi.CCHARP.TO, i, flavor='raw') try: buflen = c_strftime(outbuf, i, format, buf_value) if buflen > 0 or i >= 256 * len(format): # if the buffer is 256 times as long as the format, # it's probably not failing for lack of room! # More likely, the format yields an empty result, # e.g. an empty format, or %Z when the timezone # is unknown. result = rffi.charp2strn(outbuf, intmask(buflen)) return space.wrap(result) finally: lltype.free(outbuf, flavor='raw') i += i
def handle_keypress(self, c_type, event): self.key = 0 p = rffi.cast(RSDL.KeyboardEventPtr, event) sym = rffi.getintfield(p.c_keysym, 'c_sym') char = rffi.getintfield(p.c_keysym, 'c_unicode') if sym == RSDL.K_DOWN: self.key = key_constants.DOWN elif sym == RSDL.K_LEFT: self.key = key_constants.LEFT elif sym == RSDL.K_RIGHT: self.key = key_constants.RIGHT elif sym == RSDL.K_UP: self.key = key_constants.UP elif sym == RSDL.K_HOME: self.key = key_constants.HOME elif sym == RSDL.K_END: self.key = key_constants.END elif sym == RSDL.K_INSERT: self.key = key_constants.INSERT elif sym == RSDL.K_PAGEUP: self.key = key_constants.PAGEUP elif sym == RSDL.K_PAGEDOWN: self.key = key_constants.PAGEDOWN elif sym == RSDL.K_LSHIFT or sym == RSDL.K_RSHIFT: self.key = key_constants.SHIFT elif sym == RSDL.K_LCTRL or sym == RSDL.K_RCTRL: self.key = key_constants.CTRL elif sym == RSDL.K_LALT or sym == RSDL.K_RALT: self.key = key_constants.COMMAND elif sym == RSDL.K_BREAK: self.key = key_constants.BREAK elif sym == RSDL.K_CAPSLOCK: self.key = key_constants.CAPSLOCK elif sym == RSDL.K_NUMLOCK: self.key = key_constants.NUMLOCK elif sym == RSDL.K_SCROLLOCK: self.key = key_constants.SCROLLOCK elif char != 0: chars = unicode_encode_utf_8(unichr(char), 1, "ignore") if len(chars) == 1: asciivalue = ord(chars[0]) if asciivalue >= 32: self.key = asciivalue if self.key == 0 and sym <= 255: self.key = sym interrupt = self.interrupt_key if (interrupt & 0xFF == self.key and interrupt >> 8 == self.get_modifier_mask(0)): raise KeyboardInterrupt
def _tm_to_tuple(t): time_tuple = ( rffi.getintfield(t, 'c_tm_year') + 1900, rffi.getintfield(t, 'c_tm_mon') + 1, # want january == 1 rffi.getintfield(t, 'c_tm_mday'), rffi.getintfield(t, 'c_tm_hour'), rffi.getintfield(t, 'c_tm_min'), rffi.getintfield(t, 'c_tm_sec'), ((rffi.getintfield(t, 'c_tm_wday') + 6) % 7), # want monday == 0 rffi.getintfield(t, 'c_tm_yday') + 1, # want january, 1 == 1 rffi.getintfield(t, 'c_tm_isdst')) return time_tuple
def parse_string_to_type(self, string, consider_fn_as_fnptr): # This cannot be made @elidable because it calls general space # functions (indirectly, e.g. via the new_xxx_type() functions). # The get_string_to_type() function above is elidable, and we # hope that in almost all cases, get_string_to_type() has already # found an answer. try: x = self.types_dict[string] except KeyError: info = self.ctxobj.info index = parse_c_type.parse_c_type(info, string) if index < 0: num_spaces = rffi.getintfield(info, 'c_error_location') raise oefmt(self.w_FFIError, "%s\n%s\n%s^", rffi.charp2str(info.c_error_message), string, " " * num_spaces) x = realize_c_type.realize_c_type_or_func( self, self.ctxobj.info.c_output, index) assert x is not None if isinstance(x, realize_c_type.W_RawFuncType): x.unwrap_as_fnptr(self) # force it here self.types_dict[string] = x # if isinstance(x, W_CType): return x else: assert isinstance(x, realize_c_type.W_RawFuncType) if consider_fn_as_fnptr: return x.unwrap_as_fnptr_in_elidable() else: raise x.unexpected_fn_type(self)
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 get_protocol(self): a = self.lock(_c.sockaddr_ll) proto = rffi.getintfield(a, 'c_sll_protocol') proto = rffi.cast(rffi.USHORT, proto) res = ntohs(proto) self.unlock() return res
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 descr_dir(self): space = self.space total = rffi.getintfield(self.ctx, 'c_num_globals') g = self.ctx.c_globals names_w = [space.wrap(rffi.charp2str(g[i].c_name)) for i in range(total)] return space.newlist(names_w)
def mktime(space, w_tup): """mktime(tuple) -> floating point number Convert a time tuple in local time to seconds since the Epoch.""" buf = _gettmarg(space, w_tup, allowNone=False) rffi.setintfield(buf, "c_tm_wday", -1) rffi.setintfield(buf, "c_tm_year", rffi.getintfield(buf, "c_tm_year") - 1900) tt = c_mktime(buf) # A return value of -1 does not necessarily mean an error, but tm_wday # cannot remain set to -1 if mktime succeeds. if tt == -1 and rffi.getintfield(buf, "c_tm_wday") == -1: raise oefmt(space.w_OverflowError, "mktime argument out of range") return space.newfloat(float(tt))
def gethost_common(hostname, hostent, addr=None): if not hostent: raise HSocketError(hostname) family = rffi.getintfield(hostent, 'c_h_addrtype') if addr is not None and addr.family != family: raise CSocketError(_c.EAFNOSUPPORT) h_aliases = hostent.c_h_aliases if h_aliases: # h_aliases can be NULL, according to SF #1511317 aliases = rffi.charpp2liststr(h_aliases) else: aliases = [] address_list = [] h_addr_list = hostent.c_h_addr_list i = 0 paddr = h_addr_list[0] while paddr: if family == AF_INET: p = rffi.cast(lltype.Ptr(_c.in_addr), paddr) addr = INETAddress.from_in_addr(p) elif AF_INET6 is not None and family == AF_INET6: p = rffi.cast(lltype.Ptr(_c.in6_addr), paddr) addr = INET6Address.from_in6_addr(p) else: raise RSocketError("unknown address family") address_list.append(addr) i += 1 paddr = h_addr_list[i] return (rffi.charp2str(hostent.c_h_name), aliases, address_list)
def is_modifier_key(self, p_event): p = rffi.cast(RSDL.KeyboardEventPtr, p_event) keycode = rffi.getintfield(p.c_keysym, 'c_sym') return keycode in [RSDL.K_LSHIFT, RSDL.K_RSHIFT, RSDL.K_LCTRL, RSDL.K_RCTRL, RSDL.K_LALT, RSDL.K_RALT, RSDL.K_LMETA, RSDL.K_RMETA, RSDL.K_LSUPER, RSDL.K_RSUPER]
def set_video_mode(self, w, h, d): assert w > 0 and h > 0 assert d in [1, 2, 4, 8, 16, 32] if d < MINIMUM_DEPTH: d = MINIMUM_DEPTH self.width = w self.height = h self.depth = d flags = RSDL.HWPALETTE | RSDL.RESIZABLE | RSDL.ASYNCBLIT | RSDL.DOUBLEBUF self.screen = RSDL.SetVideoMode(w, h, d, flags) if not self.screen: print "Could not open display at depth %d" % d raise RuntimeError elif d == MINIMUM_DEPTH: self.set_squeak_colormap(self.screen) self.bpp = rffi.getintfield(self.screen.c_format, 'c_BytesPerPixel') self.pitch = rffi.getintfield(self.screen, 'c_pitch')
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 make_result_string(self): count_unoccupied = rffi.getintfield(self.bzs, 'c_avail_out') s = self._get_chunk(self.current_size - count_unoccupied) if self.temp: self.temp.append(s) return ''.join(self.temp) else: return s
def get_arg_descr(cpu, ffi_type): from rpython.rlib.jit_libffi import types kind = types.getkind(ffi_type) if kind == 'i' or kind == 'u': size = rffi.getintfield(ffi_type, 'c_size') else: size = 0 return _get_ffi2descr_dict(cpu)[kind, size]
def descr_dir(self): space = self.space total = rffi.getintfield(self.ctx, 'c_num_globals') g = self.ctx.c_globals names_w = [ space.wrap(rffi.charp2str(g[i].c_name)) for i in range(total) ] return space.newlist(names_w)
def decompress(self, data): """decompress(data) -> string Provide more data to the decompressor object. It will return chunks of decompressed data whenever possible. If you try to decompress data after the end of stream is found, EOFError will be raised. If any data was found after the end of stream, it'll be ignored and saved in unused_data attribute.""" if not self.running: raise OperationError( self.space.w_EOFError, self.space.wrap("end of stream was already found")) if data == '': return self.space.wrap('') in_bufsize = len(data) with lltype.scoped_alloc(rffi.CCHARP.TO, in_bufsize) as in_buf: for i in range(in_bufsize): in_buf[i] = data[i] self.bzs.c_next_in = in_buf rffi.setintfield(self.bzs, 'c_avail_in', in_bufsize) with OutBuffer(self.bzs) as out: while True: bzerror = BZ2_bzDecompress(self.bzs) if bzerror == BZ_STREAM_END: if rffi.getintfield(self.bzs, 'c_avail_in') != 0: unused = [ self.bzs.c_next_in[i] for i in range( rffi.getintfield(self.bzs, 'c_avail_in')) ] self.unused_data = "".join(unused) self.running = False break if bzerror != BZ_OK: _catch_bz2_error(self.space, bzerror) if rffi.getintfield(self.bzs, 'c_avail_in') == 0: break elif rffi.getintfield(self.bzs, 'c_avail_out') == 0: out.prepare_next_chunk() res = out.make_result_string() return self.space.wrap(res)
def decompress(self, data): """decompress(data) -> string Provide more data to the decompressor object. It will return chunks of decompressed data whenever possible. If you try to decompress data after the end of stream is found, EOFError will be raised. If any data was found after the end of stream, it'll be ignored and saved in unused_data attribute.""" if not self.running: raise OperationError(self.space.w_EOFError, self.space.wrap("end of stream was already found")) if data == '': return self.space.wrap('') in_bufsize = len(data) with lltype.scoped_alloc(rffi.CCHARP.TO, in_bufsize) as in_buf: for i in range(in_bufsize): in_buf[i] = data[i] self.bzs.c_next_in = in_buf rffi.setintfield(self.bzs, 'c_avail_in', in_bufsize) with OutBuffer(self.bzs) as out: while True: bzerror = BZ2_bzDecompress(self.bzs) if bzerror == BZ_STREAM_END: if rffi.getintfield(self.bzs, 'c_avail_in') != 0: unused = [self.bzs.c_next_in[i] for i in range( rffi.getintfield(self.bzs, 'c_avail_in'))] self.unused_data = "".join(unused) self.running = False break if bzerror != BZ_OK: _catch_bz2_error(self.space, bzerror) if rffi.getintfield(self.bzs, 'c_avail_in') == 0: break elif rffi.getintfield(self.bzs, 'c_avail_out') == 0: out.prepare_next_chunk() res = out.make_result_string() return self.space.wrap(res)
def gmtime(seconds): with lltype.scoped_alloc(rffi.TIME_TP.TO, 1) as t_ref: t_ref[0] = seconds t = c_gmtime(t_ref) return [ rffi.getintfield(t, 'c_tm_sec'), rffi.getintfield(t, 'c_tm_min'), rffi.getintfield(t, 'c_tm_hour'), rffi.getintfield(t, 'c_tm_mday'), rffi.getintfield(t, 'c_tm_mon') + 1, # want january == 1 rffi.getintfield(t, 'c_tm_year') + 1900, (rffi.getintfield(t, 'c_tm_wday') + 6) % 7, # want monday == 0 rffi.getintfield(t, 'c_tm_yday') + 1, # want january, 1 == 1 rffi.getintfield(t, 'c_tm_isdst')]
def get_addr(self): a = self.lock(_c.sockaddr_ll) lgt = rffi.getintfield(a, 'c_sll_halen') d = [] for i in range(lgt): d.append(a.c_sll_addr[i]) res = "".join(d) self.unlock() return res
def get_haddr(self): a = self.lock(_c.sockaddr_ll) lgt = rffi.getintfield(a, 'c_sll_halen') d = [] for i in range(lgt): d.append(a.c_sll_addr[i]) res = "".join(d) self.unlock() return res
def semlock_acquire(self, space, block, w_timeout): if not block: deadline = lltype.nullptr(TIMESPECP.TO) elif space.is_none(w_timeout): deadline = lltype.nullptr(TIMESPECP.TO) else: timeout = space.float_w(w_timeout) sec = int(timeout) nsec = int(1e9 * (timeout - sec) + 0.5) now_sec, now_usec = gettimeofday() deadline = lltype.malloc(TIMESPECP.TO, 1, flavor='raw') rffi.setintfield(deadline[0], 'c_tv_sec', now_sec + sec) rffi.setintfield(deadline[0], 'c_tv_nsec', now_usec * 1000 + nsec) val = (rffi.getintfield(deadline[0], 'c_tv_sec') + rffi.getintfield(deadline[0], 'c_tv_nsec') / 1000000000) rffi.setintfield(deadline[0], 'c_tv_sec', val) val = rffi.getintfield(deadline[0], 'c_tv_nsec') % 1000000000 rffi.setintfield(deadline[0], 'c_tv_nsec', val) try: while True: try: if not block: sem_trywait(self.handle) elif not deadline: sem_wait(self.handle) else: sem_timedwait(self.handle, deadline) except OSError as e: if e.errno == errno.EINTR: # again _check_signals(space) continue elif e.errno in (errno.EAGAIN, errno.ETIMEDOUT): return False raise _check_signals(space) self.last_tid = rthread.get_ident() self.count += 1 return True finally: if deadline: lltype.free(deadline, flavor='raw')
def method_clock_gettime(self, space, clockid, args_w): if len(args_w) > 1: raise space.error(space.w_ArgumentError, "wrong number of arguments (given %d, expected 1..2)" ) if len(args_w) == 1: unit = Coerce.symbol(space, args_w[0]) else: unit = "float_second" if rtime.HAS_CLOCK_GETTIME: with lltype.scoped_alloc(rtime.TIMESPEC) as a: if rtime.c_clock_gettime(clockid, a) == 0: sec = rffi.getintfield(a, 'c_tv_sec') nsec = rffi.getintfield(a, 'c_tv_nsec') else: raise error_for_oserror(space, OSError( errno.EINVAL, "clock_gettime") ) elif clockid == CLOCK_PROCESS_CPUTIME_ID: r = rtime.clock() sec = int(r) nsec = r * 1000000000 else: raise error_for_oserror(space, OSError( errno.EINVAL, "clock_gettime") ) if unit == "float_second": return space.newfloat(sec + nsec * 0.000000001) elif unit == "float_millisecond": return space.newfloat(sec * 1000 + nsec * 0.000001) elif unit == "float_microsecond": return space.newfloat(sec * 1000000 + nsec * 0.001) elif unit == "second": return space.newint(int(sec)) elif unit == "millisecond": return space.newint(int(sec) * 1000) elif unit == "microsecond": return space.newint(sec * 1000000) elif unit == "nanosecond": return space.newint(sec * 1000000000 + int(nsec)) else: raise space.error(space.w_ArgumentError, "unexpected unit: %s" % unit )
def gmtime(seconds): with lltype.scoped_alloc(rffi.TIME_TP.TO, 1) as t_ref: t_ref[0] = seconds t = c_gmtime(t_ref) return [ rffi.getintfield(t, 'c_tm_sec'), rffi.getintfield(t, 'c_tm_min'), rffi.getintfield(t, 'c_tm_hour'), rffi.getintfield(t, 'c_tm_mday'), rffi.getintfield(t, 'c_tm_mon') + 1, # want january == 1 rffi.getintfield(t, 'c_tm_year') + 1900, (rffi.getintfield(t, 'c_tm_wday') + 6) % 7, # want monday == 0 rffi.getintfield(t, 'c_tm_yday') + 1, # want january, 1 == 1 rffi.getintfield(t, 'c_tm_isdst') ]
def realize_c_type_or_func(ffi, opcodes, index): op = opcodes[index] from_ffi = (opcodes == ffi.ctxobj.ctx.c_types) if from_ffi and ffi.cached_types[index] is not None: return ffi.cached_types[index] case = getop(op) if case == cffi_opcode.OP_PRIMITIVE: x = get_primitive_type(ffi, getarg(op)) elif case == cffi_opcode.OP_POINTER: y = realize_c_type_or_func(ffi, opcodes, getarg(op)) if isinstance(y, W_CType): x = newtype.new_pointer_type(ffi.space, y) elif isinstance(y, W_RawFuncType): x = y.unwrap_as_fnptr(ffi) else: raise NotImplementedError elif case == cffi_opcode.OP_ARRAY: x = get_array_type(ffi, opcodes, getarg(op), rffi.cast(rffi.SIGNED, opcodes[index + 1])) elif case == cffi_opcode.OP_OPEN_ARRAY: x = get_array_type(ffi, opcodes, getarg(op), -1) elif case == cffi_opcode.OP_STRUCT_UNION: x = _realize_c_struct_or_union(ffi, getarg(op)) elif case == cffi_opcode.OP_ENUM: x = _realize_c_enum(ffi, getarg(op)) elif case == cffi_opcode.OP_FUNCTION: x = W_RawFuncType(opcodes, index) elif case == cffi_opcode.OP_NOOP: x = realize_c_type_or_func(ffi, opcodes, getarg(op)) elif case == cffi_opcode.OP_TYPENAME: # essential: the TYPENAME opcode resolves the type index looked # up in the 'ctx.c_typenames' array, but it does so in 'ctx.c_types' # instead of in 'opcodes'! type_index = rffi.getintfield(ffi.ctxobj.ctx.c_typenames[getarg(op)], 'c_type_index') x = realize_c_type_or_func(ffi, ffi.ctxobj.ctx.c_types, type_index) else: raise oefmt(ffi.space.w_NotImplementedError, "op=%d", case) if from_ffi: assert ffi.cached_types[index] is None or ffi.cached_types[index] is x ffi.cached_types[index] = x return x