From 4ea32d0797d0d061c1ea7893b9a3bb92b9a89fad Mon Sep 17 00:00:00 2001 From: Jeong Yunwon Date: Sun, 17 Apr 2022 21:33:50 +0900 Subject: [PATCH] vm.call_method takes owned object --- src/lib.rs | 6 +- stdlib/src/array.rs | 4 +- stdlib/src/bisect.rs | 4 +- stdlib/src/pyexpat.rs | 2 +- vm/src/builtins/mappingproxy.rs | 8 +- vm/src/builtins/object.rs | 2 +- vm/src/codecs.rs | 4 +- vm/src/format.rs | 2 +- vm/src/protocol/mapping.rs | 2 +- vm/src/py_io.rs | 5 +- vm/src/stdlib/builtins.rs | 17 +-- vm/src/stdlib/io.rs | 208 +++++++++++++++++--------------- vm/src/stdlib/itertools.rs | 6 +- vm/src/stdlib/marshal.rs | 4 +- vm/src/stdlib/operator.rs | 2 +- vm/src/stdlib/sre.rs | 2 +- vm/src/vm_object.rs | 16 +-- 17 files changed, 158 insertions(+), 136 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 366df3b301..33231e1c5d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -152,10 +152,10 @@ where fn flush_std(vm: &VirtualMachine) { if let Ok(stdout) = sys::get_stdout(vm) { - let _ = vm.call_method(&stdout, "flush", ()); + let _ = vm.call_method(stdout, "flush", ()); } if let Ok(stderr) = sys::get_stderr(vm) { - let _ = vm.call_method(&stderr, "flush", ()); + let _ = vm.call_method(stderr, "flush", ()); } } @@ -666,7 +666,7 @@ fn get_importer(path: &str, vm: &VirtualMachine) -> PyResult fn insert_sys_path(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<()> { let sys_path = vm.sys_module.clone().get_attr("path", vm).unwrap(); - vm.call_method(&sys_path, "insert", (0, obj))?; + vm.call_method(sys_path, "insert", (0, obj))?; Ok(()) } diff --git a/stdlib/src/array.rs b/stdlib/src/array.rs index 8f9951b068..e489148ada 100644 --- a/stdlib/src/array.rs +++ b/stdlib/src/array.rs @@ -832,7 +832,7 @@ mod array { let n = vm.check_repeat_or_overflow_error(itemsize, n)?; let nbytes = n * itemsize; - let b = vm.call_method(&f, "read", (nbytes,))?; + let b = vm.call_method(f, "read", (nbytes,))?; let b = b .downcast::() .map_err(|_| vm.new_type_error("read() didn't return bytes".to_owned()))?; @@ -898,7 +898,7 @@ mod array { for b in bytes.chunks(BLOCKSIZE) { let b = PyBytes::from(b.to_vec()).into_ref(vm); - vm.call_method(&f, "write", (b,))?; + vm.call_method(f.clone(), "write", (b,))?; } Ok(()) } diff --git a/stdlib/src/bisect.rs b/stdlib/src/bisect.rs index 555fa029bd..14ce128533 100644 --- a/stdlib/src/bisect.rs +++ b/stdlib/src/bisect.rs @@ -129,7 +129,7 @@ mod _bisect { }, vm, )?; - vm.call_method(&a, "insert", (index, x)) + vm.call_method(a, "insert", (index, x)) } /// Insert item x in list a, and keep it sorted assuming a is sorted. @@ -149,6 +149,6 @@ mod _bisect { }, vm, )?; - vm.call_method(&a, "insert", (index, x)) + vm.call_method(a, "insert", (index, x)) } } diff --git a/stdlib/src/pyexpat.rs b/stdlib/src/pyexpat.rs index 2aa7a70d58..ff6c370be5 100644 --- a/stdlib/src/pyexpat.rs +++ b/stdlib/src/pyexpat.rs @@ -162,7 +162,7 @@ mod _pyexpat { #[pymethod(name = "ParseFile")] fn parse_file(&self, file: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { // todo: read chunks at a time - let read_res = vm.call_method(&file, "read", ())?; + let read_res = vm.call_method(file, "read", ())?; let bytes_like = ArgBytesLike::try_from_object(vm, read_res)?; let buf = bytes_like.borrow_buf().to_vec(); let reader = Cursor::new(buf); diff --git a/vm/src/builtins/mappingproxy.rs b/vm/src/builtins/mappingproxy.rs index 049e530e2d..f87fc9311f 100644 --- a/vm/src/builtins/mappingproxy.rs +++ b/vm/src/builtins/mappingproxy.rs @@ -114,7 +114,7 @@ impl PyMappingProxy { PyDict::from_attributes(c.attributes.read().clone(), vm)?.into_pyobject(vm) } }; - vm.call_method(&obj, "items", ()) + vm.call_method(obj, "items", ()) } #[pymethod] pub fn keys(&self, vm: &VirtualMachine) -> PyResult { @@ -124,7 +124,7 @@ impl PyMappingProxy { PyDict::from_attributes(c.attributes.read().clone(), vm)?.into_pyobject(vm) } }; - vm.call_method(&obj, "keys", ()) + vm.call_method(obj, "keys", ()) } #[pymethod] pub fn values(&self, vm: &VirtualMachine) -> PyResult { @@ -134,12 +134,12 @@ impl PyMappingProxy { PyDict::from_attributes(c.attributes.read().clone(), vm)?.into_pyobject(vm) } }; - vm.call_method(&obj, "values", ()) + vm.call_method(obj, "values", ()) } #[pymethod] pub fn copy(&self, vm: &VirtualMachine) -> PyResult { match &self.mapping { - MappingProxyInner::Dict(d) => vm.call_method(d, "copy", ()), + MappingProxyInner::Dict(d) => vm.call_method(d.to_owned(), "copy", ()), MappingProxyInner::Class(c) => { Ok(PyDict::from_attributes(c.attributes.read().clone(), vm)?.into_pyobject(vm)) } diff --git a/vm/src/builtins/object.rs b/vm/src/builtins/object.rs index 71044ef7a2..62ae16d55f 100644 --- a/vm/src/builtins/object.rs +++ b/vm/src/builtins/object.rs @@ -230,7 +230,7 @@ impl PyBaseObject { // Get instance attributes: if let Some(object_dict) = obj.dict() { - vm.call_method(dict.as_object(), "update", (object_dict,))?; + vm.call_method(dict.clone(), "update", (object_dict,))?; } let attributes: Vec<_> = dict.into_iter().map(|(k, _v)| k).collect(); diff --git a/vm/src/codecs.rs b/vm/src/codecs.rs index ead3e024b8..d60a3eea7e 100644 --- a/vm/src/codecs.rs +++ b/vm/src/codecs.rs @@ -106,7 +106,7 @@ impl PyCodec { Some(e) => vec![e.into()], None => vec![], }; - vm.call_method(self.0.as_object(), "incrementalencoder", args) + vm.call_method(self.0.clone(), "incrementalencoder", args) } pub fn get_incremental_decoder( @@ -118,7 +118,7 @@ impl PyCodec { Some(e) => vec![e.into()], None => vec![], }; - vm.call_method(self.0.as_object(), "incrementaldecoder", args) + vm.call_method(self.0.clone(), "incrementaldecoder", args) } } diff --git a/vm/src/format.rs b/vm/src/format.rs index 448b5c86e4..994a6423f2 100644 --- a/vm/src/format.rs +++ b/vm/src/format.rs @@ -891,7 +891,7 @@ fn call_object_format( Some(FormatPreconversor::Str) => argument.str(vm)?.into(), Some(FormatPreconversor::Repr) => argument.repr(vm)?.into(), Some(FormatPreconversor::Ascii) => vm.ctx.new_str(builtins::ascii(argument, vm)?).into(), - Some(FormatPreconversor::Bytes) => vm.call_method(&argument, "decode", ())?, + Some(FormatPreconversor::Bytes) => vm.call_method(argument, "decode", ())?, None => argument, }; let result = vm.call_special_method(argument, "__format__", (format_spec,))?; diff --git a/vm/src/protocol/mapping.rs b/vm/src/protocol/mapping.rs index d9a65707c0..1d43c6282b 100644 --- a/vm/src/protocol/mapping.rs +++ b/vm/src/protocol/mapping.rs @@ -152,7 +152,7 @@ impl PyMapping<'_> { } fn method_output_as_list(&self, method_name: &str, vm: &VirtualMachine) -> PyResult { - let meth_output = vm.call_method(self.obj, method_name, ())?; + let meth_output = vm.call_method(self.obj.to_owned(), method_name, ())?; if meth_output.is(&vm.ctx.types.list_type) { return Ok(meth_output); } diff --git a/vm/src/py_io.rs b/vm/src/py_io.rs index b705765841..96ed2eae14 100644 --- a/vm/src/py_io.rs +++ b/vm/src/py_io.rs @@ -55,13 +55,14 @@ impl Write for PyWriter<'_> { type Error = PyBaseExceptionRef; fn write_fmt(&mut self, args: fmt::Arguments) -> Result<(), Self::Error> { let PyWriter(obj, vm) = self; - vm.call_method(obj, "write", (args.to_string(),)).map(drop) + vm.call_method(obj.to_owned(), "write", (args.to_string(),)) + .map(drop) } } pub fn file_readline(obj: &PyObject, size: Option, vm: &VirtualMachine) -> PyResult { let args = size.map_or_else(Vec::new, |size| vec![vm.ctx.new_int(size).into()]); - let ret = vm.call_method(obj, "readline", args)?; + let ret = vm.call_method(obj.to_owned(), "readline", args)?; let eof_err = || { vm.new_exception( vm.ctx.exceptions.eof_error.clone(), diff --git a/vm/src/stdlib/builtins.rs b/vm/src/stdlib/builtins.rs index 6a0c2f3642..aaaceb2793 100644 --- a/vm/src/stdlib/builtins.rs +++ b/vm/src/stdlib/builtins.rs @@ -306,7 +306,7 @@ mod builtins { .into_option() .unwrap_or_else(|| PyStr::from("").into_ref(vm)); - vm.call_method(&value, "__format__", (format_spec,))? + vm.call_method(value, "__format__", (format_spec,))? .downcast() .map_err(|obj| { vm.new_type_error(format!( @@ -364,7 +364,7 @@ mod builtins { let stdout = sys::get_stdout(vm)?; let stderr = sys::get_stderr(vm)?; - let _ = vm.call_method(&stderr, "flush", ()); + let _ = vm.call_method(stderr, "flush", ()); let fd_matches = |obj, expected| { vm.call_method(obj, "fileno", ()) @@ -374,7 +374,10 @@ mod builtins { }; // everything is normalish, we can just rely on rustyline to use stdin/stdout - if fd_matches(&stdin, 0) && fd_matches(&stdout, 1) && atty::is(atty::Stream::Stdin) { + if fd_matches(stdin.clone(), 0) + && fd_matches(stdout.clone(), 1) + && atty::is(atty::Stream::Stdin) + { let prompt = prompt.as_ref().map_or("", |s| s.as_str()); let mut readline = Readline::new(()); match readline.readline(prompt) { @@ -393,9 +396,9 @@ mod builtins { } } else { if let OptionalArg::Present(prompt) = prompt { - vm.call_method(&stdout, "write", (prompt,))?; + vm.call_method(stdout.clone(), "write", (prompt,))?; } - let _ = vm.call_method(&stdout, "flush", ()); + let _ = vm.call_method(stdout, "flush", ()); py_io::file_readline(&stdin, None, vm) } } @@ -648,7 +651,7 @@ mod builtins { Some(f) => f, None => sys::get_stdout(vm)?, }; - let write = |obj: PyStrRef| vm.call_method(&file, "write", (obj,)); + let write = |obj: PyStrRef| vm.call_method(file.clone(), "write", (obj,)); let sep = options.sep.unwrap_or_else(|| PyStr::from(" ").into_ref(vm)); @@ -669,7 +672,7 @@ mod builtins { write(end)?; if options.flush.to_bool() { - vm.call_method(&file, "flush", ())?; + vm.call_method(file, "flush", ())?; } Ok(()) diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index 69333715ca..9a1a663260 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -288,10 +288,11 @@ mod _io { } } - fn file_closed(file: &PyObject, vm: &VirtualMachine) -> PyResult { - file.to_owned().get_attr("closed", vm)?.try_to_bool(vm) + fn file_closed(file: PyObjectRef, vm: &VirtualMachine) -> PyResult { + file.get_attr("closed", vm)?.try_to_bool(vm) } - fn check_closed(file: &PyObject, vm: &VirtualMachine) -> PyResult<()> { + + fn check_closed(file: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { if file_closed(file, vm)? { Err(io_closed_error(vm)) } else { @@ -299,7 +300,7 @@ mod _io { } } - fn check_readable(file: &PyObject, vm: &VirtualMachine) -> PyResult<()> { + fn check_readable(file: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { if vm.call_method(file, "readable", ())?.try_to_bool(vm)? { Ok(()) } else { @@ -310,7 +311,7 @@ mod _io { } } - fn check_writable(file: &PyObject, vm: &VirtualMachine) -> PyResult<()> { + fn check_writable(file: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { if vm.call_method(file, "writable", ())?.try_to_bool(vm)? { Ok(()) } else { @@ -321,7 +322,7 @@ mod _io { } } - fn check_seekable(file: &PyObject, vm: &VirtualMachine) -> PyResult<()> { + fn check_seekable(file: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { if vm.call_method(file, "seekable", ())?.try_to_bool(vm)? { Ok(()) } else { @@ -359,7 +360,7 @@ mod _io { } #[pymethod] fn tell(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult { - vm.call_method(&zelf, "seek", (0, 1)) + vm.call_method(zelf, "seek", (0, 1)) } #[pymethod] fn truncate(zelf: PyObjectRef, _pos: OptionalArg, vm: &VirtualMachine) -> PyResult { @@ -377,20 +378,20 @@ mod _io { #[pymethod(magic)] fn enter(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult { - check_closed(&instance, vm)?; + check_closed(instance.clone(), vm)?; Ok(instance) } #[pymethod(magic)] fn exit(instance: PyObjectRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> { - vm.call_method(&instance, "close", ())?; + vm.call_method(instance, "close", ())?; Ok(()) } #[pymethod] fn flush(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { // just check if this is closed; if it isn't, do nothing - check_closed(&instance, vm) + check_closed(instance, vm) } #[pymethod] @@ -418,7 +419,7 @@ mod _io { #[pymethod] fn close(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { - iobase_close(&instance, vm) + iobase_close(instance, vm) } #[pymethod] @@ -475,37 +476,37 @@ mod _io { lines: ArgIterable, vm: &VirtualMachine, ) -> PyResult<()> { - check_closed(&instance, vm)?; + check_closed(instance.clone(), vm)?; for line in lines.iter(vm)? { - vm.call_method(&instance, "write", (line?,))?; + vm.call_method(instance.clone(), "write", (line?,))?; } Ok(()) } #[pymethod(name = "_checkClosed")] fn check_closed(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { - check_closed(&instance, vm) + check_closed(instance, vm) } #[pymethod(name = "_checkReadable")] fn check_readable(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { - check_readable(&instance, vm) + check_readable(instance, vm) } #[pymethod(name = "_checkWritable")] fn check_writable(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { - check_writable(&instance, vm) + check_writable(instance, vm) } #[pymethod(name = "_checkSeekable")] fn check_seekable(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { - check_seekable(&instance, vm) + check_seekable(instance, vm) } } impl Destructor for _IOBase { fn slot_del(zelf: &PyObject, vm: &VirtualMachine) -> PyResult<()> { - let _ = vm.call_method(zelf, "close", ()); + let _ = vm.call_method(zelf.to_owned(), "close", ()); Ok(()) } @@ -517,7 +518,7 @@ mod _io { impl Iterable for _IOBase { fn slot_iter(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult { - check_closed(&zelf, vm)?; + check_closed(zelf.clone(), vm)?; Ok(zelf) } @@ -528,7 +529,7 @@ mod _io { impl IterNext for _IOBase { fn slot_iternext(zelf: &PyObject, vm: &VirtualMachine) -> PyResult { - let line = vm.call_method(zelf, "readline", ())?; + let line = vm.call_method(zelf.to_owned(), "readline", ())?; Ok(if !line.clone().try_to_bool(vm)? { PyIterReturn::StopIteration(None) } else { @@ -541,9 +542,9 @@ mod _io { } } - pub(super) fn iobase_close(file: &PyObject, vm: &VirtualMachine) -> PyResult<()> { - if !file_closed(file, vm)? { - let res = vm.call_method(file, "flush", ()); + pub(super) fn iobase_close(file: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { + if !file_closed(file.clone(), vm)? { + let res = vm.call_method(file.clone(), "flush", ()); file.set_attr("__closed", vm.new_pyobj(true), vm)?; res?; } @@ -563,7 +564,7 @@ mod _io { let b = PyByteArray::from(vec![0; size]).into_ref(vm); let n = >::try_from_object( vm, - vm.call_method(&instance, "readinto", (b.clone(),))?, + vm.call_method(instance, "readinto", (b.clone(),))?, )?; Ok(n.map(|n| { let mut bytes = b.borrow_buf_mut(); @@ -573,7 +574,7 @@ mod _io { }) .into_pyobject(vm)) } else { - vm.call_method(&instance, "readall", ()) + vm.call_method(instance, "readall", ()) } } @@ -582,7 +583,7 @@ mod _io { let mut chunks = Vec::new(); let mut total_len = 0; loop { - let data = vm.call_method(&instance, "read", (DEFAULT_BUFFER_SIZE,))?; + let data = vm.call_method(instance.clone(), "read", (DEFAULT_BUFFER_SIZE,))?; let data = >::try_from_object(vm, data)?; match data { None => { @@ -630,7 +631,7 @@ mod _io { ) -> PyResult { let b = ArgMemoryBuffer::try_from_borrowed_object(vm, &bufobj)?; let l = b.len(); - let data = vm.call_method(&zelf, method, (l,))?; + let data = vm.call_method(zelf, method, (l,))?; if data.is(&bufobj) { return Ok(l); } @@ -800,7 +801,7 @@ mod _io { } fn raw_seek(&mut self, pos: Offset, whence: i32, vm: &VirtualMachine) -> PyResult { - let ret = vm.call_method(self.check_init(vm)?, "seek", (pos, whence))?; + let ret = vm.call_method(self.check_init(vm)?.to_owned(), "seek", (pos, whence))?; let offset = get_offset(ret, vm)?; if offset < 0 { return Err( @@ -845,7 +846,7 @@ mod _io { } fn raw_tell(&mut self, vm: &VirtualMachine) -> PyResult { - let ret = vm.call_method(self.check_init(vm)?, "tell", ())?; + let ret = vm.call_method(self.check_init(vm)?.to_owned(), "tell", ())?; let offset = get_offset(ret, vm)?; if offset < 0 { return Err( @@ -876,7 +877,7 @@ mod _io { let memobj = PyMemoryView::from_buffer_range(buf, buf_range, vm)?.into_pyobject(vm); // TODO: loop if write() raises an interrupt - vm.call_method(self.raw.as_ref().unwrap(), "write", (memobj,))? + vm.call_method(self.raw.clone().unwrap(), "write", (memobj,))? } else { let v = std::mem::take(&mut self.buffer); let writebuf = VecBuffer::from(v).into_ref(vm); @@ -888,7 +889,7 @@ mod _io { .into_ref(vm); // TODO: loop if write() raises an interrupt - let res = vm.call_method(self.raw.as_ref().unwrap(), "write", (memobj.clone(),)); + let res = vm.call_method(self.raw.clone().unwrap(), "write", (memobj.clone(),)); memobj.release(); self.buffer = writebuf.take(); @@ -1114,7 +1115,7 @@ mod _io { // TODO: loop if readinto() raises an interrupt let res = - vm.call_method(self.raw.as_ref().unwrap(), "readinto", (memobj.clone(),)); + vm.call_method(self.raw.clone().unwrap(), "readinto", (memobj.clone(),)); memobj.release(); std::mem::swap(v, &mut readbuf.take()); @@ -1124,7 +1125,7 @@ mod _io { Either::B(buf) => { let memobj = PyMemoryView::from_buffer_range(buf, buf_range, vm)?; // TODO: loop if readinto() raises an interrupt - vm.call_method(self.raw.as_ref().unwrap(), "readinto", (memobj,))? + vm.call_method(self.raw.clone().unwrap(), "readinto", (memobj,))? } }; @@ -1179,7 +1180,7 @@ mod _io { let mut read_size = 0; loop { - let read_data = vm.call_method(self.raw.as_ref().unwrap(), "read", ())?; + let read_data = vm.call_method(self.raw.clone().unwrap(), "read", ())?; let read_data = >::try_from_object(vm, read_data)?; match read_data { @@ -1366,15 +1367,15 @@ mod _io { }; if Self::SEEKABLE { - check_seekable(&raw, vm)?; + check_seekable(raw.clone(), vm)?; } if Self::READABLE { data.flags.insert(BufferedFlags::READABLE); - check_readable(&raw, vm)?; + check_readable(raw.clone(), vm)?; } if Self::WRITABLE { data.flags.insert(BufferedFlags::WRITABLE); - check_writable(&raw, vm)?; + check_writable(raw.clone(), vm)?; } data.buffer = vec![0; buffer_size]; @@ -1407,7 +1408,7 @@ mod _io { let mut data = self.lock(vm)?; let raw = data.check_init(vm)?; ensure_unclosed(raw, "seek of closed file", vm)?; - check_seekable(raw, vm)?; + check_seekable(raw.to_owned(), vm)?; let target = get_offset(target, vm)?; data.seek(target, whence, vm) } @@ -1428,13 +1429,13 @@ mod _io { if data.writable() { data.flush_rewind(vm)?; } - let res = vm.call_method(data.raw.as_ref().unwrap(), "truncate", (pos,))?; + let res = vm.call_method(data.raw.clone().unwrap(), "truncate", (pos,))?; let _ = data.raw_tell(vm); Ok(res) } #[pymethod] fn detach(zelf: PyRef, vm: &VirtualMachine) -> PyResult { - vm.call_method(zelf.as_object(), "flush", ())?; + vm.call_method(zelf.clone(), "flush", ())?; let mut data = zelf.lock(vm)?; data.flags.insert(BufferedFlags::DETACHED); data.raw @@ -1443,7 +1444,7 @@ mod _io { } #[pymethod] fn seekable(&self, vm: &VirtualMachine) -> PyResult { - vm.call_method(self.lock(vm)?.check_init(vm)?, "seekable", ()) + vm.call_method(self.lock(vm)?.check_init(vm)?.to_owned(), "seekable", ()) } #[pyproperty] fn raw(&self, vm: &VirtualMachine) -> PyResult> { @@ -1472,11 +1473,11 @@ mod _io { } #[pymethod] fn fileno(&self, vm: &VirtualMachine) -> PyResult { - vm.call_method(self.lock(vm)?.check_init(vm)?, "fileno", ()) + vm.call_method(self.lock(vm)?.check_init(vm)?.to_owned(), "fileno", ()) } #[pymethod] fn isatty(&self, vm: &VirtualMachine) -> PyResult { - vm.call_method(self.lock(vm)?.check_init(vm)?, "isatty", ()) + vm.call_method(self.lock(vm)?.check_init(vm)?.to_owned(), "isatty", ()) } #[pymethod(magic)] @@ -1495,11 +1496,11 @@ mod _io { fn close_strict(&self, vm: &VirtualMachine) -> PyResult { let mut data = self.lock(vm)?; let raw = data.check_init(vm)?; - if file_closed(raw, vm)? { + if file_closed(raw.to_owned(), vm)? { return Ok(vm.ctx.none()); } let flush_res = data.flush(vm); - let close_res = vm.call_method(data.raw.as_ref().unwrap(), "close", ()); + let close_res = vm.call_method(data.raw.clone().unwrap(), "close", ()); exeption_chain(flush_res, close_res) } @@ -1508,13 +1509,13 @@ mod _io { { let data = zelf.lock(vm)?; let raw = data.check_init(vm)?; - if file_closed(raw, vm)? { + if file_closed(raw.to_owned(), vm)? { return Ok(vm.ctx.none()); } } - let flush_res = vm.call_method(zelf.as_object(), "flush", ()).map(drop); + let flush_res = vm.call_method(zelf.clone(), "flush", ()).map(drop); let data = zelf.lock(vm)?; - let raw = data.raw.as_ref().unwrap(); + let raw = data.raw.clone().unwrap(); let close_res = vm.call_method(raw, "close", ()); exeption_chain(flush_res, close_res) } @@ -2114,7 +2115,7 @@ mod _io { set_field!(self.bytes_to_skip, BYTES_TO_SKIP_OFF); num_bigint::BigUint::from_bytes_le(&buf).into() } - fn set_decoder_state(&self, decoder: &PyObject, vm: &VirtualMachine) -> PyResult<()> { + fn set_decoder_state(&self, decoder: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { if self.start_pos == 0 && self.dec_flags == 0 { vm.call_method(decoder, "reset", ())?; } else { @@ -2186,11 +2187,16 @@ mod _io { let buffer = args.buffer; let has_read1 = vm.get_attribute_opt(buffer.clone(), "read1")?.is_some(); - let seekable = vm.call_method(&buffer, "seekable", ())?.try_to_bool(vm)?; + let seekable = vm + .call_method(buffer.clone(), "seekable", ())? + .try_to_bool(vm)?; let codec = vm.state.codec_registry.lookup(encoding.as_str(), vm)?; - let encoder = if vm.call_method(&buffer, "writable", ())?.try_to_bool(vm)? { + let encoder = if vm + .call_method(buffer.clone(), "writable", ())? + .try_to_bool(vm)? + { let incremental_encoder = codec.get_incremental_encoder(Some(errors.clone()), vm)?; let encoding_name = vm.get_attribute_opt(incremental_encoder.clone(), "name")?; @@ -2206,7 +2212,10 @@ mod _io { None }; - let decoder = if vm.call_method(&buffer, "readable", ())?.try_to_bool(vm)? { + let decoder = if vm + .call_method(buffer.clone(), "readable", ())? + .try_to_bool(vm)? + { let incremental_decoder = codec.get_incremental_decoder(Some(errors.clone()), vm)?; // TODO: wrap in IncrementalNewlineDecoder if newlines == Universal | Passthrough @@ -2242,17 +2251,17 @@ mod _io { #[pymethod] fn seekable(&self, vm: &VirtualMachine) -> PyResult { let textio = self.lock(vm)?; - vm.call_method(&textio.buffer, "seekable", ()) + vm.call_method(textio.buffer.clone(), "seekable", ()) } #[pymethod] fn readable(&self, vm: &VirtualMachine) -> PyResult { let textio = self.lock(vm)?; - vm.call_method(&textio.buffer, "readable", ()) + vm.call_method(textio.buffer.clone(), "readable", ()) } #[pymethod] fn writable(&self, vm: &VirtualMachine) -> PyResult { let textio = self.lock(vm)?; - vm.call_method(&textio.buffer, "writable", ()) + vm.call_method(textio.buffer.clone(), "writable", ()) } #[pyproperty(name = "_CHUNK_SIZE")] @@ -2276,7 +2285,7 @@ mod _io { ) -> PyResult { let how = how.unwrap_or(0); - let reset_encoder = |encoder, start_of_stream| { + let reset_encoder = |encoder: PyObjectRef, start_of_stream| { if start_of_stream { vm.call_method(encoder, "reset", ()) } else { @@ -2299,7 +2308,7 @@ mod _io { // SEEK_CUR 1 => { if vm.bool_eq(&cookie, vm.ctx.new_int(0).as_ref())? { - vm.call_method(&textio.buffer, "tell", ())? + vm.call_method(textio.buffer.clone(), "tell", ())? } else { return Err(new_unsupported_operation( vm, @@ -2311,17 +2320,17 @@ mod _io { 2 => { if vm.bool_eq(&cookie, vm.ctx.new_int(0).as_ref())? { drop(textio); - vm.call_method(zelf.as_object(), "flush", ())?; + vm.call_method(zelf.clone(), "flush", ())?; let mut textio = zelf.lock(vm)?; textio.set_decoded_chars(None); textio.snapshot = None; if let Some(decoder) = &textio.decoder { - vm.call_method(decoder, "reset", ())?; + vm.call_method(decoder.clone(), "reset", ())?; } - let res = vm.call_method(&textio.buffer, "seek", (0, 2))?; + let res = vm.call_method(textio.buffer.clone(), "seek", (0, 2))?; if let Some((encoder, _)) = &textio.encoder { let start_of_stream = vm.bool_eq(&res, vm.ctx.new_int(0).as_ref())?; - reset_encoder(encoder, start_of_stream)?; + reset_encoder(encoder.to_owned(), start_of_stream)?; } return Ok(res); } else { @@ -2343,16 +2352,16 @@ mod _io { ); } drop(textio); - vm.call_method(zelf.as_object(), "flush", ())?; + vm.call_method(zelf.clone(), "flush", ())?; let cookie_obj = crate::builtins::PyIntRef::try_from_object(vm, cookie)?; let cookie = TextIOCookie::parse(cookie_obj.as_bigint()) .ok_or_else(|| vm.new_value_error("invalid cookie".to_owned()))?; let mut textio = zelf.lock(vm)?; - vm.call_method(&textio.buffer, "seek", (cookie.start_pos,))?; + vm.call_method(textio.buffer.clone(), "seek", (cookie.start_pos,))?; textio.set_decoded_chars(None); textio.snapshot = None; if let Some(decoder) = &textio.decoder { - cookie.set_decoder_state(decoder, vm)?; + cookie.set_decoder_state(decoder.to_owned(), vm)?; } if cookie.chars_to_skip != 0 { let TextIOData { @@ -2364,7 +2373,8 @@ mod _io { let decoder = decoder .as_ref() .ok_or_else(|| vm.new_value_error("invalid cookie".to_owned()))?; - let input_chunk = vm.call_method(buffer, "read", (cookie.bytes_to_feed,))?; + let input_chunk = + vm.call_method(buffer.to_owned(), "read", (cookie.bytes_to_feed,))?; let input_chunk: PyBytesRef = input_chunk.downcast().map_err(|obj| { vm.new_type_error(format!( "underlying read() should have returned a bytes object, not '{}'", @@ -2372,7 +2382,8 @@ mod _io { )) })?; *snapshot = Some((cookie.dec_flags, input_chunk.clone())); - let decoded = vm.call_method(decoder, "decode", (input_chunk, cookie.need_eof))?; + let decoded = + vm.call_method(decoder.to_owned(), "decode", (input_chunk, cookie.need_eof))?; let decoded = check_decoded(decoded, vm)?; let pos_is_valid = decoded .as_str() @@ -2387,7 +2398,7 @@ mod _io { } if let Some((encoder, _)) = &textio.encoder { let start_of_stream = cookie.start_pos == 0 && cookie.dec_flags == 0; - reset_encoder(encoder, start_of_stream)?; + reset_encoder(encoder.clone(), start_of_stream)?; } Ok(cookie_obj.into()) } @@ -2406,9 +2417,9 @@ mod _io { } textio.write_pending(vm)?; drop(textio); - vm.call_method(zelf.as_object(), "flush", ())?; + vm.call_method(zelf.clone(), "flush", ())?; let textio = zelf.lock(vm)?; - let pos = vm.call_method(&textio.buffer, "tell", ())?; + let pos = vm.call_method(textio.buffer.clone(), "tell", ())?; let (decoder, (dec_flags, next_input)) = match (&textio.decoder, &textio.snapshot) { (Some(d), Some(s)) => (d, s), _ => return Ok(pos), @@ -2423,20 +2434,24 @@ mod _io { return Ok(cookie.build().into_pyobject(vm)); } let decoder_getstate = || { - let state = vm.call_method(decoder, "getstate", ())?; + let state = vm.call_method(decoder.to_owned(), "getstate", ())?; parse_decoder_state(state, vm) }; let decoder_decode = |b: &[u8]| { - let decoded = vm.call_method(decoder, "decode", (vm.ctx.new_bytes(b.to_vec()),))?; + let decoded = vm.call_method( + decoder.to_owned(), + "decode", + (vm.ctx.new_bytes(b.to_vec()),), + )?; let decoded = check_decoded(decoded, vm)?; Ok(Utf8size::len_pystr(&decoded)) }; - let saved_state = vm.call_method(decoder, "getstate", ())?; + let saved_state = vm.call_method(decoder.to_owned(), "getstate", ())?; let mut num_to_skip = textio.decoded_chars_used; let mut skip_bytes = (textio.b2cratio * num_to_skip.chars as f64) as isize; let mut skip_back = 1; while skip_bytes > 0 { - cookie.set_decoder_state(decoder, vm)?; + cookie.set_decoder_state(decoder.to_owned(), vm)?; let input = &next_input.as_bytes()[..skip_bytes as usize]; let ndecoded = decoder_decode(input)?; if ndecoded.chars <= num_to_skip.chars { @@ -2455,7 +2470,7 @@ mod _io { } if skip_bytes <= 0 { skip_bytes = 0; - cookie.set_decoder_state(decoder, vm)?; + cookie.set_decoder_state(decoder.to_owned(), vm)?; } let skip_bytes = skip_bytes as usize; @@ -2485,8 +2500,11 @@ mod _io { input = rest; } if input.is_empty() { - let decoded = - vm.call_method(decoder, "decode", (vm.ctx.new_bytes(vec![]), true))?; + let decoded = vm.call_method( + decoder.to_owned(), + "decode", + (vm.ctx.new_bytes(vec![]), true), + )?; let decoded = check_decoded(decoded, vm)?; let final_decoded_chars = ndecoded.chars + decoded.char_len(); cookie.need_eof = true; @@ -2497,7 +2515,7 @@ mod _io { } } } - vm.call_method(decoder, "setstate", (saved_state,))?; + vm.call_method(decoder.to_owned(), "setstate", (saved_state,))?; cookie.set_num_to_skip(num_to_skip); Ok(cookie.build().into_pyobject(vm)) } @@ -2519,7 +2537,7 @@ mod _io { #[pymethod] fn fileno(&self, vm: &VirtualMachine) -> PyResult { let buffer = self.lock(vm)?.buffer.clone(); - vm.call_method(&buffer, "fileno", ()) + vm.call_method(buffer, "fileno", ()) } #[pymethod] @@ -2562,8 +2580,8 @@ mod _io { PyStr::from(ret).into_ref(vm) } } else { - let bytes = vm.call_method(&textio.buffer, "read", ())?; - let decoded = vm.call_method(&decoder, "decode", (bytes, true))?; + let bytes = vm.call_method(textio.buffer.clone(), "read", ())?; + let decoded = vm.call_method(decoder, "decode", (bytes, true))?; let decoded = check_decoded(decoded, vm)?; let ret = textio.take_decoded_chars(Some(decoded), vm); textio.snapshot = None; @@ -2609,7 +2627,7 @@ mod _io { let chunk = if let Some(encodefunc) = *encodefunc { encodefunc(chunk) } else { - let b = vm.call_method(encoder, "encode", (chunk.clone(),))?; + let b = vm.call_method(encoder.to_owned(), "encode", (chunk.clone(),))?; b.downcast::() .map(PendingWrite::Bytes) .or_else(|obj| { @@ -2633,7 +2651,7 @@ mod _io { textio.write_pending(vm)?; } if flush { - let _ = vm.call_method(&textio.buffer, "flush", ()); + let _ = vm.call_method(textio.buffer.clone(), "flush", ()); } Ok(char_len) @@ -2645,14 +2663,14 @@ mod _io { textio.check_closed(vm)?; textio.telling = textio.seekable; textio.write_pending(vm)?; - vm.call_method(&textio.buffer, "flush", ()) + vm.call_method(textio.buffer.clone(), "flush", ()) } #[pymethod] fn isatty(&self, vm: &VirtualMachine) -> PyResult { let textio = self.lock(vm)?; textio.check_closed(vm)?; - vm.call_method(&textio.buffer, "isatty", ()) + vm.call_method(textio.buffer.clone(), "isatty", ()) } #[pymethod] @@ -2660,7 +2678,7 @@ mod _io { let limit = size.to_usize(); let mut textio = self.lock(vm)?; - check_closed(&textio.buffer, vm)?; + check_closed(textio.buffer.clone(), vm)?; textio.write_pending(vm)?; @@ -2821,11 +2839,11 @@ mod _io { #[pymethod] fn close(zelf: PyRef, vm: &VirtualMachine) -> PyResult<()> { let buffer = zelf.lock(vm)?.buffer.clone(); - if file_closed(&buffer, vm)? { + if file_closed(buffer.clone(), vm)? { return Ok(()); } - let flush_res = vm.call_method(zelf.as_object(), "flush", ()).map(drop); - let close_res = vm.call_method(&buffer, "close", ()).map(drop); + let flush_res = vm.call_method(zelf, "flush", ()).map(drop); + let close_res = vm.call_method(buffer, "close", ()).map(drop); exeption_chain(flush_res, close_res) } #[pyproperty] @@ -2870,18 +2888,18 @@ mod _io { return Ok(()); } let data = self.pending.take(vm); - vm.call_method(&self.buffer, "write", (data,))?; + vm.call_method(self.buffer.clone(), "write", (data,))?; Ok(()) } /// returns true on EOF fn read_chunk(&mut self, size_hint: usize, vm: &VirtualMachine) -> PyResult { let decoder = self .decoder - .as_ref() + .clone() .ok_or_else(|| new_unsupported_operation(vm, "not readable".to_owned()))?; let dec_state = if self.telling { - let state = vm.call_method(decoder, "getstate", ())?; + let state = vm.call_method(decoder.clone(), "getstate", ())?; Some(parse_decoder_state(state, vm)?) } else { None @@ -2894,7 +2912,7 @@ mod _io { size_hint }; let chunk_size = std::cmp::max(self.chunk_size, size_hint); - let input_chunk = vm.call_method(&self.buffer, method, (chunk_size,))?; + let input_chunk = vm.call_method(self.buffer.clone(), method, (chunk_size,))?; let buf = ArgBytesLike::try_from_borrowed_object(vm, &input_chunk).map_err(|_| { vm.new_type_error(format!( @@ -2928,7 +2946,7 @@ mod _io { } fn check_closed(&self, vm: &VirtualMachine) -> PyResult<()> { - check_closed(&self.buffer, vm) + check_closed(self.buffer.clone(), vm) } /// returns str, str.char_len() (it might not be cached in the str yet but we calculate it @@ -3529,7 +3547,7 @@ mod _io { )?; let isatty = opts.buffering < 0 && { - let atty = vm.call_method(&raw, "isatty", ())?; + let atty = vm.call_method(raw.clone(), "isatty", ())?; bool::try_from_object(vm, atty)? }; @@ -3986,7 +4004,7 @@ mod fileio { #[pymethod] fn close(zelf: PyRef, vm: &VirtualMachine) -> PyResult<()> { - let res = iobase_close(zelf.as_object(), vm); + let res = iobase_close(zelf.clone().into(), vm); if !zelf.closefd.load() { zelf.fd.store(-1); return res; diff --git a/vm/src/stdlib/itertools.rs b/vm/src/stdlib/itertools.rs index 7d7dae7ed8..938c59796e 100644 --- a/vm/src/stdlib/itertools.rs +++ b/vm/src/stdlib/itertools.rs @@ -1003,14 +1003,14 @@ mod decl { let n = n.unwrap_or(2); let copyable = if iterable.class().has_attr("__copy__") { - vm.call_method(&iterable, "__copy__", ())? + vm.call_method(iterable, "__copy__", ())? } else { PyItertoolsTee::from_iter(iterable, vm)? }; let mut tee_vec: Vec = Vec::with_capacity(n); for _ in 0..n { - tee_vec.push(vm.call_method(©able, "__copy__", ())?); + tee_vec.push(vm.call_method(copyable.clone(), "__copy__", ())?); } Ok(PyTuple::new_ref(tee_vec, &vm.ctx).into()) @@ -1022,7 +1022,7 @@ mod decl { fn from_iter(iterator: PyIter, vm: &VirtualMachine) -> PyResult { let class = PyItertoolsTee::class(vm); if iterator.class().is(PyItertoolsTee::class(vm)) { - return vm.call_method(&iterator, "__copy__", ()); + return vm.call_method(iterator, "__copy__", ()); } Ok(PyItertoolsTee { tee_data: PyItertoolsTeeData::new(iterator, vm)?, diff --git a/vm/src/stdlib/marshal.rs b/vm/src/stdlib/marshal.rs index aaad31d797..5f7a5bf274 100644 --- a/vm/src/stdlib/marshal.rs +++ b/vm/src/stdlib/marshal.rs @@ -148,7 +148,7 @@ mod decl { #[pyfunction] fn dump(value: PyObjectRef, f: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { let dumped = dumps(value, vm)?; - vm.call_method(&f, "write", (dumped,))?; + vm.call_method(f, "write", (dumped,))?; Ok(()) } @@ -318,7 +318,7 @@ mod decl { #[pyfunction] fn load(f: PyObjectRef, vm: &VirtualMachine) -> PyResult { - let read_res = vm.call_method(&f, "read", ())?; + let read_res = vm.call_method(f, "read", ())?; let bytes = ArgBytesLike::try_from_object(vm, read_res)?; loads(PyBuffer::from(bytes), vm) } diff --git a/vm/src/stdlib/operator.rs b/vm/src/stdlib/operator.rs index 1366ca7bb3..1f8a37a390 100644 --- a/vm/src/stdlib/operator.rs +++ b/vm/src/stdlib/operator.rs @@ -660,7 +660,7 @@ mod _operator { #[inline] fn call(zelf: &PyObjectView, obj: Self::Args, vm: &VirtualMachine) -> PyResult { - vm.call_method(&obj, zelf.name.as_str(), zelf.args.clone()) + vm.call_method(obj, zelf.name.as_str(), zelf.args.clone()) } } } diff --git a/vm/src/stdlib/sre.rs b/vm/src/stdlib/sre.rs index 9c41cfcb28..4ba2c7d7dd 100644 --- a/vm/src/stdlib/sre.rs +++ b/vm/src/stdlib/sre.rs @@ -490,7 +490,7 @@ mod _sre { } else { vm.ctx.new_str(ascii!("")).into() }; - let ret = vm.call_method(&join_type, "join", (list,))?; + let ret = vm.call_method(join_type, "join", (list,))?; Ok(if subn { (ret, n).into_pyobject(vm) diff --git a/vm/src/vm_object.rs b/vm/src/vm_object.rs index d9f1bd2d77..379ed5dbf9 100644 --- a/vm/src/vm_object.rs +++ b/vm/src/vm_object.rs @@ -111,18 +111,18 @@ impl VirtualMachine { } #[inline] - pub fn call_method(&self, obj: &PyObject, method_name: &str, args: T) -> PyResult + pub fn call_method( + &self, + obj: impl Into, + method_name: &str, + args: T, + ) -> PyResult where T: IntoFuncArgs, { flame_guard!(format!("call_method({:?})", method_name)); - PyMethod::get( - obj.to_owned(), - PyStr::from(method_name).into_ref(self), - self, - )? - .invoke(args, self) + PyMethod::get(obj.into(), PyStr::from(method_name).into_ref(self), self)?.invoke(args, self) } pub fn dir(&self, obj: Option) -> PyResult { @@ -131,7 +131,7 @@ impl VirtualMachine { .get_special_method(obj, "__dir__")? .map_err(|_obj| self.new_type_error("object does not provide __dir__".to_owned()))? .invoke((), self)?, - None => self.call_method(self.current_locals()?.as_object(), "keys", ())?, + None => self.call_method(self.current_locals()?, "keys", ())?, }; let items: Vec<_> = seq.try_to_value(self)?; let lst = PyList::from(items);