def wrap_getbuffer(space, w_self, w_args, func): func_target = rffi.cast(getbufferproc, func) with lltype.scoped_alloc(Py_buffer) as pybuf: _flags = 0 if space.len_w(w_args) > 0: _flags = space.int_w(space.listview(w_args)[0]) flags = rffi.cast(rffi.INT_real,_flags) size = generic_cpy_call(space, func_target, w_self, pybuf, flags) if widen(size) < 0: space.fromcache(State).check_and_raise_exception(always=True) ptr = pybuf.c_buf size = pybuf.c_len ndim = widen(pybuf.c_ndim) shape = [pybuf.c_shape[i] for i in range(ndim)] if pybuf.c_strides: strides = [pybuf.c_strides[i] for i in range(ndim)] else: strides = [1] if pybuf.c_format: format = rffi.charp2str(pybuf.c_format) else: format = 'B' return space.newbuffer(CPyBuffer(ptr, size, w_self, format=format, ndim=ndim, shape=shape, strides=strides, itemsize=pybuf.c_itemsize, readonly=widen(pybuf.c_readonly)))
def read( self, start_addr, num_bytes ): assert 0 < num_bytes <= 4 word = start_addr >> 2 byte = start_addr & 0b11 if self.debug.enabled( "mem" ): print ':: RD.MEM[%s] = ' % pad_hex( start_addr ), if self.debug.enabled( "memcheck" ): self.bounds_check( start_addr, 'RD' ) value = 0 if num_bytes == 4: # TODO: byte should only be 0 (only aligned) value = widen( self.data[ word ] ) elif num_bytes == 2: # TODO: byte should only be 0, 1, 2, not 3 mask = 0xFFFF << (byte * 8) value = ( widen( self.data[ word ] ) & mask) >> (byte * 8) elif num_bytes == 1: mask = 0xFF << (byte * 8) value = ( widen( self.data[ word ] ) & mask) >> (byte * 8) else: raise Exception('Invalid num_bytes: %d!' % num_bytes) if self.debug.enabled( "mem" ): print '%s' % pad_hex( value ), return value
def write( self, start_addr, num_bytes, value ): assert 0 < num_bytes <= 4 word = start_addr >> 2 byte = start_addr & 0b11 if self.debug.enabled( "memcheck" ): self.bounds_check( start_addr, 'WR' ) if num_bytes == 4: # TODO: byte should only be 0 (only aligned) pass # no masking needed elif num_bytes == 2: # TODO: byte should only be 0, 1, 2, not 3 mask = ~(0xFFFF << (byte * 8)) & 0xFFFFFFFF value = ( widen( self.data[ word ] ) & mask ) \ | ( (value & 0xFFFF) << (byte * 8) ) elif num_bytes == 1: mask = ~(0xFF << (byte * 8)) & 0xFFFFFFFF value = ( widen( self.data[ word ] ) & mask ) \ | ( (value & 0xFF ) << (byte * 8) ) else: raise Exception('Invalid num_bytes: %d!' % num_bytes) if self.debug.enabled( "mem" ): print ':: WR.MEM[%s] = %s' % ( pad_hex( start_addr ), pad_hex( value ) ), self.data[ word ] = r_uint32( value )
def gettimeofday(space, w_info=None): if HAVE_GETTIMEOFDAY: with lltype.scoped_alloc(TIMEVAL) as timeval: if GETTIMEOFDAY_NO_TZ: errcode = c_gettimeofday(timeval) else: void = lltype.nullptr(rffi.VOIDP.TO) errcode = c_gettimeofday(timeval, void) if rffi.cast(rffi.LONG, errcode) == 0: if w_info is not None: _setinfo(space, w_info, "gettimeofday()", 1e-6, False, True) return space.newfloat( widen(timeval.c_tv_sec) + widen(timeval.c_tv_usec) * 1e-6) if HAVE_FTIME: with lltype.scoped_alloc(TIMEB) as t: c_ftime(t) result = (widen(t.c_time) + widen(t.c_millitm) * 0.001) if w_info is not None: _setinfo(space, w_info, "ftime()", 1e-3, False, True) return space.newfloat(result) else: if w_info: _setinfo(space, w_info, "time()", 1.0, False, True) return space.newint(c_time(lltype.nullptr(rffi.TIME_TP.TO)))
def write(self, start_addr, num_bytes, value): assert 0 < num_bytes <= 4 start_addr = r_uint(start_addr) value = r_uint(value) word = start_addr >> 2 byte = start_addr & 0b11 if self.debug.enabled("memcheck") and not self.suppress_debug: self.bounds_check(start_addr, 'WR') if num_bytes == 4: # TODO: byte should only be 0 (only aligned) pass # no masking needed elif num_bytes == 2: # TODO: byte should only be 0, 1, 2, not 3 mask = ~(0xFFFF << (byte * 8)) & r_uint(0xFFFFFFFF) value = ( widen( self.data[ word ] ) & mask ) \ | ( (value & 0xFFFF) << (byte * 8) ) elif num_bytes == 1: mask = ~(0xFF << (byte * 8)) & r_uint(0xFFFFFFFF) value = ( widen( self.data[ word ] ) & mask ) \ | ( (value & 0xFF ) << (byte * 8) ) else: raise Exception('Invalid num_bytes: %d!' % num_bytes) if self.debug.enabled("mem") and not self.suppress_debug: print ':: WR.MEM[%s] = %s' % (pad_hex(start_addr), pad_hex(value)), self.data[word] = r_uint32(value)
def memory_realize(space, obj): """ Creates the memory object in the interpreter """ py_mem = rffi.cast(PyMemoryViewObject, obj) view = py_mem.c_view ndim = widen(view.c_ndim) shape = None if view.c_shape: shape = [view.c_shape[i] for i in range(ndim)] strides = None if view.c_strides: strides = [view.c_strides[i] for i in range(ndim)] format = 'B' if view.c_format: format = rffi.charp2str(view.c_format) buf = CPyBuffer(space, view.c_buf, view.c_len, from_ref(space, view.c_obj), format=format, shape=shape, strides=strides, ndim=ndim, itemsize=view.c_itemsize, readonly=widen(view.c_readonly)) # Ensure view.c_buf is released upon object finalization fq.register_finalizer(buf) # Allow subclassing W_MemeoryView w_type = from_ref(space, rffi.cast(PyObject, obj.c_ob_type)) w_obj = space.allocate_instance(W_MemoryView, w_type) w_obj.__init__(buf) track_reference(space, obj, w_obj) return w_obj
def read(self, start_addr, num_bytes): assert 0 < num_bytes <= 4 start_addr = r_uint(start_addr) word = start_addr >> 2 byte = start_addr & 0b11 if self.debug.enabled("mem") and not self.suppress_debug: print ':: RD.MEM[%s] = ' % pad_hex(start_addr), if self.debug.enabled("memcheck") and not self.suppress_debug: self.bounds_check(start_addr, 'RD') value = 0 if num_bytes == 4: # TODO: byte should only be 0 (only aligned) value = widen(self.data[word]) elif num_bytes == 2: # TODO: byte should only be 0, 1, 2, not 3 mask = 0xFFFF << (byte * 8) value = (widen(self.data[word]) & mask) >> (byte * 8) elif num_bytes == 1: mask = 0xFF << (byte * 8) value = (widen(self.data[word]) & mask) >> (byte * 8) else: raise Exception('Invalid num_bytes: %d!' % num_bytes) if self.debug.enabled("mem"): print '%s' % pad_hex(value), return r_uint(value)
def type_dealloc(space, py_obj): from pypy.module.cpyext.object import _dealloc state = space.fromcache(State) # cannot raise here, so just crash assert len(state.datetimeAPI) > 0 if state.datetimeAPI[0].c_TimeType == py_obj.c_ob_type: py_datetime = rffi.cast(PyDateTime_Time, py_obj) if (widen(py_datetime.c_hastzinfo) != 0): decref(space, py_datetime.c_tzinfo) elif state.datetimeAPI[0].c_DateTimeType == py_obj.c_ob_type: py_datetime = rffi.cast(PyDateTime_DateTime, py_obj) if (widen(py_datetime.c_hastzinfo) != 0): decref(space, py_datetime.c_tzinfo) _dealloc(space, py_obj)
def pthread_kill(space, tid, signum): "Send a signal to a thread." ret = c_pthread_kill(tid, signum) if widen(ret) < 0: raise exception_from_saved_errno(space, space.w_OSError) # the signal may have been send to the current thread space.getexecutioncontext().checksignals()
def PyObject_GetBuffer(space, w_obj, view, flags): """Export obj into a Py_buffer, view. These arguments must never be NULL. The flags argument is a bit field indicating what kind of buffer the caller is prepared to deal with and therefore what kind of buffer the exporter is allowed to return. The buffer interface allows for complicated memory sharing possibilities, but some caller may not be able to handle all the complexity but may want to see if the exporter will let them take a simpler view to its memory. Some exporters may not be able to share memory in every possible way and may need to raise errors to signal to some consumers that something is just not possible. These errors should be a BufferError unless there is another error that is actually causing the problem. The exporter can use flags information to simplify how much of the Py_buffer structure is filled in with non-default values and/or raise an error if the object can't support a simpler view of its memory. 0 is returned on success and -1 on error.""" flags = widen(flags) buf = space.buffer_w(w_obj, flags) try: view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address()) except ValueError: raise BufferError("could not create buffer from object") ret = fill_Py_buffer(space, buf, view) view.c_obj = make_ref(space, w_obj) return ret
def setupterm(space, w_termname=None, fd=-1): _fd = fd if fd == -1: w_stdout = space.getattr(space.getbuiltinmodule('sys'), space.newtext('stdout')) _fd = space.int_w( space.call_function( space.getattr(w_stdout, space.newtext('fileno')))) if space.is_none(w_termname): termname = None termname_err = 'None' else: termname = space.text_w(w_termname) termname_err = "'%s'" % termname p_errret = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') try: with rffi.scoped_str2charp(termname) as ll_term: _fd = rffi.cast(rffi.INT, _fd) errval = fficurses.setupterm(ll_term, _fd, p_errret) if errval == -1: errret = widen(p_errret[0]) if errret == 0: msg_ext = 'could not find terminal' elif errret == -1: msg_ext = 'could not find termininfo database' else: msg_ext = 'unknown error' msg = ("setupterm(%s, %d) failed (err=%d): %s" % (termname_err, fd, errret, msg_ext)) raise curses_error(space, msg) finally: lltype.free(p_errret, flavor='raw') space.fromcache(ModuleInfo).setupterm_called = True
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 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. """ flags = widen(flags) if flags & PyBUF_WRITABLE and readonly: raise oefmt(space.w_ValueError, "Object is not writable") view.c_buf = buf view.c_len = length view.c_obj = obj if obj: incref(space, obj) view.c_itemsize = 1 rffi.setintfield(view, 'c_readonly', readonly) rffi.setintfield(view, 'c_ndim', 1) view.c_format = lltype.nullptr(rffi.CCHARP.TO) if (flags & PyBUF_FORMAT) == PyBUF_FORMAT: # NB: this needs to be a static string, because nothing frees it view.c_format = DEFAULT_FMT view.c_shape = lltype.nullptr(Py_ssize_tP.TO) if (flags & PyBUF_ND) == PyBUF_ND: view.c_shape = rffi.cast(Py_ssize_tP, view.c__shape) view.c_shape[0] = view.c_len view.c_strides = lltype.nullptr(Py_ssize_tP.TO) if (flags & PyBUF_STRIDES) == PyBUF_STRIDES: view.c_strides = rffi.cast(Py_ssize_tP, view.c__strides) view.c_strides[0] = view.c_itemsize view.c_suboffsets = lltype.nullptr(Py_ssize_tP.TO) view.c_internal = lltype.nullptr(rffi.VOIDP.TO) return 0
def PyNumber_ToBase(space, w_obj, base): """Returns the integer n converted to base as a string with a base marker of '0b', '0o', or '0x' if applicable. When base is not 2, 8, 10, or 16, the format is 'x#num' where x is the base. If n is not an int object, it is converted with PyNumber_Index() first. """ base = widen(base) if not (base == 2 or base == 8 or base == 10 or base == 16): # In Python3.7 this becomes a SystemError. Before that, CPython would # assert in debug or segfault in release. bpo 38643 raise oefmt(space.w_ValueError, "PyNumber_ToBase: base must be 2, 8, 10 or 16") w_index = space.index(w_obj) # A slight hack to call the internal _*_to_base method, which # accepts an int base rather than a str spec formatter = newformat.str_formatter(space, '') try: value = space.int_w(w_index) except OperationError as e: if not e.match(space, space.w_OverflowError): raise value = space.bigint_w(w_index) return space.newtext(formatter._long_to_base(base, value)) return space.newtext(formatter._int_to_base(base, value))
def wrap_lenfunc(space, w_self, w_args, func): func_len = rffi.cast(lenfunc, func) check_num_args(space, w_args, 0) res = generic_cpy_call(space, func_len, w_self) if widen(res) == -1: space.fromcache(State).check_and_raise_exception(always=True) return space.newint(res)
def wrap_getbuffer(space, w_self, w_args, func): func_target = rffi.cast(getbufferproc, func) py_obj = make_ref(space, w_self) py_type = py_obj.c_ob_type rbp = rffi.cast(rffi.VOIDP, 0) if py_type.c_tp_as_buffer: rbp = rffi.cast(rffi.VOIDP, py_type.c_tp_as_buffer.c_bf_releasebuffer) decref(space, py_obj) with lltype.scoped_alloc(Py_buffer) as pybuf: _flags = 0 if space.len_w(w_args) > 0: _flags = space.int_w(space.listview(w_args)[0]) flags = rffi.cast(rffi.INT_real, _flags) size = generic_cpy_call(space, func_target, w_self, pybuf, flags) if widen(size) < 0: space.fromcache(State).check_and_raise_exception(always=True) ptr = pybuf.c_buf size = pybuf.c_len ndim = widen(pybuf.c_ndim) shape = None if pybuf.c_shape: shape = [pybuf.c_shape[i] for i in range(ndim)] strides = None if pybuf.c_strides: strides = [pybuf.c_strides[i] for i in range(ndim)] if pybuf.c_format: format = rffi.charp2str(pybuf.c_format) else: format = 'B' # the CPython docs mandates that you do an incref whenever you call # bf_getbuffer; so, we pass needs_decref=True to ensure that we don't # leak we release the buffer: # https://docs.python.org/3.5/c-api/typeobj.html#c.PyBufferProcs.bf_getbuffer buf = CPyBuffer(space, ptr, size, w_self, format=format, ndim=ndim, shape=shape, strides=strides, itemsize=pybuf.c_itemsize, readonly=widen(pybuf.c_readonly), needs_decref=True, releasebufferproc=rbp) fq.register_finalizer(buf) return space.newbuffer(buf)
def wrap(self, x): "Wraps the Python value 'x' into one of the wrapper classes." # You might notice that this function is rather conspicuously # not RPython. We can get away with this because the function # is specialized (see after the function body). Also worth # noting is that the isinstance's involving integer types # behave rather differently to how you might expect during # annotation (see pypy/annotation/builtin.py) if x is None: return self.w_None if isinstance(x, OperationError): raise TypeError, ("attempt to wrap already wrapped exception: %s"% (x,)) if isinstance(x, int): if isinstance(x, bool): return self.newbool(x) else: return self.newint(x) if isinstance(x, str): # this hack is temporary: look at the comment in # test_stdstdobjspace.test_wrap_string try: unicode_x = x.decode('ascii') except UnicodeDecodeError: # poor man's x.decode('ascii', 'replace'), since it's not # supported by RPython if not we_are_translated(): print 'WARNING: space.wrap() called on a non-ascii byte string: %r' % x lst = [] for ch in x: ch = ord(ch) if ch > 127: lst.append(u'\ufffd') else: lst.append(unichr(ch)) unicode_x = u''.join(lst) return wrapunicode(self, unicode_x) if isinstance(x, unicode): return wrapunicode(self, x) if isinstance(x, float): return W_FloatObject(x) if isinstance(x, W_Root): w_result = x.__spacebind__(self) #print 'wrapping', x, '->', w_result return w_result if isinstance(x, base_int): if self.config.objspace.std.withsmalllong: from pypy.objspace.std.smalllongobject import W_SmallLongObject from rpython.rlib.rarithmetic import r_longlong, r_ulonglong from rpython.rlib.rarithmetic import longlongmax if (not isinstance(x, r_ulonglong) or x <= r_ulonglong(longlongmax)): return W_SmallLongObject(r_longlong(x)) x = widen(x) if isinstance(x, int): return self.newint(x) else: return W_LongObject.fromrarith_int(x) return self._wrap_not_rpython(x)
def PyType_GetSlot(space, typ, slot): """ Use the Py_tp* macros in typeslots.h to return a slot function """ slot = widen(slot) if slot < 0 or not typ.c_tp_flags & Py_TPFLAGS_HEAPTYPE: raise oefmt(space.w_SystemError, "Bad internal call!") heapobj = rffi.cast(PyHeapTypeObject, typ) return get_ht_slot(heapobj, slot)
def call(self, space, w_self, __args__): self.check_args(__args__, 0) func = self.get_func_to_call() func_len = rffi.cast(lenfunc, func) res = generic_cpy_call(space, func_len, w_self) if widen(res) == -1: space.fromcache(State).check_and_raise_exception(always=True) return space.newint(res)
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 _ll_zero_or_null(item): # Check if 'item' is zero/null, or not. T = typeOf(item) if T is Char or T is UniChar: check = ord(item) elif isinstance(T, Number): check = widen(item) else: check = item return not check
def call(self, space, __args__): func = llapi.cts.cast("HPyFunc_lenfunc", self.cfuncptr) self.check_args(space, __args__, 1) ctx = space.fromcache(State).ctx w_self = __args__.arguments_w[0] with handles.using(space, w_self) as h_self: result = func(ctx, h_self) if widen(result) == -1: raise NotImplementedError('write a test') return space.newint(result)
def memory_dealloc(space, py_obj): mem_obj = rffi.cast(PyMemoryViewObject, py_obj) view = mem_obj.c_view if view.c_obj: decref(space, view.c_obj) view.c_obj = rffi.cast(PyObject, 0) flags = widen(view.c_flags) if flags & FORMAT_ALLOCATED == FORMAT_ALLOCATED: lltype.free(view.c_format, flavor='raw') _dealloc(space, py_obj)
def get_handle_inheritable(handle): assert lltype.typeOf(handle) is HANDLE pflags = lltype.malloc(LPDWORD.TO, 1, flavor='raw') try: if not _GetHandleInformation(handle, pflags): raise lastSavedWindowsError("GetHandleInformation") flags = widen(pflags[0]) finally: lltype.free(pflags, flavor='raw') return (flags & HANDLE_FLAG_INHERIT) != 0
def pack_float(pack_obj, fmtdesc, count): for _ in xrange(count): value = pack_obj.space.float_w(pack_obj.pop_arg()) floatval = r_singlefloat(value) value = longlong2float.singlefloat2uint(floatval) value = widen(value) for i in range(fmtdesc.size): pack_obj.result.append(chr(value & 0xff)) value >>= 8
def PyMemoryView_GetContiguous(space, w_obj, buffertype, order): """ Return a new memoryview object based on a contiguous exporter with buffertype={PyBUF_READ, PyBUF_WRITE} and order={'C', 'F'ortran, or 'A'ny}. The logical structure of the input and output buffers is the same (i.e. tolist(input) == tolist(output)), but the physical layout in memory can be explicitly chosen. As usual, if buffertype=PyBUF_WRITE, the exporter's buffer must be writable, otherwise it may be writable or read-only. If the exporter is already contiguous with the desired target order, the memoryview will be directly based on the exporter. Otherwise, if the buffertype is PyBUF_READ, the memoryview will be based on a new bytes object. If order={'C', 'A'ny}, use 'C' order, 'F'ortran order otherwise. """ buffertype = widen(buffertype) if buffertype != PyBUF_READ and buffertype != PyBUF_WRITE: raise oefmt(space.w_ValueError, "buffertype must be PyBUF_READ or PyBUF_WRITE") if order != 'C' and order != 'F' and order != 'A': raise oefmt(space.w_ValueError, "order must be in ('C', 'F', 'A')") w_mv = space.call_method(space.builtin, "memoryview", w_obj) mv = make_ref(space, w_mv) mv = rffi.cast(PyMemoryViewObject, mv) view = mv.c_view if buffertype == PyBUF_WRITE and widen(view.c_readonly): raise oefmt(space.w_BufferError, "underlying buffer is not writable") if PyBuffer_IsContiguous(space, view, order): return w_mv if buffertype == PyBUF_WRITE: raise oefmt( space.w_BufferError, "writable contiguous buffer requested " "for a non-contiguous object.") return memory_from_contiguous_copy(space, view, order)
def pack_float(fmtiter): doubleval = fmtiter.accept_float_arg() floatval = r_singlefloat(doubleval) if std.pack_fastpath(rffi.FLOAT)(fmtiter, floatval): return # slow path value = longlong2float.singlefloat2uint(floatval) value = widen(value) value = intmask(value) pack_float_to_buffer(fmtiter.wbuf, fmtiter.pos, value, 4, fmtiter.bigendian) fmtiter.advance(4)
def clock(space, w_info=None): """clock() -> floating point number Return the CPU time or real time since the start of the process or since the first call to clock(). This has as much precision as the system records.""" if _WIN: try: return win_perf_counter(space, w_info=w_info) except ValueError: pass value = widen(_clock()) if value == widen(rffi.cast(rposix.CLOCK_T, -1)): raise oefmt( space.w_RuntimeError, "the processor time used is not available or its value" "cannot be represented") if w_info is not None: _setinfo(space, w_info, "clock()", 1.0 / CLOCKS_PER_SEC, True, False) return space.newfloat(float(value) / CLOCKS_PER_SEC)
def call(self, space, __args__): func = llapi.cts.cast("HPyFunc_objobjproc", self.cfuncptr) self.check_args(space, __args__, 2) ctx = space.fromcache(State).ctx w_self = __args__.arguments_w[0] w_key = __args__.arguments_w[1] with handles.using(space, w_self, w_key) as (h_self, h_key): res = func(ctx, h_self, h_key) res = widen(res) if res == -1: raise NotImplementedError('write a test') return space.newbool(bool(res))
def call(self, space, __args__): func = llapi.cts.cast("HPyFunc_ssizeobjargproc", self.cfuncptr) self.check_args(space, __args__, 2) ctx = space.fromcache(State).ctx w_self = __args__.arguments_w[0] w_idx = __args__.arguments_w[1] idx = sq_getindex(space, w_self, w_idx) with handles.using(space, w_self) as h_self: result = func(ctx, h_self, idx, llapi.HPy_NULL) if widen(result) == -1: raise NotImplementedError('write a test') return space.w_None
def newint(self, intval): if self.config.objspace.std.withsmalllong and isinstance(intval, base_int): from pypy.objspace.std.smalllongobject import W_SmallLongObject from rpython.rlib.rarithmetic import r_longlong, r_ulonglong from rpython.rlib.rarithmetic import longlongmax if (not isinstance(intval, r_ulonglong) or intval <= r_ulonglong(longlongmax)): return W_SmallLongObject(r_longlong(intval)) intval = widen(intval) if not isinstance(intval, int): return W_LongObject.fromrarith_int(intval) return wrapint(self, intval)
def pack_float(fmtiter): doubleval = fmtiter.accept_float_arg() floatval = r_singlefloat(doubleval) value = longlong2float.singlefloat2uint(floatval) value = widen(value) if fmtiter.bigendian: for i in range_4_unroll: x = (value >> (8*i)) & 0xff fmtiter.result.append(chr(x)) else: for i in range_4_unroll: fmtiter.result.append(chr(value & 0xff)) value >>= 8
def pack_float(fmtiter): doubleval = fmtiter.accept_float_arg() floatval = r_singlefloat(doubleval) value = longlong2float.singlefloat2uint(floatval) value = widen(value) if fmtiter.bigendian: for i in range_4_unroll: x = (value >> (8 * i)) & 0xff fmtiter.result.append(chr(x)) else: for i in range_4_unroll: fmtiter.result.append(chr(value & 0xff)) value >>= 8
def PyMemoryView_FromMemory(space, mem, size, flags): """Expose a raw memory area as a view of contiguous bytes. flags can be PyBUF_READ or PyBUF_WRITE. view->format is set to "B" (unsigned bytes). The memoryview has complete buffer information. """ readonly = int(widen(flags) == PyBUF_WRITE) view = CPyBuffer(space, cts.cast('void*', mem), size, None, readonly=readonly) w_mview = W_MemoryView(view) return w_mview
def _IsCContiguous(view): ndim = widen(view.c_ndim) if ndim == 0: return 1 if not view.c_strides: return ndim == 1 sd = view.c_itemsize if ndim == 1: return view.c_shape[0] == 1 or sd == view.c_strides[0] for i in range(ndim - 1, -1, -1): dim = view.c_shape[i] if dim == 0: return 1 if view.c_strides[i] != sd: return 0 sd *= dim return 1
def getitem(self, item): if count < 2: v = raw_storage_getitem(TP, self.values, item * self.stride_size + self.start) else: v = [] for i in range(count): _v = raw_storage_getitem(TP, self.values, item * self.stride_size + self.start + step * i) v.append(_v) if comp_type == 'int': v = widen(v) elif comp_type == 'float': v = float(v) elif comp_type == 'complex': v = [float(v[0]),float(v[1])] else: raise NotImplementedError('cannot reach') return (v)
def buff_w(space, w_self, view, flags): args = Arguments(space, [space.newint(flags)]) w_obj = space.call_args(space.get(buff_fn, w_self), args) if view: #like PyObject_GetBuffer flags = widen(flags) buf = space.buffer_w(w_obj, flags) try: view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address()) view.c_obj = make_ref(space, w_obj) except ValueError: w_s = space.newbytes(buf.as_str()) view.c_obj = make_ref(space, w_s) view.c_buf = rffi.cast(rffi.VOIDP, rffi.str2charp( space.str_w(w_s), track_allocation=False)) rffi.setintfield(view, 'c_readonly', 1) ret = fill_Py_buffer(space, buf, view) return ret return 0
def ll_alloc_and_set(LIST, count, item): if count < 0: count = 0 l = LIST.ll_newlist(count) T = typeOf(item) if T is Char or T is UniChar: check = ord(item) elif isinstance(T, Number): check = widen(item) else: check = item # as long as malloc is known to zero the allocated memory avoid zeroing # twice if jit.we_are_jitted() or (not malloc_zero_filled) or check: i = 0 while i < count: l.ll_setitem_fast(i, item) i += 1 return l
def _mul_helper(space, self, w_repeat, is_inplace): try: repeat = space.getindex_w(w_repeat, space.w_OverflowError) except OperationError as e: if e.match(space, space.w_TypeError): return space.w_NotImplemented raise repeat = max(repeat, 0) try: newlen = ovfcheck(self.len * repeat) except OverflowError: raise MemoryError oldlen = self.len if is_inplace: a = self start = 1 else: a = mytype.w_class(space) start = 0 # <a performance hack> if oldlen == 1: if mytype.unwrap == 'str_w' or mytype.unwrap == 'unicode_w': zero = not ord(self.buffer[0]) elif mytype.unwrap == 'int_w' or mytype.unwrap == 'bigint_w': zero = not widen(self.buffer[0]) #elif mytype.unwrap == 'float_w': # value = ...float(self.buffer[0]) xxx handle the case of -0.0 else: zero = False if zero: a.setlen(newlen, zero=True, overallocate=False) return a a.setlen(newlen, overallocate=False) item = self.buffer[0] for r in range(start, repeat): a.buffer[r] = item return a # </a performance hack> a.setlen(newlen, overallocate=False) for r in range(start, repeat): for i in range(oldlen): a.buffer[r * oldlen + i] = self.buffer[i] return a
def getpwuid(space, w_uid): """ getpwuid(uid) -> (pw_name,pw_passwd,pw_uid, pw_gid,pw_gecos,pw_dir,pw_shell) Return the password database entry for the given numeric user ID. See pwd.__doc__ for more on password database entries. """ msg = "getpwuid(): uid not found" try: uid = uid_converter(space, w_uid) except OperationError as e: if e.match(space, space.w_OverflowError): raise oefmt(space.w_KeyError, msg) raise pw = c_getpwuid(uid) if not pw: raise OperationError(space.w_KeyError, space.wrap( "%s: %d" % (msg, widen(uid)))) return make_struct_passwd(space, pw)
def wrap(self, x): "Wraps the Python value 'x' into one of the wrapper classes." # You might notice that this function is rather conspicuously # not RPython. We can get away with this because the function # is specialized (see after the function body). Also worth # noting is that the isinstance's involving integer types # behave rather differently to how you might expect during # annotation (see pypy/annotation/builtin.py) if x is None: return self.w_None if isinstance(x, OperationError): raise TypeError, ("attempt to wrap already wrapped exception: %s"% (x,)) if isinstance(x, int): if isinstance(x, bool): return self.newbool(x) else: return self.newint(x) if isinstance(x, str): return wrapstr(self, x) if isinstance(x, unicode): return wrapunicode(self, x) if isinstance(x, float): return W_FloatObject(x) if isinstance(x, W_Root): w_result = x.__spacebind__(self) #print 'wrapping', x, '->', w_result return w_result if isinstance(x, base_int): if self.config.objspace.std.withsmalllong: from pypy.objspace.std.smalllongobject import W_SmallLongObject from rpython.rlib.rarithmetic import r_longlong, r_ulonglong from rpython.rlib.rarithmetic import longlongmax if (not isinstance(x, r_ulonglong) or x <= r_ulonglong(longlongmax)): return W_SmallLongObject(r_longlong(x)) x = widen(x) if isinstance(x, int): return self.newint(x) else: return W_LongObject.fromrarith_int(x) return self._wrap_not_rpython(x)
newlen = ovfcheck(self.len * repeat) except OverflowError: raise MemoryError oldlen = self.len if is_inplace: a = self start = 1 else: a = mytype.w_class(space) start = 0 # <a performance hack> if oldlen == 1: if mytype.unwrap == 'str_w' or mytype.unwrap == 'unicode_w': zero = not ord(self.buffer[0]) elif mytype.unwrap == 'int_w' or mytype.unwrap == 'bigint_w': zero = not widen(self.buffer[0]) #elif mytype.unwrap == 'float_w': # value = ...float(self.buffer[0]) xxx handle the case of -0.0 else: zero = False if zero: a.setlen(newlen, zero=True, overallocate=False) return a a.setlen(newlen, overallocate=False) item = self.buffer[0] for r in range(start, repeat): a.buffer[r] = item return a # </a performance hack> a.setlen(newlen, overallocate=False) for r in range(start, repeat):
def make_array(mytype): W_ArrayBase = globals()['W_ArrayBase'] class W_Array(W_ArrayBase): itemsize = mytype.bytes typecode = mytype.typecode _attrs_ = ('space', 'len', 'allocated', '_lifeline_', 'buffer') def __init__(self, space): W_ArrayBase.__init__(self, space) self.buffer = lltype.nullptr(mytype.arraytype) def item_w(self, w_item): space = self.space unwrap = getattr(space, mytype.unwrap) item = unwrap(w_item) if mytype.unwrap == 'bigint_w': try: item = item.touint() except (ValueError, OverflowError): msg = 'unsigned %d-byte integer out of range' % \ mytype.bytes raise OperationError(space.w_OverflowError, space.wrap(msg)) return rffi.cast(mytype.itemtype, item) if mytype.unwrap == 'str_w' or mytype.unwrap == 'unicode_w': if len(item) != 1: msg = 'array item must be char' raise OperationError(space.w_TypeError, space.wrap(msg)) item = item[0] return rffi.cast(mytype.itemtype, item) # # "regular" case: it fits in an rpython integer (lltype.Signed) result = rffi.cast(mytype.itemtype, item) if mytype.canoverflow: if rffi.cast(lltype.Signed, result) != item: # overflow. build the correct message if item < 0: msg = ('signed %d-byte integer is less than minimum' % mytype.bytes) else: msg = ('signed %d-byte integer is greater than maximum' % mytype.bytes) if not mytype.signed: msg = 'un' + msg # 'signed' => 'unsigned' raise OperationError(space.w_OverflowError, space.wrap(msg)) return result def __del__(self): # note that we don't call clear_all_weakrefs here because # an array with freed buffer is ok to see - it's just empty with 0 # length self.setlen(0) def setlen(self, size, zero=False, overallocate=True): if size > 0: if size > self.allocated or size < self.allocated / 2: if overallocate: if size < 9: some = 3 else: some = 6 some += size >> 3 else: some = 0 self.allocated = size + some if zero: new_buffer = lltype.malloc(mytype.arraytype, self.allocated, flavor='raw', add_memory_pressure=True, zero=True) else: new_buffer = lltype.malloc(mytype.arraytype, self.allocated, flavor='raw', add_memory_pressure=True) for i in range(min(size, self.len)): new_buffer[i] = self.buffer[i] else: self.len = size return else: assert size == 0 self.allocated = 0 new_buffer = lltype.nullptr(mytype.arraytype) if self.buffer: lltype.free(self.buffer, flavor='raw') self.buffer = new_buffer self.len = size def fromsequence(self, w_seq): space = self.space oldlen = self.len try: new = space.len_w(w_seq) self.setlen(self.len + new) except OperationError: pass i = 0 try: if mytype.typecode == 'u': myiter = space.unpackiterable else: myiter = space.listview for w_i in myiter(w_seq): if oldlen + i >= self.len: self.setlen(oldlen + i + 1) self.buffer[oldlen + i] = self.item_w(w_i) i += 1 except OperationError: self.setlen(oldlen + i) raise self.setlen(oldlen + i) def extend(self, w_iterable, accept_different_array=False): space = self.space if isinstance(w_iterable, W_Array): oldlen = self.len new = w_iterable.len self.setlen(self.len + new) i = 0 while i < new: if oldlen + i >= self.len: self.setlen(oldlen + i + 1) self.buffer[oldlen + i] = w_iterable.buffer[i] i += 1 self.setlen(oldlen + i) elif (not accept_different_array and isinstance(w_iterable, W_ArrayBase)): msg = "can only extend with array of same kind" raise OperationError(space.w_TypeError, space.wrap(msg)) else: self.fromsequence(w_iterable) def _charbuf_start(self): return rffi.cast(rffi.CCHARP, self.buffer) def _buffer_as_unsigned(self): return rffi.cast(lltype.Unsigned, self.buffer) def _charbuf_stop(self): keepalive_until_here(self) def w_getitem(self, space, idx): item = self.buffer[idx] if mytype.typecode in 'bBhHil': item = rffi.cast(lltype.Signed, item) elif mytype.typecode == 'f': item = float(item) return space.wrap(item) # interface def descr_append(self, space, w_x): x = self.item_w(w_x) self.setlen(self.len + 1) self.buffer[self.len - 1] = x # List interface def descr_count(self, space, w_val): cnt = 0 for i in range(self.len): # XXX jitdriver w_item = self.w_getitem(space, i) if space.is_true(space.eq(w_item, w_val)): cnt += 1 return space.wrap(cnt) def descr_index(self, space, w_val): for i in range(self.len): w_item = self.w_getitem(space, i) if space.is_true(space.eq(w_item, w_val)): return space.wrap(i) msg = 'array.index(x): x not in list' raise OperationError(space.w_ValueError, space.wrap(msg)) def descr_reverse(self, space): b = self.buffer for i in range(self.len / 2): b[i], b[self.len - i - 1] = b[self.len - i - 1], b[i] def descr_pop(self, space, i): if i < 0: i += self.len if i < 0 or i >= self.len: msg = 'pop index out of range' raise OperationError(space.w_IndexError, space.wrap(msg)) w_val = self.w_getitem(space, i) while i < self.len - 1: self.buffer[i] = self.buffer[i + 1] i += 1 self.setlen(self.len - 1) return w_val def descr_remove(self, space, w_val): w_idx = self.descr_index(space, w_val) self.descr_pop(space, space.int_w(w_idx)) def descr_insert(self, space, idx, w_val): if idx < 0: idx += self.len if idx < 0: idx = 0 if idx > self.len: idx = self.len val = self.item_w(w_val) self.setlen(self.len + 1) i = self.len - 1 while i > idx: self.buffer[i] = self.buffer[i - 1] i -= 1 self.buffer[i] = val def getitem_slice(self, space, w_idx): start, stop, step, size = space.decode_index4(w_idx, self.len) w_a = mytype.w_class(self.space) w_a.setlen(size, overallocate=False) assert step != 0 j = 0 for i in range(start, stop, step): w_a.buffer[j] = self.buffer[i] j += 1 return w_a def setitem(self, space, w_idx, w_item): idx, stop, step = space.decode_index(w_idx, self.len) if step != 0: msg = 'can only assign array to array slice' raise OperationError(self.space.w_TypeError, self.space.wrap(msg)) item = self.item_w(w_item) self.buffer[idx] = item def setitem_slice(self, space, w_idx, w_item): if not isinstance(w_item, W_Array): raise OperationError(space.w_TypeError, space.wrap( "can only assign to a slice array")) start, stop, step, size = self.space.decode_index4(w_idx, self.len) assert step != 0 if w_item.len != size or self is w_item: # XXX this is a giant slow hack w_lst = self.descr_tolist(space) w_item = space.call_method(w_item, 'tolist') space.setitem(w_lst, w_idx, w_item) self.setlen(0) self.fromsequence(w_lst) else: j = 0 for i in range(start, stop, step): self.buffer[i] = w_item.buffer[j] j += 1 # We can't look into this function until ptradd works with things (in the # JIT) other than rffi.CCHARP @jit.dont_look_inside def delitem(self, space, i, j): if i < 0: i += self.len if i < 0: i = 0 if j < 0: j += self.len if j < 0: j = 0 if j > self.len: j = self.len if i >= j: return None oldbuffer = self.buffer self.buffer = lltype.malloc(mytype.arraytype, max(self.len - (j - i), 0), flavor='raw', add_memory_pressure=True) if i: rffi.c_memcpy( rffi.cast(rffi.VOIDP, self.buffer), rffi.cast(rffi.VOIDP, oldbuffer), i * mytype.bytes ) if j < self.len: rffi.c_memcpy( rffi.cast(rffi.VOIDP, rffi.ptradd(self.buffer, i)), rffi.cast(rffi.VOIDP, rffi.ptradd(oldbuffer, j)), (self.len - j) * mytype.bytes ) self.len -= j - i self.allocated = self.len if oldbuffer: lltype.free(oldbuffer, flavor='raw') # Add and mul methods def descr_add(self, space, w_other): if not isinstance(w_other, W_Array): return space.w_NotImplemented a = mytype.w_class(space) a.setlen(self.len + w_other.len, overallocate=False) for i in range(self.len): a.buffer[i] = self.buffer[i] for i in range(w_other.len): a.buffer[i + self.len] = w_other.buffer[i] return a def descr_inplace_add(self, space, w_other): if not isinstance(w_other, W_Array): return space.w_NotImplemented oldlen = self.len otherlen = w_other.len self.setlen(oldlen + otherlen) for i in range(otherlen): self.buffer[oldlen + i] = w_other.buffer[i] return self def descr_mul(self, space, w_repeat): return _mul_helper(space, self, w_repeat, False) def descr_inplace_mul(self, space, w_repeat): return _mul_helper(space, self, w_repeat, True) def _mul_helper(space, self, w_repeat, is_inplace): try: repeat = space.getindex_w(w_repeat, space.w_OverflowError) except OperationError, e: if e.match(space, space.w_TypeError): return space.w_NotImplemented raise repeat = max(repeat, 0) try: newlen = ovfcheck(self.len * repeat) except OverflowError: raise MemoryError oldlen = self.len if is_inplace: a = self start = 1 else: a = mytype.w_class(space) start = 0 # <a performance hack> if oldlen == 1: if mytype.unwrap == 'str_w' or mytype.unwrap == 'unicode_w': zero = not ord(self.buffer[0]) elif mytype.unwrap == 'int_w' or mytype.unwrap == 'bigint_w': zero = not widen(self.buffer[0]) #elif mytype.unwrap == 'float_w': # value = ...float(self.buffer[0]) xxx handle the case of -0.0 else: zero = False if zero: a.setlen(newlen, zero=True, overallocate=False) return a a.setlen(newlen, overallocate=False) item = self.buffer[0] for r in range(start, repeat): a.buffer[r] = item return a # </a performance hack> a.setlen(newlen, overallocate=False) for r in range(start, repeat): for i in range(oldlen): a.buffer[r * oldlen + i] = self.buffer[i] return a
def float2bits(flt): # See note above for bits2float. We're doing the reverse: # Python Float (64-bit) -> r_singlefloat -> r_uint32 -> Python Int (64-bit) bits = widen(singlefloat2uint(rffi.cast(lltype.SingleFloat, flt))) return bits
getpwuid(uid) -> (pw_name,pw_passwd,pw_uid, pw_gid,pw_gecos,pw_dir,pw_shell) Return the password database entry for the given numeric user ID. See pwd.__doc__ for more on password database entries. """ msg = "getpwuid(): uid not found" try: uid = uid_converter(space, w_uid) except OperationError, e: if e.match(space, space.w_OverflowError): raise oefmt(space.w_KeyError, msg) raise pw = c_getpwuid(uid) if not pw: raise OperationError(space.w_KeyError, space.wrap( "%s: %d" % (msg, widen(uid)))) return make_struct_passwd(space, pw) @unwrap_spec(name=str) def getpwnam(space, name): """ getpwnam(name) -> (pw_name,pw_passwd,pw_uid, pw_gid,pw_gecos,pw_dir,pw_shell) Return the password database entry for the given user name. See pwd.__doc__ for more on password database entries. """ pw = c_getpwnam(name) if not pw: raise oefmt(space.w_KeyError, "getpwnam(): name not found: %s", name) return make_struct_passwd(space, pw)
def iread( self, start_addr, num_bytes ): assert start_addr & 0b11 == 0 # only aligned accesses allowed return widen( self.data[ start_addr >> 2 ] )
def f(i): l = [r_short(0)] * 10 l[i+1] = r_short(3) return rarithmetic.widen(l[i])
def is_enabled(self): return bool(widen(cintf.pypy_faulthandler_is_enabled()))
def getstate(self, space): state = [None] * (rrandom.N + 1) for i in range(rrandom.N): state[i] = space.wrap(widen(self._rnd.state[i])) state[rrandom.N] = space.newlong(self._rnd.index) return space.newtuple(state)