mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
Merge pull request #2476 from pca006132/master
Optimize method call performance
This commit is contained in:
@@ -629,7 +629,7 @@ fn subtype_get_dict(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
// TODO: obj.class().as_pyref() need to be supported
|
||||
let cls = obj.clone_class();
|
||||
let ret = match find_base_dict_descr(&cls, vm) {
|
||||
Some(descr) => vm.call_get_descriptor(descr, obj).unwrap_or_else(|| {
|
||||
Some(descr) => vm.call_get_descriptor(descr, obj).unwrap_or_else(|_| {
|
||||
Err(vm.new_type_error(format!(
|
||||
"this __dict__ descriptor does not support '{}' objects",
|
||||
cls.name
|
||||
|
||||
@@ -26,6 +26,11 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! count {
|
||||
() => (0usize);
|
||||
( $x:tt $($xs:tt)* ) => (1usize + count!($($xs)*));
|
||||
}
|
||||
|
||||
// A tuple of values that each implement `IntoPyObject` represents a sequence of
|
||||
// arguments that can be bound and passed to a built-in function.
|
||||
macro_rules! into_func_args_from_tuple {
|
||||
@@ -37,7 +42,9 @@ macro_rules! into_func_args_from_tuple {
|
||||
#[inline]
|
||||
fn into_args(self, vm: &VirtualMachine) -> FuncArgs {
|
||||
let ($($n,)*) = self;
|
||||
vec![$($n.into_pyobject(vm),)*].into()
|
||||
let mut result = Vec::with_capacity(count!($($n,)*) + 1);
|
||||
$(result.push($n.into_pyobject(vm), );)*
|
||||
result.into()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
18
vm/src/vm.rs
18
vm/src/vm.rs
@@ -944,19 +944,25 @@ impl VirtualMachine {
|
||||
descr: PyObjectRef,
|
||||
obj: Option<PyObjectRef>,
|
||||
cls: Option<PyObjectRef>,
|
||||
) -> Option<PyResult> {
|
||||
) -> Result<PyResult, PyObjectRef> {
|
||||
let descr_get = descr.class().mro_find_map(|cls| cls.slots.descr_get.load());
|
||||
descr_get.map(|descr_get| descr_get(descr, obj, cls, self))
|
||||
match descr_get {
|
||||
Some(descr_get) => Ok(descr_get(descr, obj, cls, self)),
|
||||
None => Err(descr),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn call_get_descriptor(&self, descr: PyObjectRef, obj: PyObjectRef) -> Option<PyResult> {
|
||||
pub fn call_get_descriptor(
|
||||
&self,
|
||||
descr: PyObjectRef,
|
||||
obj: PyObjectRef,
|
||||
) -> Result<PyResult, PyObjectRef> {
|
||||
let cls = obj.clone_class().into_object();
|
||||
self.call_get_descriptor_specific(descr, Some(obj), Some(cls))
|
||||
}
|
||||
|
||||
pub fn call_if_get_descriptor(&self, attr: PyObjectRef, obj: PyObjectRef) -> PyResult {
|
||||
self.call_get_descriptor(attr.clone(), obj)
|
||||
.unwrap_or(Ok(attr))
|
||||
self.call_get_descriptor(attr, obj).unwrap_or_else(Ok)
|
||||
}
|
||||
|
||||
pub fn call_method<T>(&self, obj: &PyObjectRef, method_name: &str, args: T) -> PyResult
|
||||
@@ -1257,7 +1263,7 @@ impl VirtualMachine {
|
||||
|
||||
if let Some(ref attr) = cls_attr {
|
||||
if attr.class().has_attr("__set__") {
|
||||
if let Some(r) = self.call_get_descriptor(attr.clone(), obj.clone()) {
|
||||
if let Ok(r) = self.call_get_descriptor(attr.clone(), obj.clone()) {
|
||||
return r.map(Some);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user