This commit is contained in:
Jeong YunWon committed 2020-09-24 07:50:11 +09:00
1 parent 9e71cb3bcc
commit d9b1ae296b
5 files changed
+43 -6

No files matched your search

+5 -2
View File
@@ -47,11 +47,14 @@ macro_rules! py_class {
py_class
}
};
(@extract_slots($ctx:expr, $slots:expr, (slot $slot_name:ident), $value:expr)) => {
$slots.$slot_name = Some(
(@extract_slots($ctx:expr, $slots:expr, (slot new), $value:expr)) => {
$slots.new = Some(
$crate::function::IntoPyNativeFunc::into_func($value)
);
};
(@extract_slots($ctx:expr, $slots:expr, (slot $slot_name:ident), $value:expr)) => {
$slots.$slot_name.store(Some($value));
};
(@extract_slots($ctx:expr, $class:expr, $name:expr, $value:expr)) => {};
(@extract_attrs($ctx:expr, $slots:expr, (slot $slot_name:ident), $value:expr)) => {};
(@extract_attrs($ctx:expr, $class:expr, $name:expr, $value:expr)) => {
+7
View File
@@ -150,6 +150,13 @@ impl PyClassRef {
} as _;
self.slots.hash.store(Some(func));
}
"__del__" => {
let func: slots::DelFunc = |zelf, vm| {
let magic = get_class_magic(&zelf, "__del__");
vm.invoke(&magic, vec![zelf.clone()]).map(|_| ())
} as _;
self.slots.del.store(Some(func));
}
_ => (),
}
}
+3 -2
View File
@@ -146,11 +146,12 @@ where
// CPython-compatible drop implementation
let zelf = Self::into_ref(self.clone());
if let Some(del_method) = zelf.inner.get_class_attr("__del__") {
if let Some(del_slot) = zelf.class().first_in_mro(|cls| cls.slots.del.load()) {
crate::vm::thread::with_vm(&zelf, |vm| {
if let Err(e) = vm.invoke(&del_method, vec![zelf.clone()]) {
if let Err(e) = del_slot(&zelf, vm) {
// exception in del will be ignored but printed
print!("Exception ignored in: ",);
let del_method = zelf.get_class_attr("__del__").unwrap();
let repr = vm.to_repr(&del_method);
match repr {
Ok(v) => println!("{}", v.to_string()),
+21
View File
@@ -41,6 +41,7 @@ impl Default for PyTpFlags {
}
pub(crate) type GenericMethod = fn(PyObjectRef, PyFuncArgs, &VirtualMachine) -> PyResult;
pub(crate) type DelFunc = fn(&PyObjectRef, &VirtualMachine) -> PyResult<()>;
pub(crate) type DescrGetFunc =
fn(PyObjectRef, Option<PyObjectRef>, Option<PyObjectRef>, &VirtualMachine) -> PyResult;
pub(crate) type HashFunc = fn(&PyObjectRef, &VirtualMachine) -> PyResult<PyHash>;
@@ -50,6 +51,7 @@ pub struct PyClassSlots {
pub flags: PyTpFlags,
pub name: PyRwLock<Option<String>>, // tp_name, not class name
pub new: Option<PyNativeFunc>,
pub del: AtomicCell<Option<DelFunc>>,
pub call: AtomicCell<Option<GenericMethod>>,
pub descr_get: AtomicCell<Option<DescrGetFunc>>,
pub hash: AtomicCell<Option<HashFunc>>,
@@ -82,6 +84,25 @@ impl std::fmt::Debug for PyClassSlots {
}
}
#[pyimpl]
pub trait SlotDesctuctor: PyValue {
#[pyslot]
fn tp_del(zelf: &PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
if let Some(zelf) = zelf.downcast_ref() {
Self::del(zelf, vm)
} else {
Err(vm.new_type_error("unexpected payload for __del__".to_owned()))
}
}
#[pymethod(magic)]
fn __del__(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<()> {
Self::del(&zelf, vm)
}
fn del(zelf: &PyRef<Self>, vm: &VirtualMachine) -> PyResult<()>;
}
#[pyimpl]
pub trait SlotCall: PyValue {
#[pymethod(magic)]
+7 -2
View File
@@ -416,11 +416,15 @@ fn io_base_cm_enter(instance: PyObjectRef) -> PyObjectRef {
instance
}
fn io_base_cm_del(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
vm.call_method(&instance, "close", vec![])?;
fn io_base_cm_del_slot(instance: &PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
vm.call_method(instance, "close", vec![])?;
Ok(())
}
fn io_base_cm_del(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
io_base_cm_del_slot(&instance, vm)
}
fn io_base_cm_exit(instance: PyObjectRef, _args: PyFuncArgs, vm: &VirtualMachine) -> PyResult<()> {
vm.call_method(&instance, "close", vec![])?;
Ok(())
@@ -1271,6 +1275,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
let io_base = py_class!(ctx, "_IOBase", &ctx.types.object_type, {
"__enter__" => ctx.new_method(io_base_cm_enter),
"__del__" => ctx.new_method(io_base_cm_del),
(slot del) => io_base_cm_del_slot,
"__exit__" => ctx.new_method(io_base_cm_exit),
"seekable" => ctx.new_method(io_base_seekable),
"readable" => ctx.new_method(io_base_readable),