mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-17 01:51:39 +09:00
Remove Box from PyObject
This commit is contained in:
@@ -35,12 +35,6 @@ impl PyValue for PyClass {
|
||||
}
|
||||
}
|
||||
|
||||
impl IdProtocol for PyClassRef {
|
||||
fn get_id(&self) -> usize {
|
||||
self.as_object().get_id()
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeProtocol for PyClassRef {
|
||||
fn type_ref(&self) -> &PyObjectRef {
|
||||
&self.as_object().type_ref()
|
||||
@@ -300,10 +294,7 @@ fn take_next_base(mut bases: Vec<Vec<PyClassRef>>) -> Option<(PyClassRef, Vec<Ve
|
||||
|
||||
for base in &bases {
|
||||
let head = base[0].clone();
|
||||
if !(&bases)
|
||||
.iter()
|
||||
.any(|x| x[1..].iter().any(|x| x.get_id() == head.get_id()))
|
||||
{
|
||||
if !(&bases).iter().any(|x| x[1..].iter().any(|x| x.is(&head))) {
|
||||
next = Some(head);
|
||||
break;
|
||||
}
|
||||
@@ -311,7 +302,7 @@ fn take_next_base(mut bases: Vec<Vec<PyClassRef>>) -> Option<(PyClassRef, Vec<Ve
|
||||
|
||||
if let Some(head) = next {
|
||||
for item in &mut bases {
|
||||
if item[0].get_id() == head.get_id() {
|
||||
if item[0].is(&head) {
|
||||
item.remove(0);
|
||||
}
|
||||
}
|
||||
@@ -347,10 +338,10 @@ pub fn new(
|
||||
let mros = bases.into_iter().map(|x| _mro(&x)).collect();
|
||||
let mro = linearise_mro(mros).unwrap();
|
||||
Ok(PyObject {
|
||||
payload: Box::new(PyClass {
|
||||
payload: PyClass {
|
||||
name: String::from(name),
|
||||
mro,
|
||||
}),
|
||||
},
|
||||
dict: Some(RefCell::new(dict)),
|
||||
typ,
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::PyValue;
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyRef, PyResult};
|
||||
use crate::pyobject::{PyContext, PyObject, PyObjectPayload, PyObjectRef, PyRef, PyResult};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use std::rc::{Rc, Weak};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyWeak {
|
||||
referent: Weak<PyObject>,
|
||||
referent: Weak<PyObject<dyn PyObjectPayload>>,
|
||||
}
|
||||
|
||||
impl PyWeak {
|
||||
|
||||
@@ -72,7 +72,7 @@ Basically reference counting, but then done by rust.
|
||||
/// this reference counting is accounted for by this type. Use the `.clone()`
|
||||
/// method to create a new reference and increment the amount of references
|
||||
/// to the python object by 1.
|
||||
pub type PyObjectRef = Rc<PyObject>;
|
||||
pub type PyObjectRef = Rc<PyObject<dyn PyObjectPayload>>;
|
||||
|
||||
/// Use this type for function which return a python object or and exception.
|
||||
/// Both the python object and the python exception are `PyObjectRef` types
|
||||
@@ -83,7 +83,7 @@ pub type PyResult<T = PyObjectRef> = Result<T, PyObjectRef>; // A valid value, o
|
||||
/// faster, unordered, and only supports strings as keys.
|
||||
pub type PyAttributes = HashMap<String, PyObjectRef>;
|
||||
|
||||
impl fmt::Display for PyObject {
|
||||
impl fmt::Display for PyObject<dyn PyObjectPayload> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use self::TypeProtocol;
|
||||
if let Some(PyClass { ref name, .. }) = self.payload::<PyClass>() {
|
||||
@@ -188,25 +188,25 @@ fn init_type_hierarchy() -> (PyObjectRef, PyObjectRef) {
|
||||
let object_type = PyObject {
|
||||
typ: mem::uninitialized(), // !
|
||||
dict: Some(RefCell::new(PyAttributes::new())),
|
||||
payload: Box::new(PyClass {
|
||||
payload: PyClass {
|
||||
name: String::from("object"),
|
||||
mro: vec![],
|
||||
}),
|
||||
},
|
||||
}
|
||||
.into_ref();
|
||||
|
||||
let type_type = PyObject {
|
||||
typ: mem::uninitialized(), // !
|
||||
dict: Some(RefCell::new(PyAttributes::new())),
|
||||
payload: Box::new(PyClass {
|
||||
payload: PyClass {
|
||||
name: String::from("type"),
|
||||
mro: vec![FromPyObjectRef::from_pyobj(&object_type)],
|
||||
}),
|
||||
},
|
||||
}
|
||||
.into_ref();
|
||||
|
||||
let object_type_ptr = PyObjectRef::into_raw(object_type.clone()) as *mut PyObject;
|
||||
let type_type_ptr = PyObjectRef::into_raw(type_type.clone()) as *mut PyObject;
|
||||
let object_type_ptr = PyObjectRef::into_raw(object_type.clone()) as *mut PyObject<PyClass>;
|
||||
let type_type_ptr = PyObjectRef::into_raw(type_type.clone()) as *mut PyObject<PyClass>;
|
||||
ptr::write(&mut (*object_type_ptr).typ, type_type.clone());
|
||||
ptr::write(&mut (*type_type_ptr).typ, type_type.clone());
|
||||
|
||||
@@ -628,7 +628,7 @@ impl PyContext {
|
||||
PyObject {
|
||||
typ: class,
|
||||
dict: Some(RefCell::new(dict)),
|
||||
payload: Box::new(objobject::PyInstance),
|
||||
payload: objobject::PyInstance,
|
||||
}
|
||||
.into_ref()
|
||||
}
|
||||
@@ -691,10 +691,13 @@ impl Default for PyContext {
|
||||
/// This is an actual python object. It consists of a `typ` which is the
|
||||
/// 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.
|
||||
pub struct PyObject {
|
||||
pub struct PyObject<T>
|
||||
where
|
||||
T: ?Sized + PyObjectPayload,
|
||||
{
|
||||
pub typ: PyObjectRef,
|
||||
pub dict: Option<RefCell<PyAttributes>>, // __dict__ member
|
||||
pub payload: Box<dyn PyObjectPayload>,
|
||||
pub payload: T,
|
||||
}
|
||||
|
||||
/// A reference to a Python object.
|
||||
@@ -788,9 +791,30 @@ pub trait IdProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
impl IdProtocol for PyObjectRef {
|
||||
#[derive(Debug)]
|
||||
enum Never {}
|
||||
|
||||
impl PyValue for Never {
|
||||
fn class(_vm: &mut VirtualMachine) -> PyObjectRef {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + PyObjectPayload> IdProtocol for PyObject<T> {
|
||||
fn get_id(&self) -> usize {
|
||||
&*self as &PyObject as *const PyObject as usize
|
||||
self as *const _ as *const PyObject<Never> as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized + IdProtocol> IdProtocol for Rc<T> {
|
||||
fn get_id(&self) -> usize {
|
||||
(**self).get_id()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: PyObjectPayload> IdProtocol for PyRef<T> {
|
||||
fn get_id(&self) -> usize {
|
||||
self.obj.get_id()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -814,7 +838,10 @@ impl TypeProtocol for PyObjectRef {
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeProtocol for PyObject {
|
||||
impl<T> TypeProtocol for PyObject<T>
|
||||
where
|
||||
T: ?Sized + PyObjectPayload,
|
||||
{
|
||||
fn type_ref(&self) -> &PyObjectRef {
|
||||
&self.typ
|
||||
}
|
||||
@@ -953,9 +980,9 @@ impl BufferProtocol for PyObjectRef {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for PyObject {
|
||||
impl fmt::Debug for PyObject<dyn PyObjectPayload> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[PyObj {:?}]", self.payload)
|
||||
write!(f, "[PyObj {:?}]", &self.payload)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1127,21 +1154,24 @@ impl PyValue for PyIteratorValue {
|
||||
}
|
||||
}
|
||||
|
||||
impl PyObject {
|
||||
pub fn new<T: PyObjectPayload>(payload: T, typ: PyObjectRef) -> PyObjectRef {
|
||||
impl<T> PyObject<T>
|
||||
where
|
||||
T: Sized + PyObjectPayload,
|
||||
{
|
||||
pub fn new(payload: T, typ: PyObjectRef) -> PyObjectRef {
|
||||
PyObject {
|
||||
typ,
|
||||
dict: Some(RefCell::new(PyAttributes::new())),
|
||||
payload: Box::new(payload),
|
||||
payload,
|
||||
}
|
||||
.into_ref()
|
||||
}
|
||||
|
||||
pub fn new_without_dict<T: PyObjectPayload>(payload: T, typ: PyObjectRef) -> PyObjectRef {
|
||||
pub fn new_without_dict(payload: T, typ: PyObjectRef) -> PyObjectRef {
|
||||
PyObject {
|
||||
typ,
|
||||
dict: None,
|
||||
payload: Box::new(payload),
|
||||
payload,
|
||||
}
|
||||
.into_ref()
|
||||
}
|
||||
@@ -1150,7 +1180,9 @@ impl PyObject {
|
||||
pub fn into_ref(self) -> PyObjectRef {
|
||||
Rc::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl PyObject<dyn PyObjectPayload> {
|
||||
#[inline]
|
||||
pub fn payload<T: PyObjectPayload>(&self) -> Option<&T> {
|
||||
self.payload.as_any().downcast_ref()
|
||||
@@ -1213,7 +1245,7 @@ impl FromPyObjectRef for PyRef<PyClass> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::PyContext;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_type_type() {
|
||||
|
||||
@@ -333,7 +333,7 @@ impl VirtualMachine {
|
||||
}
|
||||
|
||||
// TODO: is it safe to just invoke __call__ otherwise?
|
||||
trace!("invoke __call__ for: {:?}", func_ref.payload);
|
||||
trace!("invoke __call__ for: {:?}", &func_ref.payload);
|
||||
self.call_method(&func_ref, "__call__", args)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user