diff --git a/src/main.rs b/src/main.rs index 42d0462b68..dcd55aa1dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -359,7 +359,7 @@ fn run_module(vm: &VirtualMachine, module: &str) -> PyResult<()> { debug!("Running module {}", module); let runpy = vm.import("runpy", &vm.ctx.new_tuple(vec![]), 0)?; let run_module_as_main = vm.get_attribute(runpy, "_run_module_as_main")?; - vm.invoke(run_module_as_main, vec![vm.new_str(module.to_owned())])?; + vm.invoke(&run_module_as_main, vec![vm.new_str(module.to_owned())])?; Ok(()) } diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index b3b901e8a9..b36d2edf34 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -37,7 +37,7 @@ fn builtin_abs(x: PyObjectRef, vm: &VirtualMachine) -> PyResult { let method = vm.get_method_or_type_error(x.clone(), "__abs__", || { format!("bad operand type for abs(): '{}'", x.class().name) })?; - vm.invoke(method, PyFuncArgs::new(vec![], vec![])) + vm.invoke(&method, PyFuncArgs::new(vec![], vec![])) } fn builtin_all(iterable: PyIterable, vm: &VirtualMachine) -> PyResult { @@ -395,7 +395,7 @@ fn builtin_len(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { let method = vm.get_method_or_type_error(obj.clone(), "__len__", || { format!("object of type '{}' has no len()", obj.class().name) })?; - vm.invoke(method, PyFuncArgs::default()) + vm.invoke(&method, PyFuncArgs::default()) } fn builtin_locals(vm: &VirtualMachine) -> PyDictRef { @@ -428,15 +428,15 @@ fn builtin_max(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { let mut x = candidates_iter.next().unwrap(); // TODO: this key function looks pretty duplicate. Maybe we can create // a local function? - let mut x_key = if let Some(f) = &key_func { - vm.invoke(f.clone(), vec![x.clone()])? + let mut x_key = if let Some(ref f) = &key_func { + vm.invoke(f, vec![x.clone()])? } else { x.clone() }; for y in candidates_iter { - let y_key = if let Some(f) = &key_func { - vm.invoke(f.clone(), vec![y.clone()])? + let y_key = if let Some(ref f) = &key_func { + vm.invoke(f, vec![y.clone()])? } else { y.clone() }; @@ -476,15 +476,15 @@ fn builtin_min(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { let mut x = candidates_iter.next().unwrap(); // TODO: this key function looks pretty duplicate. Maybe we can create // a local function? - let mut x_key = if let Some(f) = &key_func { - vm.invoke(f.clone(), vec![x.clone()])? + let mut x_key = if let Some(ref f) = &key_func { + vm.invoke(f, vec![x.clone()])? } else { x.clone() }; for y in candidates_iter { - let y_key = if let Some(f) = &key_func { - vm.invoke(f.clone(), vec![y.clone()])? + let y_key = if let Some(ref f) = &key_func { + vm.invoke(f, vec![y.clone()])? } else { y.clone() }; @@ -711,7 +711,7 @@ fn builtin_reversed(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { arg_check!(vm, args, required = [(obj, None)]); if let Some(reversed_method) = vm.get_method(obj.clone(), "__reversed__") { - vm.invoke(reversed_method?, PyFuncArgs::default()) + vm.invoke(&reversed_method?, PyFuncArgs::default()) } else { vm.get_method_or_type_error(obj.clone(), "__getitem__", || { "argument to reversed() must be a sequence".to_string() @@ -777,7 +777,7 @@ fn builtin_sum(iterable: PyIterable, start: OptionalArg, vm: &VirtualMachine) -> // Should be renamed to builtin___import__? fn builtin_import(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { - vm.invoke(vm.import_func.borrow().clone(), args) + vm.invoke(&vm.import_func.borrow(), args) } fn builtin_vars(obj: OptionalArg, vm: &VirtualMachine) -> PyResult { @@ -964,13 +964,13 @@ pub fn builtin_build_class_( // Prepare uses full __getattribute__ resolution chain. let prepare = vm.get_attribute(metaclass.clone().into_object(), "__prepare__")?; - let namespace = vm.invoke(prepare, vec![name_obj.clone(), bases.clone()])?; + let namespace = vm.invoke(&prepare, vec![name_obj.clone(), bases.clone()])?; let namespace: PyDictRef = TryFromObject::try_from_object(vm, namespace)?; let cells = vm.ctx.new_dict(); - vm.invoke_with_locals(function, cells.clone(), namespace.clone())?; + vm.invoke_with_locals(&function, cells.clone(), namespace.clone())?; namespace.set_item("__name__", name_obj.clone(), vm)?; namespace.set_item("__qualname__", qualified_name.into_object(), vm)?; diff --git a/vm/src/frame.rs b/vm/src/frame.rs index f338b64135..9cf2999ff4 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -488,7 +488,7 @@ impl Frame { // Call function: let func_ref = self.pop_value(); - let value = vm.invoke(func_ref, args)?; + let value = vm.invoke(&func_ref, args)?; self.push_value(value); Ok(None) } @@ -599,7 +599,7 @@ impl Frame { if !expr.is(&vm.get_none()) { let repr = vm.to_repr(&expr)?; // TODO: implement sys.displayhook - if let Ok(print) = vm.get_attribute(vm.builtins.clone(), "print") { + if let Ok(ref print) = vm.get_attribute(vm.builtins.clone(), "print") { vm.invoke(print, vec![repr.into_object()])?; } } diff --git a/vm/src/import.rs b/vm/src/import.rs index 2caaeda539..188418c548 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -17,14 +17,14 @@ pub fn init_importlib(vm: &VirtualMachine, external: bool) -> PyResult { let importlib = import_frozen(vm, "_frozen_importlib")?; let impmod = import_builtin(vm, "_imp")?; let install = vm.get_attribute(importlib.clone(), "_install")?; - vm.invoke(install, vec![vm.sys_module.clone(), impmod])?; + vm.invoke(&install, vec![vm.sys_module.clone(), impmod])?; vm.import_func .replace(vm.get_attribute(importlib.clone(), "__import__")?); if external && cfg!(feature = "rustpython-compiler") { flame_guard!("install_external"); let install_external = vm.get_attribute(importlib.clone(), "_install_external_importers")?; - vm.invoke(install_external, vec![])?; + vm.invoke(&install_external, vec![])?; // Set pyc magic number to commit hash. Should be changed when bytecode will be more stable. let importlib_external = vm.import("_frozen_importlib_external", &vm.ctx.new_tuple(vec![]), 0)?; diff --git a/vm/src/obj/objbool.rs b/vm/src/obj/objbool.rs index 6988028ea9..1e1e39254c 100644 --- a/vm/src/obj/objbool.rs +++ b/vm/src/obj/objbool.rs @@ -28,7 +28,7 @@ pub fn boolval(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { Some(method_or_err) => { // If descriptor returns Error, propagate it further let method = method_or_err?; - let bool_obj = vm.invoke(method, PyFuncArgs::default())?; + let bool_obj = vm.invoke(&method, PyFuncArgs::default())?; match bool_obj.payload::() { Some(int_obj) => !int_obj.as_bigint().is_zero(), None => { @@ -42,7 +42,7 @@ pub fn boolval(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { None => match vm.get_method(obj.clone(), "__len__") { Some(method_or_err) => { let method = method_or_err?; - let bool_obj = vm.invoke(method, PyFuncArgs::default())?; + let bool_obj = vm.invoke(&method, PyFuncArgs::default())?; match bool_obj.payload::() { Some(int_obj) => !int_obj.as_bigint().is_zero(), None => { diff --git a/vm/src/obj/objdict.rs b/vm/src/obj/objdict.rs index e68c6b6a48..017a913a5c 100644 --- a/vm/src/obj/objdict.rs +++ b/vm/src/obj/objdict.rs @@ -210,7 +210,7 @@ impl PyDictRef { } if let Some(method_or_err) = vm.get_method(self.clone().into_object(), "__missing__") { let method = method_or_err?; - return vm.invoke(method, vec![key]); + return vm.invoke(&method, vec![key]); } Err(vm.new_key_error(key.clone())) } diff --git a/vm/src/obj/objfilter.rs b/vm/src/obj/objfilter.rs index 24800d6aaf..91f7dbb01c 100644 --- a/vm/src/obj/objfilter.rs +++ b/vm/src/obj/objfilter.rs @@ -52,7 +52,7 @@ impl PyFilter { } else { // the predicate itself can raise StopIteration which does stop the filter // iteration - vm.invoke(predicate.clone(), vec![next_obj.clone()])? + vm.invoke(&predicate, vec![next_obj.clone()])? }; if objbool::boolval(vm, predicate_value)? { return Ok(next_obj); diff --git a/vm/src/obj/objfloat.rs b/vm/src/obj/objfloat.rs index cfac52aa9f..95c4ca1e48 100644 --- a/vm/src/obj/objfloat.rs +++ b/vm/src/obj/objfloat.rs @@ -612,7 +612,7 @@ pub fn make_float(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult { obj.class().name ) })?; - let result = vm.invoke(method, vec![])?; + let result = vm.invoke(&method, vec![])?; Ok(get_value(&result)) } } diff --git a/vm/src/obj/objfunction.rs b/vm/src/obj/objfunction.rs index 1c7ff642af..3a7f44001e 100644 --- a/vm/src/obj/objfunction.rs +++ b/vm/src/obj/objfunction.rs @@ -42,7 +42,7 @@ impl PyValue for PyFunction { impl PyFunctionRef { fn call(self, args: Args, kwargs: KwArgs, vm: &VirtualMachine) -> PyResult { - vm.invoke(self.into_object(), (&args, &kwargs)) + vm.invoke(&self.into_object(), (&args, &kwargs)) } fn code(self, _vm: &VirtualMachine) -> PyCodeRef { diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs index 847ba4a15a..e0292575e5 100644 --- a/vm/src/obj/objint.rs +++ b/vm/src/obj/objint.rs @@ -714,7 +714,7 @@ pub fn to_int(vm: &VirtualMachine, obj: &PyObjectRef, mut base: u32) -> PyResult let method = vm.get_method_or_type_error(obj.clone(), "__int__", || { format!("int() argument must be a string or a number, not '{}'", obj.class().name) })?; - let result = vm.invoke(method, PyFuncArgs::default())?; + let result = vm.invoke(&method, PyFuncArgs::default())?; match result.payload::() { Some(int_obj) => Ok(int_obj.as_bigint().clone()), None => Err(vm.new_type_error(format!( diff --git a/vm/src/obj/objiter.rs b/vm/src/obj/objiter.rs index 0fcd078c7c..22837c7293 100644 --- a/vm/src/obj/objiter.rs +++ b/vm/src/obj/objiter.rs @@ -20,7 +20,7 @@ use super::objtype::PyClassRef; pub fn get_iter(vm: &VirtualMachine, iter_target: &PyObjectRef) -> PyResult { if let Some(method_or_err) = vm.get_method(iter_target.clone(), "__iter__") { let method = method_or_err?; - vm.invoke(method, vec![]) + vm.invoke(&method, vec![]) } else { vm.get_method_or_type_error(iter_target.clone(), "__getitem__", || { format!("Cannot iterate over {}", iter_target.class().name) diff --git a/vm/src/obj/objlist.rs b/vm/src/obj/objlist.rs index e9b4b40d54..9191781306 100644 --- a/vm/src/obj/objlist.rs +++ b/vm/src/obj/objlist.rs @@ -755,7 +755,7 @@ fn do_sort( for x in values.iter() { keys.push(match &key_func { None => x.clone(), - Some(ref func) => vm.invoke((*func).clone(), vec![x.clone()])?, + Some(ref func) => vm.invoke(func, vec![x.clone()])?, }); } diff --git a/vm/src/obj/objmap.rs b/vm/src/obj/objmap.rs index 61fe67c0d1..a8b389c996 100644 --- a/vm/src/obj/objmap.rs +++ b/vm/src/obj/objmap.rs @@ -51,7 +51,7 @@ impl PyMap { .collect::, _>>()?; // the mapper itself can raise StopIteration which does stop the map iteration - vm.invoke(self.mapper.clone(), next_objs) + vm.invoke(&self.mapper, next_objs) } #[pymethod(name = "__iter__")] diff --git a/vm/src/obj/objnone.rs b/vm/src/obj/objnone.rs index fa23ca1b08..cf1b4d3a5c 100644 --- a/vm/src/obj/objnone.rs +++ b/vm/src/obj/objnone.rs @@ -64,7 +64,7 @@ impl PyNoneRef { if let Ok(property) = PyPropertyRef::try_from_object(vm, descriptor.clone()) { property.instance_binding_get(obj, vm) } else { - vm.invoke(get_func, vec![descriptor, obj, cls]) + vm.invoke(&get_func, vec![descriptor, obj, cls]) } } @@ -95,7 +95,7 @@ impl PyNoneRef { Ok(attr) } } else if let Some(getter) = class_get_attr(&cls, "__getattr__") { - vm.invoke(getter, vec![self.into_object(), name.into_object()]) + vm.invoke(&getter, vec![self.into_object(), name.into_object()]) } else { Err(vm.new_attribute_error(format!("{} has no attribute '{}'", self.as_object(), name))) } diff --git a/vm/src/obj/objobject.rs b/vm/src/obj/objobject.rs index 8f2408dba1..97358c4cee 100644 --- a/vm/src/obj/objobject.rs +++ b/vm/src/obj/objobject.rs @@ -72,7 +72,7 @@ fn object_setattr( if let Some(attr) = objtype::class_get_attr(&cls, &attr_name.value) { if let Some(descriptor) = objtype::class_get_attr(&attr.class(), "__set__") { return vm - .invoke(descriptor, vec![attr, obj.clone(), value]) + .invoke(&descriptor, vec![attr, obj.clone(), value]) .map(|_| ()); } } @@ -94,7 +94,7 @@ fn object_delattr(obj: PyObjectRef, attr_name: PyStringRef, vm: &VirtualMachine) if let Some(attr) = objtype::class_get_attr(&cls, &attr_name.value) { if let Some(descriptor) = objtype::class_get_attr(&attr.class(), "__delete__") { - return vm.invoke(descriptor, vec![attr, obj.clone()]).map(|_| ()); + return vm.invoke(&descriptor, vec![attr, obj.clone()]).map(|_| ()); } } @@ -126,7 +126,7 @@ pub fn object_dir(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult { // Get instance attributes: if let Some(object_dict) = &obj.dict { vm.invoke( - vm.get_attribute(dict.clone().into_object(), "update")?, + &vm.get_attribute(dict.clone().into_object(), "update")?, object_dict.clone().into_object(), )?; } @@ -227,7 +227,7 @@ fn object_getattribute(obj: PyObjectRef, name_str: PyStringRef, vm: &VirtualMach let attr_class = attr.class(); if objtype::class_has_attr(&attr_class, "__set__") { if let Some(descriptor) = objtype::class_get_attr(&attr_class, "__get__") { - return vm.invoke(descriptor, vec![attr, obj, cls.into_object()]); + return vm.invoke(&descriptor, vec![attr, obj, cls.into_object()]); } } } @@ -236,7 +236,7 @@ fn object_getattribute(obj: PyObjectRef, name_str: PyStringRef, vm: &VirtualMach Ok(obj_attr) } else if let Some(attr) = objtype::class_get_attr(&cls, &name) { vm.call_get_descriptor(attr, obj) - } else if let Some(getter) = objtype::class_get_attr(&cls, "__getattr__") { + } else if let Some(ref getter) = objtype::class_get_attr(&cls, "__getattr__") { vm.invoke(getter, vec![obj, name_str.into_object()]) } else { Err(vm.new_attribute_error(format!("{} has no attribute '{}'", obj, name))) diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs index 9c8394a4cc..bef69dff14 100644 --- a/vm/src/obj/objproperty.rs +++ b/vm/src/obj/objproperty.rs @@ -37,7 +37,7 @@ impl PyReadOnlyProperty { if obj.is(vm.ctx.none.as_object()) { Ok(zelf.into_object()) } else { - vm.invoke(zelf.getter.clone(), obj) + vm.invoke(&zelf.getter, obj) } } } @@ -129,8 +129,8 @@ impl PyProperty { // specialised version that doesn't check for None pub(crate) fn instance_binding_get(&self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult { - if let Some(getter) = self.getter.as_ref() { - vm.invoke(getter.clone(), obj) + if let Some(ref getter) = self.getter.as_ref() { + vm.invoke(getter, obj) } else { Err(vm.new_attribute_error("unreadable attribute".to_string())) } @@ -147,7 +147,7 @@ impl PyProperty { if obj.is(vm.ctx.none.as_object()) { Ok(zelf.into_object()) } else { - vm.invoke(getter.clone(), obj) + vm.invoke(&getter, obj) } } else { Err(vm.new_attribute_error("unreadable attribute".to_string())) @@ -156,8 +156,8 @@ impl PyProperty { #[pymethod(name = "__set__")] fn set(&self, obj: PyObjectRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult { - if let Some(setter) = self.setter.as_ref() { - vm.invoke(setter.clone(), vec![obj, value]) + if let Some(ref setter) = self.setter.as_ref() { + vm.invoke(setter, vec![obj, value]) } else { Err(vm.new_attribute_error("can't set attribute".to_string())) } @@ -165,8 +165,8 @@ impl PyProperty { #[pymethod(name = "__delete__")] fn delete(&self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult { - if let Some(deleter) = self.deleter.as_ref() { - vm.invoke(deleter.clone(), obj) + if let Some(ref deleter) = self.deleter.as_ref() { + vm.invoke(deleter, obj) } else { Err(vm.new_attribute_error("can't delete attribute".to_string())) } diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index 9df1a829f9..9c7b0058a6 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -137,7 +137,7 @@ impl PyClassRef { if let Some(attr) = class_get_attr(&mcl, &name) { let attr_class = attr.class(); if class_has_attr(&attr_class, "__set__") { - if let Some(descriptor) = class_get_attr(&attr_class, "__get__") { + if let Some(ref descriptor) = class_get_attr(&attr_class, "__get__") { return vm.invoke( descriptor, vec![attr, self.into_object(), mcl.into_object()], @@ -148,7 +148,7 @@ impl PyClassRef { if let Some(attr) = class_get_attr(&self, &name) { let attr_class = attr.class(); - if let Some(descriptor) = class_get_attr(&attr_class, "__get__") { + if let Some(ref descriptor) = class_get_attr(&attr_class, "__get__") { let none = vm.get_none(); return vm.invoke(descriptor, vec![attr, none, self.into_object()]); } @@ -158,7 +158,7 @@ impl PyClassRef { Ok(cls_attr) } else if let Some(attr) = class_get_attr(&mcl, &name) { vm.call_get_descriptor(attr, self.into_object()) - } else if let Some(getter) = class_get_attr(&self, "__getattr__") { + } else if let Some(ref getter) = class_get_attr(&self, "__getattr__") { vm.invoke(getter, vec![mcl.into_object(), name_ref.into_object()]) } else { Err(vm.new_attribute_error(format!("{} has no attribute '{}'", self, name))) @@ -172,7 +172,7 @@ impl PyClassRef { vm: &VirtualMachine, ) -> PyResult<()> { if let Some(attr) = class_get_attr(&self.class(), &attr_name.value) { - if let Some(descriptor) = class_get_attr(&attr.class(), "__set__") { + if let Some(ref descriptor) = class_get_attr(&attr.class(), "__set__") { vm.invoke(descriptor, vec![attr, self.into_object(), value])?; return Ok(()); } @@ -288,11 +288,11 @@ pub fn type_call(class: PyClassRef, args: Args, kwargs: KwArgs, vm: &VirtualMach vm_trace!("type_call: {:?}", class); let new = class_get_attr(&class, "__new__").expect("All types should have a __new__."); let new_wrapped = vm.call_get_descriptor(new, class.into_object())?; - let obj = vm.invoke(new_wrapped, (&args, &kwargs))?; + let obj = vm.invoke(&new_wrapped, (&args, &kwargs))?; if let Some(init_method_or_err) = vm.get_method(obj.clone(), "__init__") { let init_method = init_method_or_err?; - let res = vm.invoke(init_method, (&args, &kwargs))?; + let res = vm.invoke(&init_method, (&args, &kwargs))?; if !res.is(&vm.get_none()) { return Err(vm.new_type_error("__init__ must return None".to_string())); } diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index ba40d54735..61250adbac 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -948,7 +948,7 @@ pub struct PyCallable { impl PyCallable { #[inline] pub fn invoke(&self, args: impl Into, vm: &VirtualMachine) -> PyResult { - vm.invoke(self.obj.clone(), args) + vm.invoke(&self.obj, args) } #[inline] @@ -1103,8 +1103,9 @@ impl PyIterable { /// This operation may fail if an exception is raised while invoking the /// `__iter__` method of the iterable object. pub fn iter<'a>(&self, vm: &'a VirtualMachine) -> PyResult> { + let method = &self.method; let iter_obj = vm.invoke( - self.method.clone(), + method, PyFuncArgs { args: vec![], kwargs: IndexMap::new(), diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index 41c451f79a..22f17aa5f0 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -607,7 +607,7 @@ pub fn io_open(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { // This is subsequently consumed by a Buffered Class. let file_io_class = vm.get_attribute(io_module.clone(), "FileIO").unwrap(); let file_io_obj = vm.invoke( - file_io_class, + &file_io_class, vec![file.clone(), vm.ctx.new_str(mode.clone())], )?; @@ -620,13 +620,13 @@ pub fn io_open(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { let buffered_writer_class = vm .get_attribute(io_module.clone(), "BufferedWriter") .unwrap(); - vm.invoke(buffered_writer_class, vec![file_io_obj.clone()]) + vm.invoke(&buffered_writer_class, vec![file_io_obj.clone()]) } 'r' => { let buffered_reader_class = vm .get_attribute(io_module.clone(), "BufferedReader") .unwrap(); - vm.invoke(buffered_reader_class, vec![file_io_obj.clone()]) + vm.invoke(&buffered_reader_class, vec![file_io_obj.clone()]) } //TODO: updating => PyBufferedRandom _ => unimplemented!("'a' mode is not yet implemented"), @@ -637,7 +637,7 @@ pub fn io_open(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { // a TextIOWrapper which is subsequently returned. 't' => { let text_io_wrapper_class = vm.get_attribute(io_module, "TextIOWrapper").unwrap(); - vm.invoke(text_io_wrapper_class, vec![buffered.unwrap()]) + vm.invoke(&text_io_wrapper_class, vec![buffered.unwrap()]) } // If the mode is binary this Buffered class is returned directly at // this point. diff --git a/vm/src/stdlib/itertools.rs b/vm/src/stdlib/itertools.rs index 732020480f..6039c178a0 100644 --- a/vm/src/stdlib/itertools.rs +++ b/vm/src/stdlib/itertools.rs @@ -218,8 +218,9 @@ impl PyItertoolsStarmap { #[pymethod(name = "__next__")] fn next(&self, vm: &VirtualMachine) -> PyResult { let obj = call_next(vm, &self.iter)?; + let function = &self.function; - vm.invoke(self.function.clone(), vm.extract_elements(&obj)?) + vm.invoke(function, vm.extract_elements(&obj)?) } #[pymethod(name = "__iter__")] @@ -271,8 +272,9 @@ impl PyItertoolsTakewhile { // might be StopIteration or anything else, which is propaged upwwards let obj = call_next(vm, &self.iterable)?; + let predicate = &self.predicate; - let verdict = vm.invoke(self.predicate.clone(), vec![obj.clone()])?; + let verdict = vm.invoke(predicate, vec![obj.clone()])?; let verdict = objbool::boolval(vm, verdict)?; if verdict { Ok(obj) diff --git a/vm/src/stdlib/math.rs b/vm/src/stdlib/math.rs index 36dad8bca2..31839efad3 100644 --- a/vm/src/stdlib/math.rs +++ b/vm/src/stdlib/math.rs @@ -181,7 +181,7 @@ fn try_magic_method(func_name: &str, vm: &VirtualMachine, value: &PyObjectRef) - func_name, ) })?; - vm.invoke(method, vec![]) + vm.invoke(&method, vec![]) } fn math_trunc(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { diff --git a/vm/src/stdlib/signal.rs b/vm/src/stdlib/signal.rs index d72085ea01..2950282b18 100644 --- a/vm/src/stdlib/signal.rs +++ b/vm/src/stdlib/signal.rs @@ -92,7 +92,7 @@ pub fn check_signals(vm: &VirtualMachine) { .get(&(signum as i32)) .expect("Handler should be set") .clone(); - vm.invoke(handler, vec![vm.new_int(signum), vm.get_none()]) + vm.invoke(&handler, vec![vm.new_int(signum), vm.get_none()]) .expect("Test"); } } diff --git a/vm/src/stdlib/thread.rs b/vm/src/stdlib/thread.rs index 414e7d72e7..225001c4dc 100644 --- a/vm/src/stdlib/thread.rs +++ b/vm/src/stdlib/thread.rs @@ -37,7 +37,7 @@ fn get_ident(_vm: &VirtualMachine) -> u32 { fn allocate_lock(vm: &VirtualMachine) -> PyResult { let lock_class = vm.class("_thread", "RLock"); - vm.invoke(lock_class.into_object(), vec![]) + vm.invoke(&lock_class.into_object(), vec![]) } pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { diff --git a/vm/src/vm.rs b/vm/src/vm.rs index da3348924f..bbc066c3f8 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -258,7 +258,7 @@ impl VirtualMachine { fn new_exception_obj(&self, exc_type: PyClassRef, args: Vec) -> PyResult { // TODO: add repr of args into logging? vm_trace!("New exception created: {}", exc_type.name); - self.invoke(exc_type.into_object(), args) + self.invoke(&exc_type.into_object(), args) } pub fn new_empty_exception(&self, exc_type: PyClassRef) -> PyResult { @@ -424,7 +424,7 @@ impl VirtualMachine { (self.get_none(), self.get_none()) }; self.invoke( - import_func, + &import_func, vec![ self.ctx.new_str(module.to_string()), globals, @@ -463,7 +463,7 @@ impl VirtualMachine { pub fn call_get_descriptor(&self, attr: PyObjectRef, obj: PyObjectRef) -> PyResult { let attr_class = attr.class(); - if let Some(descriptor) = objtype::class_get_attr(&attr_class, "__get__") { + if let Some(ref descriptor) = objtype::class_get_attr(&attr_class, "__get__") { let cls = obj.class(); self.invoke(descriptor, vec![attr, obj.clone(), cls.into_object()]) } else { @@ -487,14 +487,14 @@ impl VirtualMachine { func ); let wrapped = self.call_get_descriptor(func, obj.clone())?; - self.invoke(wrapped, args) + self.invoke(&wrapped, args) } None => Err(self.new_type_error(format!("Unsupported method: {}", method_name))), } } #[cfg_attr(feature = "flame-it", flame("VirtualMachine"))] - fn _invoke(&self, func_ref: PyObjectRef, args: PyFuncArgs) -> PyResult { + fn _invoke(&self, func_ref: &PyObjectRef, args: PyFuncArgs) -> PyResult { vm_trace!("Invoke: {:?} {:?}", func_ref, args); if let Some(PyFunction { @@ -513,7 +513,7 @@ impl VirtualMachine { ref object, }) = func_ref.payload() { - self.invoke(function.clone(), args.insert(object.clone())) + self.invoke(&function, args.insert(object.clone())) } else if let Some(PyBuiltinFunction { ref value }) = func_ref.payload() { value(self, args) } else { @@ -523,9 +523,8 @@ impl VirtualMachine { } } - // TODO: make func_ref an &PyObjectRef #[inline] - pub fn invoke(&self, func_ref: PyObjectRef, args: T) -> PyResult + pub fn invoke(&self, func_ref: &PyObjectRef, args: T) -> PyResult where T: Into, { @@ -546,7 +545,7 @@ impl VirtualMachine { let trace_func = self.trace_func.borrow().clone(); if !self.is_none(&trace_func) { self.use_tracing.replace(false); - let res = self.invoke(trace_func, args.clone()); + let res = self.invoke(&trace_func, args.clone()); self.use_tracing.replace(true); res?; } @@ -554,7 +553,7 @@ impl VirtualMachine { let profile_func = self.profile_func.borrow().clone(); if !self.is_none(&profile_func) { self.use_tracing.replace(false); - let res = self.invoke(profile_func, args); + let res = self.invoke(&profile_func, args); self.use_tracing.replace(true); res?; } @@ -592,7 +591,7 @@ impl VirtualMachine { pub fn invoke_with_locals( &self, - function: PyObjectRef, + function: &PyObjectRef, cells: PyDictRef, locals: PyDictRef, ) -> PyResult { @@ -605,7 +604,7 @@ impl VirtualMachine { } panic!( "invoke_with_locals: expected python function, got: {:?}", - function + *function ); } @@ -831,7 +830,7 @@ impl VirtualMachine { { if let Some(method_or_err) = self.get_method(obj.clone(), method) { let method = method_or_err?; - let result = self.invoke(method, vec![arg.clone()])?; + let result = self.invoke(&method, vec![arg.clone()])?; if !result.is(&self.ctx.not_implemented()) { return Ok(result); } @@ -1132,7 +1131,7 @@ impl VirtualMachine { pub fn _membership(&self, haystack: PyObjectRef, needle: PyObjectRef) -> PyResult { if let Some(method_or_err) = self.get_method(haystack.clone(), "__contains__") { let method = method_or_err?; - self.invoke(method, vec![needle]) + self.invoke(&method, vec![needle]) } else { self._membership_iter_search(haystack, needle) } diff --git a/wasm/lib/src/browser_module.rs b/wasm/lib/src/browser_module.rs index fed4fcbdca..abfdc2b53b 100644 --- a/wasm/lib/src/browser_module.rs +++ b/wasm/lib/src/browser_module.rs @@ -133,7 +133,7 @@ fn browser_request_animation_frame(func: PyCallable, vm: &VirtualMachine) -> PyR let vm = &stored_vm.vm; let func = func.clone(); let args = vec![vm.ctx.new_float(time)]; - let _ = vm.invoke(func.into_object(), args); + let _ = vm.invoke(&func.into_object(), args); let closure = f.borrow_mut().take(); drop(closure); @@ -212,12 +212,12 @@ impl PyPromise { } else { vec![convert::js_to_py(vm, val)] }; - vm.invoke(on_fulfill.into_object(), PyFuncArgs::new(args, vec![])) + vm.invoke(&on_fulfill.into_object(), PyFuncArgs::new(args, vec![])) } Err(err) => { if let OptionalArg::Present(on_reject) = on_reject { let err = convert::js_to_py(vm, err); - vm.invoke(on_reject.into_object(), PyFuncArgs::new(vec![err], vec![])) + vm.invoke(&on_reject.into_object(), PyFuncArgs::new(vec![err], vec![])) } else { return Err(err); } @@ -240,7 +240,7 @@ impl PyPromise { .expect("that the vm is valid when the promise resolves"); let vm = &stored_vm.vm; let err = convert::js_to_py(vm, err); - let res = vm.invoke(on_reject.into_object(), PyFuncArgs::new(vec![err], vec![])); + let res = vm.invoke(&on_reject.into_object(), PyFuncArgs::new(vec![err], vec![])); convert::pyresult_to_jsresult(vm, res) }) }); diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs index f4c71e60d5..16b7fe3f74 100644 --- a/wasm/lib/src/convert.rs +++ b/wasm/lib/src/convert.rs @@ -94,7 +94,7 @@ pub fn py_to_js(vm: &VirtualMachine, py_obj: PyObjectRef) -> JsValue { .insert(js_sys::JsString::from(key).into(), js_to_py(vm, val)); } } - let result = vm.invoke(py_obj.clone(), py_func_args); + let result = vm.invoke(&py_obj, py_func_args); pyresult_to_jsresult(vm, result) }; let closure = Closure::wrap(Box::new(closure)