mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 10:44:36 +08:00
slot call use trait function as its signature
This commit is contained in:
1 parent
6f230ff7d7
commit
5e69141884
11 files changed
+65
-97
No files matched your search
@@ -345,8 +345,10 @@ where
|
||||
match slot_name.as_str() {
|
||||
"call" => quote! {
|
||||
slots.#slot_ident.store(Some(
|
||||
|vm: &::rustpython_vm::VirtualMachine, args: ::rustpython_vm::function::PyFuncArgs| -> ::rustpython_vm::pyobject::PyResult {
|
||||
::rustpython_vm::function::IntoPyNativeFunc::call(&Self::#ident, vm, args)
|
||||
|zelf: ::rustpython_vm::pyobject::PyObjectRef, args: ::rustpython_vm::function::PyFuncArgs, vm: &::rustpython_vm::VirtualMachine| -> ::rustpython_vm::pyobject::PyResult {
|
||||
use ::rustpython_vm::pyobject::TryFromObject;
|
||||
let zelf = PyRef::<Self>::try_from_object(vm, zelf)?;
|
||||
Self::#ident(zelf, args, vm)
|
||||
} as _
|
||||
));
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use super::objclassmethod::PyClassMethod;
|
||||
use crate::function::{OptionalArg, PyFuncArgs, PyNativeFunc};
|
||||
use crate::function::{PyFuncArgs, PyNativeFunc};
|
||||
use crate::obj::objstr::PyStringRef;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{
|
||||
@@ -169,10 +169,10 @@ impl PyBuiltinMethod {
|
||||
|
||||
impl SlotDescriptor for PyBuiltinMethod {
|
||||
fn descr_get(
|
||||
vm: &VirtualMachine,
|
||||
zelf: PyObjectRef,
|
||||
obj: Option<PyObjectRef>,
|
||||
cls: OptionalArg<PyObjectRef>,
|
||||
cls: Option<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
let (zelf, obj) = match Self::_check(zelf, obj, vm) {
|
||||
Ok(obj) => obj,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use super::objtype::PyClassRef;
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{
|
||||
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
@@ -47,10 +46,10 @@ impl PyValue for PyClassMethod {
|
||||
|
||||
impl SlotDescriptor for PyClassMethod {
|
||||
fn descr_get(
|
||||
vm: &VirtualMachine,
|
||||
zelf: PyObjectRef,
|
||||
obj: Option<PyObjectRef>,
|
||||
cls: OptionalArg<PyObjectRef>,
|
||||
cls: Option<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
|
||||
let cls = cls.unwrap_or_else(|| obj.class().into_object());
|
||||
|
||||
@@ -8,7 +8,7 @@ use super::objtuple::PyTupleRef;
|
||||
use super::objtype::PyClassRef;
|
||||
use crate::bytecode;
|
||||
use crate::frame::Frame;
|
||||
use crate::function::{OptionalArg, PyFuncArgs};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::obj::objasyncgenerator::PyAsyncGen;
|
||||
use crate::obj::objcoroutine::PyCoroutine;
|
||||
use crate::obj::objgenerator::PyGenerator;
|
||||
@@ -306,10 +306,10 @@ impl PyFunction {
|
||||
|
||||
impl SlotDescriptor for PyFunction {
|
||||
fn descr_get(
|
||||
vm: &VirtualMachine,
|
||||
zelf: PyObjectRef,
|
||||
obj: Option<PyObjectRef>,
|
||||
cls: OptionalArg<PyObjectRef>,
|
||||
cls: Option<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
|
||||
if vm.is_none(&obj) && !Self::_cls_is(&cls, &obj.class()) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
*/
|
||||
use super::objtype::PyClassRef;
|
||||
use crate::function::{OptionalArg, OwnedParam, RefParam};
|
||||
use crate::function::{OwnedParam, RefParam};
|
||||
use crate::pyobject::{
|
||||
IntoPyResult, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
TypeProtocol,
|
||||
@@ -182,10 +182,10 @@ pub type PyGetSetRef = PyRef<PyGetSet>;
|
||||
|
||||
impl SlotDescriptor for PyGetSet {
|
||||
fn descr_get(
|
||||
vm: &VirtualMachine,
|
||||
zelf: PyObjectRef,
|
||||
obj: Option<PyObjectRef>,
|
||||
_cls: OptionalArg<PyObjectRef>,
|
||||
_cls: Option<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
let (zelf, obj) = match Self::_check(zelf, obj, vm) {
|
||||
Ok(obj) => obj,
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
use crate::common::cell::PyRwLock;
|
||||
|
||||
use super::objtype::PyClassRef;
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{
|
||||
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
@@ -74,10 +73,10 @@ struct PropertyArgs {
|
||||
|
||||
impl SlotDescriptor for PyProperty {
|
||||
fn descr_get(
|
||||
vm: &VirtualMachine,
|
||||
zelf: PyObjectRef,
|
||||
obj: Option<PyObjectRef>,
|
||||
_cls: OptionalArg<PyObjectRef>,
|
||||
_cls: Option<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
|
||||
if vm.is_none(&obj) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use super::objtype::PyClassRef;
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue};
|
||||
use crate::slots::SlotDescriptor;
|
||||
use crate::vm::VirtualMachine;
|
||||
@@ -19,10 +18,10 @@ impl PyValue for PyStaticMethod {
|
||||
|
||||
impl SlotDescriptor for PyStaticMethod {
|
||||
fn descr_get(
|
||||
vm: &VirtualMachine,
|
||||
zelf: PyObjectRef,
|
||||
_obj: Option<PyObjectRef>,
|
||||
_cls: OptionalArg<PyObjectRef>,
|
||||
_cls: Option<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
let zelf = Self::_zelf(zelf, vm)?;
|
||||
Ok(zelf.callable.clone())
|
||||
|
||||
@@ -132,10 +132,10 @@ impl PySuper {
|
||||
|
||||
impl SlotDescriptor for PySuper {
|
||||
fn descr_get(
|
||||
vm: &VirtualMachine,
|
||||
zelf: PyObjectRef,
|
||||
obj: Option<PyObjectRef>,
|
||||
_cls: OptionalArg<PyObjectRef>,
|
||||
_cls: Option<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
|
||||
if vm.is_none(&obj) || zelf.obj.is_some() {
|
||||
|
||||
@@ -11,7 +11,7 @@ use super::objstaticmethod::PyStaticMethod;
|
||||
use super::objstr::PyStringRef;
|
||||
use super::objtuple::PyTuple;
|
||||
use super::objweakref::PyWeak;
|
||||
use crate::function::{KwArgs, OptionalArg, PyFuncArgs};
|
||||
use crate::function::{KwArgs, PyFuncArgs};
|
||||
use crate::pyobject::{
|
||||
BorrowValue, IdProtocol, PyAttributes, PyClassImpl, PyContext, PyIterable, PyLease,
|
||||
PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
|
||||
@@ -214,12 +214,7 @@ impl PyClass {
|
||||
PyLease::into_pyref(attr_class).first_in_mro(|cls| cls.slots.descr_get.load())
|
||||
{
|
||||
let mcl = PyLease::into_pyref(mcl).into_object();
|
||||
return descr_get(
|
||||
vm,
|
||||
attr,
|
||||
Some(zelf.into_object()),
|
||||
OptionalArg::Present(mcl),
|
||||
);
|
||||
return descr_get(attr, Some(zelf.into_object()), Some(mcl), vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,7 +223,7 @@ impl PyClass {
|
||||
let attr_class = attr.class();
|
||||
if let Some(ref descr_get) = attr_class.first_in_mro(|cls| cls.slots.descr_get.load()) {
|
||||
drop(mcl);
|
||||
return descr_get(vm, attr, None, OptionalArg::Present(zelf.into_object()));
|
||||
return descr_get(attr, None, Some(zelf.into_object()), vm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+31
-55
@@ -2,7 +2,7 @@ use std::cmp::Ordering;
|
||||
|
||||
use crate::common::cell::PyRwLock;
|
||||
use crate::common::hash::PyHash;
|
||||
use crate::function::{IntoPyNativeFunc, OptionalArg, PyFuncArgs, PyNativeFunc};
|
||||
use crate::function::{OptionalArg, PyFuncArgs, PyNativeFunc};
|
||||
use crate::pyobject::{
|
||||
IdProtocol, PyComparisonValue, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
TypeProtocol,
|
||||
@@ -41,9 +41,9 @@ impl Default for PyTpFlags {
|
||||
}
|
||||
}
|
||||
|
||||
type GenericFunc = fn(&VirtualMachine, PyFuncArgs) -> PyResult;
|
||||
type GenericMethod = fn(PyObjectRef, PyFuncArgs, &VirtualMachine) -> PyResult;
|
||||
type DescrGetFunc =
|
||||
fn(&VirtualMachine, PyObjectRef, Option<PyObjectRef>, OptionalArg<PyObjectRef>) -> PyResult;
|
||||
fn(PyObjectRef, Option<PyObjectRef>, Option<PyObjectRef>, &VirtualMachine) -> PyResult;
|
||||
type HashFunc = Box<py_dyn_fn!(dyn Fn(PyObjectRef, &VirtualMachine) -> PyResult<PyHash>)>;
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -51,7 +51,7 @@ pub struct PyClassSlots {
|
||||
pub flags: PyTpFlags,
|
||||
pub name: PyRwLock<Option<String>>, // tp_name, not class name
|
||||
pub new: Option<PyNativeFunc>,
|
||||
pub call: AtomicCell<Option<GenericFunc>>,
|
||||
pub call: AtomicCell<Option<GenericMethod>>,
|
||||
pub descr_get: AtomicCell<Option<DescrGetFunc>>,
|
||||
pub hash: Option<HashFunc>,
|
||||
pub cmp: Option<CmpFunc>,
|
||||
@@ -80,13 +80,21 @@ impl PyClassSlots {
|
||||
pub(crate) fn update_slot_func(&self, name: &str) {
|
||||
match name {
|
||||
"__call__" => {
|
||||
let func: GenericFunc =
|
||||
|vm, args| { IntoPyNativeFunc::call(&call_magic_call, vm, args) } as _;
|
||||
let func: GenericMethod = |zelf, args, vm| {
|
||||
let magic = get_class_magic(&zelf, "__call__");
|
||||
let magic = vm.call_if_get_descriptor(magic, zelf.clone())?;
|
||||
vm.invoke(&magic, args)
|
||||
} as _;
|
||||
self.call.store(Some(func))
|
||||
}
|
||||
"__get__" => {
|
||||
let func: DescrGetFunc =
|
||||
|vm, zelf, obj, cls| { call_magic_descr_get(vm, zelf, obj, cls) } as _;
|
||||
let func: DescrGetFunc = |zelf, obj, cls, vm| {
|
||||
let magic = get_class_magic(&zelf, "__get__");
|
||||
vm.invoke(
|
||||
&magic,
|
||||
vec![zelf, vm.unwrap_or_none(obj), vm.unwrap_or_none(cls)],
|
||||
)
|
||||
} as _;
|
||||
self.descr_get.store(Some(func))
|
||||
}
|
||||
_ => (),
|
||||
@@ -94,6 +102,16 @@ impl PyClassSlots {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_class_magic(zelf: &PyObjectRef, name: &str) -> PyObjectRef {
|
||||
zelf.get_class_attr(name).unwrap()
|
||||
|
||||
// TODO: we already looked up the matching class but lost the information here
|
||||
// let cls = zelf.lease_class();
|
||||
// let attrs = cls.attributes.read();
|
||||
// attrs.get(name).unwrap().clone()
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PyClassSlots {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str("PyClassSlots")
|
||||
@@ -107,53 +125,14 @@ pub trait SlotCall: PyValue {
|
||||
fn call(zelf: PyRef<Self>, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_class_magic(zelf: &PyObjectRef, name: &str) -> PyObjectRef {
|
||||
zelf.get_class_attr(name).unwrap()
|
||||
// let cls = zelf.lease_class();
|
||||
// let attrs = cls.attributes.read();
|
||||
// let attr = attrs.get(name);
|
||||
// attr.unwrap().clone()
|
||||
}
|
||||
|
||||
fn call_magic_call(zelf: PyObjectRef, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
let magic = get_class_magic(&zelf, "__call__");
|
||||
let magic = vm.call_if_get_descriptor(magic, zelf.clone())?;
|
||||
args.insert(zelf);
|
||||
vm.invoke(&magic, args)
|
||||
}
|
||||
|
||||
fn call_magic_descr_get(
|
||||
vm: &VirtualMachine,
|
||||
zelf: PyObjectRef,
|
||||
obj: Option<PyObjectRef>,
|
||||
cls: OptionalArg<PyObjectRef>,
|
||||
) -> PyResult {
|
||||
let magic = get_class_magic(&zelf, "__get__");
|
||||
vm.invoke(
|
||||
&magic,
|
||||
vec![
|
||||
zelf,
|
||||
vm.unwrap_or_none(obj),
|
||||
vm.unwrap_or_none(cls.into_option()),
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
pub type PyDescrGetFunc = Box<
|
||||
dyn Fn(&VirtualMachine, PyObjectRef, Option<PyObjectRef>, OptionalArg<PyObjectRef>) -> PyResult
|
||||
+ Send
|
||||
+ Sync,
|
||||
>;
|
||||
|
||||
#[pyimpl]
|
||||
pub trait SlotDescriptor: PyValue {
|
||||
#[pyslot]
|
||||
fn descr_get(
|
||||
vm: &VirtualMachine,
|
||||
zelf: PyObjectRef,
|
||||
obj: Option<PyObjectRef>,
|
||||
cls: OptionalArg<PyObjectRef>,
|
||||
cls: Option<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult;
|
||||
|
||||
#[pymethod(magic)]
|
||||
@@ -163,7 +142,7 @@ pub trait SlotDescriptor: PyValue {
|
||||
cls: OptionalArg<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult {
|
||||
Self::descr_get(vm, zelf, Some(obj), cls)
|
||||
Self::descr_get(zelf, Some(obj), cls.into_option(), vm)
|
||||
}
|
||||
|
||||
fn _zelf(zelf: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
|
||||
@@ -204,14 +183,11 @@ pub trait SlotDescriptor: PyValue {
|
||||
}
|
||||
}
|
||||
|
||||
fn _cls_is<T>(cls: &OptionalArg<PyObjectRef>, other: &T) -> bool
|
||||
fn _cls_is<T>(cls: &Option<PyObjectRef>, other: &T) -> bool
|
||||
where
|
||||
T: IdProtocol,
|
||||
{
|
||||
match cls {
|
||||
OptionalArg::Present(cls) => cls.is(other),
|
||||
OptionalArg::Missing => false,
|
||||
}
|
||||
cls.as_ref().map_or(false, |cls| cls.is(other))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-12
@@ -23,7 +23,7 @@ use crate::common::{cell::PyMutex, hash::HashSecret, rc::PyRc};
|
||||
use crate::exceptions::{self, PyBaseException, PyBaseExceptionRef};
|
||||
use crate::frame::{ExecutionResult, Frame, FrameRef};
|
||||
use crate::frozen;
|
||||
use crate::function::{OptionalArg, PyFuncArgs};
|
||||
use crate::function::PyFuncArgs;
|
||||
use crate::import;
|
||||
use crate::obj::objbool;
|
||||
use crate::obj::objcode::{PyCode, PyCodeRef};
|
||||
@@ -844,7 +844,7 @@ impl VirtualMachine {
|
||||
descr
|
||||
.class()
|
||||
.first_in_mro(|cls| cls.slots.descr_get.load())
|
||||
.map(|descr_get| descr_get(self, descr, obj, OptionalArg::from_option(cls)))
|
||||
.map(|descr_get| descr_get(descr, obj, cls, self))
|
||||
}
|
||||
|
||||
pub fn call_get_descriptor(&self, descr: PyObjectRef, obj: PyObjectRef) -> Option<PyResult> {
|
||||
@@ -882,21 +882,19 @@ impl VirtualMachine {
|
||||
|
||||
fn _invoke(&self, callable: &PyObjectRef, args: PyFuncArgs) -> PyResult {
|
||||
vm_trace!("Invoke: {:?} {:?}", callable, args);
|
||||
let invoked = callable.class().first_in_mro(|cls| {
|
||||
cls.slots.call.load().map(|slot_call| {
|
||||
let slot_call = callable.class().first_in_mro(|cls| cls.slots.call.load());
|
||||
match slot_call {
|
||||
Some(slot_call) => {
|
||||
self.trace_event(TraceEvent::Call)?;
|
||||
let args = args.insert(callable.clone());
|
||||
let result = slot_call(self, args);
|
||||
let result = slot_call(callable.clone(), args, self);
|
||||
self.trace_event(TraceEvent::Return)?;
|
||||
result
|
||||
})
|
||||
});
|
||||
invoked.unwrap_or_else(|| {
|
||||
Err(self.new_type_error(format!(
|
||||
}
|
||||
None => Err(self.new_type_error(format!(
|
||||
"'{}' object is not callable",
|
||||
callable.lease_class().name
|
||||
)))
|
||||
})
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
Reference in new issue
Block a user