diff --git a/examples/call_between_rust_and_python.rs b/examples/call_between_rust_and_python.rs index 576390d059..80bf65526a 100644 --- a/examples/call_between_rust_and_python.rs +++ b/examples/call_between_rust_and_python.rs @@ -31,7 +31,7 @@ pub fn main() { #[pymodule] mod rust_py_module { use super::*; - use rustpython::vm::{PyObjectRef, builtins::PyList, convert::ToPyObject}; + use rustpython::vm::{PyObjectRef, convert::ToPyObject}; #[pyfunction] fn rust_function( @@ -58,7 +58,7 @@ python_person.name: {}", impl ToPyObject for NumVec { fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { let list = self.0.into_iter().map(|e| vm.new_pyobj(e)).collect(); - PyList::new_ref(list, vm.as_ref()).to_pyobject(vm) + vm.ctx.new_list(list).to_pyobject(vm) } } diff --git a/vm/src/builtins/bytearray.rs b/vm/src/builtins/bytearray.rs index 0a13c04dc8..5be976c3a1 100644 --- a/vm/src/builtins/bytearray.rs +++ b/vm/src/builtins/bytearray.rs @@ -134,7 +134,7 @@ impl PyByteArray { SequenceIndex::Slice(slice) => self .borrow_buf() .getitem_by_slice(vm, slice) - .map(|x| Self::new_ref(x, &vm.ctx).into()), + .map(|x| vm.ctx.new_bytearray(x).into()), } } @@ -463,11 +463,8 @@ impl PyByteArray { options: ByteInnerSplitOptions, vm: &VirtualMachine, ) -> PyResult> { - self.inner().split( - options, - |s, vm| Self::new_ref(s.to_vec(), &vm.ctx).into(), - vm, - ) + self.inner() + .split(options, |s, vm| vm.ctx.new_bytearray(s.to_vec()).into(), vm) } #[pymethod] @@ -476,11 +473,8 @@ impl PyByteArray { options: ByteInnerSplitOptions, vm: &VirtualMachine, ) -> PyResult> { - self.inner().rsplit( - options, - |s, vm| Self::new_ref(s.to_vec(), &vm.ctx).into(), - vm, - ) + self.inner() + .rsplit(options, |s, vm| vm.ctx.new_bytearray(s.to_vec()).into(), vm) } #[pymethod] @@ -490,9 +484,10 @@ impl PyByteArray { let value = self.inner(); let (front, has_mid, back) = value.partition(&sep, vm)?; Ok(vm.new_tuple(( - Self::new_ref(front.to_vec(), &vm.ctx), - Self::new_ref(if has_mid { sep.elements } else { Vec::new() }, &vm.ctx), - Self::new_ref(back.to_vec(), &vm.ctx), + vm.ctx.new_bytearray(front.to_vec()), + vm.ctx + .new_bytearray(if has_mid { sep.elements } else { Vec::new() }), + vm.ctx.new_bytearray(back.to_vec()), ))) } @@ -501,9 +496,10 @@ impl PyByteArray { let value = self.inner(); let (back, has_mid, front) = value.rpartition(&sep, vm)?; Ok(vm.new_tuple(( - Self::new_ref(front.to_vec(), &vm.ctx), - Self::new_ref(if has_mid { sep.elements } else { Vec::new() }, &vm.ctx), - Self::new_ref(back.to_vec(), &vm.ctx), + vm.ctx.new_bytearray(front.to_vec()), + vm.ctx + .new_bytearray(if has_mid { sep.elements } else { Vec::new() }), + vm.ctx.new_bytearray(back.to_vec()), ))) } @@ -515,7 +511,7 @@ impl PyByteArray { #[pymethod] fn splitlines(&self, options: anystr::SplitLinesArgs, vm: &VirtualMachine) -> Vec { self.inner() - .splitlines(options, |x| Self::new_ref(x.to_vec(), &vm.ctx).into()) + .splitlines(options, |x| vm.ctx.new_bytearray(x.to_vec()).into()) } #[pymethod] @@ -878,10 +874,6 @@ impl Representable for PyByteArray { } } -// fn set_value(obj: &PyObject, value: Vec) { -// obj.borrow_mut().kind = PyObjectPayload::Bytes { value }; -// } - #[pyclass(module = false, name = "bytearray_iterator")] #[derive(Debug)] pub struct PyByteArrayIterator { diff --git a/vm/src/builtins/classmethod.rs b/vm/src/builtins/classmethod.rs index 47e115a10c..f48152d503 100644 --- a/vm/src/builtins/classmethod.rs +++ b/vm/src/builtins/classmethod.rs @@ -58,7 +58,9 @@ impl GetDescriptor for PyClassMethod { let cls = cls.unwrap_or_else(|| _obj.class().to_owned().into()); let call_descr_get: PyResult = zelf.callable.lock().get_attr("__get__", vm); match call_descr_get { - Err(_) => Ok(PyBoundMethod::new_ref(cls, zelf.callable.lock().clone(), &vm.ctx).into()), + Err(_) => Ok(PyBoundMethod::new(cls, zelf.callable.lock().clone()) + .into_ref(&vm.ctx) + .into()), Ok(call_descr_get) => call_descr_get.call((cls.clone(), cls), vm), } } diff --git a/vm/src/builtins/complex.rs b/vm/src/builtins/complex.rs index 88f694e9d1..752d941061 100644 --- a/vm/src/builtins/complex.rs +++ b/vm/src/builtins/complex.rs @@ -42,7 +42,7 @@ impl PyPayload for PyComplex { impl ToPyObject for Complex64 { fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { - PyComplex::new_ref(self, &vm.ctx).into() + PyComplex::from(self).to_pyobject(vm) } } diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index 1130fec606..f9610af5dc 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -44,6 +44,7 @@ impl fmt::Debug for PyDict { } impl PyPayload for PyDict { + #[inline] fn class(ctx: &Context) -> &'static Py { ctx.types.dict_type } diff --git a/vm/src/builtins/function.rs b/vm/src/builtins/function.rs index 9dd9daa105..7bcd6bd7b0 100644 --- a/vm/src/builtins/function.rs +++ b/vm/src/builtins/function.rs @@ -554,7 +554,7 @@ impl GetDescriptor for PyFunction { let obj = if vm.is_none(&obj) && !Self::_cls_is(&cls, obj.class()) { zelf } else { - PyBoundMethod::new_ref(obj, zelf, &vm.ctx).into() + PyBoundMethod::new(obj, zelf).into_ref(&vm.ctx).into() }; Ok(obj) } @@ -722,7 +722,7 @@ impl Constructor for PyBoundMethod { } impl PyBoundMethod { - fn new(object: PyObjectRef, function: PyObjectRef) -> Self { + pub fn new(object: PyObjectRef, function: PyObjectRef) -> Self { PyBoundMethod { object, function } } diff --git a/vm/src/builtins/list.rs b/vm/src/builtins/list.rs index fe867ebd75..9cd7ecbe47 100644 --- a/vm/src/builtins/list.rs +++ b/vm/src/builtins/list.rs @@ -58,7 +58,7 @@ impl PyPayload for PyList { impl ToPyObject for Vec { fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { - PyList::new_ref(self, &vm.ctx).into() + PyList::from(self).into_ref(&vm.ctx).into() } } @@ -78,7 +78,7 @@ impl PyList { fn repeat(&self, n: isize, vm: &VirtualMachine) -> PyResult> { let elements = &*self.borrow_vec(); let v = elements.mul(vm, n)?; - Ok(Self::new_ref(v, &vm.ctx)) + Ok(Self::from(v).into_ref(&vm.ctx)) } fn irepeat(zelf: PyRef, n: isize, vm: &VirtualMachine) -> PyResult> { @@ -140,7 +140,7 @@ impl PyList { })?; let mut elements = self.borrow_vec().to_vec(); elements.extend(other.borrow_vec().iter().cloned()); - Ok(Self::new_ref(elements, &vm.ctx)) + Ok(Self::from(elements).into_ref(&vm.ctx)) } #[pymethod] @@ -176,7 +176,7 @@ impl PyList { #[pymethod] fn copy(&self, vm: &VirtualMachine) -> PyRef { - Self::new_ref(self.borrow_vec().to_vec(), &vm.ctx) + Self::from(self.borrow_vec().to_vec()).into_ref(&vm.ctx) } #[allow(clippy::len_without_is_empty)] diff --git a/vm/src/bytes_inner.rs b/vm/src/bytes_inner.rs index fef9e67b56..8f189ee35e 100644 --- a/vm/src/bytes_inner.rs +++ b/vm/src/bytes_inner.rs @@ -96,7 +96,7 @@ impl ByteInnerNewOptions { (OptionalArg::Present(obj), OptionalArg::Missing, OptionalArg::Missing) => { let obj = obj.clone(); // construct an exact bytes from an exact bytes do not clone - let obj = if cls.is(PyBytes::class(&vm.ctx)) { + let obj = if cls.is(vm.ctx.types.bytes_type) { match obj.downcast_exact::(vm) { Ok(b) => return Ok(b.into_pyref()), Err(obj) => obj, @@ -109,7 +109,7 @@ impl ByteInnerNewOptions { // construct an exact bytes from __bytes__ slot. // if __bytes__ return a bytes, use the bytes object except we are the subclass of the bytes let bytes = bytes_method?.call((), vm)?; - let bytes = if cls.is(PyBytes::class(&vm.ctx)) { + let bytes = if cls.is(vm.ctx.types.bytes_type) { match bytes.downcast::() { Ok(b) => return Ok(b), Err(bytes) => bytes, diff --git a/vm/src/class.rs b/vm/src/class.rs index 799fde1644..f977f07ca7 100644 --- a/vm/src/class.rs +++ b/vm/src/class.rs @@ -13,16 +13,23 @@ use rustpython_common::static_cell; pub trait StaticType { // Ideally, saving PyType is better than PyTypeRef fn static_cell() -> &'static static_cell::StaticCell; + #[inline] fn static_metaclass() -> &'static Py { PyType::static_type() } + #[inline] fn static_baseclass() -> &'static Py { PyBaseObject::static_type() } + #[inline] fn static_type() -> &'static Py { - Self::static_cell() - .get() - .expect("static type has not been initialized. e.g. the native types defined in different module may be used before importing library.") + #[cold] + fn fail() -> ! { + panic!( + "static type has not been initialized. e.g. the native types defined in different module may be used before importing library." + ); + } + Self::static_cell().get().unwrap_or_else(|| fail()) } fn init_manually(typ: PyTypeRef) -> &'static Py { let cell = Self::static_cell(); diff --git a/vm/src/vm/context.rs b/vm/src/vm/context.rs index efa50b238e..54f3dfabda 100644 --- a/vm/src/vm/context.rs +++ b/vm/src/vm/context.rs @@ -1,9 +1,9 @@ use crate::{ PyResult, VirtualMachine, builtins::{ - PyBaseException, PyBytes, PyComplex, PyDict, PyDictRef, PyEllipsis, PyFloat, PyFrozenSet, - PyInt, PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented, PyStr, PyStrInterned, - PyTuple, PyTupleRef, PyType, PyTypeRef, bytes, + PyBaseException, PyByteArray, PyBytes, PyComplex, PyDict, PyDictRef, PyEllipsis, PyFloat, + PyFrozenSet, PyInt, PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented, PyStr, + PyStrInterned, PyTuple, PyTupleRef, PyType, PyTypeRef, code::{self, PyCode}, descriptor::{ MemberGetter, MemberKind, MemberSetter, MemberSetterFunc, PyDescriptorOwned, @@ -418,7 +418,7 @@ impl Context { #[inline] pub fn new_str(&self, s: impl Into) -> PyRef { - pystr::PyStr::new_ref(s, self) + s.into().into_ref(self) } pub fn interned_or_new_str(&self, s: S) -> PyRef @@ -433,8 +433,13 @@ impl Context { } #[inline] - pub fn new_bytes(&self, data: Vec) -> PyRef { - bytes::PyBytes::new_ref(data, self) + pub fn new_bytes(&self, data: Vec) -> PyRef { + PyBytes::from(data).into_ref(self) + } + + #[inline] + pub fn new_bytearray(&self, data: Vec) -> PyRef { + PyByteArray::from(data).into_ref(self) } #[inline(always)] @@ -454,12 +459,12 @@ impl Context { #[inline(always)] pub fn new_list(&self, elements: Vec) -> PyListRef { - PyList::new_ref(elements, self) + PyList::from(elements).into_ref(self) } #[inline(always)] pub fn new_dict(&self) -> PyDictRef { - PyDict::new_ref(self) + PyDict::default().into_ref(self) } pub fn new_class( diff --git a/vm/src/warn.rs b/vm/src/warn.rs index 6c195d5f2e..761cd69a0d 100644 --- a/vm/src/warn.rs +++ b/vm/src/warn.rs @@ -1,8 +1,7 @@ use crate::{ AsObject, Context, Py, PyObjectRef, PyResult, VirtualMachine, builtins::{ - PyDict, PyDictRef, PyListRef, PyStr, PyStrInterned, PyStrRef, PyTuple, PyTupleRef, - PyTypeRef, + PyDictRef, PyListRef, PyStr, PyStrInterned, PyStrRef, PyTuple, PyTupleRef, PyTypeRef, }, convert::{IntoObject, TryFromObject}, types::PyComparisonOp, @@ -32,7 +31,7 @@ impl WarningsState { pub fn init_state(ctx: &Context) -> WarningsState { WarningsState { filters: Self::create_filter(ctx), - _once_registry: PyDict::new_ref(ctx), + _once_registry: ctx.new_dict(), default_action: ctx.new_str("default"), filters_version: 0, } @@ -401,7 +400,7 @@ fn setup_context( let registry = if let Ok(registry) = globals.get_item(__warningregistry__, vm) { registry } else { - let registry = PyDict::new_ref(&vm.ctx); + let registry = vm.ctx.new_dict(); globals.set_item(__warningregistry__, registry.clone().into(), vm)?; registry.into() };