From b60271a6cf195e62046d4cf1d2a84c75f3d55fa4 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Tue, 7 Mar 2023 23:54:20 +0900 Subject: [PATCH] deprecate vm.invoke --- examples/call_between_rust_and_python.rs | 10 +++---- examples/package_embed.rs | 2 +- stdlib/src/array.rs | 13 ++++----- stdlib/src/bisect.rs | 8 ++--- stdlib/src/csv.rs | 2 +- stdlib/src/json.rs | 37 ++++++++++-------------- stdlib/src/math.rs | 2 +- stdlib/src/pyexpat.rs | 2 +- stdlib/src/select.rs | 2 +- stdlib/src/sqlite.rs | 28 +++++++++--------- vm/src/builtins/bool.rs | 4 +-- vm/src/builtins/classmethod.rs | 2 +- vm/src/builtins/complex.rs | 2 +- vm/src/builtins/dict.rs | 4 +-- vm/src/builtins/filter.rs | 2 +- vm/src/builtins/function.rs | 2 +- vm/src/builtins/list.rs | 2 +- vm/src/builtins/map.rs | 2 +- vm/src/builtins/module.rs | 4 +-- vm/src/builtins/object.rs | 6 ++-- vm/src/builtins/property.rs | 6 ++-- vm/src/builtins/staticmethod.rs | 2 +- vm/src/builtins/str.rs | 2 +- vm/src/builtins/super.rs | 6 ++-- vm/src/builtins/type.rs | 23 +++++++-------- vm/src/bytesinner.rs | 2 +- vm/src/cformat.rs | 4 +-- vm/src/codecs.rs | 6 ++-- vm/src/exceptions.rs | 14 ++++----- vm/src/frame.rs | 12 ++++---- vm/src/import.rs | 4 +-- vm/src/object/core.rs | 2 +- vm/src/protocol/callable.rs | 4 +-- vm/src/protocol/object.rs | 2 +- vm/src/stdlib/atexit.rs | 2 +- vm/src/stdlib/builtins.rs | 27 ++++++++--------- vm/src/stdlib/codecs.rs | 6 ++-- vm/src/stdlib/functools.rs | 2 +- vm/src/stdlib/io.rs | 33 ++++++++++++--------- vm/src/stdlib/itertools.rs | 12 ++++---- vm/src/stdlib/operator.rs | 12 ++++---- vm/src/stdlib/os.rs | 2 +- vm/src/stdlib/sre.rs | 6 ++-- vm/src/stdlib/sys.rs | 4 +-- vm/src/stdlib/warnings.rs | 2 +- vm/src/types/slot.rs | 2 +- vm/src/vm/compile.rs | 7 ++--- vm/src/vm/method.rs | 6 ++-- vm/src/vm/mod.rs | 9 +++--- vm/src/vm/vm_object.rs | 2 +- vm/src/vm/vm_ops.rs | 4 +-- vm/src/warn.rs | 4 +-- wasm/lib/src/browser_module.rs | 2 +- wasm/lib/src/convert.rs | 2 +- wasm/lib/src/js_module.rs | 10 +++---- 55 files changed, 186 insertions(+), 195 deletions(-) diff --git a/examples/call_between_rust_and_python.rs b/examples/call_between_rust_and_python.rs index 591304228..c139309e8 100644 --- a/examples/call_between_rust_and_python.rs +++ b/examples/call_between_rust_and_python.rs @@ -19,14 +19,12 @@ pub fn main() { let module = vm.import("call_between_rust_and_python", None, 0).unwrap(); let init_fn = module.get_attr("python_callback", vm).unwrap(); - vm.invoke(&init_fn, ()).unwrap(); + init_fn.call((), vm).unwrap(); let take_string_fn = module.get_attr("take_string", vm).unwrap(); - vm.invoke( - &take_string_fn, - (String::from("Rust string sent to python"),), - ) - .unwrap(); + take_string_fn + .call((String::from("Rust string sent to python"),), vm) + .unwrap(); }) } diff --git a/examples/package_embed.rs b/examples/package_embed.rs index fe6b07cec..bd3d26885 100644 --- a/examples/package_embed.rs +++ b/examples/package_embed.rs @@ -8,7 +8,7 @@ fn py_main(interp: &Interpreter) -> vm::PyResult { .expect("add path"); let module = vm.import("package_embed", None, 0)?; let name_func = module.get_attr("context", vm)?; - let result = vm.invoke(&name_func, ())?; + let result = name_func.call((), vm)?; let result: PyStrRef = result.get_attr("name", vm)?.try_into_value(vm)?; vm::PyResult::Ok(result) }) diff --git a/stdlib/src/array.rs b/stdlib/src/array.rs index d88f69a47..b34206422 100644 --- a/stdlib/src/array.rs +++ b/stdlib/src/array.rs @@ -17,13 +17,12 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef { .get_attr("MutableSequence", vm) .expect("Expect collections.abc has MutableSequence type."); - vm.invoke( - &mutable_sequence - .get_attr("register", vm) - .expect("Expect collections.abc.MutableSequence has register method."), - (array,), - ) - .expect("Expect collections.abc.MutableSequence.register(array.array) not fail."); + let register = &mutable_sequence + .get_attr("register", vm) + .expect("Expect collections.abc.MutableSequence has register method."); + register + .call((array,), vm) + .expect("Expect collections.abc.MutableSequence.register(array.array) not fail."); module } diff --git a/stdlib/src/bisect.rs b/stdlib/src/bisect.rs index 1358ab22e..25cc5b608 100644 --- a/stdlib/src/bisect.rs +++ b/stdlib/src/bisect.rs @@ -70,7 +70,7 @@ mod _bisect { let mid = (lo + hi) / 2; let a_mid = a.get_item(&mid, vm)?; let comp = if let Some(ref key) = key { - vm.invoke(key, (a_mid,))? + key.call((a_mid,), vm)? } else { a_mid }; @@ -96,7 +96,7 @@ mod _bisect { let mid = (lo + hi) / 2; let a_mid = a.get_item(&mid, vm)?; let comp = if let Some(ref key) = key { - vm.invoke(key, (a_mid,))? + key.call((a_mid,), vm)? } else { a_mid }; @@ -112,7 +112,7 @@ mod _bisect { #[pyfunction] fn insort_left(BisectArgs { a, x, lo, hi, key }: BisectArgs, vm: &VirtualMachine) -> PyResult { let x = if let Some(ref key) = key { - vm.invoke(key, (x,))? + key.call((x,), vm)? } else { x }; @@ -132,7 +132,7 @@ mod _bisect { #[pyfunction] fn insort_right(BisectArgs { a, x, lo, hi, key }: BisectArgs, vm: &VirtualMachine) -> PyResult { let x = if let Some(ref key) = key { - vm.invoke(key, (x,))? + key.call((x,), vm)? } else { x }; diff --git a/stdlib/src/csv.rs b/stdlib/src/csv.rs index a47ba71b6..be1b68715 100644 --- a/stdlib/src/csv.rs +++ b/stdlib/src/csv.rs @@ -309,7 +309,7 @@ mod _csv { let s = std::str::from_utf8(&buffer[..buffer_offset]) .map_err(|_| vm.new_unicode_decode_error("csv not utf8".to_owned()))?; - vm.invoke(&self.write, (s.to_owned(),)) + self.write.call((s,), vm) } #[pymethod] diff --git a/stdlib/src/json.rs b/stdlib/src/json.rs index 7a2a1ce97..31871130c 100644 --- a/stdlib/src/json.rs +++ b/stdlib/src/json.rs @@ -5,9 +5,9 @@ mod machinery; mod _json { use super::machinery; use crate::vm::{ - builtins::{PyBaseExceptionRef, PyStrRef, PyTypeRef}, + builtins::{PyBaseExceptionRef, PyStrRef, PyType, PyTypeRef}, convert::{ToPyObject, ToPyResult}, - function::OptionalArg, + function::{IntoFuncArgs, OptionalArg}, protocol::PyIterReturn, types::{Callable, Constructor}, AsObject, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine, @@ -91,25 +91,23 @@ mod _json { '{' => { // TODO: parse the object in rust let parse_obj = self.ctx.get_attr("parse_object", vm)?; - return PyIterReturn::from_pyresult( - vm.invoke( - &parse_obj, - ( - (pystr, next_idx), - self.strict, - scan_once, - self.object_hook.clone(), - self.object_pairs_hook.clone(), - ), + let result = parse_obj.call( + ( + (pystr, next_idx), + self.strict, + scan_once, + self.object_hook.clone(), + self.object_pairs_hook.clone(), ), vm, ); + return PyIterReturn::from_pyresult(result, vm); } '[' => { // TODO: parse the array in rust let parse_array = self.ctx.get_attr("parse_array", vm)?; return PyIterReturn::from_pyresult( - vm.invoke(&parse_array, ((pystr, next_idx), scan_once)), + parse_array.call(((pystr, next_idx), scan_once), vm), vm, ); } @@ -138,11 +136,8 @@ mod _json { ($s:literal) => { if s.starts_with($s) { return Ok(PyIterReturn::Return( - vm.new_tuple(( - vm.invoke(&self.parse_constant, ($s.to_owned(),))?, - idx + $s.len(), - )) - .into(), + vm.new_tuple((self.parse_constant.call(($s,), vm)?, idx + $s.len())) + .into(), )); } }; @@ -181,12 +176,12 @@ mod _json { let ret = if has_decimal || has_exponent { // float if let Some(ref parse_float) = self.parse_float { - vm.invoke(parse_float, (buf.to_owned(),)) + parse_float.call((buf,), vm) } else { Ok(vm.ctx.new_float(f64::from_str(buf).unwrap()).into()) } } else if let Some(ref parse_int) = self.parse_int { - vm.invoke(parse_int, (buf.to_owned(),)) + parse_int.call((buf,), vm) } else { Ok(vm.new_pyobj(BigInt::from_str(buf).unwrap())) }; @@ -243,7 +238,7 @@ mod _json { ) -> PyBaseExceptionRef { let get_error = || -> PyResult<_> { let cls = vm.try_class("json", "JSONDecodeError")?; - let exc = vm.invoke(&cls, (e.msg, s, e.pos))?; + let exc = PyType::call(&cls, (e.msg, s, e.pos).into_args(vm), vm)?; exc.try_into_value(vm) }; match get_error() { diff --git a/stdlib/src/math.rs b/stdlib/src/math.rs index 6ed6def79..5f60a6683 100644 --- a/stdlib/src/math.rs +++ b/stdlib/src/math.rs @@ -512,7 +512,7 @@ mod math { func_name.as_str(), ) })?; - vm.invoke(&method, ()) + method.call((), vm) } #[pyfunction] diff --git a/stdlib/src/pyexpat.rs b/stdlib/src/pyexpat.rs index c865fc816..d620419e1 100644 --- a/stdlib/src/pyexpat.rs +++ b/stdlib/src/pyexpat.rs @@ -59,7 +59,7 @@ mod _pyexpat { where T: IntoFuncArgs, { - vm.invoke(&handler.read().clone(), args).ok(); + handler.read().call(args, vm).ok(); } #[pyclass] diff --git a/stdlib/src/select.rs b/stdlib/src/select.rs index a6ecd10d0..9d3afa0e4 100644 --- a/stdlib/src/select.rs +++ b/stdlib/src/select.rs @@ -80,7 +80,7 @@ impl TryFromObject for Selectable { vm.ctx.interned_str("fileno").unwrap(), || "select arg must be an int or object with a fileno() method".to_owned(), )?; - vm.invoke(&meth, ())?.try_into_value(vm) + meth.call((), vm)?.try_into_value(vm) })?; Ok(Selectable { obj, fno }) } diff --git a/stdlib/src/sqlite.rs b/stdlib/src/sqlite.rs index a828e7201..fca32f3cc 100644 --- a/stdlib/src/sqlite.rs +++ b/stdlib/src/sqlite.rs @@ -390,7 +390,7 @@ mod _sqlite { .map(|val| value_to_object(val, db, vm)) .collect::>>()?; - let val = vm.invoke(func, args)?; + let val = func.call(args, vm)?; context.result_from_object(&val, vm) }; @@ -410,7 +410,7 @@ mod _sqlite { let args = std::slice::from_raw_parts(argv, argc as usize); let instance = context.aggregate_context::<*const PyObject>(); if (*instance).is_null() { - match vm.invoke(cls, ()) { + match cls.call((), vm) { Ok(obj) => *instance = obj.into_raw(), Err(exc) => { return context.result_exception( @@ -450,7 +450,7 @@ mod _sqlite { let text2 = ptr_to_string(b_ptr.cast(), b_len, null_mut(), vm)?; let text2 = vm.ctx.new_str(text2); - let val = vm.invoke(callable, (text1, text2))?; + let val = callable.call((text1, text2), vm)?; let Some(val) = val.to_number().index(vm) else { return Ok(0); }; @@ -505,7 +505,7 @@ mod _sqlite { let db_name = ptr_to_str(db_name, vm)?; let access = ptr_to_str(access, vm)?; - let val = vm.invoke(callable, (action, arg1, arg2, db_name, access))?; + let val = callable.call((action, arg1, arg2, db_name, access), vm)?; let Some(val) = val.payload::() else { return Ok(SQLITE_DENY); }; @@ -525,7 +525,8 @@ mod _sqlite { let expanded = sqlite3_expanded_sql(stmt.cast()); let f = || -> PyResult<()> { let stmt = ptr_to_str(expanded, vm).or_else(|_| ptr_to_str(sql.cast(), vm))?; - vm.invoke(callable, (stmt,)).map(drop) + callable.call((stmt,), vm)?; + Ok(()) }; let _ = f(); 0 @@ -533,7 +534,7 @@ mod _sqlite { unsafe extern "C" fn progress_callback(data: *mut c_void) -> c_int { let (callable, vm) = (*data.cast::()).retrive(); - if let Ok(val) = vm.invoke(callable, ()) { + if let Ok(val) = callable.call((), vm) { if let Ok(val) = val.is_true(vm) { return val as c_int; } @@ -661,10 +662,10 @@ mod _sqlite { .new_tuple(vec![obj.class().to_owned().into(), proto.clone()]); if let Some(adapter) = adapters().get_item_opt(key.as_object(), vm)? { - return vm.invoke(&adapter, (obj,)); + return adapter.call((obj,), vm); } if let Ok(adapter) = proto.get_attr("__adapt__", vm) { - match vm.invoke(&adapter, (obj,)) { + match adapter.call((obj,), vm) { Ok(val) => return Ok(val), Err(exc) => { if !exc.fast_isinstance(vm.ctx.exceptions.type_error) { @@ -674,7 +675,7 @@ mod _sqlite { } } if let Ok(adapter) = obj.get_attr("__conform__", vm) { - match vm.invoke(&adapter, (proto,)) { + match adapter.call((proto,), vm) { Ok(val) => return Ok(val), Err(exc) => { if !exc.fast_isinstance(vm.ctx.exceptions.type_error) { @@ -1228,7 +1229,7 @@ mod _sqlite { fn iterdump(zelf: PyRef, vm: &VirtualMachine) -> PyResult { let module = vm.import("sqlite3.dump", None, 0)?; let func = module.get_attr("_iterdump", vm)?; - vm.invoke(&func, (zelf,)) + func.call((zelf,), vm) } #[pymethod] @@ -1699,7 +1700,7 @@ mod _sqlite { std::slice::from_raw_parts(blob.cast::(), nbytes as usize) }; let blob = vm.ctx.new_bytes(blob.to_vec()); - vm.invoke(&converter, (blob,))? + converter.call((blob,), vm)? } } else { let col_type = st.column_type(i); @@ -1724,7 +1725,7 @@ mod _sqlite { PyByteArray::from(text).into_ref(vm).into() } else { let bytes = vm.ctx.new_bytes(text); - vm.invoke(&text_factory, (bytes,))? + text_factory.call((bytes,), vm)? } } SQLITE_BLOB => { @@ -1765,7 +1766,8 @@ mod _sqlite { let row = vm.ctx.new_tuple(row); if let Some(row_factory) = zelf.row_factory.to_owned() { - vm.invoke(&row_factory, (zelf.to_owned(), row)) + row_factory + .call((zelf.to_owned(), row), vm) .map(PyIterReturn::Return) } else { Ok(PyIterReturn::Return(row.into())) diff --git a/vm/src/builtins/bool.rs b/vm/src/builtins/bool.rs index 06cf95de5..ed21290f6 100644 --- a/vm/src/builtins/bool.rs +++ b/vm/src/builtins/bool.rs @@ -37,7 +37,7 @@ impl PyObjectRef { Some(method_or_err) => { // If descriptor returns Error, propagate it further let method = method_or_err?; - let bool_obj = vm.invoke(&method, ())?; + let bool_obj = method.call((), vm)?; if !bool_obj.fast_isinstance(vm.ctx.types.bool_type) { return Err(vm.new_type_error(format!( "__bool__ should return bool, returned type {}", @@ -50,7 +50,7 @@ impl PyObjectRef { None => match vm.get_method(self, identifier!(vm, __len__)) { Some(method_or_err) => { let method = method_or_err?; - let bool_obj = vm.invoke(&method, ())?; + let bool_obj = method.call((), vm)?; let int_obj = bool_obj.payload::().ok_or_else(|| { vm.new_type_error(format!( "'{}' object cannot be interpreted as an integer", diff --git a/vm/src/builtins/classmethod.rs b/vm/src/builtins/classmethod.rs index fb1111305..6398108ad 100644 --- a/vm/src/builtins/classmethod.rs +++ b/vm/src/builtins/classmethod.rs @@ -58,7 +58,7 @@ impl GetDescriptor for PyClassMethod { let call_descr_get: PyResult = zelf.callable.lock().get_attr("__get__", vm); match call_descr_get { Err(_) => Ok(PyBoundMethod::new_ref(cls, zelf.callable.lock().clone(), &vm.ctx).into()), - Ok(call_descr_get) => vm.invoke(&call_descr_get, (cls.clone(), cls)), + Ok(call_descr_get) => call_descr_get.call((cls.clone(), cls), vm), } } } diff --git a/vm/src/builtins/complex.rs b/vm/src/builtins/complex.rs index 3aaa4d697..baf1d2875 100644 --- a/vm/src/builtins/complex.rs +++ b/vm/src/builtins/complex.rs @@ -60,7 +60,7 @@ impl PyObjectRef { return Ok(Some((complex.value, true))); } if let Some(method) = vm.get_method(self.clone(), identifier!(vm, __complex__)) { - let result = vm.invoke(&method?, ())?; + let result = method?.call((), vm)?; // TODO: returning strict subclasses of complex in __complex__ is deprecated return match result.payload::() { Some(complex_obj) => Ok(Some((complex_obj.value, true))), diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index 5c9c6fcde..8841bc6d8 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -72,7 +72,7 @@ impl PyDict { }; let dict = &self.entries; if let Some(keys) = vm.get_method(other.clone(), vm.ctx.intern_str("keys")) { - let keys = vm.invoke(&keys?, ())?.get_iter(vm)?; + let keys = keys?.call((), vm)?.get_iter(vm)?; while let PyIterReturn::Return(key) = keys.next(vm)? { let val = other.get_item(&*key, vm)?; dict.insert(vm, &*key, val)?; @@ -511,7 +511,7 @@ impl Py { vm: &VirtualMachine, ) -> PyResult> { vm.get_method(self.to_owned().into(), identifier!(vm, __missing__)) - .map(|methods| vm.invoke(&methods?, (key.to_pyobject(vm),))) + .map(|methods| methods?.call((key.to_pyobject(vm),), vm)) .transpose() } diff --git a/vm/src/builtins/filter.rs b/vm/src/builtins/filter.rs index ccdbd0b11..0f823e6b6 100644 --- a/vm/src/builtins/filter.rs +++ b/vm/src/builtins/filter.rs @@ -57,7 +57,7 @@ impl IterNext for PyFilter { } else { // the predicate itself can raise StopIteration which does stop the filter // iteration - match PyIterReturn::from_pyresult(vm.invoke(predicate, (next_obj.clone(),)), vm)? { + match PyIterReturn::from_pyresult(predicate.call((next_obj.clone(),), vm), vm)? { PyIterReturn::Return(obj) => obj, PyIterReturn::StopIteration(v) => return Ok(PyIterReturn::StopIteration(v)), } diff --git a/vm/src/builtins/function.rs b/vm/src/builtins/function.rs index 2c41b5224..6c476b55a 100644 --- a/vm/src/builtins/function.rs +++ b/vm/src/builtins/function.rs @@ -469,7 +469,7 @@ impl Callable for PyBoundMethod { #[inline] fn call(zelf: &crate::Py, mut args: FuncArgs, vm: &VirtualMachine) -> PyResult { args.prepend_arg(zelf.object.clone()); - vm.invoke(&zelf.function, args) + zelf.function.call(args, vm) } } diff --git a/vm/src/builtins/list.rs b/vm/src/builtins/list.rs index 2374e7746..b53acce41 100644 --- a/vm/src/builtins/list.rs +++ b/vm/src/builtins/list.rs @@ -510,7 +510,7 @@ fn do_sort( if let Some(ref key_func) = key_func { let mut items = values .iter() - .map(|x| Ok((x.clone(), vm.invoke(key_func, (x.clone(),))?))) + .map(|x| Ok((x.clone(), key_func.call((x.clone(),), vm)?))) .collect::, _>>()?; timsort::try_sort_by_gt(&mut items, |a, b| cmp(&a.1, &b.1))?; *values = items.into_iter().map(|(val, _)| val).collect(); diff --git a/vm/src/builtins/map.rs b/vm/src/builtins/map.rs index 0851114e7..26fac1410 100644 --- a/vm/src/builtins/map.rs +++ b/vm/src/builtins/map.rs @@ -64,7 +64,7 @@ impl IterNext for PyMap { } // the mapper itself can raise StopIteration which does stop the map iteration - PyIterReturn::from_pyresult(vm.invoke(&zelf.mapper, next_objs), vm) + PyIterReturn::from_pyresult(zelf.mapper.call(next_objs, vm), vm) } } diff --git a/vm/src/builtins/module.rs b/vm/src/builtins/module.rs index f907a538b..d73c02540 100644 --- a/vm/src/builtins/module.rs +++ b/vm/src/builtins/module.rs @@ -50,7 +50,7 @@ impl PyModule { return Ok(attr); } if let Ok(getattr) = zelf.dict().get_item(identifier!(vm, __getattr__), vm) { - return vm.invoke(&getattr, (name,)); + return getattr.call((name,), vm); } let module_name = if let Some(name) = Self::name(zelf.to_owned(), vm) { format!(" '{name}'") @@ -71,7 +71,7 @@ impl PyModule { fn repr(zelf: PyRef, vm: &VirtualMachine) -> PyResult { let importlib = vm.import("_frozen_importlib", None, 0)?; let module_repr = importlib.get_attr("_module_repr", vm)?; - vm.invoke(&module_repr, (zelf,)) + module_repr.call((zelf,), vm) } #[pymethod(magic)] diff --git a/vm/src/builtins/object.rs b/vm/src/builtins/object.rs index 2b0e061cd..6beef5eaa 100644 --- a/vm/src/builtins/object.rs +++ b/vm/src/builtins/object.rs @@ -313,7 +313,7 @@ impl PyBaseObject { let typ_obj: PyObjectRef = obj.class().to_owned().into(); let class_reduce = typ_obj.get_attr(__reduce__, vm)?; if !class_reduce.is(&object_reduce) { - return vm.invoke(&reduce, ()); + return reduce.call((), vm); } } common_reduce(obj, proto, vm) @@ -353,10 +353,10 @@ fn common_reduce(obj: PyObjectRef, proto: usize, vm: &VirtualMachine) -> PyResul if proto >= 2 { let reducelib = vm.import("__reducelib", None, 0)?; let reduce_2 = reducelib.get_attr("reduce_2", vm)?; - vm.invoke(&reduce_2, (obj,)) + reduce_2.call((obj,), vm) } else { let copyreg = vm.import("copyreg", None, 0)?; let reduce_ex = copyreg.get_attr("_reduce_ex", vm)?; - vm.invoke(&reduce_ex, (obj, proto)) + reduce_ex.call((obj, proto), vm) } } diff --git a/vm/src/builtins/property.rs b/vm/src/builtins/property.rs index fde9eb403..075afc2cd 100644 --- a/vm/src/builtins/property.rs +++ b/vm/src/builtins/property.rs @@ -49,7 +49,7 @@ impl GetDescriptor for PyProperty { if vm.is_none(&obj) { Ok(zelf.into()) } else if let Some(getter) = zelf.getter.read().as_ref() { - vm.invoke(getter, (obj,)) + getter.call((obj,), vm) } else { Err(vm.new_attribute_error("unreadable attribute".to_string())) } @@ -71,14 +71,14 @@ impl PyProperty { match value { PySetterValue::Assign(value) => { if let Some(setter) = zelf.setter.read().as_ref() { - vm.invoke(setter, (obj, value)).map(drop) + setter.call((obj, value), vm).map(drop) } else { Err(vm.new_attribute_error("can't set attribute".to_owned())) } } PySetterValue::Delete => { if let Some(deleter) = zelf.deleter.read().as_ref() { - vm.invoke(deleter, (obj,)).map(drop) + deleter.call((obj,), vm).map(drop) } else { Err(vm.new_attribute_error("can't delete attribute".to_owned())) } diff --git a/vm/src/builtins/staticmethod.rs b/vm/src/builtins/staticmethod.rs index 44add3e4e..47630360c 100644 --- a/vm/src/builtins/staticmethod.rs +++ b/vm/src/builtins/staticmethod.rs @@ -180,7 +180,7 @@ impl Callable for PyStaticMethod { #[inline] fn call(zelf: &crate::Py, args: FuncArgs, vm: &VirtualMachine) -> PyResult { let callable = zelf.callable.lock().clone(); - vm.invoke(&callable, args) + callable.call(args, vm) } } diff --git a/vm/src/builtins/str.rs b/vm/src/builtins/str.rs index ddc9aa92b..514db2bfc 100644 --- a/vm/src/builtins/str.rs +++ b/vm/src/builtins/str.rs @@ -377,7 +377,7 @@ impl PyStr { .to_pyobject(vm)) } else if let Some(radd) = vm.get_method(other.clone(), identifier!(vm, __radd__)) { // hack to get around not distinguishing number add from seq concat - vm.invoke(&radd?, (zelf,)) + radd?.call((zelf,), vm) } else { Err(vm.new_type_error(format!( "can only concatenate str (not \"{}\") to str", diff --git a/vm/src/builtins/super.rs b/vm/src/builtins/super.rs index 7f2494292..dd68b5c3c 100644 --- a/vm/src/builtins/super.rs +++ b/vm/src/builtins/super.rs @@ -6,8 +6,8 @@ See also [CPython source code.](https://github.com/python/cpython/blob/50b48572d use super::{PyStrRef, PyType, PyTypeRef}; use crate::{ class::PyClassImpl, - function::OptionalArg, - types::{Constructor, GetAttr, GetDescriptor}, + function::{IntoFuncArgs, OptionalArg}, + types::{Callable, Constructor, GetAttr, GetDescriptor}, AsObject, Context, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; @@ -188,7 +188,7 @@ impl GetDescriptor for PySuper { Ok(PySuper::new(zelf.typ.clone(), obj, vm)?.into_pyobject(vm)) } else { let obj = vm.unwrap_or_none(zelf.obj.clone().map(|(o, _)| o)); - vm.invoke(zelf.class(), (zelf.typ.clone(), obj)) + PyType::call(zelf.class(), (zelf.typ.clone(), obj).into_args(vm), vm) } } } diff --git a/vm/src/builtins/type.rs b/vm/src/builtins/type.rs index f277ae92b..ffe184a7c 100644 --- a/vm/src/builtins/type.rs +++ b/vm/src/builtins/type.rs @@ -858,24 +858,23 @@ impl PyType { }) .collect::>>()?; for (obj, name, set_name) in attributes { - vm.invoke(&set_name, (typ.clone(), name.to_owned())) - .map_err(|e| { - let err = vm.new_runtime_error(format!( - "Error calling __set_name__ on '{}' instance {} in '{}'", - obj.class().name(), - name, - typ.name() - )); - err.set_cause(Some(e)); - err - })?; + set_name.call((typ.clone(), name), vm).map_err(|e| { + let err = vm.new_runtime_error(format!( + "Error calling __set_name__ on '{}' instance {} in '{}'", + obj.class().name(), + name, + typ.name() + )); + err.set_cause(Some(e)); + err + })?; } if let Some(init_subclass) = typ.get_super_attr(identifier!(vm, __init_subclass__)) { let init_subclass = vm .call_get_descriptor_specific(init_subclass.clone(), None, Some(typ.clone().into())) .unwrap_or(Ok(init_subclass))?; - vm.invoke(&init_subclass, kwargs)?; + init_subclass.call(kwargs, vm)?; }; Ok(typ.into()) diff --git a/vm/src/bytesinner.rs b/vm/src/bytesinner.rs index 07ff56a47..fce0522a4 100644 --- a/vm/src/bytesinner.rs +++ b/vm/src/bytesinner.rs @@ -90,7 +90,7 @@ impl ByteInnerNewOptions { if let Some(bytes_method) = vm.get_method(obj, identifier!(vm, __bytes__)) { // construct an exact bytes from __bytes__ slot. // if __bytes__ return a bytes, use the bytes object except we are the subclass of the bytes - let bytes = vm.invoke(&bytes_method?, ())?; + let bytes = bytes_method?.call((), vm)?; let bytes = if cls.is(PyBytes::class(vm)) { match bytes.downcast::() { Ok(b) => return Ok(b), diff --git a/vm/src/cformat.rs b/vm/src/cformat.rs index 998ac6744..4deb874d8 100644 --- a/vm/src/cformat.rs +++ b/vm/src/cformat.rs @@ -59,7 +59,7 @@ fn spec_format_bytes( } obj => { if let Some(method) = vm.get_method(obj.clone(), identifier!(vm, __int__)) { - let result = vm.invoke(&method?, ())?; + let result = method?.call((), vm)?; if let Some(i) = result.payload::() { return Ok(spec.format_number(i.as_bigint()).into_bytes()); } @@ -152,7 +152,7 @@ fn spec_format_string( } obj => { if let Some(method) = vm.get_method(obj.clone(), identifier!(vm, __int__)) { - let result = vm.invoke(&method?, ())?; + let result = method?.call((), vm)?; if let Some(i) = result.payload::() { return Ok(spec.format_number(i.as_bigint())); } diff --git a/vm/src/codecs.rs b/vm/src/codecs.rs index 6f882c192..4bf5709dd 100644 --- a/vm/src/codecs.rs +++ b/vm/src/codecs.rs @@ -63,7 +63,7 @@ impl PyCodec { Some(errors) => vec![obj, errors.into()], None => vec![obj], }; - let res = vm.invoke(self.get_encode_func(), args)?; + let res = self.get_encode_func().call(args, vm)?; let res = res .downcast::() .ok() @@ -85,7 +85,7 @@ impl PyCodec { Some(errors) => vec![obj, errors.into()], None => vec![obj], }; - let res = vm.invoke(self.get_decode_func(), args)?; + let res = self.get_decode_func().call(args, vm)?; let res = res .downcast::() .ok() @@ -230,7 +230,7 @@ impl CodecsRegistry { }; let encoding = PyStr::from(encoding.into_owned()).into_ref(vm); for func in search_path { - let res = vm.invoke(&func, (encoding.clone(),))?; + let res = func.call((encoding.clone(),), vm)?; let res: Option = res.try_into_value(vm)?; if let Some(codec) = res { let mut inner = self.inner.write(); diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 5174301ac..e6f3b4005 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -1,17 +1,17 @@ use self::types::{PyBaseException, PyBaseExceptionRef}; -use crate::builtins::tuple::IntoPyTuple; -use crate::common::lock::PyRwLock; -use crate::common::str::ReprOverflowError; +use crate::common::{lock::PyRwLock, str::ReprOverflowError}; use crate::{ builtins::{ - traceback::PyTracebackRef, PyNone, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef, + traceback::PyTracebackRef, tuple::IntoPyTuple, PyNone, PyStr, PyStrRef, PyTuple, + PyTupleRef, PyType, PyTypeRef, }, class::{PyClassImpl, StaticType}, convert::{ToPyException, ToPyObject}, - function::{ArgIterable, FuncArgs}, + function::{ArgIterable, FuncArgs, IntoFuncArgs}, py_io::{self, Write}, stdlib::sys, suggestion::offer_suggestions, + types::Callable, AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, }; use crossbeam_utils::atomic::AtomicCell; @@ -54,7 +54,7 @@ impl VirtualMachine { }; if let Ok(excepthook) = vm.sys_module.get_attr("excepthook", vm) { let (exc_type, exc_val, exc_tb) = vm.split_exception(exc.clone()); - if let Err(eh_exc) = vm.invoke(&excepthook, (exc_type, exc_val, exc_tb)) { + if let Err(eh_exc) = excepthook.call((exc_type, exc_val, exc_tb), vm) { write_fallback(&eh_exc, "Error in sys.excepthook:"); write_fallback(&exc, "Original exception was:"); } @@ -208,7 +208,7 @@ impl VirtualMachine { args: Vec, ) -> PyResult { // TODO: fast-path built-in exceptions by directly instantiating them? Is that really worth it? - let res = self.invoke(&cls, args)?; + let res = PyType::call(&cls, args.into_args(self), self)?; PyBaseExceptionRef::try_from_object(self, res) } } diff --git a/vm/src/frame.rs b/vm/src/frame.rs index af3cd1aa1..c3a9682b7 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -436,7 +436,7 @@ impl ExecutingFrame<'_> { Either::A(coro) => coro .throw(gen, exc_type, exc_val, exc_tb, vm) .to_pyresult(vm), // FIXME: - Either::B(meth) => vm.invoke(&meth, (exc_type, exc_val, exc_tb)), + Either::B(meth) => meth.call((exc_type, exc_val, exc_tb), vm), }; return ret.map(ExecutionResult::Yield).or_else(|err| { self.pop_value(); @@ -889,7 +889,7 @@ impl ExecutingFrame<'_> { } else { (vm.ctx.none(), vm.ctx.none(), vm.ctx.none()) }; - let exit_res = vm.invoke(&exit, args)?; + let exit_res = exit.call(args, vm)?; self.push_value(exit_res); Ok(None) @@ -938,7 +938,7 @@ impl ExecutingFrame<'_> { ) }, )?; - vm.invoke(&await_method, ())? + await_method.call((), vm)? }; self.push_value(awaitable); Ok(None) @@ -1353,7 +1353,7 @@ impl ExecutingFrame<'_> { #[inline] fn execute_call(&mut self, args: FuncArgs, vm: &VirtualMachine) -> FrameResult { let func_ref = self.pop_value(); - let value = vm.invoke(&func_ref, args)?; + let value = func_ref.call(args, vm)?; self.push_value(value); Ok(None) } @@ -1429,7 +1429,7 @@ impl ExecutingFrame<'_> { None if vm.is_none(&val) => PyIter::new(gen).next(vm), None => { let meth = gen.to_owned().get_attr("send", vm)?; - PyIterReturn::from_pyresult(vm.invoke(&meth, (val,)), vm) + PyIterReturn::from_pyresult(meth.call((val,), vm), vm) } } } @@ -1716,7 +1716,7 @@ impl ExecutingFrame<'_> { .clone() .get_attr("displayhook", vm) .map_err(|_| vm.new_runtime_error("lost sys.displayhook".to_owned()))?; - vm.invoke(&displayhook, (expr,))?; + displayhook.call((expr,), vm)?; Ok(None) } diff --git a/vm/src/import.rs b/vm/src/import.rs index 9fc8e56ea..1e036ee36 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -24,7 +24,7 @@ pub(crate) fn init_importlib_base(vm: &mut VirtualMachine) -> PyResult = std::mem::take(&mut *vm.state.atexit_funcs.lock()); for (func, args) in funcs.into_iter().rev() { - if let Err(e) = vm.invoke(&func, args) { + if let Err(e) = func.call(args, vm) { let exit = e.fast_isinstance(vm.ctx.exceptions.system_exit); vm.run_unraisable(e, Some("Error in atexit._run_exitfuncs".to_owned()), func); if exit { diff --git a/vm/src/stdlib/builtins.rs b/vm/src/stdlib/builtins.rs index ccf5c7c2d..fa2d91768 100644 --- a/vm/src/stdlib/builtins.rs +++ b/vm/src/stdlib/builtins.rs @@ -354,7 +354,7 @@ mod builtins { .sys_module .get_attr(vm.ctx.intern_str("breakpointhook"), vm) { - Ok(hook) => vm.invoke(hook.as_ref(), args), + Ok(hook) => hook.as_ref().call(args, vm), Err(_) => Err(vm.new_runtime_error("lost sys.breakpointhook".to_owned())), } } @@ -498,9 +498,9 @@ mod builtins { let key_func = key_func.filter(|f| !vm.is_none(f)); if let Some(ref key_func) = key_func { - let mut x_key = vm.invoke(key_func, (x.clone(),))?; + let mut x_key = key_func.call((x.clone(),), vm)?; for y in candidates_iter { - let y_key = vm.invoke(key_func, (y.clone(),))?; + let y_key = key_func.call((y.clone(),), vm)?; if y_key.rich_compare_bool(&x_key, op, vm)? { x = y; x_key = y_key; @@ -617,7 +617,7 @@ mod builtins { args: (PyObjectRef, PyObjectRef, PyObjectRef)| -> Option { let method = obj.get_class_attr(identifier!(vm, __pow__))?; - let result = match vm.invoke(&method, args) { + let result = match method.call(args, vm) { Ok(x) => x, Err(e) => return Some(Err(e)), }; @@ -704,7 +704,7 @@ mod builtins { #[pyfunction] fn reversed(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult { if let Some(reversed_method) = vm.get_method(obj.clone(), identifier!(vm, __reversed__)) { - vm.invoke(&reversed_method?, ()) + reversed_method?.call((), vm) } else { vm.get_method_or_type_error(obj.clone(), identifier!(vm, __getitem__), || { "argument to reversed() must be a sequence".to_owned() @@ -804,7 +804,7 @@ mod builtins { #[pyfunction] fn __import__(args: FuncArgs, vm: &VirtualMachine) -> PyResult { - vm.invoke(&vm.import_func, args) + vm.import_func.call(args, vm) } #[pyfunction] @@ -843,7 +843,7 @@ mod builtins { let mro_entries = vm.get_attribute_opt(base.clone(), identifier!(vm, __mro_entries__))?; let entries = match mro_entries { - Some(meth) => vm.invoke(&meth, (bases.clone(),))?, + Some(meth) => meth.call((bases.clone(),), vm)?, None => { if let Some(bases) = &mut new_bases { bases.push(base.clone()); @@ -900,10 +900,9 @@ mod builtins { let namespace = vm .get_attribute_opt(metaclass.clone(), identifier!(vm, __prepare__))? .map_or(Ok(vm.ctx.new_dict().into()), |prepare| { - vm.invoke( - &prepare, - FuncArgs::new(vec![name_obj.clone().into(), bases.clone()], kwargs.clone()), - ) + let args = + FuncArgs::new(vec![name_obj.clone().into(), bases.clone()], kwargs.clone()); + prepare.call(args, vm) })?; // Accept any PyMapping as namespace. @@ -926,10 +925,8 @@ mod builtins { )?; } - let class = vm.invoke( - &metaclass, - FuncArgs::new(vec![name_obj.into(), bases, namespace.into()], kwargs), - )?; + let args = FuncArgs::new(vec![name_obj.into(), bases, namespace.into()], kwargs); + let class = metaclass.call(args, vm)?; if let Some(ref classcell) = classcell { let classcell = classcell.get().ok_or_else(|| { diff --git a/vm/src/stdlib/codecs.rs b/vm/src/stdlib/codecs.rs index 6e7779fa8..4eb639b64 100644 --- a/vm/src/stdlib/codecs.rs +++ b/vm/src/stdlib/codecs.rs @@ -130,7 +130,7 @@ mod _codecs { vm.ctx.new_str(reason).into(), ], ); - let res = vm.invoke(self.handler_func()?, (encode_exc,))?; + let res = self.handler_func()?.call((encode_exc,), vm)?; let tuple_err = || { vm.new_type_error( "encoding error handler must return (str/bytes, int) tuple".to_owned(), @@ -174,7 +174,7 @@ mod _codecs { ], ); let handler = self.handler_func()?; - let res = vm.invoke(handler, (decode_exc.clone(),))?; + let res = handler.call((decode_exc.clone(),), vm)?; let new_data = decode_exc .get_arg(1) .ok_or_else(|| vm.new_type_error("object attribute not set".to_owned()))?; @@ -358,7 +358,7 @@ mod _codecs { let module = vm.import("_pycodecs", None, 0)?; module.get_attr(name, vm) })?; - vm.invoke(f, args) + f.call(args, vm) } macro_rules! delegate_pycodecs { ($name:ident, $args:ident, $vm:ident) => {{ diff --git a/vm/src/stdlib/functools.rs b/vm/src/stdlib/functools.rs index 9d653288a..d13b9b84f 100644 --- a/vm/src/stdlib/functools.rs +++ b/vm/src/stdlib/functools.rs @@ -26,7 +26,7 @@ mod _functools { let mut accumulator = start_value; for next_obj in iter { - accumulator = vm.invoke(&function, (accumulator, next_obj?))? + accumulator = function.call((accumulator, next_obj?), vm)? } Ok(accumulator) } diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index 5d9645778..087d01008 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -80,7 +80,8 @@ impl TryFromObject for Fildes { "argument must be an int, or have a fileno() method.".to_owned(), ) })?; - vm.invoke(&fileno_meth, ())? + fileno_meth + .call((), vm)? .downcast() .map_err(|_| vm.new_type_error("fileno() returned a non-integer".to_owned()))? } @@ -98,7 +99,6 @@ impl TryFromObject for Fildes { #[pymodule] mod _io { use super::*; - use crate::{ builtins::{ PyBaseExceptionRef, PyByteArray, PyBytes, PyBytesRef, PyIntRef, PyMemoryView, PyStr, @@ -111,14 +111,16 @@ mod _io { }, convert::ToPyObject, function::{ - ArgBytesLike, ArgIterable, ArgMemoryBuffer, Either, FuncArgs, OptionalArg, - OptionalOption, PySetterValue, + ArgBytesLike, ArgIterable, ArgMemoryBuffer, Either, FuncArgs, IntoFuncArgs, + OptionalArg, OptionalOption, PySetterValue, }, protocol::{ BufferDescriptor, BufferMethods, BufferResizeGuard, PyBuffer, PyIterReturn, VecBuffer, }, recursion::ReprGuard, - types::{Constructor, DefaultConstructor, Destructor, Initializer, IterNext, Iterable}, + types::{ + Callable, Constructor, DefaultConstructor, Destructor, Initializer, IterNext, Iterable, + }, vm::VirtualMachine, AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromBorrowedObject, TryFromObject, @@ -463,7 +465,7 @@ mod _io { let read = instance.get_attr("read", vm)?; let mut res = Vec::new(); while size.map_or(true, |s| res.len() < s) { - let read_res = ArgBytesLike::try_from_object(vm, vm.invoke(&read, (1,))?)?; + let read_res = ArgBytesLike::try_from_object(vm, read.call((1,), vm)?)?; if read_res.with_ref(|b| b.is_empty()) { break; } @@ -865,7 +867,7 @@ mod _io { } } } - // vm.invoke(&raw.get_attr("seek", vm)?, args) + // raw.get_attr("seek", vm)?.call(args, vm) if self.writable() { self.flush(vm)?; } @@ -1198,7 +1200,7 @@ mod _io { .get_str_method(self.raw.clone().unwrap(), "readall") .transpose()?; if let Some(readall) = readall { - let res = vm.invoke(&readall, ())?; + let res = readall.call((), vm)?; let res = >::try_from_object(vm, res)?; let ret = if let Some(mut data) = data { if let Some(bytes) = res { @@ -3596,9 +3598,10 @@ mod _io { "Couldn't get FileIO, io.open likely isn't supported on your platform".to_owned(), ) })?; - let raw = vm.invoke( + let raw = PyType::call( file_io_class, - (file, mode.rawmode(), opts.closefd, opts.opener), + (file, mode.rawmode(), opts.closefd, opts.opener).into_args(vm), + vm, )?; let isatty = opts.buffering < 0 && { @@ -3631,12 +3634,12 @@ mod _io { } else { BufferedWriter::static_type() }; - let buffered = vm.invoke(cls, (raw, buffering))?; + let buffered = PyType::call(cls, (raw, buffering).into_args(vm), vm)?; match mode.encode { EncodeMode::Text => { let tio = TextIOWrapper::static_type(); - let wrapper = vm.invoke( + let wrapper = PyType::call( tio, ( buffered, @@ -3644,7 +3647,9 @@ mod _io { opts.errors, opts.newline, line_buffering, - ), + ) + .into_args(vm), + vm, )?; wrapper.set_attr("mode", vm.new_pyobj(mode_string), vm)?; Ok(wrapper) @@ -3886,7 +3891,7 @@ mod fileio { compute_mode(mode_str).map_err(|e| vm.new_value_error(e.error_msg(mode_str)))?; zelf.mode.store(mode); let fd = if let Some(opener) = args.opener { - let fd = vm.invoke(&opener, (name.clone(), flags))?; + let fd = opener.call((name.clone(), flags), vm)?; if !fd.fast_isinstance(vm.ctx.types.int_type) { return Err(vm.new_type_error("expected integer from opener".to_owned())); } diff --git a/vm/src/stdlib/itertools.rs b/vm/src/stdlib/itertools.rs index b5f5686c4..ee22a2574 100644 --- a/vm/src/stdlib/itertools.rs +++ b/vm/src/stdlib/itertools.rs @@ -470,7 +470,7 @@ mod decl { match obj { PyIterReturn::Return(obj) => { let args: Vec<_> = obj.try_to_value(vm)?; - PyIterReturn::from_pyresult(vm.invoke(function, args), vm) + PyIterReturn::from_pyresult(function.call(args, vm), vm) } PyIterReturn::StopIteration(v) => Ok(PyIterReturn::StopIteration(v)), } @@ -547,7 +547,7 @@ mod decl { }; let predicate = &zelf.predicate; - let verdict = vm.invoke(predicate, (obj.clone(),))?; + let verdict = predicate.call((obj.clone(),), vm)?; let verdict = verdict.try_to_bool(vm)?; if verdict { Ok(PyIterReturn::Return(obj)) @@ -629,7 +629,7 @@ mod decl { } }; let pred = predicate.clone(); - let pred_value = vm.invoke(&pred, (obj.clone(),))?; + let pred_value = pred.invoke((obj.clone(),), vm)?; if !pred_value.try_to_bool(vm)? { zelf.start_flag.store(true); return Ok(PyIterReturn::Return(obj)); @@ -726,7 +726,7 @@ mod decl { PyIterReturn::StopIteration(v) => return Ok(PyIterReturn::StopIteration(v)), }; let new_key = if let Some(ref kf) = self.key_func { - vm.invoke(kf, (new_value.clone(),))? + kf.call((new_value.clone(),), vm)? } else { new_value.clone() }; @@ -1043,7 +1043,7 @@ mod decl { let pred_value = if vm.is_none(predicate) { obj.clone() } else { - vm.invoke(predicate, (obj.clone(),))? + predicate.call((obj.clone(),), vm)? }; if !pred_value.try_to_bool(vm)? { @@ -1116,7 +1116,7 @@ mod decl { }; match &zelf.binop { None => vm._add(&value, &obj)?, - Some(op) => vm.invoke(op, (value, obj))?, + Some(op) => op.call((value, obj), vm)?, } } }; diff --git a/vm/src/stdlib/operator.rs b/vm/src/stdlib/operator.rs index f3cbfc498..85124ab97 100644 --- a/vm/src/stdlib/operator.rs +++ b/vm/src/stdlib/operator.rs @@ -563,13 +563,11 @@ mod _operator { // If we have kwargs, create a partial function that contains them and pass back that // along with the args. let partial = vm.import("functools", None, 0)?.get_attr("partial", vm)?; - let callable = vm.invoke( - &partial, - FuncArgs::new( - vec![zelf.class().to_owned().into(), zelf.name.clone().into()], - KwArgs::new(zelf.args.kwargs.clone()), - ), - )?; + let args = FuncArgs::new( + vec![zelf.class().to_owned().into(), zelf.name.clone().into()], + KwArgs::new(zelf.args.kwargs.clone()), + ); + let callable = partial.call(args, vm)?; Ok(vm.new_tuple((callable, vm.ctx.new_tuple(zelf.args.args.clone())))) } } diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index 7804a4a2a..6069fd606 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -150,7 +150,7 @@ impl FsPath { obj.class().name() ) })?; - let result = vm.invoke(&method, ())?; + let result = method.call((), vm)?; match1(result)?.map_err(|result| { vm.new_type_error(format!( "expected {}.__fspath__() to return str or bytes, not {}", diff --git a/vm/src/stdlib/sre.rs b/vm/src/stdlib/sre.rs index a531d6629..a07a048bf 100644 --- a/vm/src/stdlib/sre.rs +++ b/vm/src/stdlib/sre.rs @@ -421,7 +421,7 @@ mod _sre { if is_template { let re = vm.import("re", None, 0)?; let func = re.get_attr("_subx", vm)?; - let filter = vm.invoke(&func, (zelf.clone(), repl))?; + let filter = func.call((zelf.clone(), repl), vm)?; (filter.is_callable(), filter) } else { (false, repl) @@ -444,7 +444,7 @@ mod _sre { if is_callable { let m = Match::new(&iter.state, zelf.clone(), string.clone()); - let ret = vm.invoke(&filter, (m.into_ref(vm),))?; + let ret = filter.call((m.into_ref(vm),), vm)?; sublist.push(ret); } else { sublist.push(filter.clone()); @@ -617,7 +617,7 @@ mod _sre { fn expand(zelf: PyRef, template: PyStrRef, vm: &VirtualMachine) -> PyResult { let re = vm.import("re", None, 0)?; let func = re.get_attr("_expand", vm)?; - vm.invoke(&func, (zelf.pattern.clone(), zelf, template)) + func.call((zelf.pattern.clone(), zelf, template), vm) } #[pymethod] diff --git a/vm/src/stdlib/sys.rs b/vm/src/stdlib/sys.rs index e202958b5..ad98ebc51 100644 --- a/vm/src/stdlib/sys.rs +++ b/vm/src/stdlib/sys.rs @@ -381,7 +381,7 @@ mod sys { }; match vm.get_attribute_opt(module, attrname) { - Ok(Some(hook)) => vm.invoke(hook.as_ref(), args), + Ok(Some(hook)) => hook.as_ref().call(args, vm), _ => print_unimportable_module_warn(), } } @@ -560,7 +560,7 @@ mod sys { // TODO: print received unraisable.exc_traceback let tb_module = vm.import("traceback", None, 0)?; let print_stack = tb_module.get_attr("print_stack", vm)?; - vm.invoke(&print_stack, ())?; + print_stack.call((), vm)?; if vm.is_none(unraisable.exc_type.as_object()) { // TODO: early return, but with what error? diff --git a/vm/src/stdlib/warnings.rs b/vm/src/stdlib/warnings.rs index c5da9be56..ef72490f1 100644 --- a/vm/src/stdlib/warnings.rs +++ b/vm/src/stdlib/warnings.rs @@ -11,7 +11,7 @@ pub fn warn( // TODO: use rust warnings module if let Ok(module) = vm.import("warnings", None, 0) { if let Ok(func) = module.get_attr("warn", vm) { - let _ = vm.invoke(&func, (message, category.to_owned(), stack_level)); + let _ = func.call((message, category.to_owned(), stack_level), vm); } } Ok(()) diff --git a/vm/src/types/slot.rs b/vm/src/types/slot.rs index 1be87b4f1..84100a365 100644 --- a/vm/src/types/slot.rs +++ b/vm/src/types/slot.rs @@ -337,7 +337,7 @@ fn init_wrapper(obj: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResu fn new_wrapper(cls: PyTypeRef, mut args: FuncArgs, vm: &VirtualMachine) -> PyResult { let new = cls.get_attr(identifier!(vm, __new__)).unwrap(); args.prepend_arg(cls.into()); - vm.invoke(&new, args) + new.call(args, vm) } fn del_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> PyResult<()> { diff --git a/vm/src/vm/compile.rs b/vm/src/vm/compile.rs index 3b1be7ec5..d2bfb18ab 100644 --- a/vm/src/vm/compile.rs +++ b/vm/src/vm/compile.rs @@ -31,10 +31,7 @@ impl VirtualMachine { self.insert_sys_path(self.new_pyobj(path))?; let runpy = self.import("runpy", None, 0)?; let run_module_as_main = runpy.get_attr("_run_module_as_main", self)?; - self.invoke( - &run_module_as_main, - (identifier!(self, __main__).to_owned(), false), - )?; + run_module_as_main.call((identifier!(self, __main__).to_owned(), false), self)?; return Ok(()); } @@ -91,7 +88,7 @@ fn get_importer(path: &str, vm: &VirtualMachine) -> PyResult let mut importer = None; let path_hooks: Vec = path_hooks.try_into_value(vm)?; for path_hook in path_hooks { - match vm.invoke(&path_hook, (path.clone(),)) { + match path_hook.call((path.clone(),), vm) { Ok(imp) => { importer = Some(imp); break; diff --git a/vm/src/vm/method.rs b/vm/src/vm/method.rs index a1e3bb250..0436f5028 100644 --- a/vm/src/vm/method.rs +++ b/vm/src/vm/method.rs @@ -72,7 +72,7 @@ impl PyMethod { None => Ok(Self::Attribute(attr)), } } else if let Some(getter) = cls.get_attr(identifier!(vm, __getattr__)) { - vm.invoke(&getter, (obj, name)).map(Self::Attribute) + getter.call((obj, name), vm).map(Self::Attribute) } else { let exc = vm.new_attribute_error(format!( "'{}' object has no attribute '{}'", @@ -118,7 +118,7 @@ impl PyMethod { PyMethod::Function { target, func } => (func, args.into_method_args(target, vm)), PyMethod::Attribute(func) => (func, args.into_args(vm)), }; - vm.invoke(&func, args) + func.call(args, vm) } #[allow(dead_code)] @@ -129,6 +129,6 @@ impl PyMethod { } PyMethod::Attribute(func) => (func, args.into_args(vm)), }; - vm.invoke(func, args) + func.call(args, vm) } } diff --git a/vm/src/vm/mod.rs b/vm/src/vm/mod.rs index eb34e4784..240df3e72 100644 --- a/vm/src/vm/mod.rs +++ b/vm/src/vm/mod.rs @@ -226,7 +226,7 @@ impl VirtualMachine { }; let encoding_module = import::import_frozen(self, encoding_module_name)?; let getregentry = encoding_module.get_attr("getregentry", self)?; - let codec_info = self.invoke(&getregentry, ())?; + let codec_info = getregentry.call((), self)?; self.state .codec_registry .register_manual("utf-8", codec_info.try_into_value(self)?)?; @@ -360,7 +360,7 @@ impl VirtualMachine { err_msg: self.new_pyobj(msg), object, }; - if let Err(e) = self.invoke(&unraisablehook, (args,)) { + if let Err(e) = unraisablehook.call((args,), self) { println!("{}", e.as_object().repr(self).unwrap().as_str()); } } @@ -521,7 +521,8 @@ impl VirtualMachine { Some(tup) => tup.to_pyobject(self), None => self.new_tuple(()).into(), }; - self.invoke(&import_func, (module, globals, locals, from_list, level)) + import_func + .call((module, globals, locals, from_list, level), self) .map_err(|exc| import::remove_importlib_frames(self, &exc)) } } @@ -814,7 +815,7 @@ impl VirtualMachine { pub fn run_module(&self, module: &str) -> PyResult<()> { let runpy = self.import("runpy", None, 0)?; let run_module_as_main = runpy.get_attr("_run_module_as_main", self)?; - self.invoke(&run_module_as_main, (module,))?; + run_module_as_main.call((module,), self)?; Ok(()) } } diff --git a/vm/src/vm/vm_object.rs b/vm/src/vm/vm_object.rs index fb2f3b5ce..ee0fdbe2f 100644 --- a/vm/src/vm/vm_object.rs +++ b/vm/src/vm/vm_object.rs @@ -151,7 +151,7 @@ impl VirtualMachine { .invoke(args, self) } - // #[deprecated(note = "in favor of `obj.call(args, vm)`")] + #[deprecated(note = "in favor of `obj.call(args, vm)`")] pub fn invoke(&self, obj: &impl AsObject, args: impl IntoFuncArgs) -> PyResult { obj.as_object().call(args, self) } diff --git a/vm/src/vm/vm_ops.rs b/vm/src/vm/vm_ops.rs index d38d0d007..c0530a691 100644 --- a/vm/src/vm/vm_ops.rs +++ b/vm/src/vm/vm_ops.rs @@ -57,7 +57,7 @@ impl VirtualMachine { Some(hint) => hint?, None => return Ok(None), }; - let result = match self.invoke(&hint, ()) { + let result = match hint.call((), self) { Ok(res) => { if res.is(&self.ctx.not_implemented) { return Ok(None); @@ -119,7 +119,7 @@ impl VirtualMachine { { if let Some(method_or_err) = self.get_method(obj.to_owned(), method) { let method = method_or_err?; - let result = self.invoke(&method, (arg.to_owned(),))?; + let result = method.call((arg.to_owned(),), self)?; if let PyArithmeticValue::Implemented(x) = PyArithmeticValue::from_object(self, result) { return Ok(x); diff --git a/vm/src/warn.rs b/vm/src/warn.rs index d6dfd7a8e..28460be63 100644 --- a/vm/src/warn.rs +++ b/vm/src/warn.rs @@ -44,7 +44,7 @@ fn check_matched(obj: &PyObjectRef, arg: &PyObjectRef, vm: &VirtualMachine) -> P return Ok(false); } - let result = vm.invoke(obj, (arg.to_owned(),)); + let result = obj.call((arg.to_owned(),), vm); Ok(result.is_ok()) } @@ -57,7 +57,7 @@ pub fn py_warn( // TODO: use rust warnings module if let Ok(module) = vm.import("warnings", None, 0) { if let Ok(func) = module.get_attr("warn", vm) { - let _ = vm.invoke(&func, (message, category.to_owned(), stack_level)); + let _ = func.call((message, category.to_owned(), stack_level), vm); } } Ok(()) diff --git a/wasm/lib/src/browser_module.rs b/wasm/lib/src/browser_module.rs index 9f302440c..32e7877a5 100644 --- a/wasm/lib/src/browser_module.rs +++ b/wasm/lib/src/browser_module.rs @@ -134,7 +134,7 @@ mod _browser { stored_vm.interp.enter(|vm| { let func = func.clone(); let args = vec![vm.ctx.new_float(time).into()]; - let _ = vm.invoke(&func, args); + let _ = func.invoke(args, vm); let closure = f.borrow_mut().take(); drop(closure); diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs index ed7aa8f29..5c78ed8d6 100644 --- a/wasm/lib/src/convert.rs +++ b/wasm/lib/src/convert.rs @@ -113,7 +113,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, py_func_args); + let result = py_obj.call(py_func_args, vm); pyresult_to_jsresult(vm, result) }) }; diff --git a/wasm/lib/src/js_module.rs b/wasm/lib/src/js_module.rs index 409e061e9..9c6cf64cd 100644 --- a/wasm/lib/src/js_module.rs +++ b/wasm/lib/src/js_module.rs @@ -324,7 +324,7 @@ mod _js { .into_iter() .map(|arg| PyJsValue::new(arg).into_pyobject(vm)), ); - let res = vm.invoke(&py_obj, pyargs); + let res = py_obj.call(pyargs, vm); convert::pyresult_to_jsresult(vm, res) }) }; @@ -420,12 +420,12 @@ mod _js { let _ = js_reject .call1(&JsValue::UNDEFINED, &convert::py_err_to_js_err(vm, &err)); }; - let _ = vm.invoke( - then, + let _ = then.call( ( vm.ctx.new_function("resolve", resolve), vm.ctx.new_function("reject", reject), ), + vm, ); }), PromiseKind::PyResolved(obj) => { @@ -517,12 +517,12 @@ mod _js { Ok(PyPromise::from_future(ret_future)) } PromiseKind::PyProm { then } => Self::cast_result( - vm.invoke( - then, + then.call( ( on_fulfill.map(IntoObject::into_object), on_reject.map(IntoObject::into_object), ), + vm, ), vm, ),