mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-09 22:49:57 +09:00
PyObject -> PyGenericObject
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ use std::fmt;
|
||||
use std::mem::ManuallyDrop;
|
||||
use std::ops::Deref;
|
||||
|
||||
// so, PyObjectRef is basically equivalent to `PyRc<PyObject<dyn PyObjectPayload>>`, except it's
|
||||
// so, PyObjectRef is basically equivalent to `PyRc<PyGenericObject<dyn PyObjectPayload>>`, 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<dyn PyObjectPayload>`, which has a huge performance impact when *every
|
||||
// `payload` in `PyGenericObject<dyn PyObjectPayload>`, 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<T>
|
||||
// - pointer cast directly to *const PyGenericObject<T>
|
||||
//
|
||||
// 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<T: fmt::Debug> fmt::Debug for PyInner<T> {
|
||||
/// 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<T> {
|
||||
pub struct PyGenericObject<T> {
|
||||
inner: ManuallyDrop<PyInner<T>>,
|
||||
}
|
||||
|
||||
impl<T: PyObjectPayload> PyObject<T> {
|
||||
impl<T: PyObjectPayload> PyGenericObject<T> {
|
||||
#[allow(clippy::new_ret_no_self)]
|
||||
pub fn new(payload: T, typ: PyTypeRef, dict: Option<PyDictRef>) -> PyObjectRef {
|
||||
let inner = PyInner {
|
||||
@@ -107,13 +107,13 @@ impl<T: PyObjectPayload> PyObject<T> {
|
||||
dict: dict.map(PyRwLock::new),
|
||||
payload,
|
||||
};
|
||||
PyObjectRef::new(PyObject {
|
||||
PyObjectRef::new(PyGenericObject {
|
||||
inner: ManuallyDrop::new(inner),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for PyObject<T> {
|
||||
impl<T> Drop for PyGenericObject<T> {
|
||||
fn drop(&mut self) {
|
||||
let erased = &mut *self.inner as *mut _ as *mut PyInner<Erased>;
|
||||
// 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<Erased>);
|
||||
pub struct PyObj(PyGenericObject<Erased>);
|
||||
|
||||
impl Deref for PyObjectRef {
|
||||
type Target = PyObj;
|
||||
@@ -188,8 +188,8 @@ impl PyObjectRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn new<T: PyObjectPayload>(value: PyObject<T>) -> Self {
|
||||
let inner: *const PyObject<T> = PyRc::into_raw(PyRc::new(value));
|
||||
fn new<T: PyObjectPayload>(value: PyGenericObject<T>) -> Self {
|
||||
let inner: *const PyGenericObject<T> = PyRc::into_raw(PyRc::new(value));
|
||||
let rc = unsafe { PyRc::from_raw(inner as *const PyObj) };
|
||||
Self { rc }
|
||||
}
|
||||
@@ -574,7 +574,7 @@ impl<T: PyObjectPayload> PyRef<T> {
|
||||
typ: crate::builtins::PyTypeRef,
|
||||
dict: Option<crate::builtins::PyDictRef>,
|
||||
) -> 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) }
|
||||
}
|
||||
|
||||
11
vm/src/vm.rs
11
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;
|
||||
|
||||
@@ -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"),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user