def test_file_getline(self, space, api): filename = rffi.str2charp(str(udir / "_test_file")) mode = rffi.str2charp("w") w_file = api.PyFile_FromString(filename, mode) space.call_method(w_file, "write", space.wrap("line1\nline2\nline3\nline4")) space.call_method(w_file, "close") rffi.free_charp(mode) mode = rffi.str2charp("r") w_file = api.PyFile_FromString(filename, mode) rffi.free_charp(filename) rffi.free_charp(mode) w_line = api.PyFile_GetLine(w_file, 0) assert space.str_w(w_line) == "line1\n" w_line = api.PyFile_GetLine(w_file, 4) assert space.str_w(w_line) == "line" w_line = api.PyFile_GetLine(w_file, 0) assert space.str_w(w_line) == "2\n" # XXX We ought to raise an EOFError here, but don't w_line = api.PyFile_GetLine(w_file, -1) # assert api.PyErr_Occurred() is space.w_EOFError assert space.str_w(w_line) == "line3\n" space.call_method(w_file, "close")
def load_lib(self): if not self._is_inited: load_paths = rt.deref(rt.deref(rt.load_paths)) for x in range(rt.count(load_paths)): s = rffi.str2charp(str(rt.name(rt.nth(load_paths, rt.wrap(x)))) + "/" + str(self._name)) try: self._dyn_lib = dynload.dlopen(s) self._is_inited = True except dynload.DLOpenError as ex: continue finally: rffi.free_charp(s) break if not self._is_inited: s = rffi.str2charp(str(self._name)) try: self._dyn_lib = dynload.dlopen(s) self._is_inited = True except dynload.DLOpenError as ex: raise object.runtime_error(u"Couldn't Load Library: " + self._name, u"pixie.stdlib/LibraryNotFoundException") finally: rffi.free_charp(s)
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_DecodeUTF32(encoded_charp, len(encoded), strict_charp, pendian) assert space.eq_w(space.call_method(w_ustr, 'encode', space.wrap('ascii')), space.wrap("ab")) 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 timelib_time_from_format(time_format_string, time_string): time_string = time_string or 'now' error = '' ll_s = rffi.str2charp(time_string) ll_format = rffi.str2charp(time_format_string) error_c = lltype.malloc(timelib_error_containerP.TO, 1, flavor='raw') ll_res = timelib_parse_from_format( ll_format, ll_s, len(time_string), error_c, timelib_builtin_db(), tzinfo_callback ) error_count = rffi.cast(lltype.Signed, error_c[0].c_error_count) if error_count: position = int(error_c[0].c_error_messages[0].c_position) message = rffi.charp2str(error_c[0].c_error_messages[0].c_message) char = error_c[0].c_error_messages[0].c_character error = "Failed to parse time string (%s) at position %s (%s): %s" % ( time_string, position, char, message ) lltype.free(error_c, flavor='raw') return ll_res, error
def strcoll(space, w_s1, w_s2): "string,string -> int. Compares two strings according to the locale." if (space.isinstance_w(w_s1, space.w_str) and space.isinstance_w(w_s2, space.w_str)): s1, s2 = space.str_w(w_s1), space.str_w(w_s2) s1_c = rffi.str2charp(s1) s2_c = rffi.str2charp(s2) try: return space.wrap(_strcoll(s1_c, s2_c)) finally: rffi.free_charp(s1_c) rffi.free_charp(s2_c) s1, s2 = space.unicode_w(w_s1), space.unicode_w(w_s2) s1_c = rffi.unicode2wcharp(s1) s2_c = rffi.unicode2wcharp(s2) try: result = _wcscoll(s1_c, s2_c) finally: rffi.free_wcharp(s1_c) rffi.free_wcharp(s2_c) return space.wrap(result)
def test_ascii_codec(self, space, api): s = 'abcdefg' data = rffi.str2charp(s) w_u = api.PyUnicode_DecodeASCII(data, len(s), lltype.nullptr(rffi.CCHARP.TO)) assert space.eq_w(w_u, space.wrap(u"abcdefg")) rffi.free_charp(data) s = 'abcd\xFF' data = rffi.str2charp(s) self.raises(space, api, UnicodeDecodeError, api.PyUnicode_DecodeASCII, data, len(s), lltype.nullptr(rffi.CCHARP.TO)) rffi.free_charp(data) uni = u'abcdefg' data = rffi.unicode2wcharp(uni) w_s = api.PyUnicode_EncodeASCII(data, len(uni), lltype.nullptr(rffi.CCHARP.TO)) assert space.eq_w(space.wrap("abcdefg"), w_s) rffi.free_wcharp(data) u = u'äbcdéfg' data = rffi.unicode2wcharp(u) w_s = api.PyUnicode_EncodeASCII(data, len(u), lltype.nullptr(rffi.CCHARP.TO)) self.raises(space, api, UnicodeEncodeError, api.PyUnicode_EncodeASCII, data, len(u), lltype.nullptr(rffi.CCHARP.TO)) rffi.free_wcharp(data)
def test_AsEncodedObject(self, space, api): ptr = space.wrap('abc') errors = rffi.str2charp("strict") encoding = rffi.str2charp("hex") res = api.PyString_AsEncodedObject( ptr, encoding, errors) assert space.unwrap(res) == "616263" res = api.PyString_AsEncodedObject( ptr, encoding, lltype.nullptr(rffi.CCHARP.TO)) assert space.unwrap(res) == "616263" rffi.free_charp(encoding) encoding = rffi.str2charp("unknown_encoding") self.raises(space, api, LookupError, api.PyString_AsEncodedObject, ptr, encoding, errors) rffi.free_charp(encoding) rffi.free_charp(errors) res = api.PyString_AsEncodedObject( ptr, lltype.nullptr(rffi.CCHARP.TO), lltype.nullptr(rffi.CCHARP.TO)) assert space.unwrap(res) == "abc" self.raises(space, api, TypeError, api.PyString_AsEncodedObject, space.wrap(2), lltype.nullptr(rffi.CCHARP.TO), lltype.nullptr(rffi.CCHARP.TO) )
def strxfrm(space, s): "string -> string. Returns a string that behaves for cmp locale-aware." n1 = len(s) + 1 buf = lltype.malloc(rffi.CCHARP.TO, n1, flavor="raw", zero=True) s_c = rffi.str2charp(s) try: n2 = _strxfrm(buf, s_c, n1) + 1 finally: rffi.free_charp(s_c) if n2 > n1: # more space needed lltype.free(buf, flavor="raw") buf = lltype.malloc(rffi.CCHARP.TO, intmask(n2), flavor="raw", zero=True) s_c = rffi.str2charp(s) try: _strxfrm(buf, s_c, n2) finally: rffi.free_charp(s_c) val = rffi.charp2str(buf) lltype.free(buf, flavor="raw") return space.wrap(val)
def dcgettext(space, w_domain, msg, category): """dcgettext(domain, msg, category) -> string Return translation of msg in domain and category.""" if space.is_w(w_domain, space.w_None): domain = None msg_c = rffi.str2charp(msg) try: result = _dcgettext(domain, msg_c, rffi.cast(rffi.INT, category)) # note that 'result' may be the same pointer as 'msg_c', # so it must be converted to an RPython string *before* # we free msg_c. result = rffi.charp2str(result) finally: rffi.free_charp(msg_c) else: domain = space.str_w(w_domain) domain_c = rffi.str2charp(domain) msg_c = rffi.str2charp(msg) try: result = _dcgettext(domain_c, msg_c, rffi.cast(rffi.INT, category)) # note that 'result' may be the same pointer as 'msg_c', # so it must be converted to an RPython string *before* # we free msg_c. result = rffi.charp2str(result) finally: rffi.free_charp(domain_c) rffi.free_charp(msg_c) return space.wrap(result)
def bindtextdomain(space, domain, w_dir): """bindtextdomain(domain, dir) -> string Bind the C library's domain to dir.""" if space.is_w(w_dir, space.w_None): dir = None domain_c = rffi.str2charp(domain) try: dirname = _bindtextdomain(domain_c, dir) finally: rffi.free_charp(domain_c) else: dir = space.str_w(w_dir) domain_c = rffi.str2charp(domain) dir_c = rffi.str2charp(dir) try: dirname = _bindtextdomain(domain_c, dir_c) finally: rffi.free_charp(domain_c) rffi.free_charp(dir_c) if not dirname: errno = rposix.get_saved_errno() raise OperationError(space.w_OSError, space.wrap(errno)) return space.wrap(rffi.charp2str(dirname))
def bind_textdomain_codeset(space, domain, w_codeset): """bind_textdomain_codeset(domain, codeset) -> string Bind the C library's domain to codeset.""" if space.is_w(w_codeset, space.w_None): codeset = None domain_c = rffi.str2charp(domain) try: result = _bind_textdomain_codeset(domain_c, codeset) finally: rffi.free_charp(domain_c) else: codeset = space.str_w(w_codeset) domain_c = rffi.str2charp(domain) codeset_c = rffi.str2charp(codeset) try: result = _bind_textdomain_codeset(domain_c, codeset_c) finally: rffi.free_charp(domain_c) rffi.free_charp(codeset_c) if not result: return space.w_None else: return space.wrap(rffi.charp2str(result))
def test_dlopen(self): s = rffi.str2charp("xxxxxxxxxxxx") py.test.raises(DLOpenError, "dlopen(s)") rffi.free_charp(s) # s = rffi.str2charp(get_libc_name()) assert dlopen(s) rffi.free_charp(s)
def test_newcode(self, space, api): filename = rffi.str2charp('filename') funcname = rffi.str2charp('funcname') w_code = api.PyCode_NewEmpty(filename, funcname, 3) assert w_code.co_filename == 'filename' assert w_code.co_firstlineno == 3 rffi.free_charp(filename) rffi.free_charp(funcname)
def test_file_fromstring(self, space, api): filename = rffi.str2charp(str(udir / "_test_file")) mode = rffi.str2charp("wb") w_file = api.PyFile_FromString(filename, mode) rffi.free_charp(filename) rffi.free_charp(mode) space.call_method(w_file, "write", space.wrapbytes("text")) space.call_method(w_file, "close") assert (udir / "_test_file").read() == "text"
def test_newcode(self, space, api): filename = rffi.str2charp("filename") funcname = rffi.str2charp("funcname") w_code = api.PyCode_NewEmpty(filename, funcname, 3) assert w_code.co_filename == "filename" assert w_code.co_firstlineno == 3 ref = make_ref(space, w_code) assert "filename" == space.unwrap(from_ref(space, rffi.cast(PyCodeObject, ref).c_co_filename)) api.Py_DecRef(ref) rffi.free_charp(filename) rffi.free_charp(funcname)
def get_new_method_def(space): state = space.fromcache(State) if state.new_method_def: return state.new_method_def from pypy.module.cpyext.modsupport import PyMethodDef ptr = lltype.malloc(PyMethodDef, flavor="raw", zero=True, immortal=True) ptr.c_ml_name = rffi.str2charp("__new__") lltype.render_immortal(ptr.c_ml_name) rffi.setintfield(ptr, "c_ml_flags", METH_VARARGS | METH_KEYWORDS) ptr.c_ml_doc = rffi.str2charp("T.__new__(S, ...) -> a new object with type S, a subtype of T") lltype.render_immortal(ptr.c_ml_doc) state.new_method_def = ptr return ptr
def get_new_method_def(space): state = space.fromcache(State) if state.new_method_def: return state.new_method_def ptr = lltype.malloc(PyMethodDef, flavor="raw", zero=True, immortal=True) ptr.c_ml_name = rffi.cast(rffi.CONST_CCHARP, rffi.str2charp("__new__")) lltype.render_immortal(ptr.c_ml_name) rffi.setintfield(ptr, 'c_ml_flags', METH_VARARGS | METH_KEYWORDS) ptr.c_ml_doc = rffi.cast(rffi.CONST_CCHARP, rffi.str2charp( "T.__new__(S, ...) -> a new object with type S, a subtype of T")) lltype.render_immortal(ptr.c_ml_doc) state.new_method_def = ptr return ptr
def create_popen_file(command, type): ll_command = rffi.str2charp(command) try: ll_type = rffi.str2charp(type) try: ll_file = c_popen(ll_command, ll_type) if not ll_file: errno = rposix.get_saved_errno() raise OSError(errno, os.strerror(errno)) finally: lltype.free(ll_type, flavor='raw') finally: lltype.free(ll_command, flavor='raw') return RFile(ll_file, close2=_pclose2)
def load_extension_module(space, path, name): if os.sep not in path: path = os.curdir + os.sep + path # force a '/' in the path state = space.fromcache(State) if state.find_extension(name, path) is not None: return old_context = state.package_context state.package_context = name, path try: from rpython.rlib import rdynload try: ll_libname = rffi.str2charp(path) try: dll = rdynload.dlopen(ll_libname) finally: lltype.free(ll_libname, flavor='raw') except rdynload.DLOpenError, e: raise operationerrfmt( space.w_ImportError, "unable to load extension module '%s': %s", path, e.msg) try: initptr = rdynload.dlsym(dll, 'init%s' % (name.split('.')[-1],)) except KeyError: raise operationerrfmt( space.w_ImportError, "function init%s not found in library %s", name, path) initfunc = rffi.cast(initfunctype, initptr) generic_cpy_call(space, initfunc) state.check_and_raise_exception()
def test_dlsym(self): s = rffi.str2charp(get_libc_name()) lib = dlopen(s) rffi.free_charp(s) handle = rffi.cast(lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)), dlsym(lib, "abs")) assert 1 == handle(1) assert 1 == handle(-1)
def c_stdvector_valuetype(space, pystr): cstr = rffi.str2charp(pystr) result = _c_stdvector_valuetype(cstr) rffi.free_charp(cstr) if result: return charp2str_free(space, result) return ""
def buffer_attach(space, py_obj, w_obj): """ Fills a newly allocated PyBufferObject with the given (str) buffer object. """ py_buf = rffi.cast(PyBufferObject, py_obj) py_buf.c_b_offset = 0 rffi.setintfield(py_buf, 'c_b_readonly', 1) rffi.setintfield(py_buf, 'c_b_hash', -1) assert isinstance(w_obj, W_Buffer) buf = w_obj.buf if isinstance(buf, SubBuffer): py_buf.c_b_offset = buf.offset buf = buf.buffer # If buf already allocated a fixed buffer, use it, and keep a # reference to buf. # Otherwise, b_base stays NULL, and we own the b_ptr. if isinstance(buf, StringBuffer): py_buf.c_b_base = lltype.nullptr(PyObject.TO) py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, rffi.str2charp(buf.value)) py_buf.c_b_size = buf.getlength() elif isinstance(buf, ArrayBuffer): w_base = buf.array py_buf.c_b_base = make_ref(space, w_base) py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, buf.array._charbuf_start()) py_buf.c_b_size = buf.getlength() else: raise OperationError(space.w_NotImplementedError, space.wrap( "buffer flavor not supported"))
def _make_mode(vm_path, path, bc, verbosity, mk_fresh): # Try to work out a plausible cached path name. dp = path.rfind(os.extsep) if dp >= 0 and os.sep not in path[dp:]: cp = path[:dp] else: cp = None if not cp or mk_fresh: return _do_make_mode(vm_path, path, None, verbosity, mk_fresh) else: # There is a cached path, so now we try and load it and see if it is upto date. If any part # of this fails, we simply go straight to full make mode. try: st = os.stat(cp) except OSError: return _do_make_mode(vm_path, path, cp, verbosity, mk_fresh) cbc, start = _read_bc(cp, "CONVEXEC") if start == -1: return _do_make_mode(vm_path, path, cp, verbosity, mk_fresh) assert start >= 0 useful_bc = cbc[start:] if Bytecode.exec_upto_date(None, rffi.str2charp(useful_bc), st.st_mtime): return cbc, start, 0 return _do_make_mode(vm_path, path, cp, verbosity, mk_fresh)
def get_fn_ptr(self, nm): assert isinstance(nm, unicode) self.thaw() s = rffi.str2charp(str(nm)) sym = dynload.dlsym(self._dyn_lib, s) rffi.free_charp(s) return sym
def test_overflow_neg(self, api): s = rffi.str2charp('-1e500') null = lltype.nullptr(rffi.CCHARPP.TO) r = api.PyOS_string_to_double(s, null, None) assert math.isinf(r) assert r < 0 rffi.free_charp(s)
def PyString_AsStringAndSize(space, ref, buffer, length): if not PyString_Check(space, ref): from pypy.module.cpyext.unicodeobject import ( PyUnicode_Check, _PyUnicode_AsDefaultEncodedString) if PyUnicode_Check(space, ref): ref = _PyUnicode_AsDefaultEncodedString(space, ref, lltype.nullptr(rffi.CCHARP.TO)) else: raise oefmt(space.w_TypeError, "expected string or Unicode object, %T found", from_ref(space, ref)) ref_str = rffi.cast(PyStringObject, ref) if not ref_str.c_buffer: # copy string buffer w_str = from_ref(space, ref) s = space.str_w(w_str) ref_str.c_buffer = rffi.str2charp(s) buffer[0] = ref_str.c_buffer if length: length[0] = ref_str.c_size else: i = 0 while ref_str.c_buffer[i] != '\0': i += 1 if i != ref_str.c_size: raise OperationError(space.w_TypeError, space.wrap( "expected string without null bytes")) return 0
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 prep_string(s): """Takes a Pixie string and returns a VoidP to that string. The string should be freed via dispose!, otherwise memory leaks could result.""" affirm(isinstance(s, String), u"Can only prep strings with prep-string") utf8 = unicode_to_utf8(rt.name(s)) raw = rffi.str2charp(utf8) return VoidP(rffi.cast(rffi.VOIDP, raw))
def test_getattr(self, space, api): charp1 = rffi.str2charp("__len__") charp2 = rffi.str2charp("not_real") assert api.PyObject_GetAttrString(space.wrap(""), charp1) assert not api.PyObject_GetAttrString(space.wrap(""), charp2) assert api.PyErr_Occurred() is space.w_AttributeError api.PyErr_Clear() assert api.PyObject_DelAttrString(space.wrap(""), charp1) == -1 assert api.PyErr_Occurred() is space.w_AttributeError api.PyErr_Clear() rffi.free_charp(charp1) rffi.free_charp(charp2) assert api.PyObject_GetAttr(space.wrap(""), space.wrap("__len__")) assert api.PyObject_DelAttr(space.wrap(""), space.wrap("__len__")) == -1 api.PyErr_Clear()
def parse_c_type(info, input): p_input = rffi.str2charp(input) try: res = ll_parse_c_type(info, p_input) finally: rffi.free_charp(p_input) return rffi.cast(lltype.Signed, res)
def test_AS(self, space, api): word = space.wrap(u'spam') array = rffi.cast(rffi.CWCHARP, api.PyUnicode_AS_DATA(word)) array2 = api.PyUnicode_AS_UNICODE(word) array3 = api.PyUnicode_AsUnicode(word) for (i, char) in enumerate(space.unwrap(word)): assert array[i] == char assert array2[i] == char assert array3[i] == char self.raises(space, api, TypeError, api.PyUnicode_AsUnicode, space.wrapbytes('spam')) utf_8 = rffi.str2charp('utf-8') encoded = api.PyUnicode_AsEncodedString(space.wrap(u'späm'), utf_8, None) assert space.unwrap(encoded) == 'sp\xc3\xa4m' encoded_obj = api.PyUnicode_AsEncodedObject(space.wrap(u'späm'), utf_8, None) assert space.eq_w(encoded, encoded_obj) self.raises(space, api, TypeError, api.PyUnicode_AsEncodedString, space.newtuple([1, 2, 3]), None, None) self.raises(space, api, TypeError, api.PyUnicode_AsEncodedString, space.wrapbytes(''), None, None) ascii = rffi.str2charp('ascii') replace = rffi.str2charp('replace') encoded = api.PyUnicode_AsEncodedString(space.wrap(u'späm'), ascii, replace) assert space.unwrap(encoded) == 'sp?m' rffi.free_charp(utf_8) rffi.free_charp(replace) rffi.free_charp(ascii) buf = rffi.unicode2wcharp(u"12345") api.PyUnicode_AsWideChar(space.wrap(u'longword'), buf, 5) assert rffi.wcharp2unicode(buf) == 'longw' api.PyUnicode_AsWideChar(space.wrap(u'a'), buf, 5) assert rffi.wcharp2unicode(buf) == 'a' rffi.free_wcharp(buf)
def test_execute_source(space): _, d = create_entry_point(space, None) execute_source = d['pypy_execute_source'] lls = rffi.str2charp("import sys; sys.modules['xyz'] = 3") res = execute_source(lls) lltype.free(lls, flavor='raw') assert lltype.typeOf(res) == rffi.INT assert rffi.cast(lltype.Signed, res) == 0 x = space.int_w( space.getitem( space.getattr(space.builtin_modules['sys'], space.wrap('modules')), space.wrap('xyz'))) assert x == 3 lls = rffi.str2charp("sys # should give a NameError") execute_source(lls) lltype.free(lls, flavor='raw') # did not crash - the same globals pypy_setup_home = d['pypy_setup_home'] lls = rffi.str2charp(__file__) res = pypy_setup_home(lls, rffi.cast(rffi.INT, 1)) assert lltype.typeOf(res) == rffi.INT assert rffi.cast(lltype.Signed, res) == 0 lltype.free(lls, flavor='raw')
def _import_lib(vm, leaf, vm_path, cnd_dirs): vm_dir = _dirname(vm_path) for d in cnd_dirs: path = "%s/%s/%s" % (vm_dir, d, leaf) if os.path.exists(path): break else: _warning(vm_path, "Warning: Can't find %s." % leaf) return bc, start = _read_bc(path, "CONVLIBR") if start != 0: raise Exception("XXX") Bytecode.add_lib(vm, rffi.str2charp(bc))
def rcall(self, funcaddr, args): assert self.cif_descr self = jit.promote(self) # no checking of len(args) needed, as calls in this context are not dynamic # The following code is functionally similar to W_CTypeFunc._call, but its # implementation is tailored to the restricted use (include memory handling) # of the CAPI calls. space = self.space cif_descr = self.cif_descr size = cif_descr.exchange_size raw_string = rffi.cast(rffi.CCHARP, 0) # only ever have one in the CAPI buffer = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw') try: for i in range(len(args)): data = rffi.ptradd(buffer, cif_descr.exchange_args[i]) obj = args[i] argtype = self.fargs[i] # the following is clumsy, but the data types used as arguments are # very limited, so it'll do for now if isinstance(argtype, ctypeprim.W_CTypePrimitiveSigned): misc.write_raw_signed_data(data, rffi.cast(rffi.LONG, obj._long), argtype.size) elif isinstance(argtype, ctypeprim.W_CTypePrimitiveUnsigned): misc.write_raw_unsigned_data( data, rffi.cast(rffi.ULONG, obj._handle), argtype.size) elif obj._voidp != rffi.cast(rffi.VOIDP, 0): data = rffi.cast(rffi.VOIDPP, data) data[0] = obj._voidp else: # only other use is sring n = len(obj._string) assert raw_string == rffi.cast(rffi.CCHARP, 0) raw_string = rffi.str2charp(obj._string) data = rffi.cast(rffi.CCHARPP, data) data[0] = raw_string jit_libffi.jit_ffi_call(cif_descr, rffi.cast(rffi.VOIDP, funcaddr), buffer) resultdata = rffi.ptradd(buffer, cif_descr.exchange_result) # this wrapping is unnecessary, but the assumption is that given the # immediate unwrapping, the round-trip is removed w_res = self.ctitem.copy_and_convert_to_object(resultdata) finally: if raw_string != rffi.cast(rffi.CCHARP, 0): rffi.free_charp(raw_string) lltype.free(buffer, flavor='raw') return w_res
def PyBytes_AsString(space, ref): if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_str: pass # typecheck returned "ok" without forcing 'ref' at all elif not PyBytes_Check(space, ref): # otherwise, use the alternate way raise OperationError( space.w_TypeError, space.wrap("PyBytes_AsString only support strings")) ref_str = rffi.cast(PyBytesObject, ref) if not ref_str.c_buffer: # copy string buffer w_str = from_ref(space, ref) s = space.bytes_w(w_str) ref_str.c_buffer = rffi.str2charp(s) return ref_str.c_buffer
def test_decode_null_encoding(self, space): null_charp = lltype.nullptr(rffi.CCHARP.TO) u_text = u'abcdefg' s_text = space.str_w( PyUnicode_AsEncodedString(space, space.wrap(u_text), null_charp, null_charp)) b_text = rffi.str2charp(s_text) assert space.unicode_w( PyUnicode_Decode(space, b_text, len(s_text), null_charp, null_charp)) == u_text with raises_w(space, TypeError): PyUnicode_FromEncodedObject(space, space.wrap(u_text), null_charp, None) rffi.free_charp(b_text)
def build_scalar(space, w_dtype, w_state): if not isinstance(w_dtype, descriptor.W_Dtype): raise oefmt(space.w_TypeError, "argument 1 must be numpy.dtype, not %T", w_dtype) if w_dtype.elsize == 0: raise oefmt(space.w_ValueError, "itemsize cannot be zero") if not space.isinstance_w(w_state, space.w_str): raise oefmt(space.w_TypeError, "initializing object must be a string") if space.len_w(w_state) != w_dtype.elsize: raise oefmt(space.w_ValueError, "initialization string is too small") state = rffi.str2charp(space.str_w(w_state)) box = w_dtype.itemtype.box_raw_data(state) lltype.free(state, flavor="raw") return box
def test_unicodeobject(self, space, api): assert api.PyUnicode_GET_SIZE(space.wrap(u'späm')) == 4 assert api.PyUnicode_GetSize(space.wrap(u'späm')) == 4 unichar = rffi.sizeof(Py_UNICODE) assert api.PyUnicode_GET_DATA_SIZE(space.wrap(u'späm')) == 4 * unichar encoding = rffi.charp2str(api.PyUnicode_GetDefaultEncoding()) w_default_encoding = space.call_function( space.sys.get('getdefaultencoding')) assert encoding == space.unwrap(w_default_encoding) invalid = rffi.str2charp('invalid') utf_8 = rffi.str2charp('utf-8') prev_encoding = rffi.str2charp(space.unwrap(w_default_encoding)) self.raises(space, api, TypeError, api.PyUnicode_SetDefaultEncoding, lltype.nullptr(rffi.CCHARP.TO)) assert api.PyUnicode_SetDefaultEncoding(invalid) == -1 assert api.PyErr_Occurred() is space.w_LookupError api.PyErr_Clear() assert api.PyUnicode_SetDefaultEncoding(utf_8) == 0 assert rffi.charp2str(api.PyUnicode_GetDefaultEncoding()) == 'utf-8' assert api.PyUnicode_SetDefaultEncoding(prev_encoding) == 0 rffi.free_charp(invalid) rffi.free_charp(utf_8) rffi.free_charp(prev_encoding)
def _cast_aovalue_to_ffivalue(space, value, type, ptr): if value.type == 'str' and type == 'char *': pnt = rffi.cast(rffi.CCHARPP, ptr) pnt[0] = rffi.str2charp(value.strvalue) elif value.type == 'int' and type == 'int': pnt = rffi.cast(rffi.INTP, ptr) pnt[0] = rffi.cast(rffi.INT, value.intvalue) elif value.type == 'float' and type == 'float': pnt = rffi.cast(rffi.FLOATP, ptr) pnt[0] = rffi.cast(rffi.FLOAT, value.floatvalue) elif value.type == 'float' and type == 'double': pnt = rffi.cast(rffi.DOUBLEP, ptr) pnt[0] = rffi.cast(rffi.DOUBLE, value.floatvalue) else: raise ValueError('not implemented aovalue->ffivalue.')
def test_ldscripts(self): # this test only makes sense on linux if platform.name != "linux": return fname = os.path.join(os.path.dirname(__file__), "ldscript_working1.so") s = rffi.str2charp(fname) assert "C object" in str(dlopen(s)) rffi.free_charp(s) fname = os.path.join(os.path.dirname(__file__), "ldscript_working2.so") s = rffi.str2charp(fname) assert "C object" in str(dlopen(s)) rffi.free_charp(s) fname = os.path.join(os.path.dirname(__file__), "ldscript_broken1.so") s = rffi.str2charp(fname) py.test.raises(DLOpenError, 'dlopen(s)') rffi.free_charp(s) fname = os.path.join(os.path.dirname(__file__), "ldscript_broken2.so") s = rffi.str2charp(fname) py.test.raises(DLOpenError, 'dlopen(s)') rffi.free_charp(s)
def create_fdopen_rfile(fd, mode="r", buffering=-1): newmode = _sanitize_mode(mode) rposix.validate_fd(fd) ll_mode = rffi.str2charp(newmode) try: ll_file = c_fdopen(fd, ll_mode) if not ll_file: errno = rposix.get_saved_errno() raise OSError(errno, os.strerror(errno)) finally: lltype.free(ll_mode, flavor='raw') _dircheck(ll_file) f = RFile(ll_file, mode) f._setbufsize(buffering) return f
def test_decode(self, space): b_text = rffi.str2charp('caf\x82xx') b_encoding = rffi.str2charp('cp437') b_errors = rffi.str2charp('strict') assert space.text_w( PyUnicode_Decode(space, b_text, 4, b_encoding, b_errors)).decode('utf8') == u'caf\xe9' assert (space.text_w( PyUnicode_Decode(space, b_text, 4, b_encoding, None)) == u'caf\xe9'.encode("utf-8")) w_text = PyUnicode_FromEncodedObject(space, space.newbytes("test"), b_encoding, None) assert space.isinstance_w(w_text, space.w_unicode) assert space.utf8_w(w_text) == "test" with raises_w(space, TypeError): PyUnicode_FromEncodedObject(space, space.wrap(u"test"), b_encoding, None) with raises_w(space, TypeError): PyUnicode_FromEncodedObject(space, space.wrap(1), b_encoding, None) rffi.free_charp(b_text) rffi.free_charp(b_encoding)
def store(self, pool, offset, value): if value is null: ptr = rffi.cast(rffi.VOIDPP, offset) ptr[0] = lltype.nullptr(rffi.VOIDP.TO) elif isinstance(value, Mem): pool_mark_object(pool, value) # It could be worthwhile to typecheck the ctype here. if not self.typecheck(value.ctype): raise unwind(LTypeError(u"incompatible pointer store: %s = %s" % (self.repr(), value.ctype.repr()))) ptr = rffi.cast(rffi.VOIDPP, offset) ptr[0] = value.pointer elif isinstance(value, Uint8Array): pool_mark_object(pool, value) ptr = rffi.cast(rffi.VOIDPP, offset) ptr[0] = rffi.cast(rffi.VOIDP, value.uint8data) elif pool is None: raise unwind(LTypeError(u"cannot store other than memory references into non-pool-backed pointers")) elif isinstance(value, String): to = self.to if isinstance(to, Type) and to.size == 1: pointer = rffi.str2charp(as_cstring(value)) pointer = rffi.cast(rffi.VOIDP, pointer) ptr = rffi.cast(rffi.VOIDPP, offset) ptr[0] = pointer pool_mark(pool, pointer) else: raise unwind(LTypeError(u"cannot pointer store string to %s" % self.repr())) elif isinstance(value, List): # Won't possibly work in parametric objects.. hm. length = len(value.contents) if length > 0: pointer = pool_alloc(pool, sizeof_a(self.to, length)) ptr = rffi.cast(rffi.VOIDPP, offset) ptr[0] = pointer mem = Mem(self, pointer, length, pool) for i, val in enumerate(value.contents): mem.setitem(Integer(i), val) else: ptr = rffi.cast(rffi.VOIDPP, offset) ptr[0] = lltype.nullptr(rffi.VOIDP.TO) else: pointer = pool_alloc(pool, sizeof(self.to)) ptr = rffi.cast(rffi.VOIDPP, offset) ptr[0] = pointer self.to.store(pool, pointer, value) #else: # raise unwind(LTypeError(u"cannot pointer store %s to %s" % (value.repr(), self.repr()))) return value
def test_latin1(self, space, api): s = 'abcdefg' data = rffi.str2charp(s) w_u = api.PyUnicode_DecodeLatin1(data, len(s), lltype.nullptr(rffi.CCHARP.TO)) assert space.eq_w(w_u, space.wrap(u"abcdefg")) rffi.free_charp(data) uni = u'abcdefg' data = rffi.unicode2wcharp(uni) w_s = api.PyUnicode_EncodeLatin1(data, len(uni), lltype.nullptr(rffi.CCHARP.TO)) assert space.eq_w(space.wrapbytes("abcdefg"), w_s) rffi.free_wcharp(data) ustr = "abcdef" w_ustr = space.wrap(ustr.decode("ascii")) result = api.PyUnicode_AsLatin1String(w_ustr) assert space.eq_w(space.wrapbytes(ustr), result)
def PyUnicode_AsUTF8AndSize(space, ref, psize): if not PyUnicode_Check(space, ref): PyErr_BadArgument(space) if not get_ready(ref): res = _PyUnicode_Ready(space, ref) if not get_utf8(ref): # Copy unicode buffer w_unicode = from_ref(space, ref) w_encoded = unicodeobject.encode_object(space, w_unicode, "utf-8", "strict") s = space.bytes_w(w_encoded) set_utf8(ref, rffi.str2charp(s)) set_utf8_len(ref, len(s)) if psize: psize[0] = get_utf8_len(ref) return get_utf8(ref)
def initialize_timezone(interp, func_name, this, name, warning=False): this.timelib_timezone = timelib.timelib_parse_tzfile( rffi.str2charp(name), timelib.timelib_builtin_db()) if this.timelib_timezone == lltype.nullptr(timelib.timelib_tzinfo.TO): message = "%s(): Unknown or bad timezone (%s)" % (func_name, name) if warning: interp.space.ec.warn(message) else: raise PHPException( k_Exception.call_args(interp, [interp.space.wrap(message)])) return False this.timezone_info = TimeZoneWrapper(this.timelib_timezone, 3) return True
def test_run_file(self, space): filepath = udir / "cpyext_test_runfile.py" filepath.write("raise ZeroDivisionError") fp = c_fopen(str(filepath), "rb") filename = rffi.str2charp(str(filepath)) w_globals = w_locals = space.newdict() with raises_w(space, ZeroDivisionError): PyRun_File(space, fp, filename, Py_file_input, w_globals, w_locals) c_fclose(fp) # try again, but with a closed file fp = c_fopen(str(filepath), "rb") os.close(c_fileno(fp)) with raises_w(space, IOError): PyRun_File(space, fp, filename, Py_file_input, w_globals, w_locals) c_fclose(fp) rffi.free_charp(filename)
def timelib_time_modify(timelib_time, modifier, tzi): ll_s = rffi.str2charp(modifier) error_c = lltype.malloc(timelib_error_containerP.TO, 1, flavor='raw') tmp_timelib_time = timelib_strtotime(ll_s, len(modifier), error_c, timelib_builtin_db(), tzinfo_callback) lltype.free(error_c, flavor='raw') rffi.c_memcpy(rffi.cast(rffi.VOIDP, timelib_time.c_relative), rffi.cast(rffi.VOIDP, tmp_timelib_time.c_relative), rffi.sizeof(timelib_rel_time)) timelib_time.c_have_relative = tmp_timelib_time.c_have_relative timelib_time.c_sse_uptodate = rffi.cast(rffi.UINT, 0) if intmask(tmp_timelib_time.c_y) != -99999: timelib_time.c_y = tmp_timelib_time.c_y if intmask(tmp_timelib_time.c_m) != -99999: timelib_time.c_m = tmp_timelib_time.c_m if intmask(tmp_timelib_time.c_d) != -99999: timelib_time.c_d = tmp_timelib_time.c_d if intmask(tmp_timelib_time.c_h) != -99999: timelib_time.c_h = tmp_timelib_time.c_h if intmask(tmp_timelib_time.c_i) != -99999: timelib_time.c_i = tmp_timelib_time.c_i if intmask(tmp_timelib_time.c_s) != -99999: timelib_time.c_s = tmp_timelib_time.c_s else: timelib_time.c_s = rffi.cast(lltype.Signed, 0) else: timelib_time.c_i = rffi.cast(lltype.Signed, 0) timelib_time.c_s = rffi.cast(lltype.Signed, 0) timelib_time_dtor(tmp_timelib_time) timelib_update_ts(timelib_time, lltype.nullptr(timelib_tzinfo.TO)) timelib_update_from_sse(timelib_time) timelib_time.c_have_relative = rffi.cast(rffi.UINT, 0) return timelib_time
def test_SetAttr(self, space, api): w_obj = space.appexec([], """(): class C: pass return C()""") api.PyObject_SetAttr(w_obj, space.wrap('test'), space.wrap(5)) assert not api.PyErr_Occurred() assert space.unwrap(space.getattr(w_obj, space.wrap('test'))) == 5 assert api.PyObject_HasAttr(w_obj, space.wrap('test')) api.PyObject_SetAttr(w_obj, space.wrap('test'), space.wrap(10)) assert space.unwrap(space.getattr(w_obj, space.wrap('test'))) == 10 buf = rffi.str2charp('test') api.PyObject_SetAttrString(w_obj, buf, space.wrap(20)) rffi.free_charp(buf) assert space.unwrap(space.getattr(w_obj, space.wrap('test'))) == 20
def test_run_file(self, space): filepath = udir / "cpyext_test_runfile.py" filepath.write("raise ZeroDivisionError") fp = c_fopen(str(filepath), "rb") filename = rffi.str2charp(str(filepath)) w_globals = w_locals = space.newdict() with raises_w(space, ZeroDivisionError): PyRun_File(space, fp, filename, Py_file_input, w_globals, w_locals) c_fclose(fp) # try again, but with a closed file if self.runappdirect: # according to man 2 fclose, any access of fp is undefined # behaviour. This crashes on some linux systems untranslated fp = c_fopen(str(filepath), "rb") c_fclose(fp) with raises_w(space, IOError): PyRun_File(space, fp, filename, Py_file_input, w_globals, w_locals) rffi.free_charp(filename)
def buff_w(space, w_self, view, flags): w_obj = w_self 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: s = buf.as_str() w_s = space.newbytes(s) view.c_obj = make_ref(space, w_s) view.c_buf = rffi.cast( rffi.VOIDP, rffi.str2charp(s, track_allocation=False)) rffi.setintfield(view, 'c_readonly', 1) ret = fill_Py_buffer(space, buf, view) return ret return 0
def test_run_file(self, space, api): filepath = udir / "cpyext_test_runfile.py" filepath.write("raise ZeroDivisionError") fp = fopen(str(filepath), "rb") filename = rffi.str2charp(str(filepath)) w_globals = w_locals = space.newdict() api.PyRun_File(fp, filename, Py_file_input, w_globals, w_locals) fclose(fp) assert api.PyErr_Occurred() is space.w_ZeroDivisionError api.PyErr_Clear() # try again, but with a closed file fp = fopen(str(filepath), "rb") os.close(fileno(fp)) api.PyRun_File(fp, filename, Py_file_input, w_globals, w_locals) fclose(fp) assert api.PyErr_Occurred() is space.w_IOError api.PyErr_Clear() rffi.free_charp(filename)
def ffi_set_value(self, ptr, val): pnt = rffi.cast(rffi.VOIDPP, ptr) if isinstance(val, String): pnt = rffi.cast(rffi.CCHARPP, ptr) utf8 = unicode_to_utf8(rt.name(val)) raw = rffi.str2charp(utf8) pnt[0] = raw return CCharPToken(raw) elif isinstance(val, Buffer): pnt[0] = val.buffer() elif isinstance(val, VoidP): pnt[0] = val.raw_data() elif val is nil: pnt[0] = rffi.cast(rffi.VOIDP, 0) elif isinstance(val, CStruct): pnt[0] = rffi.cast(rffi.VOIDP, val.raw_data()) else: frm_name = rt.name(rt.str(val.type())) to_name = rt.name(rt.str(self)) affirm(False, u"Cannot encode " + frm_name + u" as " + to_name)
def strtod(input): if len(input) > _INT_LIMIT: raise MemoryError end_ptr = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw') try: ll_input = rffi.str2charp(input) try: result = dg_strtod(ll_input, end_ptr) endpos = (rffi.cast(lltype.Signed, end_ptr[0]) - rffi.cast(lltype.Signed, ll_input)) if endpos == 0 or endpos < len(input): raise ValueError("invalid input at position %d" % (endpos, )) return result finally: rffi.free_charp(ll_input) finally: lltype.free(end_ptr, flavor='raw')
def buff_w(space, w_self, c_view, flags): args = Arguments(space, [space.newint(flags)]) w_obj = space.call_args(space.get(buff_fn, w_self), args) if c_view: #like PyObject_GetBuffer flags = widen(flags) buf = space.buffer_w(w_obj, flags) try: c_view.c_buf = rffi.cast(rffi.VOIDP, buf.get_raw_address()) c_view.c_obj = make_ref(space, w_obj) except ValueError: s = buf.as_str() w_s = space.newbytes(s) c_view.c_obj = make_ref(space, w_s) c_view.c_buf = rffi.cast( rffi.VOIDP, rffi.str2charp(s, track_allocation=False)) rffi.setintfield(c_view, 'c_readonly', 1) ret = fill_Py_buffer(space, buf, c_view) return ret return 0
def do_send_string(self, space, buf, offset, size): from pypy.module._multiprocessing.interp_win32 import ( _WriteFile, ERROR_NO_SYSTEM_RESOURCES) from rpython.rlib import rwin32 charp = rffi.str2charp(buf) written_ptr = lltype.malloc(rffi.CArrayPtr(rwin32.DWORD).TO, 1, flavor='raw') try: result = _WriteFile(self.handle, rffi.ptradd(charp, offset), size, written_ptr, rffi.NULL) if (result == 0 and rwin32.GetLastError_saved() == ERROR_NO_SYSTEM_RESOURCES): raise oefmt(space.w_ValueError, "Cannot send %d bytes over connection", size) finally: rffi.free_charp(charp) lltype.free(written_ptr, flavor='raw')
def _retry_as_ldscript(err, mode): """ ld scripts are fairly straightforward to parse (the library we want is in a form like 'GROUP ( <actual-filepath.so>'. A simple state machine can parse that out (avoids regexes).""" parts = err.split(":") if len(parts) != 2: return lltype.nullptr(rffi.VOIDP.TO) fullpath = parts[0] actual = "" last_five = " " state = 0 ldscript = os.open(fullpath, os.O_RDONLY, 0777) c = os.read(ldscript, 1) while c != "": if state == 0: last_five += c last_five = last_five[1:6] if last_five == "GROUP": state = 1 elif state == 1: if c == "(": state = 2 elif state == 2: if c not in string.whitespace: actual += c state = 3 elif state == 3: if c in string.whitespace or c == ")": break else: actual += c c = os.read(ldscript, 1) os.close(ldscript) if actual != "": a = rffi.str2charp(actual) lib = c_dlopen(a, rffi.cast(rffi.INT, mode)) rffi.free_charp(a) return lib else: return lltype.nullptr(rffi.VOIDP.TO)
def buffer_attach(space, py_obj, w_obj, w_userdata=None): """ Fills a newly allocated PyBufferObject with the given buffer object. """ py_buf = rffi.cast(PyBufferObject, py_obj) py_buf.c_b_offset = 0 rffi.setintfield(py_buf, 'c_b_readonly', 1) rffi.setintfield(py_buf, 'c_b_hash', -1) assert isinstance(w_obj, W_Buffer) buf = w_obj.buf if isinstance(buf, SubBuffer): py_buf.c_b_offset = buf.offset buf = buf.buffer # If buf already allocated a fixed buffer, use it, and keep a # reference to buf. # Otherwise, b_base stays NULL, and we own the b_ptr. if isinstance(buf, StringBuffer): py_buf.c_b_base = lltype.nullptr(PyObject.TO) py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, rffi.str2charp(buf.value)) py_buf.c_b_size = buf.getlength() elif isinstance(buf, ArrayBuffer): w_base = buf.w_array py_buf.c_b_base = make_ref(space, w_base) py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, buf.w_array._charbuf_start()) py_buf.c_b_size = buf.getlength() elif isinstance(buf, CBuffer): py_buf.c_b_base = make_ref(space, buf.view.w_obj) py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, buf.view.ptr) py_buf.c_b_size = buf.getlength() else: # Raising in attach will segfault. # It would be nice if we could handle the error more gracefully # with something like this # py_buf.c_b_base = lltype.nullptr(PyObject.TO) # py_buf.c_b_ptr = rffi.cast(rffi.VOIDP, 0) # py_buf.c_b_size = buf.getlength() raise oefmt(space.w_NotImplementedError, "buffer flavor not supported")
def textdomain(space, w_domain): """textdomain(domain) -> string Set the C library's textdomain to domain, returning the new domain.""" if space.is_w(w_domain, space.w_None): domain = None result = _textdomain(domain) result = rffi.charp2str(result) else: domain = space.str_w(w_domain) domain_c = rffi.str2charp(domain) try: result = _textdomain(domain_c) # note that 'result' may be the same pointer as 'domain_c' # (maybe?) so it must be converted to an RPython string # *before* we free domain_c. result = rffi.charp2str(result) finally: rffi.free_charp(domain_c) return space.wrap(result)
def PyString_AsStringAndSize(space, ref, buffer, length): if not PyString_Check(space, ref): raise OperationError(space.w_TypeError, space.wrap( "PyString_AsStringAndSize only support strings")) ref_str = rffi.cast(PyStringObject, ref) if not ref_str.c_buffer: # copy string buffer w_str = from_ref(space, ref) s = space.str_w(w_str) ref_str.c_buffer = rffi.str2charp(s) buffer[0] = ref_str.c_buffer if length: length[0] = ref_str.c_size else: i = 0 while ref_str.c_buffer[i] != '\0': i += 1 if i != ref_str.c_size: raise OperationError(space.w_TypeError, space.wrap( "expected string without null bytes")) return 0