diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index 44a3c5543..2754a3c04 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -667,7 +667,7 @@ impl ToTokens for GetSetNursery { #( #cfgs )* class.set_str_attr( #name, - ::rustpython_vm::PyObject::new( + ::rustpython_vm::PyGenericObject::new( ::rustpython_vm::builtins::PyGetSet::new(#name.into(), class.clone()) .with_get(&Self::#getter) #setter #deleter, diff --git a/vm/src/builtins/object.rs b/vm/src/builtins/object.rs index dc5af30ba..9337308b9 100644 --- a/vm/src/builtins/object.rs +++ b/vm/src/builtins/object.rs @@ -2,8 +2,8 @@ use super::{PyDict, PyDictRef, PyList, PyStr, PyStrRef, PyType, PyTypeRef}; use crate::common::hash::PyHash; use crate::{ function::FuncArgs, types::PyComparisonOp, utils::Either, IdProtocol, ItemProtocol, - PyArithmeticValue, PyAttributes, PyClassImpl, PyComparisonValue, PyContext, PyObj, PyObject, - PyObjectRef, PyResult, PyValue, TypeProtocol, VirtualMachine, + PyArithmeticValue, PyAttributes, PyClassImpl, PyComparisonValue, PyContext, PyGenericObject, + PyObj, PyObjectRef, PyResult, PyValue, TypeProtocol, VirtualMachine, }; /// object() @@ -34,7 +34,7 @@ impl PyBaseObject { } else { Some(vm.ctx.new_dict()) }; - Ok(PyObject::new(PyBaseObject, cls, dict)) + Ok(PyGenericObject::new(PyBaseObject, cls, dict)) } #[pyslot] diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index f93f17095..bbfa64a55 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -4,7 +4,7 @@ use crate::common::{ static_cell, }; pub use crate::pyobjectrc::{ - Py, PyObj, PyObject, PyObjectRef, PyObjectWeak, PyObjectWrap, PyRef, PyWeakRef, + Py, PyGenericObject, PyObj, PyObjectRef, PyObjectWeak, PyObjectWrap, PyRef, PyWeakRef, }; use crate::{ builtins::{ @@ -298,7 +298,7 @@ impl PyContext { class.slots.flags.contains(PyTypeFlags::HAS_DICT), dict.is_some() ); - PyObject::new(object::PyBaseObject, class, dict) + PyGenericObject::new(object::PyBaseObject, class, dict) } } diff --git a/vm/src/pyobjectrc.rs b/vm/src/pyobjectrc.rs index 24463844d..8566ba668 100644 --- a/vm/src/pyobjectrc.rs +++ b/vm/src/pyobjectrc.rs @@ -12,7 +12,7 @@ use std::fmt; use std::mem::ManuallyDrop; use std::ops::Deref; -// so, PyObjectRef is basically equivalent to `PyRc>`, except it's +// so, PyObjectRef is basically equivalent to `PyRc>`, except it's // only one pointer in width rather than 2. We do that by manually creating a vtable, and putting // a &'static reference to it inside the `PyRc` rather than adjacent to it, like trait objects do. // This can lead to faster code since there's just less data to pass around, as well as because of @@ -29,18 +29,18 @@ use std::ops::Deref; // There has to be padding in the space between the 2 fields. But, if that field is a trait object // (like `dyn PyObjectPayload`) we don't *know* how much padding there is between the `payload` // field and the previous field. So, Rust has to consult the vtable to know the exact offset of -// `payload` in `PyObject`, which has a huge performance impact when *every +// `payload` in `PyGenericObject`, which has a huge performance impact when *every // single payload access* requires a vtable lookup. Thankfully, we're able to avoid that because of // the way we use PyObjectRef, in that whenever we want to access the payload we (almost) always // access it from a generic function. So, rather than doing // // - check vtable for payload offset -// - get offset in PyObject struct +// - get offset in PyGenericObject struct // - call as_any() method of PyObjectPayload // - call downcast_ref() method of Any // we can just do // - check vtable that typeid matches -// - pointer cast directly to *const PyObject +// - pointer cast directly to *const PyGenericObject // // and at that point the compiler can know the offset of `payload` for us because **we've given it a // concrete type to work with before we ever access the `payload` field** @@ -93,11 +93,11 @@ impl fmt::Debug for PyInner { /// python class, and carries some rust payload optionally. This rust /// payload can be a rust float or rust int in case of float and int objects. #[repr(transparent)] -pub struct PyObject { +pub struct PyGenericObject { inner: ManuallyDrop>, } -impl PyObject { +impl PyGenericObject { #[allow(clippy::new_ret_no_self)] pub fn new(payload: T, typ: PyTypeRef, dict: Option) -> PyObjectRef { let inner = PyInner { @@ -107,13 +107,13 @@ impl PyObject { dict: dict.map(PyRwLock::new), payload, }; - PyObjectRef::new(PyObject { + PyObjectRef::new(PyGenericObject { inner: ManuallyDrop::new(inner), }) } } -impl Drop for PyObject { +impl Drop for PyGenericObject { fn drop(&mut self) { let erased = &mut *self.inner as *mut _ as *mut PyInner; // SAFETY: the vtable contains functions that accept payload types that always match up @@ -140,7 +140,7 @@ pub struct PyObjectWeak { } #[repr(transparent)] -pub struct PyObj(PyObject); +pub struct PyObj(PyGenericObject); impl Deref for PyObjectRef { type Target = PyObj; @@ -188,8 +188,8 @@ impl PyObjectRef { } } - fn new(value: PyObject) -> Self { - let inner: *const PyObject = PyRc::into_raw(PyRc::new(value)); + fn new(value: PyGenericObject) -> Self { + let inner: *const PyGenericObject = PyRc::into_raw(PyRc::new(value)); let rc = unsafe { PyRc::from_raw(inner as *const PyObj) }; Self { rc } } @@ -574,7 +574,7 @@ impl PyRef { typ: crate::builtins::PyTypeRef, dict: Option, ) -> Self { - let obj = PyObject::new(payload, typ, dict); + let obj = PyGenericObject::new(payload, typ, dict); // SAFETY: we just created the object from a payload of type T unsafe { Self::from_obj_unchecked(obj) } } diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 510854d40..bbe98ed5f 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -27,8 +27,9 @@ use crate::{ signal::NSIG, stdlib, types::PyComparisonOp, - IdProtocol, ItemProtocol, PyArithmeticValue, PyContext, PyLease, PyMethod, PyObj, PyObject, - PyObjectRef, PyObjectWrap, PyRef, PyRefExact, PyResult, PyValue, TryFromObject, TypeProtocol, + IdProtocol, ItemProtocol, PyArithmeticValue, PyContext, PyGenericObject, PyLease, PyMethod, + PyObj, PyObjectRef, PyObjectWrap, PyRef, PyRefExact, PyResult, PyValue, TryFromObject, + TypeProtocol, }; use crossbeam_utils::atomic::AtomicCell; use num_traits::{Signed, ToPrimitive}; @@ -248,7 +249,7 @@ impl VirtualMachine { // make a new module without access to the vm; doesn't // set __spec__, __loader__, etc. attributes let new_module = - |dict| PyObject::new(PyModule {}, ctx.types.module_type.clone(), Some(dict)); + |dict| PyGenericObject::new(PyModule {}, ctx.types.module_type.clone(), Some(dict)); // Hard-core modules: let builtins_dict = ctx.new_dict(); @@ -611,7 +612,7 @@ impl VirtualMachine { doc.map(|doc| self.new_pyobj(doc.to_owned())) .unwrap_or_else(|| self.ctx.none()), ); - PyObject::new(PyModule {}, self.ctx.types.module_type.clone(), Some(dict)) + PyGenericObject::new(PyModule {}, self.ctx.types.module_type.clone(), Some(dict)) } /// Instantiate an exception with arguments. @@ -2059,7 +2060,7 @@ impl<'vm> ReprGuard<'vm> { let mut guards = vm.repr_guards.borrow_mut(); // Should this be a flag on the obj itself? putting it in a global variable for now until it - // decided the form of the PyObject. https://github.com/RustPython/RustPython/issues/371 + // decided the form of the PyGenericObject. https://github.com/RustPython/RustPython/issues/371 let id = obj.get_id(); if guards.contains(&id) { return None; diff --git a/wasm/lib/src/browser_module.rs b/wasm/lib/src/browser_module.rs index 9f6b651aa..83582bf21 100644 --- a/wasm/lib/src/browser_module.rs +++ b/wasm/lib/src/browser_module.rs @@ -4,7 +4,7 @@ use rustpython_vm::{ builtins::{PyDictRef, PyStrRef}, function::{ArgCallable, IntoPyObject, OptionalArg}, import::import_file, - PyClassImpl, PyObject, PyObjectRef, PyResult, PyValue, VirtualMachine, + PyClassImpl, PyGenericObject, PyObjectRef, PyResult, PyValue, VirtualMachine, }; use wasm_bindgen::{prelude::*, JsCast}; use wasm_bindgen_futures::JsFuture; @@ -236,7 +236,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { let document_class = Document::make_class(ctx); - let document = PyObject::new( + let document = PyGenericObject::new( Document { doc: window().document().expect("Document missing from window"), },