def test_struct_fields(self): longsize = 4 if IS_32_BIT else 8 POINT = lltype.Struct('POINT', ('x', rffi.LONG), ('y', rffi.SHORT), ('z', rffi.VOIDP), ) y_ofs = longsize z_ofs = longsize*2 p = lltype.malloc(POINT, flavor='raw') p.x = 42 p.y = rffi.cast(rffi.SHORT, -1) p.z = rffi.cast(rffi.VOIDP, 0x1234) addr = rffi.cast(rffi.VOIDP, p) assert struct_getfield_int(types.slong, addr, 0) == 42 assert struct_getfield_int(types.sshort, addr, y_ofs) == -1 assert struct_getfield_int(types.pointer, addr, z_ofs) == 0x1234 # struct_setfield_int(types.slong, addr, 0, 43) struct_setfield_int(types.sshort, addr, y_ofs, 0x1234FFFE) # 0x1234 is masked out struct_setfield_int(types.pointer, addr, z_ofs, 0x4321) assert p.x == 43 assert p.y == -2 assert rffi.cast(rffi.LONG, p.z) == 0x4321 # lltype.free(p, flavor='raw')
def getattr(self, space, attr): try: attribute = self.objectType.attributesByName[attr] except KeyError: msg = "ExternalObject has no attribute '%s'" %(attr,) raise OperationError(space.w_AttributeError, space.wrap(msg)) environment = self.objectType.environment scalarvalueindicatorptr = lltype.malloc(rffi.CArrayPtr(roci.OCIInd).TO, 1, flavor='raw') valueindicatorptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, 1, flavor='raw') valueptr = lltype.malloc(rffi.CArrayPtr(roci.dvoidp).TO, 1, flavor='raw') tdoptr = lltype.malloc(rffi.CArrayPtr(roci.OCIType).TO, 1, flavor='raw') nameptr = lltype.malloc(rffi.CArrayPtr(roci.oratext).TO, 1, flavor='raw') nameptr[0] = rffi.str2charp(attr) namelenptr = lltype.malloc(rffi.CArrayPtr(roci.ub4).TO, 1, flavor='raw') namelenptr[0] = rffi.cast(roci.ub4, len(attr)) try: status = roci.OCIObjectGetAttr( environment.handle, environment.errorHandle, self.instance, self.indicator, self.objectType.tdo, nameptr, namelenptr, 1, lltype.nullptr(roci.Ptr(roci.ub4).TO), 0, scalarvalueindicatorptr, valueindicatorptr, valueptr, tdoptr) environment.checkForError( status, "ExternalObject_GetAttributeValue(): getting value") # determine the proper null indicator valueIndicator = valueindicatorptr[0] if not valueIndicator: valueIndicator = rffi.cast(roci.dvoidp, scalarvalueindicatorptr) value = valueptr[0] return convertObject( space, environment, attribute.typeCode, value, valueIndicator, self, attribute.subType) finally: lltype.free(scalarvalueindicatorptr, flavor='raw') lltype.free(valueindicatorptr, flavor='raw') lltype.free(valueptr, flavor='raw') lltype.free(tdoptr, flavor='raw') rffi.free_charp(nameptr[0]) lltype.free(nameptr, flavor='raw') lltype.free(namelenptr, flavor='raw')
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 frame_dealloc(space, py_obj): py_frame = rffi.cast(PyFrameObject, py_obj) py_code = rffi.cast(PyObject, py_frame.c_f_code) Py_DecRef(space, py_code) Py_DecRef(space, py_frame.c_f_globals) from pypy.module.cpyext.object import PyObject_dealloc PyObject_dealloc(space, py_obj)
def hook_malloc_slowpath(self): num_entries = self.addrs[0] - rffi.cast(lltype.Signed, self.addrs) assert num_entries == 5*WORD # 3 initially, plus 2 by the asm frame assert self.addrs[1] == 123456 # unchanged assert self.addrs[2] == 654321 # unchanged frame_addr = self.addrs[3] # pushed by the asm frame assert self.addrs[4] == self.MARKER_FRAME # pushed by the asm frame # from pypy.jit.backend.x86.arch import FORCE_INDEX_OFS addr = rffi.cast(rffi.CArrayPtr(lltype.Signed), frame_addr + FORCE_INDEX_OFS) force_index = addr[0] assert force_index == 43 # in this test: the 2nd call_malloc_nursery # # The callshapes[43] saved above should list addresses both in the # COPY_AREA and in the "normal" stack, where all the 16 values p1-p16 # of test_save_regs_at_correct_place should have been stored. Here # we replace them with new addresses, to emulate a moving GC. shape = self.callshapes[force_index] assert len(shape[1:]) == len(self.should_see) new_objects = [None] * len(self.should_see) for ofs in shape[1:]: assert isinstance(ofs, int) # not a register at all here addr = rffi.cast(rffi.CArrayPtr(lltype.Signed), frame_addr + ofs) contains = addr[0] for j in range(len(self.should_see)): obj = self.should_see[j] if contains == rffi.cast(lltype.Signed, obj): assert new_objects[j] is None # duplicate? break else: assert 0 # the value read from the stack looks random? new_objects[j] = lltype.malloc(self.S1) addr[0] = rffi.cast(lltype.Signed, new_objects[j]) self.should_see[:] = new_objects
def PyUnicode_GetSize(space, ref): if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_unicode: ref = rffi.cast(PyUnicodeObject, ref) return ref.c_size else: w_obj = from_ref(space, ref) return space.len_w(w_obj)
def test_call_stubs(): c0 = GcCache(False) ARGS = [lltype.Char, lltype.Signed] RES = lltype.Char descr1 = get_call_descr(c0, ARGS, RES) def f(a, b): return 'c' call_stub = descr1.call_stub fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) res = call_stub(rffi.cast(lltype.Signed, fnptr), [1, 2], None, None) assert res == ord('c') ARRAY = lltype.GcArray(lltype.Signed) ARGS = [lltype.Float, lltype.Ptr(ARRAY)] RES = lltype.Float def f(a, b): return float(b[0]) + a fnptr = llhelper(lltype.Ptr(lltype.FuncType(ARGS, RES)), f) descr2 = get_call_descr(c0, ARGS, RES) a = lltype.malloc(ARRAY, 3) opaquea = lltype.cast_opaque_ptr(llmemory.GCREF, a) a[0] = 1 res = descr2.call_stub(rffi.cast(lltype.Signed, fnptr), [], [opaquea], [longlong.getfloatstorage(3.5)]) assert longlong.getrealfloat(res) == 4.5
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 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) if isinstance(w_obj, SubBuffer): py_buf.c_b_offset = w_obj.offset w_obj = w_obj.buffer # If w_obj already allocated a fixed buffer, use it, and keep a # reference to w_obj. # Otherwise, b_base stays NULL, and we own the b_ptr. if isinstance(w_obj, StringBuffer): py_buf.c_b_base = lltype.nullptr(PyObject.TO) py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, rffi.str2charp(w_obj.value)) py_buf.c_b_size = w_obj.getlength() elif isinstance(w_obj, ArrayBuffer): w_base = w_obj.array py_buf.c_b_base = make_ref(space, w_base) py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, w_obj.array._charbuf_start()) py_buf.c_b_size = w_obj.getlength() else: raise OperationError(space.w_NotImplementedError, space.wrap( "buffer flavor not supported"))
def wrap_descr_delete(space, w_self, w_args, func): func_target = rffi.cast(descrsetfunc, func) check_num_args(space, w_args, 1) w_obj, = space.fixedview(w_args) res = generic_cpy_call(space, func_target, w_self, w_obj, None) if rffi.cast(lltype.Signed, res) == -1: space.fromcache(State).check_and_raise_exception(always=True)
def _do_call(self, funcsym, ll_args, RESULT): # XXX: check len(args)? ll_result = lltype.nullptr(rffi.CCHARP.TO) if self.restype != types.void: ll_result = lltype.malloc(rffi.CCHARP.TO, intmask(self.restype.c_size), flavor='raw') ffires = c_ffi_call(self.ll_cif, self.funcsym, rffi.cast(rffi.VOIDP, ll_result), rffi.cast(rffi.VOIDPP, ll_args)) if RESULT is not lltype.Void: TP = lltype.Ptr(rffi.CArray(RESULT)) buf = rffi.cast(TP, ll_result) if types.is_struct(self.restype): assert RESULT == rffi.SIGNED # for structs, we directly return the buffer and transfer the # ownership res = rffi.cast(RESULT, buf) else: res = buf[0] else: res = None self._free_buffers(ll_result, ll_args) clibffi.check_fficall_result(ffires, self.flags) return res
def PyString_Size(space, ref): if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_str: ref = rffi.cast(PyStringObject, ref) return ref.c_size else: w_obj = from_ref(space, ref) return space.len_w(w_obj)
def llimpl_FormatError(code): "Return a message corresponding to the given Windows error code." buf = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw') try: msglen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, None, rffi.cast(DWORD, code), DEFAULT_LANGUAGE, rffi.cast(rffi.CCHARP, buf), 0, None) if msglen <= 2: # includes the case msglen < 0 return fake_FormatError(code) # FormatMessage always appends \r\n. buflen = intmask(msglen - 2) assert buflen > 0 result = rffi.charpsize2str(buf[0], buflen) LocalFree(rffi.cast(rffi.VOIDP, buf[0])) finally: lltype.free(buf, flavor='raw') return result
def test_keypresses(self): if not self.is_interactive: py.test.skip("interactive test only") RSDL.EnableUNICODE(1) print print "Keys pressed in the Pygame window should be printed below." print " Use Escape to quit." event = lltype.malloc(RSDL.Event, flavor='raw') try: while True: ok = RSDL.WaitEvent(event) assert rffi.cast(lltype.Signed, ok) == 1 c_type = rffi.getintfield(event, 'c_type') if c_type == RSDL.KEYDOWN: p = rffi.cast(RSDL.KeyboardEventPtr, event) if rffi.getintfield(p.c_keysym, 'c_sym') == RSDL.K_ESCAPE: print 'Escape key' break char = rffi.getintfield(p.c_keysym, 'c_unicode') if char != 0: print 'Key:', unichr(char).encode('utf-8') else: print 'Some special key' else: print '(event of type %d)' % c_type finally: lltype.free(event, flavor='raw')
def _base_do_getfield_f(self, struct, fielddescr): ofs = self.unpack_fielddescr(fielddescr) # --- start of GC unsafe code (no GC operation!) --- fieldptr = rffi.ptradd(rffi.cast(rffi.CCHARP, struct), ofs) fval = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), fieldptr)[0] # --- end of GC unsafe code --- return fval
def bh_setarrayitem_gc_r(self, arraydescr, gcref, itemindex, newvalue): ofs = self.unpack_arraydescr(arraydescr) self.gc_ll_descr.do_write_barrier(gcref, newvalue) # --- start of GC unsafe code (no GC operation!) --- items = rffi.ptradd(rffi.cast(rffi.CCHARP, gcref), ofs) items = rffi.cast(rffi.CArrayPtr(lltype.Signed), items) items[itemindex] = self.cast_gcref_to_int(newvalue)
def test_poll(self): if not self.is_interactive: py.test.skip("interactive test only") import time, sys RSDL.EnableUNICODE(1) print print "Keys pressed in the Pygame window give a dot." print " Wait 3 seconds to quit." timeout = time.time() + 3 event = lltype.malloc(RSDL.Event, flavor='raw') try: while True: # busy polling ok = RSDL.PollEvent(event) ok = rffi.cast(lltype.Signed, ok) assert ok >= 0 if ok > 0: c_type = rffi.getintfield(event, 'c_type') if c_type == RSDL.KEYDOWN: sys.stderr.write('.') p = rffi.cast(RSDL.KeyboardEventPtr, event) if rffi.getintfield(p.c_keysym, 'c_sym') == RSDL.K_ESCAPE: print 'Escape key' break timeout = time.time() + 3 else: if time.time() > timeout: break time.sleep(0.05) finally: lltype.free(event, flavor='raw')
def make_struct_ffitype(size, aligment): tp = lltype.malloc(FFI_TYPE_P.TO, flavor='raw') tp.c_type = FFI_TYPE_STRUCT tp.c_size = rffi.cast(rffi.SIZE_T, size) tp.c_alignment = rffi.cast(rffi.USHORT, aligment) tp.c_elements = lltype.nullptr(FFI_TYPE_PP.TO) return tp
def test_mousemove(self): if not self.is_interactive: py.test.skip("interactive test only") print print "Move the Mouse up and down:" print " Use Escape to quit." event = lltype.malloc(RSDL.Event, flavor="raw") directions = [False]*4 try: while True: ok = RSDL.WaitEvent(event) assert rffi.cast(lltype.Signed, ok) == 1 c_type = rffi.getintfield(event, "c_type") if c_type == RSDL.MOUSEMOTION: m = rffi.cast(RSDL.MouseMotionEventPtr, event) assert rffi.getintfield(m, "c_x") >= 0 assert rffi.getintfield(m, "c_y") >= 0 print rffi.getintfield(m, "c_xrel") directions[0] |= rffi.getintfield(m, "c_xrel")>0 directions[1] |= rffi.getintfield(m, "c_xrel")<0 directions[2] |= rffi.getintfield(m, "c_yrel")>0 directions[3] |= rffi.getintfield(m, "c_yrel")<0 if False not in directions: break elif c_type == RSDL.KEYUP: p = rffi.cast(RSDL.KeyboardEventPtr, event) if rffi.getintfield(p.c_keysym, 'c_sym') == RSDL.K_ESCAPE: print " test manually aborted" py.test.fail(" mousemovement test aborted") break finally: lltype.free(event, flavor='raw')
def _PyLong_FromByteArray(space, bytes, n, little_endian, signed): little_endian = rffi.cast(lltype.Signed, little_endian) signed = rffi.cast(lltype.Signed, signed) result = rbigint() negative = False for i in range(0, n): if little_endian: c = intmask(bytes[i]) else: c = intmask(bytes[n - i - 1]) if i == 0 and signed and c & 0x80: negative = True if negative: c = c ^ 0xFF digit = rbigint.fromint(c) result = result.lshift(8) result = result.add(digit) if negative: result = result.neg() return space.newlong_from_rbigint(result)
def _more(self): chunk = rffi.cast(CLOSURES, alloc(CHUNK)) count = CHUNK//rffi.sizeof(FFI_CLOSUREP.TO) for i in range(count): rffi.cast(rffi.VOIDPP, chunk)[0] = self.free_list self.free_list = rffi.cast(rffi.VOIDP, chunk) chunk = rffi.ptradd(chunk, 1)
def test_simple_cast(self): assert rffi.cast(rffi.SIGNEDCHAR, 0x123456) == 0x56 assert rffi.cast(rffi.SIGNEDCHAR, 0x123481) == -127 assert rffi.cast(rffi.CHAR, 0x123456) == '\x56' assert rffi.cast(rffi.CHAR, 0x123481) == '\x81' assert rffi.cast(rffi.UCHAR, 0x123481) == 0x81 assert not ALLOCATED # detects memory leaks in the test
def freeing_block(self, start, stop): # if [start:stop] is a raw block of assembler, then look up the # corresponding gcroot markers, and mark them as freed now in # self._gcmap by setting the 2nd address of every entry to NULL. gcmapstart = self.gcmapstart() gcmapend = self.gcmapend() if gcmapstart == gcmapend: return if not self.gcmarksorted(): asmgcroot.sort_gcmap(gcmapstart, gcmapend) # A note about gcmarksorted(): the deletion we do here keeps the # array sorted. This avoids needing too many sort_gcmap()s. # Indeed, freeing_block() is typically called many times in a row, # so it will call sort_gcmap() at most the first time. startaddr = rffi.cast(llmemory.Address, start) stopaddr = rffi.cast(llmemory.Address, stop) item = asmgcroot.binary_search(gcmapstart, gcmapend, startaddr) # 'item' points to one of the entries. Because the whole array # is sorted, we know that it points either to the first entry we # want to kill, or to the previous entry. if item.address[0] < startaddr: item += asmgcroot.arrayitemsize # go forward one entry assert item == gcmapend or item.address[0] >= startaddr while item != gcmapend and item.address[0] < stopaddr: item.address[1] = llmemory.NULL self._gcmap_deadentries += 1 item += asmgcroot.arrayitemsize
def test_qsort(self): CMPFUNC = lltype.FuncType([rffi.VOIDP, rffi.VOIDP], rffi.INT) qsort = rffi.llexternal('qsort', [rffi.VOIDP, rffi.SIZE_T, rffi.SIZE_T, lltype.Ptr(CMPFUNC)], lltype.Void) lst = [23, 43, 24, 324, 242, 34, 78, 5, 3, 10] A = lltype.Array(lltype.Signed, hints={'nolength': True}) a = lltype.malloc(A, 10, flavor='raw') for i in range(10): a[i] = lst[i] SIGNEDPTR = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1)) def my_compar(p1, p2): p1 = rffi.cast(SIGNEDPTR, p1) p2 = rffi.cast(SIGNEDPTR, p2) print 'my_compar:', p1[0], p2[0] return rffi.cast(rffi.INT, cmp(p1[0], p2[0])) qsort(rffi.cast(rffi.VOIDP, a), rffi.cast(rffi.SIZE_T, 10), rffi.cast(rffi.SIZE_T, llmemory.sizeof(lltype.Signed)), llhelper(lltype.Ptr(CMPFUNC), my_compar)) for i in range(10): print a[i], print lst.sort() for i in range(10): assert a[i] == lst[i] lltype.free(a, flavor='raw') assert not ALLOCATED # detects memory leaks in the test
def test_forced_ptr_cast(self): import array A = lltype.Array(lltype.Signed, hints={'nolength': True}) B = lltype.Array(lltype.Char, hints={'nolength': True}) a = lltype.malloc(A, 10, flavor='raw') for i in range(10): a[i] = i*i b = rffi.cast(lltype.Ptr(B), a) checker = array.array('l') for i in range(10): checker.append(i*i) expected = checker.tostring() for i in range(len(expected)): assert b[i] == expected[i] c = rffi.cast(rffi.VOIDP, a) addr = lltype2ctypes(c) #assert addr == ctypes.addressof(a._obj._ctypes_storage) d = ctypes2lltype(rffi.VOIDP, addr) assert lltype.typeOf(d) == rffi.VOIDP assert c == d e = rffi.cast(lltype.Ptr(A), d) for i in range(10): assert e[i] == i*i c = lltype.nullptr(rffi.VOIDP.TO) addr = rffi.cast(lltype.Signed, c) assert addr == 0 lltype.free(a, flavor='raw') assert not ALLOCATED # detects memory leaks in the test
def __init__(self, name, argtypes, restype, flags=FUNCFLAG_CDECL): self.name = name self.argtypes = argtypes self.restype = restype self.flags = flags argnum = len(argtypes) self.ll_argtypes = lltype.malloc( FFI_TYPE_PP.TO, argnum, flavor="raw", track_allocation=False ) # freed by the __del__ for i in range(argnum): self.ll_argtypes[i] = argtypes[i] self.ll_cif = lltype.malloc(FFI_CIFP.TO, flavor="raw", track_allocation=False) # freed by the __del__ if _MSVC: # This little trick works correctly with MSVC. # It returns small structures in registers if intmask(restype.c_type) == FFI_TYPE_STRUCT: if restype.c_size <= 4: restype = ffi_type_sint32 elif restype.c_size <= 8: restype = ffi_type_sint64 res = c_ffi_prep_cif( self.ll_cif, rffi.cast(rffi.USHORT, get_call_conv(flags, False)), rffi.cast(rffi.UINT, argnum), restype, self.ll_argtypes, ) if not res == FFI_OK: raise OSError(-1, "Wrong typedef")
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 _PyString_Resize(space, ref, newsize): """A way to resize a string object even though it is "immutable". Only use this to build up a brand new string object; don't use this if the string may already be known in other parts of the code. It is an error to call this function if the refcount on the input string object is not one. Pass the address of an existing string object as an lvalue (it may be written into), and the new size desired. On success, *string holds the resized string object and 0 is returned; the address in *string may differ from its input value. If the reallocation fails, the original string object at *string is deallocated, *string is set to NULL, a memory exception is set, and -1 is returned. """ # XXX always create a new string so far py_str = rffi.cast(PyStringObject, ref[0]) if not py_str.c_buffer: raise OperationError(space.w_SystemError, space.wrap( "_PyString_Resize called on already created string")) try: py_newstr = new_empty_str(space, newsize) except MemoryError: Py_DecRef(space, ref[0]) ref[0] = lltype.nullptr(PyObject.TO) raise to_cp = newsize oldsize = py_str.c_size if oldsize < newsize: to_cp = oldsize for i in range(to_cp): py_newstr.c_buffer[i] = py_str.c_buffer[i] Py_DecRef(space, ref[0]) ref[0] = rffi.cast(PyObject, py_newstr) return 0
def _type_realize(space, py_obj): """ Creates an interpreter type from a PyTypeObject structure. """ # missing: # inheriting tp_as_* slots # unsupported: # tp_mro, tp_subclasses py_type = rffi.cast(PyTypeObjectPtr, py_obj) if not py_type.c_tp_base: # borrowed reference, but w_object is unlikely to disappear base = make_ref(space, space.w_object) Py_DecRef(space, base) py_type.c_tp_base = rffi.cast(PyTypeObjectPtr, base) finish_type_1(space, py_type) w_metatype = from_ref(space, rffi.cast(PyObject, py_type.c_ob_type)) w_obj = space.allocate_instance(W_PyCTypeObject, w_metatype) track_reference(space, py_obj, w_obj) w_obj.__init__(space, py_type) w_obj.ready() finish_type_2(space, py_type, w_obj) state = space.fromcache(RefcountState) state.non_heaptypes_w.append(w_obj) return w_obj
def test(encoded, endian, realendian=None): encoded_charp = rffi.str2charp(encoded) strict_charp = rffi.str2charp("strict") if endian is not None: if endian < 0: value = -1 elif endian > 0: value = 1 else: value = 0 pendian = lltype.malloc(rffi.INTP.TO, 1, flavor='raw') pendian[0] = rffi.cast(rffi.INT, value) else: pendian = None w_ustr = api.PyUnicode_DecodeUTF16(encoded_charp, len(encoded), strict_charp, pendian) assert space.eq_w(space.call_method(w_ustr, 'encode', space.wrap('ascii')), space.wrap("abcd")) rffi.free_charp(encoded_charp) rffi.free_charp(strict_charp) if pendian: if realendian is not None: assert rffi.cast(rffi.INT, realendian) == pendian[0] lltype.free(pendian, flavor='raw')
def descr_get_udata(self, space): return space.wrap(rffi.cast(rffi.UINTPTR_T, self.event.c_udata))
def FAILED(hr): return rffi.cast(HRESULT, hr) < 0
for name in """FORMAT_MESSAGE_ALLOCATE_BUFFER FORMAT_MESSAGE_FROM_SYSTEM MAX_PATH """.split(): locals()[name] = rffi_platform.ConstantInteger(name) for k, v in rffi_platform.configure(CConfig).items(): globals()[k] = v def winexternal(name, args, result): return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv='win') if WIN32: HANDLE = rffi.ULONG LPHANDLE = rffi.CArrayPtr(HANDLE) HMODULE = HANDLE INVALID_HANDLE_VALUE = rffi.cast(HANDLE, -1) PFILETIME = rffi.CArrayPtr(FILETIME) GetLastError = winexternal('GetLastError', [], DWORD) SetLastError = winexternal('SetLastError', [DWORD], lltype.Void) LoadLibrary = winexternal('LoadLibraryA', [rffi.CCHARP], rffi.VOIDP) GetProcAddress = winexternal('GetProcAddress', [rffi.VOIDP, rffi.CCHARP], rffi.VOIDP) FreeLibrary = winexternal('FreeLibrary', [rffi.VOIDP], BOOL) LocalFree = winexternal('LocalFree', [HLOCAL], DWORD) CloseHandle = winexternal('CloseHandle', [HANDLE], lltype.Void) FormatMessage = winexternal(
def get_addr_of_const_float(self, num_arr, num_pos): arr = self.constant_arrays[num_arr] return heap64(rffi.cast(lltype.Signed, arr) + num_pos * WORD * 2)
def get_ident(): return rffi.cast(lltype.Signed, c_thread_get_ident())
def gcmapstart(self): return rffi.cast(llmemory.Address, self._gcmap)
def SetLastError(err): _SetLastError(rffi.cast(DWORD, err))
def PyObject_dealloc(space, obj): pto = obj.c_ob_type obj_voidp = rffi.cast(rffi.VOIDP, obj) generic_cpy_call(space, pto.c_tp_free, obj_voidp) if pto.c_tp_flags & Py_TPFLAGS_HEAPTYPE: Py_DecRef(space, rffi.cast(PyObject, pto))
def test_ret_struct_val(self): from pypy.translator.tool.cbuild import compile_c_module, \ ExternalCompilationInfo from pypy.tool.udir import udir c_file = udir.ensure("test_libffi", dir=1).join("xlib.c") c_file.write( py.code.Source(''' #include <stdlib.h> #include <stdio.h> struct s2h { short x; short y; }; struct s2h give(short x, short y) { struct s2h out; out.x = x; out.y = y; return out; } struct s2h perturb(struct s2h inp) { inp.x *= 2; inp.y *= 3; return inp; } ''')) lib_name = compile_c_module([c_file], 'x', ExternalCompilationInfo()) lib = CDLL(lib_name) size = ffi_type_sshort.c_size * 2 alignment = ffi_type_sshort.c_alignment tp = make_struct_ffitype(size, alignment) give = lib.getrawpointer('give', [ffi_type_sshort, ffi_type_sshort], tp) inbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor='raw') inbuffer[0] = rffi.cast(rffi.SHORT, 40) inbuffer[1] = rffi.cast(rffi.SHORT, 72) outbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor='raw') give.call([ rffi.cast(rffi.VOIDP, inbuffer), rffi.cast(rffi.VOIDP, rffi.ptradd(inbuffer, 1)) ], rffi.cast(rffi.VOIDP, outbuffer)) assert outbuffer[0] == 40 assert outbuffer[1] == 72 perturb = lib.getrawpointer('perturb', [tp], tp) inbuffer[0] = rffi.cast(rffi.SHORT, 7) inbuffer[1] = rffi.cast(rffi.SHORT, 11) perturb.call([rffi.cast(rffi.VOIDP, inbuffer)], rffi.cast(rffi.VOIDP, outbuffer)) assert inbuffer[0] == 7 assert inbuffer[1] == 11 assert outbuffer[0] == 14 assert outbuffer[1] == 33 lltype.free(outbuffer, flavor='raw') lltype.free(inbuffer, flavor='raw') del give del perturb lltype.free(tp, flavor='raw') del lib assert not ALLOCATED
def get_root_stack_top_addr(self): rst_addr = llop.gc_adr_of_root_stack_top(llmemory.Address) return rffi.cast(lltype.Signed, rst_addr)
def nextleft(iself, gc, range_lowest, prev): # Return the next valid GC object's address, in right-to-left # order from the shadowstack array. This usually means just # returning "prev - sizeofaddr", until we reach "range_lowest", # except that we are skipping NULLs. If "prev - sizeofaddr" # contains a MARKER_FRAME instead, then we go into # JIT-frame-lookup mode. # while True: # # If we are not iterating right now in a JIT frame if iself.frame_addr == 0: # # Look for the next shadowstack address that # contains a valid pointer while prev != range_lowest: prev -= llmemory.sizeof(llmemory.Address) if prev.signed[0] == self.MARKER_FRAME: break if gc.points_to_valid_gc_object(prev): return prev else: return llmemory.NULL # done # # It's a JIT frame. Save away 'prev' for later, and # go into JIT-frame-exploring mode. prev -= llmemory.sizeof(llmemory.Address) frame_addr = prev.signed[0] iself.saved_prev = prev iself.frame_addr = frame_addr addr = llmemory.cast_int_to_adr(frame_addr + self.force_index_ofs) addr = iself.translateptr(iself.context, addr) force_index = addr.signed[0] if force_index < 0: force_index = ~force_index # NB: the next line reads a still-alive _callshapes, # because we ensure that just before we called this # piece of assembler, we put on the (same) stack a # pointer to a loop_token that keeps the force_index # alive. callshape = self._callshapes[force_index] else: # Continuing to explore this JIT frame callshape = iself.callshape # # 'callshape' points to the next INT of the callshape. # If it's zero we are done with the JIT frame. while rffi.cast(lltype.Signed, callshape[0]) != 0: # # Non-zero: it's an offset inside the JIT frame. # Read it and increment 'callshape'. offset = rffi.cast(lltype.Signed, callshape[0]) callshape = lltype.direct_ptradd(callshape, 1) addr = llmemory.cast_int_to_adr(iself.frame_addr + offset) addr = iself.translateptr(iself.context, addr) if gc.points_to_valid_gc_object(addr): # # The JIT frame contains a valid GC pointer at # this address (as opposed to NULL). Save # 'callshape' for the next call, and return the # address. iself.callshape = callshape return addr # # Restore 'prev' and loop back to the start. iself.frame_addr = 0 prev = iself.saved_prev
for k, v in rffi_platform.configure(CConfig).items(): globals()[k] = v def winexternal(name, args, result, **kwds): return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv='win', **kwds) if WIN32: HANDLE = rffi.COpaquePtr(typedef='HANDLE') assert rffi.cast(HANDLE, -1) == rffi.cast(HANDLE, -1) LPHANDLE = rffi.CArrayPtr(HANDLE) HMODULE = HANDLE NULL_HANDLE = rffi.cast(HANDLE, 0) INVALID_HANDLE_VALUE = rffi.cast(HANDLE, -1) PFILETIME = rffi.CArrayPtr(FILETIME) _GetLastError = winexternal('GetLastError', [], DWORD, threadsafe=False) _SetLastError = winexternal('SetLastError', [DWORD], lltype.Void) def GetLastError(): return rffi.cast(lltype.Signed, _GetLastError()) def SetLastError(err): _SetLastError(rffi.cast(DWORD, err))
def GetLastError(): return rffi.cast(lltype.Signed, _GetLastError())
def acquire(self, flag): res = c_thread_acquirelock(self._lock, int(flag)) res = rffi.cast(lltype.Signed, res) return bool(res)
def set_errno(errno): _set_errno(rffi.cast(INT, errno))
def call(self, funcspec, args, RESULT, is_struct=False, jitif=[]): """ Call the function specified by funcspec in a loop, and let the jit to see and optimize it. """ # lib, name, argtypes, restype = funcspec method_and_args = [] for argval in args: if isinstance(argval, tuple): method_name, argval = argval else: method_name = 'arg' method_and_args.append((method_name, argval)) method_and_args = unrolling_iterable(method_and_args) # reds = ['n', 'res', 'func'] if (RESULT is rffi.DOUBLE or IS_32_BIT and RESULT in [rffi.LONGLONG, rffi.ULONGLONG]): reds = ['n', 'func', 'res'] # 'double' floats must be *after* refs driver = JitDriver(reds=reds, greens=[]) init_result = rffi.cast(RESULT, 0) # def g(func): # a different function, which is marked as "dont_look_inside" # in case it uses an unsupported argument argchain = ArgChain() # this loop is unrolled for method_name, argval in method_and_args: getattr(argchain, method_name)(argval) return func.call(argchain, RESULT, is_struct=is_struct) # def f(n): func = lib.getpointer(name, argtypes, restype) res = init_result while n < 10: driver.jit_merge_point(n=n, res=res, func=func) promote(func) res = g(func) n += 1 return res # res = self.meta_interp(f, [0], backendopt=True, supports_floats=self.supports_all, supports_longlong=self.supports_all, supports_singlefloats=self.supports_all) d = { 'floats': self.supports_all, 'longlong': self.supports_all or not IS_32_BIT, 'singlefloats': self.supports_all, 'byval': False } supported = all(d[check] for check in jitif) if supported: self.check_resops( call_release_gil=2, # a CALL_RELEASE_GIL, and no other CALLs call=0, call_may_force=0, guard_no_exception=2, guard_not_forced=2, int_add=2, int_lt=2, guard_true=2, jump=1) else: self.check_resops( call_release_gil=0, # no CALL_RELEASE_GIL int_add=2, int_lt=2, guard_true=2, jump=1) return res
def main(n): with lltype.scoped_alloc(rffi.CArray(TYPE), 1) as data: data[0] = rffi.cast(TYPE, 200) return f(data, n)
def acquire_NOAUTO(ll_lock, flag): flag = rffi.cast(rffi.INT, int(flag)) res = c_thread_acquirelock_NOAUTO(ll_lock, flag) res = rffi.cast(lltype.Signed, res) return bool(res)
def wrap_binaryfunc(space, w_self, w_args, func): func_binary = rffi.cast(binaryfunc, func) check_num_args(space, w_args, 1) args_w = space.fixedview(w_args) return generic_cpy_call(space, func_binary, w_self, args_w[0])
def wrap_init(space, w_self, w_args, func, w_kwargs): func_init = rffi.cast(initproc, func) res = generic_cpy_call(space, func_init, w_self, w_args, w_kwargs) if rffi.cast(lltype.Signed, res) == -1: space.fromcache(State).check_and_raise_exception(always=True) return None
def wrap_unaryfunc(space, w_self, w_args, func): func_unary = rffi.cast(unaryfunc, func) check_num_args(space, w_args, 0) return generic_cpy_call(space, func_unary, w_self)
def wrap_getattro(space, w_self, w_args, func): func_target = rffi.cast(getattrofunc, func) check_num_args(space, w_args, 1) args_w = space.fixedview(w_args) return generic_cpy_call(space, func_target, w_self, args_w[0])
def wrap_hashfunc(space, w_self, w_args, func): func_target = rffi.cast(hashfunc, func) check_num_args(space, w_args, 0) return space.wrap(generic_cpy_call(space, func_target, w_self))
def wrap_lenfunc(space, w_self, w_args, func): func_len = rffi.cast(lenfunc, func) check_num_args(space, w_args, 0) return space.wrap(generic_cpy_call(space, func_len, w_self))
def wrap_sq_item(space, w_self, w_args, func): func_target = rffi.cast(ssizeargfunc, func) check_num_args(space, w_args, 1) args_w = space.fixedview(w_args) index = space.int_w(space.index(args_w[0])) return generic_cpy_call(space, func_target, w_self, index)
def inner(space, w_self, w_args, func): func_target = rffi.cast(richcmpfunc, func) check_num_args(space, w_args, 1) w_other, = space.fixedview(w_args) return generic_cpy_call(space, func_target, w_self, w_other, rffi.cast(rffi.INT_real, OP_CONST))
def _operate(stream, data, flush, max_length, cfunc, while_doing): """Common code for compress() and decompress(). """ # Prepare the input buffer for the stream inbuf = lltype.malloc(rffi.CCHARP.TO, len(data), flavor='raw') try: 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 outbuf = lltype.malloc(rffi.CCHARP.TO, OUTPUT_BUFFER_SIZE, flavor='raw') try: # Strategy: we call deflate() to get as much output data as # fits in the buffer, then accumulate all output into a list # of characters 'result'. We don't need to gradually # increase the output buffer size because there is no # quadratic factor. result = [] 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) for i in xrange(bufsize - avail_out): result.append(outbuf[i]) # 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) finally: lltype.free(outbuf, flavor='raw') finally: lltype.free(inbuf, flavor='raw') # 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 (''.join(result), err == Z_STREAM_END, rffi.cast(lltype.Signed, stream.c_avail_in))
def stack_check(): if rffi.cast(lltype.Signed, stack_too_big()): # stack_unwind implementation is different depending on if stackless # is enabled. If it is it unwinds the stack, otherwise it simply # raises a RuntimeError. stack_unwind()
def get_nursery_top_addr(self): nurs_top_addr = llop.gc_adr_of_nursery_top(llmemory.Address) return rffi.cast(lltype.Signed, nurs_top_addr)
def wrap_call(space, w_self, w_args, func, w_kwds): func_target = rffi.cast(ternaryfunc, func) return generic_cpy_call(space, func_target, w_self, w_args, w_kwds)