diff --git a/ast/asdl_rs.py b/ast/asdl_rs.py index be809a8e15..de5f4bbb02 100755 --- a/ast/asdl_rs.py +++ b/ast/asdl_rs.py @@ -387,7 +387,7 @@ def gen_classdef(self, name, fields, attrs, depth, base="AstNode"): self.emit("#[pyimpl(flags(HAS_DICT, BASETYPE))]", depth) self.emit(f"impl {structname} {{", depth) self.emit(f"#[extend_class]", depth + 1) - self.emit("fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) {", depth + 1) + self.emit("fn extend_class_with_fields(ctx: &Context, class: &'static Py) {", depth + 1) fields = ",".join(f"ctx.new_str(ascii!({json.dumps(f.name)})).into()" for f in fields) self.emit(f'class.set_str_attr("_fields", ctx.new_list(vec![{fields}]));', depth + 2) attrs = ",".join(f"ctx.new_str(ascii!({json.dumps(attr.name)})).into()" for attr in attrs) @@ -481,7 +481,7 @@ def visitProduct(self, product, name, depth): def make_node(self, variant, fields, depth): lines = [] - self.emit(f"let _node = AstNode.into_ref_with_type(_vm, Node{variant}::static_type().clone()).unwrap();", depth) + self.emit(f"let _node = AstNode.into_ref_with_type(_vm, Node{variant}::static_type().to_owned()).unwrap();", depth) if fields: self.emit("let _dict = _node.as_object().dict().unwrap();", depth) for f in fields: diff --git a/common/src/refcount.rs b/common/src/refcount.rs index 6db81e5ab0..cbac8424dc 100644 --- a/common/src/refcount.rs +++ b/common/src/refcount.rs @@ -5,7 +5,7 @@ use crate::atomic::{Ordering::*, PyAtomic, Radium}; /// /// Going above this limit will abort your program (although not /// necessarily) at _exactly_ `MAX_REFCOUNT + 1` references. -const MAX_REFCOUNT: usize = (isize::MAX) as usize; +const MAX_REFCOUNT: usize = isize::MAX as usize; pub struct RefCount { strong: PyAtomic, @@ -18,6 +18,8 @@ impl Default for RefCount { } impl RefCount { + const MASK: usize = MAX_REFCOUNT; + pub fn new() -> Self { RefCount { strong: Radium::new(1), @@ -33,7 +35,7 @@ impl RefCount { pub fn inc(&self) { let old_size = self.strong.fetch_add(1, Relaxed); - if old_size > MAX_REFCOUNT { + if old_size & Self::MASK == Self::MASK { std::process::abort(); } } @@ -58,3 +60,19 @@ impl RefCount { true } } + +impl RefCount { + // move these functions out and give separated type once type range is stabilized + + pub fn leak(&self) { + debug_assert!(!self.is_leaked()); + const BIT_MARKER: usize = (std::isize::MAX as usize) + 1; + debug_assert_eq!(BIT_MARKER.count_ones(), 1); + debug_assert_eq!(BIT_MARKER.leading_zeros(), 0); + self.strong.fetch_add(BIT_MARKER, Relaxed); + } + + pub fn is_leaked(&self) -> bool { + (self.strong.load(Acquire) as isize) < 0 + } +} diff --git a/derive/src/pyclass.rs b/derive/src/pyclass.rs index 6cd2958914..8d4815a790 100644 --- a/derive/src/pyclass.rs +++ b/derive/src/pyclass.rs @@ -117,7 +117,7 @@ pub(crate) fn impl_pyimpl(attr: AttributeArgs, item: Item) -> Result, ) { #getset_impl #extend_impl @@ -150,7 +150,7 @@ pub(crate) fn impl_pyimpl(attr: AttributeArgs, item: Item) -> Result, ) { #getset_impl #extend_impl @@ -237,7 +237,7 @@ fn generate_class_def( } .map(|typ| { quote! { - fn static_baseclass() -> &'static ::rustpython_vm::builtins::PyTypeRef { + fn static_baseclass() -> &'static ::rustpython_vm::Py<::rustpython_vm::builtins::PyType> { use rustpython_vm::class::StaticType; #typ::static_type() } @@ -247,7 +247,7 @@ fn generate_class_def( let meta_class = metaclass.map(|typ| { let typ = Ident::new(&typ, ident.span()); quote! { - fn static_metaclass() -> &'static ::rustpython_vm::builtins::PyTypeRef { + fn static_metaclass() -> &'static ::rustpython_vm::Py<::rustpython_vm::builtins::PyType> { use rustpython_vm::class::StaticType; #typ::static_type() } @@ -367,8 +367,8 @@ pub(crate) fn impl_define_exception(exc_def: PyExceptionDef) -> Result &::rustpython_vm::builtins::PyTypeRef { - &vm.ctx.exceptions.#ctx_name + fn class(ctx: &::rustpython_vm::vm::Context) -> &'static ::rustpython_vm::Py<::rustpython_vm::builtins::PyType> { + ctx.exceptions.#ctx_name } } @@ -490,9 +490,9 @@ where quote!(.with_doc(#doc.to_owned(), ctx)) }); let build_func = match self.inner.attr_name { - AttrName::Method => quote!(.build_method(ctx, class.clone())), - AttrName::ClassMethod => quote!(.build_classmethod(ctx, class.clone())), - AttrName::StaticMethod => quote!(.build_staticmethod(ctx, class.clone())), + AttrName::Method => quote!(.build_method(ctx, class)), + AttrName::ClassMethod => quote!(.build_classmethod(ctx, class)), + AttrName::StaticMethod => quote!(.build_staticmethod(ctx, class)), other => unreachable!( "Only 'method', 'classmethod' and 'staticmethod' are supported, got {:?}", other @@ -733,10 +733,10 @@ impl ToTokens for GetSetNursery { class.set_str_attr( #name, ::rustpython_vm::PyRef::new_ref( - ::rustpython_vm::builtins::PyGetSet::new(#name.into(), class.clone()) + ::rustpython_vm::builtins::PyGetSet::new(#name.into(), class) .with_get(&Self::#getter) #setter #deleter, - ctx.types.getset_type.clone(), None) + ctx.types.getset_type.to_owned(), None) ); } }); diff --git a/derive/src/pymodule.rs b/derive/src/pymodule.rs index fee1c9c2a6..06df3f2c47 100644 --- a/derive/src/pymodule.rs +++ b/derive/src/pymodule.rs @@ -332,11 +332,12 @@ impl ModuleItem for FunctionItem { }; let doc = quote!(.with_doc(#doc.to_owned(), &vm.ctx)); let new_func = quote_spanned!(ident.span()=> - vm.ctx.make_funcdef(#py_name, #ident) - #doc - .into_function() - .with_module(vm.new_pyobj(#module.to_owned())) - .into_ref(&vm.ctx) + ::rustpython_vm::object::PyPayload::into_ref( + vm.ctx.make_funcdef(#py_name, #ident) + #doc + .into_function() + .with_module(vm.new_pyobj(#module.to_owned())), + &vm.ctx) ); if self.pyattrs.is_empty() { diff --git a/derive/src/pypayload.rs b/derive/src/pypayload.rs index fd8ea4df64..eeae27c3fa 100644 --- a/derive/src/pypayload.rs +++ b/derive/src/pypayload.rs @@ -7,7 +7,8 @@ pub(crate) fn impl_pypayload(input: DeriveInput) -> Result { let ret = quote! { impl ::rustpython_vm::PyPayload for #ty { - fn class(_vm: &::rustpython_vm::VirtualMachine) -> &rustpython_vm::builtins::PyTypeRef { + #[inline] + fn class(_ctx: &::rustpython_vm::vm::Context) -> &'static rustpython_vm::Py<::rustpython_vm::builtins::PyType> { ::static_type() } } diff --git a/src/lib.rs b/src/lib.rs index d30792ea0e..b81fdf95dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -517,7 +517,7 @@ __import__("io").TextIOWrapper( #[cfg(not(feature = "ssl"))] fn install_pip(_: Scope, vm: &VirtualMachine) -> PyResult { Err(vm.new_exception_msg( - vm.ctx.exceptions.system_error.clone(), + vm.ctx.exceptions.system_error.to_owned(), "install-pip requires rustpython be build with the 'ssl' feature enabled.".to_owned(), )) } diff --git a/src/shell.rs b/src/shell.rs index 3edb9434a9..d7a548bf46 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -106,7 +106,7 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> { continuing = false; full_input.clear(); let keyboard_interrupt = - vm.new_exception_empty(vm.ctx.exceptions.keyboard_interrupt.clone()); + vm.new_exception_empty(vm.ctx.exceptions.keyboard_interrupt.to_owned()); Err(keyboard_interrupt) } ReadlineResult::Eof => { @@ -127,7 +127,7 @@ pub fn run_shell(vm: &VirtualMachine, scope: Scope) -> PyResult<()> { }; if let Err(exc) = result { - if exc.fast_isinstance(&vm.ctx.exceptions.system_exit) { + if exc.fast_isinstance(vm.ctx.exceptions.system_exit) { repl.save_history(&repl_history_path).unwrap(); return Err(exc); } diff --git a/stdlib/src/array.rs b/stdlib/src/array.rs index 6ceef4f205..27a89063a2 100644 --- a/stdlib/src/array.rs +++ b/stdlib/src/array.rs @@ -683,7 +683,7 @@ mod array { fn typecode(&self, vm: &VirtualMachine) -> PyStrRef { vm.ctx .intern_str(self.read().typecode().to_string()) - .to_str() + .to_owned() } #[pyproperty] @@ -843,7 +843,7 @@ mod array { if not_enough_bytes { Err(vm.new_exception_msg( - vm.ctx.exceptions.eof_error.clone(), + vm.ctx.exceptions.eof_error.to_owned(), "read() didn't return enough bytes".to_owned(), )) } else { @@ -897,7 +897,7 @@ mod array { let bytes = bytes.get_bytes(); for b in bytes.chunks(BLOCKSIZE) { - let b = PyBytes::from(b.to_vec()).into_ref(vm); + let b = PyBytes::from(b.to_vec()).into_ref(&vm.ctx); vm.call_method(&f, "write", (b,))?; } Ok(()) @@ -1017,7 +1017,7 @@ mod array { if let Some(other) = other.payload::() { self.read() .add(&*other.read(), vm) - .map(|array| PyArray::from(array).into_ref(vm)) + .map(|array| PyArray::from(array).into_ref(&vm.ctx)) } else { Err(vm.new_type_error(format!( "can only append array (not \"{}\") to array", @@ -1050,7 +1050,7 @@ mod array { fn mul(&self, value: isize, vm: &VirtualMachine) -> PyResult> { self.read() .mul(value, vm) - .map(|x| Self::from(x).into_ref(vm)) + .map(|x| Self::from(x).into_ref(&vm.ctx)) } #[pymethod(magic)] @@ -1444,7 +1444,7 @@ mod array { } fn check_array_type(typ: PyTypeRef, vm: &VirtualMachine) -> PyResult { - if !typ.fast_issubclass(PyArray::class(vm)) { + if !typ.fast_issubclass(PyArray::class(&vm.ctx)) { return Err( vm.new_type_error(format!("{} is not a subtype of array.array", typ.name())) ); diff --git a/stdlib/src/binascii.rs b/stdlib/src/binascii.rs index 739a9bb5f7..5dad5dce01 100644 --- a/stdlib/src/binascii.rs +++ b/stdlib/src/binascii.rs @@ -16,7 +16,7 @@ mod decl { vm.ctx.new_exception_type( "binascii", "Error", - Some(vec![vm.ctx.exceptions.value_error.clone()]), + Some(vec![vm.ctx.exceptions.value_error.to_owned()]), ) } diff --git a/stdlib/src/csv.rs b/stdlib/src/csv.rs index c0efe957f3..66848ca8fa 100644 --- a/stdlib/src/csv.rs +++ b/stdlib/src/csv.rs @@ -28,7 +28,7 @@ mod _csv { vm.ctx.new_exception_type( "_csv", "Error", - Some(vec![vm.ctx.exceptions.exception_type.clone()]), + Some(vec![vm.ctx.exceptions.exception_type.to_owned()]), ) } diff --git a/stdlib/src/json.rs b/stdlib/src/json.rs index 47d53600e0..79b31da2a2 100644 --- a/stdlib/src/json.rs +++ b/stdlib/src/json.rs @@ -36,14 +36,14 @@ mod _json { let object_hook = vm.option_if_none(ctx.get_attr("object_hook", vm)?); let object_pairs_hook = vm.option_if_none(ctx.get_attr("object_pairs_hook", vm)?); let parse_float = ctx.get_attr("parse_float", vm)?; - let parse_float = - if vm.is_none(&parse_float) || parse_float.is(&vm.ctx.types.float_type) { - None - } else { - Some(parse_float) - }; + let parse_float = if vm.is_none(&parse_float) || parse_float.is(vm.ctx.types.float_type) + { + None + } else { + Some(parse_float) + }; let parse_int = ctx.get_attr("parse_int", vm)?; - let parse_int = if vm.is_none(&parse_int) || parse_int.is(&vm.ctx.types.int_type) { + let parse_int = if vm.is_none(&parse_int) || parse_int.is(vm.ctx.types.int_type) { None } else { Some(parse_int) diff --git a/stdlib/src/pyexpat.rs b/stdlib/src/pyexpat.rs index 8a9cb33b91..42e341e02b 100644 --- a/stdlib/src/pyexpat.rs +++ b/stdlib/src/pyexpat.rs @@ -32,10 +32,10 @@ macro_rules! create_property { #[pymodule(name = "pyexpat")] mod _pyexpat { use crate::vm::{ - builtins::{PyStr, PyStrRef, PyTypeRef}, + builtins::{PyStr, PyStrRef, PyType}, function::ArgBytesLike, function::{IntoFuncArgs, OptionalArg}, - Context, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, + Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, }; use rustpython_common::lock::PyRwLock; use std::io::Cursor; @@ -72,42 +72,24 @@ mod _pyexpat { entity_decl: MutableObject::new(vm.ctx.none()), buffer_text: MutableObject::new(vm.ctx.new_bool(false).into()), } - .into_ref(vm)) + .into_ref(&vm.ctx)) } #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { let mut attributes = class.attributes.write(); - create_property!( - ctx, - attributes, - "StartElementHandler", - class.clone(), - start_element - ); - create_property!( - ctx, - attributes, - "EndElementHandler", - class.clone(), - end_element - ); + create_property!(ctx, attributes, "StartElementHandler", class, start_element); + create_property!(ctx, attributes, "EndElementHandler", class, end_element); create_property!( ctx, attributes, "CharacterDataHandler", - class.clone(), + class, character_data ); - create_property!( - ctx, - attributes, - "EntityDeclHandler", - class.clone(), - entity_decl - ); - create_property!(ctx, attributes, "buffer_text", class.clone(), buffer_text); + create_property!(ctx, attributes, "EntityDeclHandler", class, entity_decl); + create_property!(ctx, attributes, "buffer_text", class, buffer_text); } fn create_config(&self) -> xml::ParserConfig { @@ -136,15 +118,15 @@ mod _pyexpat { .unwrap(); } - let name_str = PyStr::from(name.local_name).into_ref(vm); + let name_str = PyStr::from(name.local_name).into_ref(&vm.ctx); invoke_handler(vm, &self.start_element, (name_str, dict)); } Ok(XmlEvent::EndElement { name, .. }) => { - let name_str = PyStr::from(name.local_name).into_ref(vm); + let name_str = PyStr::from(name.local_name).into_ref(&vm.ctx); invoke_handler(vm, &self.end_element, (name_str,)); } Ok(XmlEvent::Characters(chars)) => { - let str = PyStr::from(chars).into_ref(vm); + let str = PyStr::from(chars).into_ref(&vm.ctx); invoke_handler(vm, &self.character_data, (str,)); } _ => {} diff --git a/stdlib/src/pystruct.rs b/stdlib/src/pystruct.rs index 56668db882..2612a3477f 100644 --- a/stdlib/src/pystruct.rs +++ b/stdlib/src/pystruct.rs @@ -36,7 +36,7 @@ pub(crate) mod _struct { b @ PyBytes => if b.is_ascii() { Some(unsafe { PyStr::new_ascii_unchecked(b.as_bytes().to_vec()) - }.into_ref(vm)) + }.into_ref(&vm.ctx)) } else { None }, diff --git a/stdlib/src/select.rs b/stdlib/src/select.rs index 0a75fd5b4b..798c1cc692 100644 --- a/stdlib/src/select.rs +++ b/stdlib/src/select.rs @@ -163,7 +163,7 @@ mod decl { #[pyattr] fn error(vm: &VirtualMachine) -> PyTypeRef { - vm.ctx.exceptions.os_error.clone() + vm.ctx.exceptions.os_error.to_owned() } #[pyfunction] diff --git a/stdlib/src/socket.rs b/stdlib/src/socket.rs index 4c0227d5ca..2015c5c4e1 100644 --- a/stdlib/src/socket.rs +++ b/stdlib/src/socket.rs @@ -80,7 +80,7 @@ mod _socket { #[pyattr] fn error(vm: &VirtualMachine) -> PyTypeRef { - vm.ctx.exceptions.os_error.clone() + vm.ctx.exceptions.os_error.to_owned() } #[pyattr(once)] @@ -88,7 +88,7 @@ mod _socket { vm.ctx.new_exception_type( "socket", "timeout", - Some(vec![vm.ctx.exceptions.os_error.clone()]), + Some(vec![vm.ctx.exceptions.os_error.to_owned()]), ) } #[pyattr(once)] @@ -96,7 +96,7 @@ mod _socket { vm.ctx.new_exception_type( "socket", "herror", - Some(vec![vm.ctx.exceptions.os_error.clone()]), + Some(vec![vm.ctx.exceptions.os_error.to_owned()]), ) } #[pyattr(once)] @@ -104,7 +104,7 @@ mod _socket { vm.ctx.new_exception_type( "socket", "gaierror", - Some(vec![vm.ctx.exceptions.os_error.clone()]), + Some(vec![vm.ctx.exceptions.os_error.to_owned()]), ) } @@ -153,7 +153,7 @@ mod _socket { type CastFrom = libc::c_longlong; // should really just be to_index() but test_socket tests the error messages explicitly - if obj.fast_isinstance(&vm.ctx.types.float_type) { + if obj.fast_isinstance(vm.ctx.types.float_type) { return Err(vm.new_type_error("integer argument expected, got float".to_owned())); } let int = vm diff --git a/stdlib/src/ssl.rs b/stdlib/src/ssl.rs index d4b8addc5e..f01a7b2b57 100644 --- a/stdlib/src/ssl.rs +++ b/stdlib/src/ssl.rs @@ -180,7 +180,7 @@ mod _ssl { vm.ctx.new_exception_type( "ssl", "SSLError", - Some(vec![vm.ctx.exceptions.os_error.clone()]), + Some(vec![vm.ctx.exceptions.os_error.to_owned()]), ) } @@ -190,7 +190,10 @@ mod _ssl { vm.ctx.new_exception_type( "ssl", "SSLCertVerificationError", - Some(vec![ssl_error(vm), vm.ctx.exceptions.value_error.clone()]), + Some(vec![ + ssl_error(vm), + vm.ctx.exceptions.value_error.to_owned(), + ]), ) } @@ -1435,7 +1438,7 @@ mod windows { oids.into_iter().map(|oid| vm.ctx.new_str(oid).into()), ) .unwrap() - .into_ref(vm) + .into_ref(&vm.ctx) .into(), }; Ok(vm.new_tuple((cert, enc_type, usage)).into()) diff --git a/stdlib/src/syslog.rs b/stdlib/src/syslog.rs index d32ec7cfd9..3e9097c69f 100644 --- a/stdlib/src/syslog.rs +++ b/stdlib/src/syslog.rs @@ -31,7 +31,7 @@ mod syslog { Some(value) => &argv[value..], None => argv, }) - .into_ref(vm), + .into_ref(&vm.ctx), ); } } diff --git a/stdlib/src/termios.rs b/stdlib/src/termios.rs index 12d6417397..b698dd7419 100644 --- a/stdlib/src/termios.rs +++ b/stdlib/src/termios.rs @@ -271,7 +271,7 @@ mod termios { vm.ctx.new_exception_type( "termios", "error", - Some(vec![vm.ctx.exceptions.os_error.clone()]), + Some(vec![vm.ctx.exceptions.os_error.to_owned()]), ) } } diff --git a/stdlib/src/unicodedata.rs b/stdlib/src/unicodedata.rs index d8fad12192..64355f90d0 100644 --- a/stdlib/src/unicodedata.rs +++ b/stdlib/src/unicodedata.rs @@ -7,7 +7,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { let module = unicodedata::make_module(vm); let ucd: PyObjectRef = unicodedata::Ucd::new(unic_ucd_age::UNICODE_VERSION) - .into_ref(vm) + .into_ref(&vm.ctx) .into(); for attr in ["category", "lookup", "name", "bidirectional", "normalize"] @@ -147,7 +147,7 @@ mod unicodedata { micro: 0, }, } - .into_ref(vm) + .into_ref(&vm.ctx) } #[pyattr] diff --git a/stdlib/src/zlib.rs b/stdlib/src/zlib.rs index 7986c6fbfd..b2b4a7a1cf 100644 --- a/stdlib/src/zlib.rs +++ b/stdlib/src/zlib.rs @@ -58,7 +58,7 @@ mod zlib { vm.ctx.new_exception_type( "zlib", "error", - Some(vec![vm.ctx.exceptions.exception_type.clone()]), + Some(vec![vm.ctx.exceptions.exception_type.to_owned()]), ) } @@ -275,8 +275,8 @@ mod zlib { Ok(PyDecompress { decompress: PyMutex::new(decompress), eof: AtomicCell::new(false), - unused_data: PyMutex::new(PyBytes::from(vec![]).into_ref(vm)), - unconsumed_tail: PyMutex::new(PyBytes::from(vec![]).into_ref(vm)), + unused_data: PyMutex::new(PyBytes::from(vec![]).into_ref(&vm.ctx)), + unconsumed_tail: PyMutex::new(PyBytes::from(vec![]).into_ref(&vm.ctx)), }) } #[pyattr] @@ -357,7 +357,7 @@ mod zlib { let mut unconsumed_tail = self.unconsumed_tail.lock(); if !leftover.is_empty() || !unconsumed_tail.is_empty() { - *unconsumed_tail = PyBytes::from(leftover.to_owned()).into_ref(vm); + *unconsumed_tail = PyBytes::from(leftover.to_owned()).into_ref(&vm.ctx); } ret @@ -384,7 +384,7 @@ mod zlib { }; self.save_unused_input(&mut d, &data, stream_end, orig_in, vm); - *data = PyBytes::from(Vec::new()).into_ref(vm); + *data = PyBytes::from(Vec::new()).into_ref(&vm.ctx); // TODO: drop the inner decompressor, somehow // if stream_end { diff --git a/vm/src/builtins/asyncgenerator.rs b/vm/src/builtins/asyncgenerator.rs index 1bede4e67e..476e3bd032 100644 --- a/vm/src/builtins/asyncgenerator.rs +++ b/vm/src/builtins/asyncgenerator.rs @@ -1,4 +1,4 @@ -use super::{PyCode, PyGenericAlias, PyStrRef, PyTypeRef}; +use super::{PyCode, PyGenericAlias, PyStrRef, PyType, PyTypeRef}; use crate::{ builtins::PyBaseExceptionRef, class::PyClassImpl, @@ -7,7 +7,7 @@ use crate::{ function::OptionalArg, protocol::PyIterReturn, types::{Constructor, IterNext, IterNextIterable, Unconstructible}, - AsObject, Context, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; use crossbeam_utils::atomic::AtomicCell; @@ -21,8 +21,9 @@ pub struct PyAsyncGen { type PyAsyncGenRef = PyRef; impl PyPayload for PyAsyncGen { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.async_generator + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.async_generator } } @@ -100,7 +101,7 @@ impl PyAsyncGen { aclose: true, state: AtomicCell::new(AwaitableState::Init), value: ( - vm.ctx.exceptions.generator_exit.clone().into(), + vm.ctx.exceptions.generator_exit.to_owned().into(), vm.ctx.none(), vm.ctx.none(), ), @@ -135,8 +136,9 @@ impl Unconstructible for PyAsyncGen {} #[derive(Debug)] pub(crate) struct PyAsyncGenWrappedValue(pub PyObjectRef); impl PyPayload for PyAsyncGenWrappedValue { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.async_generator_wrapped_value + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.async_generator_wrapped_value } } @@ -147,7 +149,7 @@ impl PyAsyncGenWrappedValue { fn unbox(ag: &PyAsyncGen, val: PyResult, vm: &VirtualMachine) -> PyResult { let (closed, async_done) = match &val { Ok(PyIterReturn::StopIteration(_)) => (true, true), - Err(e) if e.fast_isinstance(&vm.ctx.exceptions.generator_exit) => (true, true), + Err(e) if e.fast_isinstance(vm.ctx.exceptions.generator_exit) => (true, true), Err(_) => (false, true), _ => (false, false), }; @@ -184,8 +186,9 @@ pub(crate) struct PyAsyncGenASend { } impl PyPayload for PyAsyncGenASend { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.async_generator_asend + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.async_generator_asend } } @@ -279,8 +282,9 @@ pub(crate) struct PyAsyncGenAThrow { } impl PyPayload for PyAsyncGenAThrow { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.async_generator_athrow + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.async_generator_athrow } } @@ -398,8 +402,8 @@ impl PyAsyncGenAThrow { self.ag.running_async.store(false); self.state.store(AwaitableState::Closed); if self.aclose - && (exc.fast_isinstance(&vm.ctx.exceptions.stop_async_iteration) - || exc.fast_isinstance(&vm.ctx.exceptions.generator_exit)) + && (exc.fast_isinstance(vm.ctx.exceptions.stop_async_iteration) + || exc.fast_isinstance(vm.ctx.exceptions.generator_exit)) { vm.new_stop_iteration(None) } else { @@ -416,7 +420,7 @@ impl IterNext for PyAsyncGenAThrow { } pub fn init(ctx: &Context) { - PyAsyncGen::extend_class(ctx, &ctx.types.async_generator); - PyAsyncGenASend::extend_class(ctx, &ctx.types.async_generator_asend); - PyAsyncGenAThrow::extend_class(ctx, &ctx.types.async_generator_athrow); + PyAsyncGen::extend_class(ctx, ctx.types.async_generator); + PyAsyncGenASend::extend_class(ctx, ctx.types.async_generator_asend); + PyAsyncGenAThrow::extend_class(ctx, ctx.types.async_generator_athrow); } diff --git a/vm/src/builtins/bool.rs b/vm/src/builtins/bool.rs index fab3e9cfe9..4277b8781f 100644 --- a/vm/src/builtins/bool.rs +++ b/vm/src/builtins/bool.rs @@ -1,7 +1,7 @@ -use super::{PyInt, PyStrRef, PyTypeRef}; +use super::{PyInt, PyStrRef, PyType, PyTypeRef}; use crate::{ class::PyClassImpl, convert::ToPyObject, function::OptionalArg, types::Constructor, AsObject, - Context, PyObject, PyObjectRef, PyPayload, PyResult, TryFromBorrowedObject, VirtualMachine, + Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, TryFromBorrowedObject, VirtualMachine, }; use num_bigint::Sign; use num_traits::Zero; @@ -15,7 +15,7 @@ impl ToPyObject for bool { impl TryFromBorrowedObject for bool { fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult { - if obj.fast_isinstance(&vm.ctx.types.int_type) { + if obj.fast_isinstance(vm.ctx.types.int_type) { Ok(get_value(obj)) } else { Err(vm.new_type_error(format!("Expected type bool, not {}", obj.class().name()))) @@ -37,7 +37,7 @@ impl PyObjectRef { // If descriptor returns Error, propagate it further let method = method_or_err?; let bool_obj = vm.invoke(&method, ())?; - if !bool_obj.fast_isinstance(&vm.ctx.types.bool_type) { + if !bool_obj.fast_isinstance(vm.ctx.types.bool_type) { return Err(vm.new_type_error(format!( "__bool__ should return bool, returned type {}", bool_obj.class().name() @@ -79,8 +79,9 @@ impl PyObjectRef { pub struct PyBool; impl PyPayload for PyBool { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.bool_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.bool_type } } @@ -94,7 +95,7 @@ impl Constructor for PyBool { type Args = OptionalArg; fn py_new(zelf: PyTypeRef, x: Self::Args, vm: &VirtualMachine) -> PyResult { - if !zelf.fast_isinstance(&vm.ctx.types.type_type) { + if !zelf.fast_isinstance(vm.ctx.types.type_type) { let actual_class = zelf.class(); let actual_type = &actual_class.name(); return Err(vm.new_type_error(format!( @@ -117,7 +118,6 @@ impl PyBool { vm.ctx.false_str } .to_owned() - .into_pyref() } #[pymethod(magic)] @@ -132,8 +132,8 @@ impl PyBool { #[pymethod(name = "__ror__")] #[pymethod(magic)] fn or(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef { - if lhs.fast_isinstance(&vm.ctx.types.bool_type) - && rhs.fast_isinstance(&vm.ctx.types.bool_type) + if lhs.fast_isinstance(vm.ctx.types.bool_type) + && rhs.fast_isinstance(vm.ctx.types.bool_type) { let lhs = get_value(&lhs); let rhs = get_value(&rhs); @@ -146,8 +146,8 @@ impl PyBool { #[pymethod(name = "__rand__")] #[pymethod(magic)] fn and(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef { - if lhs.fast_isinstance(&vm.ctx.types.bool_type) - && rhs.fast_isinstance(&vm.ctx.types.bool_type) + if lhs.fast_isinstance(vm.ctx.types.bool_type) + && rhs.fast_isinstance(vm.ctx.types.bool_type) { let lhs = get_value(&lhs); let rhs = get_value(&rhs); @@ -160,8 +160,8 @@ impl PyBool { #[pymethod(name = "__rxor__")] #[pymethod(magic)] fn xor(lhs: PyObjectRef, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef { - if lhs.fast_isinstance(&vm.ctx.types.bool_type) - && rhs.fast_isinstance(&vm.ctx.types.bool_type) + if lhs.fast_isinstance(vm.ctx.types.bool_type) + && rhs.fast_isinstance(vm.ctx.types.bool_type) { let lhs = get_value(&lhs); let rhs = get_value(&rhs); @@ -173,11 +173,11 @@ impl PyBool { } pub(crate) fn init(context: &Context) { - PyBool::extend_class(context, &context.types.bool_type); + PyBool::extend_class(context, context.types.bool_type); } // pub fn not(vm: &VirtualMachine, obj: &PyObject) -> PyResult { -// if obj.fast_isinstance(&vm.ctx.types.bool_type) { +// if obj.fast_isinstance(vm.ctx.types.bool_type) { // let value = get_value(obj); // Ok(!value) // } else { diff --git a/vm/src/builtins/builtinfunc.rs b/vm/src/builtins/builtinfunc.rs index b3c55ab150..d11e84f189 100644 --- a/vm/src/builtins/builtinfunc.rs +++ b/vm/src/builtins/builtinfunc.rs @@ -1,10 +1,10 @@ -use super::{type_, PyClassMethod, PyStaticMethod, PyStr, PyStrRef, PyTypeRef}; +use super::{type_, PyClassMethod, PyStaticMethod, PyStr, PyStrRef, PyType}; use crate::{ builtins::PyBoundMethod, class::PyClassImpl, function::{FuncArgs, IntoPyNativeFunc, PyNativeFunc}, types::{Callable, Constructor, GetDescriptor, Unconstructible}, - AsObject, Context, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; use std::fmt; @@ -34,23 +34,31 @@ impl PyNativeFuncDef { pub fn build_function(self, ctx: &Context) -> PyRef { self.into_function().into_ref(ctx) } - pub fn build_method(self, ctx: &Context, class: PyTypeRef) -> PyRef { + pub fn build_method(self, ctx: &Context, class: &'static Py) -> PyRef { PyRef::new_ref( PyBuiltinMethod { value: self, class }, - ctx.types.method_descriptor_type.clone(), + ctx.types.method_descriptor_type.to_owned(), None, ) } - pub fn build_classmethod(self, ctx: &Context, class: PyTypeRef) -> PyRef { + pub fn build_classmethod( + self, + ctx: &Context, + class: &'static Py, + ) -> PyRef { // TODO: classmethod_descriptor - let callable = self.build_method(ctx, class).into(); + let callable: PyObjectRef = self.build_method(ctx, class).into(); PyClassMethod::new_ref(callable, ctx) } - pub fn build_staticmethod(self, ctx: &Context, class: PyTypeRef) -> PyRef { + pub fn build_staticmethod( + self, + ctx: &Context, + class: &'static Py, + ) -> PyRef { let callable = self.build_method(ctx, class).into(); PyRef::new_ref( PyStaticMethod { callable }, - ctx.types.staticmethod_type.clone(), + ctx.types.staticmethod_type.to_owned(), None, ) } @@ -63,8 +71,9 @@ pub struct PyBuiltinFunction { } impl PyPayload for PyBuiltinFunction { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.builtin_function_or_method_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.builtin_function_or_method_type } } @@ -89,14 +98,6 @@ impl PyBuiltinFunction { self } - pub fn into_ref(self, ctx: &Context) -> PyRef { - PyRef::new_ref( - self, - ctx.types.builtin_function_or_method_type.clone(), - None, - ) - } - pub fn as_func(&self) -> &PyNativeFunc { &self.value.func } @@ -164,12 +165,13 @@ impl Unconstructible for PyBuiltinFunction {} #[pyclass(module = false, name = "method_descriptor")] pub struct PyBuiltinMethod { value: PyNativeFuncDef, - class: PyTypeRef, + class: &'static Py, } impl PyPayload for PyBuiltinMethod { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.method_descriptor_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.method_descriptor_type } } @@ -193,7 +195,9 @@ impl GetDescriptor for PyBuiltinMethod { let r = if vm.is_none(&obj) && !Self::_cls_is(&cls, &obj.class()) { zelf.into() } else { - PyBoundMethod::new_ref(obj, zelf.into(), &vm.ctx).into() + PyBoundMethod::new(obj, zelf.into()) + .into_ref(&vm.ctx) + .into() }; Ok(r) } @@ -210,7 +214,7 @@ impl Callable for PyBuiltinMethod { impl PyBuiltinMethod { pub fn new_ref( name: impl Into, - class: PyTypeRef, + class: &'static Py, f: F, ctx: &Context, ) -> PyRef @@ -254,6 +258,6 @@ impl PyBuiltinMethod { impl Unconstructible for PyBuiltinMethod {} pub fn init(context: &Context) { - PyBuiltinFunction::extend_class(context, &context.types.builtin_function_or_method_type); - PyBuiltinMethod::extend_class(context, &context.types.method_descriptor_type); + PyBuiltinFunction::extend_class(context, context.types.builtin_function_or_method_type); + PyBuiltinMethod::extend_class(context, context.types.method_descriptor_type); } diff --git a/vm/src/builtins/bytearray.rs b/vm/src/builtins/bytearray.rs index 21e3ac1b10..a242d47794 100644 --- a/vm/src/builtins/bytearray.rs +++ b/vm/src/builtins/bytearray.rs @@ -1,11 +1,10 @@ //! Implementation of the python bytearray object. use super::{ PositionIterInternal, PyBytes, PyBytesRef, PyDictRef, PyIntRef, PyStrRef, PyTuple, PyTupleRef, - PyTypeRef, + PyType, PyTypeRef, }; use crate::{ anystr::{self, AnyStr}, - builtins::PyType, bytesinner::{ bytes_decode, bytes_from_object, value_from_object, ByteInnerFindOptions, ByteInnerNewOptions, ByteInnerPaddingOptions, ByteInnerSplitOptions, @@ -49,10 +48,6 @@ pub struct PyByteArray { pub type PyByteArrayRef = PyRef; impl PyByteArray { - pub fn new_ref(data: Vec, ctx: &Context) -> PyRef { - PyRef::new_ref(Self::from(data), ctx.types.bytearray_type.clone(), None) - } - fn from_inner(inner: PyBytesInner) -> Self { PyByteArray { inner: PyRwLock::new(inner), @@ -82,15 +77,16 @@ impl From> for PyByteArray { } impl PyPayload for PyByteArray { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.bytearray_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.bytearray_type } } /// Fill bytearray class methods dictionary. pub(crate) fn init(context: &Context) { - PyByteArray::extend_class(context, &context.types.bytearray_type); - PyByteArrayIterator::extend_class(context, &context.types.bytearray_iterator_type); + PyByteArray::extend_class(context, context.types.bytearray_type); + PyByteArrayIterator::extend_class(context, context.types.bytearray_iterator_type); } #[pyimpl( @@ -215,7 +211,7 @@ impl PyByteArray { SequenceIndex::Slice(slice) => self .borrow_buf() .get_item_by_slice(vm, slice) - .map(|x| Self::new_ref(x, &vm.ctx).into()), + .map(|x| vm.ctx.new_bytearray(x).into()), } } @@ -548,11 +544,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] @@ -561,11 +554,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] @@ -575,9 +565,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()), ))) } @@ -586,9 +577,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()), ))) } @@ -600,7 +592,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] @@ -862,8 +854,9 @@ pub struct PyByteArrayIterator { } impl PyPayload for PyByteArrayIterator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.bytearray_iterator_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.bytearray_iterator_type } } diff --git a/vm/src/builtins/bytes.rs b/vm/src/builtins/bytes.rs index b03d41e12a..a7300b2ee4 100644 --- a/vm/src/builtins/bytes.rs +++ b/vm/src/builtins/bytes.rs @@ -1,7 +1,8 @@ -use super::{PositionIterInternal, PyDictRef, PyIntRef, PyStrRef, PyTuple, PyTupleRef, PyTypeRef}; +use super::{ + PositionIterInternal, PyDictRef, PyIntRef, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef, +}; use crate::{ anystr::{self, AnyStr}, - builtins::PyType, bytesinner::{ bytes_decode, ByteInnerFindOptions, ByteInnerNewOptions, ByteInnerPaddingOptions, ByteInnerSplitOptions, ByteInnerTranslateOptions, DecodeArgs, PyBytesInner, @@ -74,14 +75,15 @@ impl AsRef<[u8]> for PyBytesRef { } impl PyPayload for PyBytes { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.bytes_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.bytes_type } } pub(crate) fn init(context: &Context) { - PyBytes::extend_class(context, &context.types.bytes_type); - PyBytesIterator::extend_class(context, &context.types.bytes_iterator_type); + PyBytes::extend_class(context, context.types.bytes_type); + PyBytesIterator::extend_class(context, context.types.bytes_iterator_type); } impl Constructor for PyBytes { @@ -92,12 +94,6 @@ impl Constructor for PyBytes { } } -impl PyBytes { - pub fn new_ref(data: Vec, ctx: &Context) -> PyRef { - PyRef::new_ref(Self::from(data), ctx.types.bytes_type.clone(), None) - } -} - #[pyimpl( flags(BASETYPE), with( @@ -134,10 +130,10 @@ impl PyBytes { #[pymethod(magic)] fn bytes(zelf: PyRef, vm: &VirtualMachine) -> PyRef { - if zelf.is(&vm.ctx.types.bytes_type) { + if zelf.is(vm.ctx.types.bytes_type) { zelf } else { - PyBytes::from(zelf.inner.clone()).into_ref(vm) + PyBytes::from(zelf.inner.clone()).into_ref(&vm.ctx) } } @@ -480,7 +476,7 @@ impl PyBytes { #[pymethod(name = "__rmul__")] #[pymethod(magic)] fn mul(zelf: PyRef, value: isize, vm: &VirtualMachine) -> PyResult> { - if value == 1 && zelf.class().is(&vm.ctx.types.bytes_type) { + if value == 1 && zelf.class().is(vm.ctx.types.bytes_type) { // Special case: when some `bytes` is multiplied by `1`, // nothing really happens, we need to return an object itself // with the same `id()` to be compatible with CPython. @@ -489,7 +485,7 @@ impl PyBytes { } zelf.inner .mul(value, vm) - .map(|x| Self::from(x).into_ref(vm)) + .map(|x| Self::from(x).into_ref(&vm.ctx)) } #[pymethod(name = "__mod__")] @@ -633,7 +629,7 @@ impl Comparable for PyBytes { ) -> PyResult { Ok(if let Some(res) = op.identical_optimization(zelf, other) { res.into() - } else if other.fast_isinstance(&vm.ctx.types.memoryview_type) + } else if other.fast_isinstance(vm.ctx.types.memoryview_type) && op != PyComparisonOp::Eq && op != PyComparisonOp::Ne { @@ -665,8 +661,9 @@ pub struct PyBytesIterator { } impl PyPayload for PyBytesIterator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.bytes_iterator_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.bytes_iterator_type } } diff --git a/vm/src/builtins/classmethod.rs b/vm/src/builtins/classmethod.rs index a01dc4569b..0280237c08 100644 --- a/vm/src/builtins/classmethod.rs +++ b/vm/src/builtins/classmethod.rs @@ -1,9 +1,8 @@ -use super::PyTypeRef; +use super::{PyBoundMethod, PyType, PyTypeRef}; use crate::{ - builtins::PyBoundMethod, class::PyClassImpl, types::{Constructor, GetDescriptor}, - AsObject, Context, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + AsObject, Context, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; /// classmethod(function) -> method @@ -39,8 +38,9 @@ impl From for PyClassMethod { } impl PyPayload for PyClassMethod { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.classmethod_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.classmethod_type } } @@ -53,7 +53,9 @@ impl GetDescriptor for PyClassMethod { ) -> PyResult { let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?; let cls = cls.unwrap_or_else(|| obj.class().clone().into()); - Ok(PyBoundMethod::new_ref(cls, zelf.callable.clone(), &vm.ctx).into()) + Ok(PyBoundMethod::new(cls, zelf.callable.clone()) + .into_ref(&vm.ctx) + .into()) } } @@ -67,12 +69,6 @@ impl Constructor for PyClassMethod { } } -impl PyClassMethod { - pub fn new_ref(callable: PyObjectRef, ctx: &Context) -> PyRef { - PyRef::new_ref(Self { callable }, ctx.types.classmethod_type.clone(), None) - } -} - #[pyimpl(with(GetDescriptor, Constructor), flags(BASETYPE, HAS_DICT))] impl PyClassMethod { #[pyproperty(magic)] @@ -96,5 +92,5 @@ impl PyClassMethod { } pub(crate) fn init(context: &Context) { - PyClassMethod::extend_class(context, &context.types.classmethod_type); + PyClassMethod::extend_class(context, context.types.classmethod_type); } diff --git a/vm/src/builtins/code.rs b/vm/src/builtins/code.rs index c0f216f13e..df998cfbc6 100644 --- a/vm/src/builtins/code.rs +++ b/vm/src/builtins/code.rs @@ -2,13 +2,13 @@ */ -use super::{PyStrRef, PyTupleRef, PyTypeRef}; +use super::{PyStrRef, PyTupleRef, PyType, PyTypeRef}; use crate::{ bytecode::{self, BorrowedConstant, Constant, ConstantBag}, class::{PyClassImpl, StaticType}, convert::ToPyObject, function::FuncArgs, - AsObject, Context, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; use num_traits::Zero; use std::{borrow::Borrow, fmt, ops::Deref}; @@ -104,7 +104,7 @@ impl ConstantBag for PyObjBag<'_> { } fn make_name(&self, name: &str) -> PyStrRef { - self.0.intern_str(name).to_str() + self.0.intern_str(name).to_owned() } } @@ -151,8 +151,9 @@ impl fmt::Debug for PyCode { } impl PyPayload for PyCode { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.code_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.code_type } } @@ -250,5 +251,5 @@ impl ToPyObject for bytecode::CodeObject { } pub fn init(ctx: &Context) { - PyRef::::extend_class(ctx, &ctx.types.code_type); + PyRef::::extend_class(ctx, ctx.types.code_type); } diff --git a/vm/src/builtins/complex.rs b/vm/src/builtins/complex.rs index f33d4856f7..57685089c8 100644 --- a/vm/src/builtins/complex.rs +++ b/vm/src/builtins/complex.rs @@ -1,4 +1,4 @@ -use super::{float, PyStr, PyTypeRef}; +use super::{float, PyStr, PyType, PyTypeRef}; use crate::{ class::PyClassImpl, convert::ToPyObject, @@ -8,7 +8,7 @@ use crate::{ PyComparisonValue, }, types::{Comparable, Constructor, Hashable, PyComparisonOp}, - AsObject, Context, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; use num_complex::Complex64; use num_traits::Zero; @@ -24,14 +24,15 @@ pub struct PyComplex { } impl PyPayload for PyComplex { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.complex_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.complex_type } } impl ToPyObject for Complex64 { fn to_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { - PyComplex::new_ref(self, &vm.ctx).into() + PyComplex::from(self).to_pyobject(vm) } } @@ -72,7 +73,7 @@ impl PyObjectRef { } pub fn init(context: &Context) { - PyComplex::extend_class(context, &context.types.complex_type); + PyComplex::extend_class(context, context.types.complex_type); } fn to_op_complex(value: &PyObject, vm: &VirtualMachine) -> PyResult> { @@ -120,7 +121,7 @@ impl Constructor for PyComplex { let (real, real_was_complex) = match args.real { OptionalArg::Missing => (Complex64::new(0.0, 0.0), false), OptionalArg::Present(val) => { - let val = if cls.is(&vm.ctx.types.complex_type) && imag_missing { + let val = if cls.is(vm.ctx.types.complex_type) && imag_missing { match val.downcast_exact::(vm) { Ok(c) => { return Ok(c.into()); @@ -161,7 +162,7 @@ impl Constructor for PyComplex { OptionalArg::Present(obj) => { if let Some(c) = obj.try_complex(vm)? { c - } else if obj.class().fast_issubclass(&vm.ctx.types.str_type) { + } else if obj.class().fast_issubclass(vm.ctx.types.str_type) { return Err( vm.new_type_error("complex() second arg can't be a string".to_owned()) ); @@ -193,10 +194,6 @@ impl Constructor for PyComplex { } impl PyComplex { - pub fn new_ref(value: Complex64, ctx: &Context) -> PyRef { - PyRef::new_ref(Self::from(value), ctx.types.complex_type.clone(), None) - } - pub fn to_complex(&self) -> Complex64 { self.value } @@ -206,10 +203,10 @@ impl PyComplex { impl PyComplex { #[pymethod(magic)] fn complex(zelf: PyRef, vm: &VirtualMachine) -> PyRef { - if zelf.is(&vm.ctx.types.complex_type) { + if zelf.is(vm.ctx.types.complex_type) { zelf } else { - PyComplex::from(zelf.value).into_ref(vm) + PyComplex::from(zelf.value).into_ref(&vm.ctx) } } diff --git a/vm/src/builtins/coroutine.rs b/vm/src/builtins/coroutine.rs index 8a4de8cdd7..0b19ff77d5 100644 --- a/vm/src/builtins/coroutine.rs +++ b/vm/src/builtins/coroutine.rs @@ -1,4 +1,4 @@ -use super::{PyCode, PyStrRef, PyTypeRef}; +use super::{PyCode, PyStrRef, PyType}; use crate::{ class::PyClassImpl, coroutine::Coro, @@ -6,7 +6,7 @@ use crate::{ function::OptionalArg, protocol::PyIterReturn, types::{Constructor, IterNext, IterNextIterable, Unconstructible}, - AsObject, Context, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; #[pyclass(module = false, name = "coroutine")] @@ -17,8 +17,9 @@ pub struct PyCoroutine { } impl PyPayload for PyCoroutine { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.coroutine_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.coroutine_type } } @@ -121,8 +122,9 @@ pub struct PyCoroutineWrapper { } impl PyPayload for PyCoroutineWrapper { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.coroutine_wrapper_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.coroutine_wrapper_type } } @@ -153,6 +155,6 @@ impl IterNext for PyCoroutineWrapper { } pub fn init(ctx: &Context) { - PyCoroutine::extend_class(ctx, &ctx.types.coroutine_type); - PyCoroutineWrapper::extend_class(ctx, &ctx.types.coroutine_wrapper_type); + PyCoroutine::extend_class(ctx, ctx.types.coroutine_type); + PyCoroutineWrapper::extend_class(ctx, ctx.types.coroutine_wrapper_type); } diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index 9c1f0e8ed3..2e1402bf8b 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -53,16 +53,13 @@ impl fmt::Debug for PyDict { } impl PyPayload for PyDict { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.dict_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.dict_type } } impl PyDict { - pub fn new_ref(ctx: &Context) -> PyRef { - PyRef::new_ref(Self::default(), ctx.types.dict_type.clone(), None) - } - /// escape hatch to access the underlying data structure directly. prefer adding a method on /// PyDict instead of using this pub(crate) fn _as_dict_inner(&self) -> &DictContentType { @@ -519,7 +516,7 @@ impl Iterable for PyDict { impl Py { #[inline] fn exact_dict(&self, vm: &VirtualMachine) -> bool { - self.class().is(&vm.ctx.types.dict_type) + self.class().is(vm.ctx.types.dict_type) } fn missing_opt( @@ -568,7 +565,7 @@ impl Py { } else { match self.as_object().get_item(key, vm) { Ok(value) => Ok(Some(value)), - Err(e) if e.fast_isinstance(&vm.ctx.exceptions.key_error) => { + Err(e) if e.fast_isinstance(vm.ctx.exceptions.key_error) => { self.missing_opt(key, vm) } Err(e) => Err(e), @@ -748,8 +745,9 @@ macro_rules! dict_view { } impl PyPayload for $name { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.$class + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.$class } } @@ -761,8 +759,9 @@ macro_rules! dict_view { } impl PyPayload for $iter_name { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.$iter_class + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.$iter_class } } @@ -834,8 +833,9 @@ macro_rules! dict_view { } impl PyPayload for $reverse_iter_name { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.$reverse_iter_class + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.$reverse_iter_class } } @@ -1011,7 +1011,7 @@ trait ViewSetOps: DictView { zelf.dict(), dictview.dict(), op, - !zelf.class().is(&vm.ctx.types.dict_keys_type), + !zelf.class().is(vm.ctx.types.dict_keys_type), vm, ) } @@ -1145,17 +1145,14 @@ impl PyDictValues { } pub(crate) fn init(context: &Context) { - PyDict::extend_class(context, &context.types.dict_type); - PyDictKeys::extend_class(context, &context.types.dict_keys_type); - PyDictKeyIterator::extend_class(context, &context.types.dict_keyiterator_type); - PyDictReverseKeyIterator::extend_class(context, &context.types.dict_reversekeyiterator_type); - PyDictValues::extend_class(context, &context.types.dict_values_type); - PyDictValueIterator::extend_class(context, &context.types.dict_valueiterator_type); - PyDictReverseValueIterator::extend_class( - context, - &context.types.dict_reversevalueiterator_type, - ); - PyDictItems::extend_class(context, &context.types.dict_items_type); - PyDictItemIterator::extend_class(context, &context.types.dict_itemiterator_type); - PyDictReverseItemIterator::extend_class(context, &context.types.dict_reverseitemiterator_type); + PyDict::extend_class(context, context.types.dict_type); + PyDictKeys::extend_class(context, context.types.dict_keys_type); + PyDictKeyIterator::extend_class(context, context.types.dict_keyiterator_type); + PyDictReverseKeyIterator::extend_class(context, context.types.dict_reversekeyiterator_type); + PyDictValues::extend_class(context, context.types.dict_values_type); + PyDictValueIterator::extend_class(context, context.types.dict_valueiterator_type); + PyDictReverseValueIterator::extend_class(context, context.types.dict_reversevalueiterator_type); + PyDictItems::extend_class(context, context.types.dict_items_type); + PyDictItemIterator::extend_class(context, context.types.dict_itemiterator_type); + PyDictReverseItemIterator::extend_class(context, context.types.dict_reverseitemiterator_type); } diff --git a/vm/src/builtins/enumerate.rs b/vm/src/builtins/enumerate.rs index a71f0c51a1..153e9b3e97 100644 --- a/vm/src/builtins/enumerate.rs +++ b/vm/src/builtins/enumerate.rs @@ -1,4 +1,6 @@ -use super::{IterStatus, PositionIterInternal, PyGenericAlias, PyIntRef, PyTupleRef, PyTypeRef}; +use super::{ + IterStatus, PositionIterInternal, PyGenericAlias, PyIntRef, PyTupleRef, PyType, PyTypeRef, +}; use crate::common::lock::{PyMutex, PyRwLock}; use crate::{ class::PyClassImpl, @@ -6,7 +8,7 @@ use crate::{ function::OptionalArg, protocol::{PyIter, PyIterReturn}, types::{Constructor, IterNext, IterNextIterable}, - AsObject, Context, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; use num_bigint::BigInt; use num_traits::Zero; @@ -19,8 +21,9 @@ pub struct PyEnumerate { } impl PyPayload for PyEnumerate { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.enumerate_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.enumerate_type } } @@ -85,8 +88,9 @@ pub struct PyReverseSequenceIterator { } impl PyPayload for PyReverseSequenceIterator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.reverse_iter_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.reverse_iter_type } } @@ -133,6 +137,6 @@ impl IterNext for PyReverseSequenceIterator { } pub fn init(context: &Context) { - PyEnumerate::extend_class(context, &context.types.enumerate_type); - PyReverseSequenceIterator::extend_class(context, &context.types.reverse_iter_type); + PyEnumerate::extend_class(context, context.types.enumerate_type); + PyReverseSequenceIterator::extend_class(context, context.types.reverse_iter_type); } diff --git a/vm/src/builtins/filter.rs b/vm/src/builtins/filter.rs index 39bf70e57e..6362d4dcf7 100644 --- a/vm/src/builtins/filter.rs +++ b/vm/src/builtins/filter.rs @@ -1,9 +1,9 @@ -use super::PyTypeRef; +use super::{PyType, PyTypeRef}; use crate::{ class::PyClassImpl, protocol::{PyIter, PyIterReturn}, types::{Constructor, IterNext, IterNextIterable}, - Context, PyObjectRef, PyPayload, PyResult, VirtualMachine, + Context, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; /// filter(function or None, iterable) --> filter object @@ -18,8 +18,9 @@ pub struct PyFilter { } impl PyPayload for PyFilter { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.filter_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.filter_type } } @@ -41,7 +42,7 @@ impl PyFilter { #[pymethod(magic)] fn reduce(&self, vm: &VirtualMachine) -> (PyTypeRef, (PyObjectRef, PyIter)) { ( - vm.ctx.types.filter_type.clone(), + vm.ctx.types.filter_type.to_owned(), (self.predicate.clone(), self.iterator.clone()), ) } @@ -74,5 +75,5 @@ impl IterNext for PyFilter { } pub fn init(context: &Context) { - PyFilter::extend_class(context, &context.types.filter_type); + PyFilter::extend_class(context, context.types.filter_type); } diff --git a/vm/src/builtins/float.rs b/vm/src/builtins/float.rs index 5040ab3582..f0fdfadcfe 100644 --- a/vm/src/builtins/float.rs +++ b/vm/src/builtins/float.rs @@ -1,4 +1,6 @@ -use super::{try_bigint_to_f64, PyByteArray, PyBytes, PyInt, PyIntRef, PyStr, PyStrRef, PyTypeRef}; +use super::{ + try_bigint_to_f64, PyByteArray, PyBytes, PyInt, PyIntRef, PyStr, PyStrRef, PyType, PyTypeRef, +}; use crate::common::{float_ops, hash}; use crate::{ class::PyClassImpl, @@ -10,8 +12,8 @@ use crate::{ PyComparisonValue, }, types::{Comparable, Constructor, Hashable, PyComparisonOp}, - AsObject, Context, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromBorrowedObject, - TryFromObject, VirtualMachine, + AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, + TryFromBorrowedObject, TryFromObject, VirtualMachine, }; use num_bigint::{BigInt, ToBigInt}; use num_complex::Complex64; @@ -32,8 +34,9 @@ impl PyFloat { } impl PyPayload for PyFloat { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.float_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.float_type } } @@ -167,7 +170,7 @@ impl Constructor for PyFloat { let float_val = match arg { OptionalArg::Missing => 0.0, OptionalArg::Present(val) => { - let val = if cls.is(&vm.ctx.types.float_type) { + let val = if cls.is(vm.ctx.types.float_type) { match val.downcast_exact::(vm) { Ok(f) => return Ok(f.into()), Err(val) => val, @@ -566,5 +569,5 @@ pub(crate) fn get_value(obj: &PyObject) -> f64 { #[rustfmt::skip] // to avoid line splitting pub fn init(context: &Context) { - PyFloat::extend_class(context, &context.types.float_type); + PyFloat::extend_class(context, context.types.float_type); } diff --git a/vm/src/builtins/frame.rs b/vm/src/builtins/frame.rs index e0b119cef3..38fc48b7b0 100644 --- a/vm/src/builtins/frame.rs +++ b/vm/src/builtins/frame.rs @@ -11,7 +11,7 @@ use crate::{ }; pub fn init(context: &Context) { - FrameRef::extend_class(context, &context.types.frame_type); + FrameRef::extend_class(context, context.types.frame_type); } #[pyimpl(with(Constructor, PyRef))] diff --git a/vm/src/builtins/function.rs b/vm/src/builtins/function.rs index bf1451c920..40519bdb28 100644 --- a/vm/src/builtins/function.rs +++ b/vm/src/builtins/function.rs @@ -3,7 +3,7 @@ mod jitfunc; use super::{ tuple::PyTupleTyped, PyAsyncGen, PyCode, PyCoroutine, PyDictRef, PyGenerator, PyStr, PyStrRef, - PyTupleRef, PyTypeRef, + PyTupleRef, PyType, PyTypeRef, }; use crate::common::lock::PyMutex; use crate::function::ArgMapping; @@ -300,7 +300,7 @@ impl PyFunction { self.closure.as_ref().map_or(&[], |c| c.as_slice()), vm, ) - .into_ref(vm); + .into_ref(&vm.ctx); self.fill_locals_from_args(&frame, func_args, vm)?; @@ -322,8 +322,9 @@ impl PyFunction { } impl PyPayload for PyFunction { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.function_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.function_type } } @@ -410,7 +411,9 @@ impl GetDescriptor for PyFunction { let obj = if vm.is_none(&obj) && !Self::_cls_is(&cls, &obj.class()) { zelf.into() } else { - PyBoundMethod::new_ref(obj, zelf.into(), &vm.ctx).into() + PyBoundMethod::new(obj, zelf.into()) + .into_ref(&vm.ctx) + .into() }; Ok(obj) } @@ -489,17 +492,9 @@ impl Constructor for PyBoundMethod { } impl PyBoundMethod { - fn new(object: PyObjectRef, function: PyObjectRef) -> Self { + pub fn new(object: PyObjectRef, function: PyObjectRef) -> Self { PyBoundMethod { object, function } } - - pub fn new_ref(object: PyObjectRef, function: PyObjectRef, ctx: &Context) -> PyRef { - PyRef::new_ref( - Self::new(object, function), - ctx.types.bound_method_type.clone(), - None, - ) - } } #[pyimpl(with(Callable, Comparable, GetAttr, Constructor), flags(HAS_DICT))] @@ -545,7 +540,7 @@ impl PyBoundMethod { fn qualname(&self, vm: &VirtualMachine) -> PyResult { if self .function - .fast_isinstance(&vm.ctx.types.builtin_function_or_method_type) + .fast_isinstance(vm.ctx.types.builtin_function_or_method_type) { // Special case: we work with `__new__`, which is not really a method. // It is a function, so its `__qualname__` is just `__new__`. @@ -565,8 +560,9 @@ impl PyBoundMethod { } impl PyPayload for PyBoundMethod { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.bound_method_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.bound_method_type } } @@ -578,8 +574,9 @@ pub(crate) struct PyCell { pub(crate) type PyCellRef = PyRef; impl PyPayload for PyCell { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.cell_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.cell_type } } @@ -624,7 +621,7 @@ impl PyCell { } pub fn init(context: &Context) { - PyFunction::extend_class(context, &context.types.function_type); - PyBoundMethod::extend_class(context, &context.types.bound_method_type); - PyCell::extend_class(context, &context.types.cell_type); + PyFunction::extend_class(context, context.types.function_type); + PyBoundMethod::extend_class(context, context.types.bound_method_type); + PyCell::extend_class(context, context.types.cell_type); } diff --git a/vm/src/builtins/function/jitfunc.rs b/vm/src/builtins/function/jitfunc.rs index 6d7f4ddb08..b88d9e8784 100644 --- a/vm/src/builtins/function/jitfunc.rs +++ b/vm/src/builtins/function/jitfunc.rs @@ -38,17 +38,17 @@ impl ToPyObject for AbiValue { } pub fn new_jit_error(msg: String, vm: &VirtualMachine) -> PyBaseExceptionRef { - let jit_error = vm.ctx.exceptions.jit_error.clone(); + let jit_error = vm.ctx.exceptions.jit_error.to_owned(); vm.new_exception_msg(jit_error, msg) } fn get_jit_arg_type(dict: &PyDictRef, name: &str, vm: &VirtualMachine) -> PyResult { if let Some(value) = dict.get_item_opt(name, vm)? { - if value.is(&vm.ctx.types.int_type) { + if value.is(vm.ctx.types.int_type) { Ok(JitType::Int) - } else if value.is(&vm.ctx.types.float_type) { + } else if value.is(vm.ctx.types.float_type) { Ok(JitType::Float) - } else if value.is(&vm.ctx.types.bool_type) { + } else if value.is(vm.ctx.types.bool_type) { Ok(JitType::Bool) } else { Err(new_jit_error( @@ -112,14 +112,14 @@ pub fn get_jit_arg_types( fn get_jit_value(vm: &VirtualMachine, obj: &PyObject) -> Result { // This does exact type checks as subclasses of int/float can't be passed to jitted functions let cls = obj.class(); - if cls.is(&vm.ctx.types.int_type) { + if cls.is(vm.ctx.types.int_type) { int::get_value(obj) .to_i64() .map(AbiValue::Int) .ok_or(ArgsError::IntOverflow) - } else if cls.is(&vm.ctx.types.float_type) { + } else if cls.is(vm.ctx.types.float_type) { Ok(AbiValue::Float(float::get_value(obj))) - } else if cls.is(&vm.ctx.types.bool_type) { + } else if cls.is(vm.ctx.types.bool_type) { Ok(AbiValue::Bool(bool_::get_value(obj))) } else { Err(ArgsError::NonJitType) diff --git a/vm/src/builtins/generator.rs b/vm/src/builtins/generator.rs index 00000e9997..4a102fb378 100644 --- a/vm/src/builtins/generator.rs +++ b/vm/src/builtins/generator.rs @@ -2,7 +2,7 @@ * The mythical generator. */ -use super::{PyCode, PyStrRef, PyTypeRef}; +use super::{PyCode, PyStrRef, PyType}; use crate::{ class::PyClassImpl, coroutine::Coro, @@ -10,7 +10,7 @@ use crate::{ function::OptionalArg, protocol::PyIterReturn, types::{Constructor, IterNext, IterNextIterable, Unconstructible}, - AsObject, Context, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; #[pyclass(module = false, name = "generator")] @@ -20,8 +20,9 @@ pub struct PyGenerator { } impl PyPayload for PyGenerator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.generator_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.generator_type } } @@ -106,5 +107,5 @@ impl IterNext for PyGenerator { } pub fn init(ctx: &Context) { - PyGenerator::extend_class(ctx, &ctx.types.generator_type); + PyGenerator::extend_class(ctx, ctx.types.generator_type); } diff --git a/vm/src/builtins/genericalias.rs b/vm/src/builtins/genericalias.rs index 7ef891b8ae..da9fb6b5cb 100644 --- a/vm/src/builtins/genericalias.rs +++ b/vm/src/builtins/genericalias.rs @@ -36,8 +36,9 @@ impl fmt::Debug for PyGenericAlias { } impl PyPayload for PyGenericAlias { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.generic_alias_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.generic_alias_type } } @@ -163,7 +164,7 @@ impl PyGenericAlias { #[pymethod(magic)] fn reduce(zelf: PyRef, vm: &VirtualMachine) -> (PyTypeRef, (PyTypeRef, PyTupleRef)) { ( - vm.ctx.types.generic_alias_type.clone(), + vm.ctx.types.generic_alias_type.to_owned(), (zelf.origin.clone(), zelf.args.clone()), ) } @@ -323,8 +324,8 @@ impl Callable for PyGenericAlias { fn call(zelf: &crate::Py, args: FuncArgs, vm: &VirtualMachine) -> PyResult { PyType::call(&zelf.origin, args, vm).map(|obj| { if let Err(exc) = obj.set_attr("__orig_class__", zelf.to_owned(), vm) { - if !exc.fast_isinstance(&vm.ctx.exceptions.attribute_error) - && !exc.fast_isinstance(&vm.ctx.exceptions.type_error) + if !exc.fast_isinstance(vm.ctx.exceptions.attribute_error) + && !exc.fast_isinstance(vm.ctx.exceptions.type_error) { return Err(exc); } diff --git a/vm/src/builtins/getset.rs b/vm/src/builtins/getset.rs index da46f9ebac..e287d6beaf 100644 --- a/vm/src/builtins/getset.rs +++ b/vm/src/builtins/getset.rs @@ -1,14 +1,14 @@ /*! Python `attribute` descriptor class. (PyGetSet) */ -use super::PyTypeRef; +use super::PyType; use crate::{ class::PyClassImpl, convert::ToPyResult, function::{OwnedParam, RefParam}, object::PyThreadingConstraint, types::{Constructor, GetDescriptor, Unconstructible}, - AsObject, Context, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, + AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, }; pub type PyGetterFunc = Box PyResult)>; @@ -210,7 +210,7 @@ where #[pyclass(module = false, name = "getset_descriptor")] pub struct PyGetSet { name: String, - class: PyTypeRef, + class: &'static Py, getter: Option, setter: Option, deleter: Option, @@ -238,8 +238,9 @@ impl std::fmt::Debug for PyGetSet { } impl PyPayload for PyGetSet { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.getset_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.getset_type } } @@ -260,14 +261,14 @@ impl GetDescriptor for PyGetSet { Err(vm.new_attribute_error(format!( "attribute '{}' of '{}' objects is not readable", zelf.name, - Self::class(vm).name() + Self::class(&vm.ctx).name() ))) } } } impl PyGetSet { - pub fn new(name: String, class: PyTypeRef) -> Self { + pub fn new(name: String, class: &'static Py) -> Self { Self { name, class, @@ -366,5 +367,5 @@ impl PyGetSet { impl Unconstructible for PyGetSet {} pub(crate) fn init(context: &Context) { - PyGetSet::extend_class(context, &context.types.getset_type); + PyGetSet::extend_class(context, context.types.getset_type); } diff --git a/vm/src/builtins/int.rs b/vm/src/builtins/int.rs index 6710f238ad..e7d8a720da 100644 --- a/vm/src/builtins/int.rs +++ b/vm/src/builtins/int.rs @@ -1,4 +1,4 @@ -use super::{float, PyByteArray, PyBytes, PyStr, PyStrRef, PyTypeRef}; +use super::{float, PyByteArray, PyBytes, PyStr, PyStrRef, PyType, PyTypeRef}; use crate::{ bytesinner::PyBytesInner, class::PyClassImpl, @@ -10,8 +10,8 @@ use crate::{ PyComparisonValue, }, types::{Comparable, Constructor, Hashable, PyComparisonOp}, - AsObject, Context, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromBorrowedObject, - VirtualMachine, + AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, + TryFromBorrowedObject, VirtualMachine, }; use bstr::ByteSlice; use num_bigint::{BigInt, BigUint, Sign}; @@ -57,8 +57,9 @@ where } impl PyPayload for PyInt { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.int_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.int_type } fn into_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { @@ -252,7 +253,7 @@ impl Constructor for PyInt { })?; try_int_radix(&val, base, vm) } else { - let val = if cls.is(&vm.ctx.types.int_type) { + let val = if cls.is(vm.ctx.types.int_type) { match val.downcast_exact::(vm) { Ok(i) => { return Ok(i.to_pyobject(vm)); @@ -280,9 +281,9 @@ impl PyInt { where T: Into + ToPrimitive, { - if cls.is(&vm.ctx.types.int_type) { + if cls.is(vm.ctx.types.int_type) { Ok(vm.ctx.new_int(value)) - } else if cls.is(&vm.ctx.types.bool_type) { + } else if cls.is(vm.ctx.types.bool_type) { Ok(vm.ctx.new_bool(!value.into().eq(&BigInt::zero()))) } else { PyInt::from(value).into_ref_with_type(vm, cls) @@ -690,7 +691,7 @@ impl PyInt { #[inline] fn clone_if_subclass(zelf: PyRef, vm: &VirtualMachine) -> PyRef { - if zelf.class().is(&vm.ctx.types.int_type) { + if zelf.class().is(vm.ctx.types.int_type) { return zelf; } @@ -986,7 +987,7 @@ pub(crate) fn try_int(obj: &PyObject, vm: &VirtualMachine) -> PyResult { } pub(crate) fn init(context: &Context) { - PyInt::extend_class(context, &context.types.int_type); + PyInt::extend_class(context, context.types.int_type); } #[test] diff --git a/vm/src/builtins/iter.rs b/vm/src/builtins/iter.rs index 20832e1caf..4f0d1c68e1 100644 --- a/vm/src/builtins/iter.rs +++ b/vm/src/builtins/iter.rs @@ -2,20 +2,19 @@ * iterator types */ -use std::borrow::Cow; - -use super::{PyInt, PyTupleRef, PyTypeRef}; +use super::{PyInt, PyTupleRef, PyType}; use crate::{ class::PyClassImpl, function::ArgCallable, protocol::{PyIterReturn, PySequence, PySequenceMethods}, types::{IterNext, IterNextIterable}, - Context, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine, + Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; use rustpython_common::{ lock::{PyMutex, PyRwLock, PyRwLockUpgradableReadGuard}, static_cell, }; +use std::borrow::Cow; /// Marks status of iterator. #[derive(Debug, Clone)] @@ -169,8 +168,9 @@ pub struct PySequenceIterator { } impl PyPayload for PySequenceIterator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.iter_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.iter_type } } @@ -227,8 +227,9 @@ pub struct PyCallableIterator { } impl PyPayload for PyCallableIterator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.callable_iterator + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.callable_iterator } } @@ -262,6 +263,6 @@ impl IterNext for PyCallableIterator { } pub fn init(context: &Context) { - PySequenceIterator::extend_class(context, &context.types.iter_type); - PyCallableIterator::extend_class(context, &context.types.callable_iterator); + PySequenceIterator::extend_class(context, context.types.iter_type); + PyCallableIterator::extend_class(context, context.types.callable_iterator); } diff --git a/vm/src/builtins/list.rs b/vm/src/builtins/list.rs index 272e845267..655bd1933f 100644 --- a/vm/src/builtins/list.rs +++ b/vm/src/builtins/list.rs @@ -1,4 +1,4 @@ -use super::{PositionIterInternal, PyGenericAlias, PyTupleRef, PyTypeRef}; +use super::{PositionIterInternal, PyGenericAlias, PyTupleRef, PyType, PyTypeRef}; use crate::common::lock::{ PyMappedRwLockReadGuard, PyMutex, PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard, }; @@ -53,8 +53,9 @@ impl FromIterator for PyList { } impl PyPayload for PyList { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.list_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.list_type } } @@ -65,10 +66,6 @@ impl ToPyObject for Vec { } impl PyList { - pub fn new_ref(elements: Vec, ctx: &Context) -> PyRef { - PyRef::new_ref(Self::from(elements), ctx.types.list_type.clone(), None) - } - pub fn borrow_vec(&self) -> PyMappedRwLockReadGuard<'_, [PyObjectRef]> { PyRwLockReadGuard::map(self.elements.read(), |v| &**v) } @@ -124,7 +121,7 @@ impl PyList { let other = other.payload_if_subclass::(vm).ok_or_else(|| { vm.new_type_error(format!( "Cannot add {} and {}", - Self::class(vm).name(), + Self::class(&vm.ctx).name(), other.class().name() )) })?; @@ -521,8 +518,9 @@ pub struct PyListIterator { } impl PyPayload for PyListIterator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.list_iterator_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.list_iterator_type } } @@ -566,8 +564,9 @@ pub struct PyListReverseIterator { } impl PyPayload for PyListReverseIterator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.list_reverseiterator_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.list_reverseiterator_type } } @@ -608,6 +607,6 @@ pub fn init(context: &Context) { let list_type = &context.types.list_type; PyList::extend_class(context, list_type); - PyListIterator::extend_class(context, &context.types.list_iterator_type); - PyListReverseIterator::extend_class(context, &context.types.list_reverseiterator_type); + PyListIterator::extend_class(context, context.types.list_iterator_type); + PyListReverseIterator::extend_class(context, context.types.list_reverseiterator_type); } diff --git a/vm/src/builtins/map.rs b/vm/src/builtins/map.rs index 3e85727371..dfafe926e6 100644 --- a/vm/src/builtins/map.rs +++ b/vm/src/builtins/map.rs @@ -1,11 +1,11 @@ -use super::PyTypeRef; +use super::{PyType, PyTypeRef}; use crate::{ builtins::PyTupleRef, class::PyClassImpl, function::PosArgs, protocol::{PyIter, PyIterReturn}, types::{Constructor, IterNext, IterNextIterable}, - Context, PyObjectRef, PyPayload, PyResult, VirtualMachine, + Context, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; /// map(func, *iterables) --> map object @@ -20,8 +20,9 @@ pub struct PyMap { } impl PyPayload for PyMap { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.map_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.map_type } } @@ -51,7 +52,7 @@ impl PyMap { fn reduce(&self, vm: &VirtualMachine) -> (PyTypeRef, PyTupleRef) { let mut vec = vec![self.mapper.clone()]; vec.extend(self.iterators.iter().map(|o| o.clone().into())); - (vm.ctx.types.map_type.clone(), vm.new_tuple(vec)) + (vm.ctx.types.map_type.to_owned(), vm.new_tuple(vec)) } } @@ -73,5 +74,5 @@ impl IterNext for PyMap { } pub fn init(context: &Context) { - PyMap::extend_class(context, &context.types.map_type); + PyMap::extend_class(context, context.types.map_type); } diff --git a/vm/src/builtins/mappingproxy.rs b/vm/src/builtins/mappingproxy.rs index 0e054571f0..a4a811226c 100644 --- a/vm/src/builtins/mappingproxy.rs +++ b/vm/src/builtins/mappingproxy.rs @@ -1,15 +1,14 @@ -use std::borrow::Cow; - -use super::{PyDict, PyGenericAlias, PyList, PyStr, PyStrRef, PyTuple, PyTypeRef}; +use super::{PyDict, PyGenericAlias, PyList, PyStr, PyStrRef, PyTuple, PyType, PyTypeRef}; use crate::{ class::PyClassImpl, convert::ToPyObject, function::OptionalArg, protocol::{PyMapping, PyMappingMethods, PySequence, PySequenceMethods}, types::{AsMapping, AsSequence, Constructor, Iterable}, - AsObject, Context, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, + AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, }; +use std::borrow::Cow; #[pyclass(module = false, name = "mappingproxy")] #[derive(Debug)] @@ -24,8 +23,9 @@ enum MappingProxyInner { } impl PyPayload for PyMappingProxy { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.mappingproxy_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.mappingproxy_type } } @@ -96,7 +96,7 @@ impl PyMappingProxy { // let key = PyStrRef::try_from_object(vm, key)?; let key = key .payload::() - .ok_or_else(|| vm.new_downcast_type_error(PyStr::class(vm), key))?; + .ok_or_else(|| vm.new_downcast_type_error(vm.ctx.types.str_type, key))?; Ok(class.attributes.read().contains_key(key.as_str())) } MappingProxyInner::Dict(obj) => PySequence::from(obj.as_ref()).contains(key, vm), @@ -211,5 +211,5 @@ impl Iterable for PyMappingProxy { } pub fn init(context: &Context) { - PyMappingProxy::extend_class(context, &context.types.mappingproxy_type) + PyMappingProxy::extend_class(context, context.types.mappingproxy_type) } diff --git a/vm/src/builtins/memory.rs b/vm/src/builtins/memory.rs index 3eec1abe8e..49b8204a1b 100644 --- a/vm/src/builtins/memory.rs +++ b/vm/src/builtins/memory.rs @@ -1,5 +1,6 @@ use super::{ - PyBytes, PyBytesRef, PyInt, PyListRef, PySlice, PyStr, PyStrRef, PyTuple, PyTupleRef, PyTypeRef, + PyBytes, PyBytesRef, PyInt, PyListRef, PySlice, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, + PyTypeRef, }; use crate::{ buffer::FormatSpec, @@ -254,7 +255,7 @@ impl PyMemoryView { other.init_slice(slice, 0, vm)?; other.init_len(); - Ok(other.into_ref(vm).into()) + Ok(other.into_ref(&vm.ctx).into()) } fn getitem_by_multi_idx(&self, indexes: &[isize], vm: &VirtualMachine) -> PyResult { @@ -520,7 +521,7 @@ impl PyMemoryView { self.try_not_released(vm)?; let mut v = vec![]; self.append_to(&mut v); - Ok(PyBytes::from(v).into_ref(vm)) + Ok(PyBytes::from(v).into_ref(&vm.ctx)) } fn _to_list( @@ -572,7 +573,7 @@ impl PyMemoryView { self.try_not_released(vm)?; let mut other = self.new_view(); other.desc.readonly = true; - Ok(other.into_ref(vm)) + Ok(other.into_ref(&vm.ctx)) } #[pymethod(magic)] @@ -668,7 +669,7 @@ impl PyMemoryView { if shape_ndim == 0 { other.desc.dim_desc = vec![]; other.desc.len = itemsize; - return Ok(other.into_ref(vm)); + return Ok(other.into_ref(&vm.ctx)); } let mut product_shape = itemsize; @@ -699,9 +700,9 @@ impl PyMemoryView { other.desc.dim_desc = dim_descriptor; - Ok(other.into_ref(vm)) + Ok(other.into_ref(&vm.ctx)) } else { - Ok(self.cast_to_1d(format, vm)?.into_ref(vm)) + Ok(self.cast_to_1d(format, vm)?.into_ref(&vm.ctx)) } } @@ -853,7 +854,7 @@ impl PyMemoryView { if self.desc.ndim() == 0 { return VecBuffer::from(data) - .into_ref(vm) + .into_ref(&vm.ctx) .into_pybuffer_with_descriptor(self.desc.clone()); } @@ -874,7 +875,7 @@ impl PyMemoryView { }; VecBuffer::from(data) - .into_ref(vm) + .into_ref(&vm.ctx) .into_pybuffer_with_descriptor(desc) } } @@ -1041,13 +1042,14 @@ impl Hashable for PyMemoryView { } impl PyPayload for PyMemoryView { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.memoryview_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.memoryview_type } } pub(crate) fn init(ctx: &Context) { - PyMemoryView::extend_class(ctx, &ctx.types.memoryview_type) + PyMemoryView::extend_class(ctx, ctx.types.memoryview_type) } fn format_unpack( diff --git a/vm/src/builtins/module.rs b/vm/src/builtins/module.rs index 239a2107e7..000f3f7e40 100644 --- a/vm/src/builtins/module.rs +++ b/vm/src/builtins/module.rs @@ -1,5 +1,5 @@ use super::pystr::IntoPyStrRef; -use super::{PyDictRef, PyStr, PyStrRef, PyTypeRef}; +use super::{PyDictRef, PyStr, PyStrRef, PyType, PyTypeRef}; use crate::{ class::PyClassImpl, convert::ToPyObject, @@ -13,8 +13,9 @@ use crate::{ pub struct PyModule {} impl PyPayload for PyModule { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.module_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.module_type } } @@ -61,7 +62,7 @@ impl PyModule { fn name(zelf: PyRef, vm: &VirtualMachine) -> Option { zelf.as_object() - .generic_getattr_opt(PyStr::from("__name__").into_ref(vm), None, vm) + .generic_getattr_opt(PyStr::from("__name__").into_ref(&vm.ctx), None, vm) .unwrap_or(None) .and_then(|obj| obj.downcast::().ok()) } @@ -143,5 +144,5 @@ impl GetAttr for PyModule { } pub(crate) fn init(context: &Context) { - PyModule::extend_class(context, &context.types.module_type); + PyModule::extend_class(context, context.types.module_type); } diff --git a/vm/src/builtins/namespace.rs b/vm/src/builtins/namespace.rs index 3d48388030..d5101b1b57 100644 --- a/vm/src/builtins/namespace.rs +++ b/vm/src/builtins/namespace.rs @@ -1,11 +1,11 @@ -use super::PyTypeRef; +use super::{PyType, PyTypeRef}; use crate::{ builtins::PyDict, class::PyClassImpl, function::{FuncArgs, PyComparisonValue}, recursion::ReprGuard, types::{Comparable, Constructor, Initializer, PyComparisonOp}, - AsObject, Context, PyObject, PyPayload, PyRef, PyResult, VirtualMachine, + AsObject, Context, Py, PyObject, PyPayload, PyRef, PyResult, VirtualMachine, }; /// A simple attribute-based namespace. @@ -16,8 +16,9 @@ use crate::{ pub struct PyNamespace {} impl PyPayload for PyNamespace { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.namespace_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.namespace_type } } @@ -33,7 +34,7 @@ impl PyNamespace { pub fn new_ref(ctx: &Context) -> PyRef { PyRef::new_ref( Self {}, - ctx.types.namespace_type.clone(), + ctx.types.namespace_type.to_owned(), Some(ctx.new_dict()), ) } @@ -44,7 +45,7 @@ impl PyNamespace { #[pymethod(magic)] fn repr(zelf: PyRef, vm: &VirtualMachine) -> PyResult { let o = zelf.as_object(); - let name = if o.class().is(&vm.ctx.types.namespace_type) { + let name = if o.class().is(vm.ctx.types.namespace_type) { "namespace".to_owned() } else { o.class().slot_name() @@ -98,5 +99,5 @@ impl Comparable for PyNamespace { } pub fn init(context: &Context) { - PyNamespace::extend_class(context, &context.types.namespace_type); + PyNamespace::extend_class(context, context.types.namespace_type); } diff --git a/vm/src/builtins/object.rs b/vm/src/builtins/object.rs index 4d1173e1b4..9cad613f3b 100644 --- a/vm/src/builtins/object.rs +++ b/vm/src/builtins/object.rs @@ -5,7 +5,7 @@ use crate::{ function::Either, function::{FuncArgs, PyArithmeticValue, PyComparisonValue}, types::PyComparisonOp, - AsObject, Context, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine, + AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; /// object() @@ -20,8 +20,9 @@ use crate::{ pub struct PyBaseObject; impl PyPayload for PyBaseObject { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.object_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.object_type } } @@ -31,7 +32,7 @@ impl PyBaseObject { #[pyslot] fn slot_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult { // more or less __new__ operator - let dict = if cls.is(&vm.ctx.types.object_type) { + let dict = if cls.is(vm.ctx.types.object_type) { None } else { Some(vm.ctx.new_dict()) @@ -226,7 +227,7 @@ impl PyBaseObject { pub fn dir(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult { let attributes = obj.class().get_attributes(); - let dict = PyDict::from_attributes(attributes, vm)?.into_ref(vm); + let dict = PyDict::from_attributes(attributes, vm)?.into_ref(&vm.ctx); // Get instance attributes: if let Some(object_dict) = obj.dict() { @@ -343,7 +344,7 @@ pub fn object_set_dict(obj: PyObjectRef, dict: PyDictRef, vm: &VirtualMachine) - } pub fn init(ctx: &Context) { - PyBaseObject::extend_class(ctx, &ctx.types.object_type); + PyBaseObject::extend_class(ctx, ctx.types.object_type); } fn common_reduce(obj: PyObjectRef, proto: usize, vm: &VirtualMachine) -> PyResult { diff --git a/vm/src/builtins/property.rs b/vm/src/builtins/property.rs index 86523fa0f6..7442d249d5 100644 --- a/vm/src/builtins/property.rs +++ b/vm/src/builtins/property.rs @@ -1,13 +1,13 @@ /*! Python `property` descriptor class. */ -use super::PyTypeRef; +use super::{PyType, PyTypeRef}; use crate::common::lock::PyRwLock; use crate::{ class::PyClassImpl, function::FuncArgs, types::{Constructor, GetDescriptor, Initializer}, - AsObject, Context, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, + AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, }; /// Property attribute. @@ -52,8 +52,9 @@ pub struct PyProperty { } impl PyPayload for PyProperty { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.property_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.property_type } } @@ -256,14 +257,14 @@ impl Initializer for PyProperty { } pub(crate) fn init(context: &Context) { - PyProperty::extend_class(context, &context.types.property_type); + PyProperty::extend_class(context, context.types.property_type); // This is a bit unfortunate, but this instance attribute overlaps with the // class __doc__ string.. - extend_class!(context, &context.types.property_type, { + extend_class!(context, context.types.property_type, { "__doc__" => context.new_getset( "__doc__", - context.types.property_type.clone(), + context.types.property_type, PyProperty::doc_getter, PyProperty::doc_setter, ), diff --git a/vm/src/builtins/range.rs b/vm/src/builtins/range.rs index fb34d59d26..fe1a10ff5f 100644 --- a/vm/src/builtins/range.rs +++ b/vm/src/builtins/range.rs @@ -1,4 +1,4 @@ -use super::{PyInt, PyIntRef, PySlice, PyTupleRef, PyTypeRef}; +use super::{PyInt, PyIntRef, PySlice, PyTupleRef, PyType, PyTypeRef}; use crate::common::hash::PyHash; use crate::{ builtins::builtins_iter, @@ -75,8 +75,9 @@ pub struct PyRange { } impl PyPayload for PyRange { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.range_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.range_type } } @@ -174,9 +175,9 @@ impl PyRange { // } pub fn init(context: &Context) { - PyRange::extend_class(context, &context.types.range_type); - PyLongRangeIterator::extend_class(context, &context.types.longrange_iterator_type); - PyRangeIterator::extend_class(context, &context.types.range_iterator_type); + PyRange::extend_class(context, context.types.range_type); + PyLongRangeIterator::extend_class(context, context.types.longrange_iterator_type); + PyRangeIterator::extend_class(context, context.types.range_iterator_type); } #[pyimpl(with(AsMapping, AsSequence, Hashable, Comparable, Iterable))] @@ -301,7 +302,7 @@ impl PyRange { .map(|x| x.as_object().to_owned()) .collect(); let range_paramters_tuple = vm.ctx.new_tuple(range_paramters); - (vm.ctx.types.range_type.clone(), range_paramters_tuple) + (vm.ctx.types.range_type.to_owned(), range_paramters_tuple) } #[pymethod] @@ -359,7 +360,7 @@ impl PyRange { stop: vm.new_pyref(substop), step: vm.new_pyref(substep), } - .into_ref(vm) + .into_ref(&vm.ctx) .into()) } RangeIndex::Int(index) => match self.get(index.as_bigint()) { @@ -403,7 +404,7 @@ impl PyRange { item: Some(|seq, i, vm| { Self::sequence_downcast(seq) .get(&i.into()) - .map(|x| PyInt::from(x).into_ref(vm).into()) + .map(|x| PyInt::from(x).into_ref(&vm.ctx).into()) .ok_or_else(|| vm.new_index_error("index out of range".to_owned())) }), contains: Some(|seq, needle, vm| { @@ -529,8 +530,9 @@ pub struct PyLongRangeIterator { } impl PyPayload for PyLongRangeIterator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.longrange_iterator_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.longrange_iterator_type } } @@ -594,8 +596,9 @@ pub struct PyRangeIterator { } impl PyPayload for PyRangeIterator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.range_iterator_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.range_iterator_type } } @@ -658,9 +661,9 @@ fn range_iter_reduce( let iter = builtins_iter(vm).to_owned(); let stop = start.clone() + length * step.clone(); let range = PyRange { - start: PyInt::from(start).into_ref(vm), - stop: PyInt::from(stop).into_ref(vm), - step: PyInt::from(step).into_ref(vm), + start: PyInt::from(start).into_ref(&vm.ctx), + stop: PyInt::from(stop).into_ref(&vm.ctx), + step: PyInt::from(step).into_ref(&vm.ctx), }; Ok(vm.new_tuple((iter, (range,), index))) } diff --git a/vm/src/builtins/set.rs b/vm/src/builtins/set.rs index da5cd9d8c1..f4904f44c0 100644 --- a/vm/src/builtins/set.rs +++ b/vm/src/builtins/set.rs @@ -2,7 +2,7 @@ * Builtin set type with a sequence of unique items. */ use super::{ - builtins_iter, IterStatus, PositionIterInternal, PyDictRef, PyGenericAlias, PyTupleRef, + builtins_iter, IterStatus, PositionIterInternal, PyDictRef, PyGenericAlias, PyTupleRef, PyType, PyTypeRef, }; use crate::common::{ascii, hash::PyHash, lock::PyMutex, rc::PyRc}; @@ -18,7 +18,7 @@ use crate::{ }, utils::collection_repr, vm::VirtualMachine, - AsObject, Context, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, + AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, }; use std::borrow::Cow; use std::{fmt, ops::Deref}; @@ -72,14 +72,16 @@ impl fmt::Debug for PyFrozenSet { } impl PyPayload for PySet { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.set_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.set_type } } impl PyPayload for PyFrozenSet { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.frozenset_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.frozenset_type } } @@ -342,7 +344,7 @@ impl PySetInner { ) // If operation raised KeyError, report original set (set.remove) .map_err(|op_err| { - if op_err.fast_isinstance(&vm.ctx.exceptions.key_error) { + if op_err.fast_isinstance(vm.ctx.exceptions.key_error) { vm.new_key_error(item.to_owned()) } else { op_err @@ -388,7 +390,7 @@ impl PySet { pub fn new_ref(ctx: &Context) -> PyRef { // Initialized empty, as calling __hash__ is required for adding each object to the set // which requires a VM context - this is done in the set code itself. - PyRef::new_ref(Self::default(), ctx.types.set_type.clone(), None) + PyRef::new_ref(Self::default(), ctx.types.set_type.to_owned(), None) } } @@ -715,7 +717,7 @@ impl Constructor for PyFrozenSet { fn py_new(cls: PyTypeRef, iterable: Self::Args, vm: &VirtualMachine) -> PyResult { let elements = if let OptionalArg::Present(iterable) = iterable { - let iterable = if cls.is(&vm.ctx.types.frozenset_type) { + let iterable = if cls.is(vm.ctx.types.frozenset_type) { match iterable.downcast_exact::(vm) { Ok(fs) => return Ok(fs.into()), Err(iterable) => iterable, @@ -729,7 +731,7 @@ impl Constructor for PyFrozenSet { }; // Return empty fs if iterable passed is empty and only for exact fs types. - if elements.is_empty() && cls.is(&vm.ctx.types.frozenset_type) { + if elements.is_empty() && cls.is(vm.ctx.types.frozenset_type) { Ok(vm.ctx.empty_frozenset.clone().into()) } else { Self::from_iter(vm, elements) @@ -768,13 +770,13 @@ impl PyFrozenSet { #[pymethod] fn copy(zelf: PyRef, vm: &VirtualMachine) -> PyRef { - if zelf.class().is(&vm.ctx.types.frozenset_type) { + if zelf.class().is(vm.ctx.types.frozenset_type) { zelf } else { Self { inner: zelf.inner.copy(), } - .into_ref(vm) + .into_ref(&vm.ctx) } } @@ -953,8 +955,8 @@ struct SetIterable { impl TryFromObject for SetIterable { fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { let class = obj.class(); - if class.fast_issubclass(&vm.ctx.types.set_type) - || class.fast_issubclass(&vm.ctx.types.frozenset_type) + if class.fast_issubclass(vm.ctx.types.set_type) + || class.fast_issubclass(vm.ctx.types.frozenset_type) { // the class lease needs to be drop to be able to return the object drop(class); @@ -981,8 +983,9 @@ impl fmt::Debug for PySetIterator { } impl PyPayload for PySetIterator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.set_iterator_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.set_iterator_type } } @@ -1038,7 +1041,7 @@ impl IterNext for PySetIterator { } pub fn init(context: &Context) { - PySet::extend_class(context, &context.types.set_type); - PyFrozenSet::extend_class(context, &context.types.frozenset_type); - PySetIterator::extend_class(context, &context.types.set_iterator_type); + PySet::extend_class(context, context.types.set_type); + PyFrozenSet::extend_class(context, context.types.frozenset_type); + PySetIterator::extend_class(context, context.types.set_iterator_type); } diff --git a/vm/src/builtins/singletons.rs b/vm/src/builtins/singletons.rs index 0f3b987059..10491835dd 100644 --- a/vm/src/builtins/singletons.rs +++ b/vm/src/builtins/singletons.rs @@ -1,6 +1,6 @@ -use super::PyTypeRef; +use super::{PyType, PyTypeRef}; use crate::{ - class::PyClassImpl, convert::ToPyObject, types::Constructor, AsObject, Context, PyObjectRef, + class::PyClassImpl, convert::ToPyObject, types::Constructor, Context, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; @@ -9,8 +9,9 @@ use crate::{ pub struct PyNone; impl PyPayload for PyNone { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.none_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.none_type } } @@ -57,8 +58,9 @@ impl PyNone { pub struct PyNotImplemented; impl PyPayload for PyNotImplemented { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.not_implemented_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.not_implemented_type } } @@ -92,6 +94,6 @@ impl PyNotImplemented { } pub fn init(context: &Context) { - PyNone::extend_class(context, &context.none.class()); - PyNotImplemented::extend_class(context, &context.not_implemented.class()); + PyNone::extend_class(context, context.types.none_type); + PyNotImplemented::extend_class(context, context.types.not_implemented_type); } diff --git a/vm/src/builtins/slice.rs b/vm/src/builtins/slice.rs index d7ff6a3c2c..ae7b41de3c 100644 --- a/vm/src/builtins/slice.rs +++ b/vm/src/builtins/slice.rs @@ -1,12 +1,12 @@ // sliceobject.{h,c} in CPython -use super::{PyInt, PyIntRef, PyTupleRef, PyTypeRef}; +use super::{PyInt, PyIntRef, PyTupleRef, PyType, PyTypeRef}; use crate::{ class::PyClassImpl, convert::ToPyObject, function::{FuncArgs, OptionalArg, PyComparisonValue}, sliceable::SaturatedSlice, types::{Comparable, Constructor, Hashable, PyComparisonOp, Unhashable}, - AsObject, Context, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; use num_bigint::{BigInt, ToBigInt}; use num_traits::{One, Signed, Zero}; @@ -20,8 +20,9 @@ pub struct PySlice { } impl PyPayload for PySlice { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.slice_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.slice_type } } @@ -265,8 +266,9 @@ impl Unhashable for PySlice {} pub struct PyEllipsis; impl PyPayload for PyEllipsis { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.ellipsis_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.ellipsis_type } } @@ -291,7 +293,7 @@ impl PyEllipsis { } } -pub fn init(context: &Context) { - PySlice::extend_class(context, &context.types.slice_type); - PyEllipsis::extend_class(context, &context.ellipsis.class().clone()); +pub fn init(ctx: &Context) { + PySlice::extend_class(ctx, ctx.types.slice_type); + PyEllipsis::extend_class(ctx, ctx.types.ellipsis_type); } diff --git a/vm/src/builtins/staticmethod.rs b/vm/src/builtins/staticmethod.rs index 39cf8f3621..e84da86ae6 100644 --- a/vm/src/builtins/staticmethod.rs +++ b/vm/src/builtins/staticmethod.rs @@ -1,10 +1,9 @@ -use super::{PyStr, PyTypeRef}; +use super::{PyType, PyTypeRef}; use crate::{ - builtins::builtinfunc::PyBuiltinMethod, class::PyClassImpl, - function::{FuncArgs, IntoPyNativeFunc}, + function::FuncArgs, types::{Callable, Constructor, GetDescriptor}, - Context, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + Context, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; #[pyclass(module = false, name = "staticmethod")] @@ -14,8 +13,9 @@ pub struct PyStaticMethod { } impl PyPayload for PyStaticMethod { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.staticmethod_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.staticmethod_type } } @@ -48,17 +48,8 @@ impl Constructor for PyStaticMethod { } impl PyStaticMethod { - pub fn new_ref( - name: impl Into, - class: PyTypeRef, - f: F, - ctx: &Context, - ) -> PyRef - where - F: IntoPyNativeFunc, - { - let callable = PyBuiltinMethod::new_ref(name, class, f, ctx).into(); - PyRef::new_ref(Self { callable }, ctx.types.staticmethod_type.clone(), None) + pub fn new(callable: PyObjectRef) -> Self { + Self { callable } } } @@ -88,5 +79,5 @@ impl Callable for PyStaticMethod { } pub fn init(context: &Context) { - PyStaticMethod::extend_class(context, &context.types.staticmethod_type); + PyStaticMethod::extend_class(context, context.types.staticmethod_type); } diff --git a/vm/src/builtins/str.rs b/vm/src/builtins/str.rs index 40f610c45d..fb3b70f8eb 100644 --- a/vm/src/builtins/str.rs +++ b/vm/src/builtins/str.rs @@ -1,7 +1,7 @@ use super::{ int::{PyInt, PyIntRef}, iter::IterStatus::{self, Exhausted}, - PositionIterInternal, PyBytesRef, PyDict, PyTupleRef, PyTypeRef, + PositionIterInternal, PyBytesRef, PyDict, PyTupleRef, PyType, PyTypeRef, }; use crate::{ anystr::{self, adjust_indices, AnyStr, AnyStrContainer, AnyStrWrapper}, @@ -202,35 +202,35 @@ impl IntoPyStrRef for PyStrRef { impl IntoPyStrRef for PyStr { #[inline] fn into_pystr_ref(self, vm: &VirtualMachine) -> PyRef { - self.into_ref(vm) + self.into_ref(&vm.ctx) } } impl IntoPyStrRef for AsciiString { #[inline] fn into_pystr_ref(self, vm: &VirtualMachine) -> PyRef { - PyStr::from(self).into_ref(vm) + PyStr::from(self).into_ref(&vm.ctx) } } impl IntoPyStrRef for String { #[inline] fn into_pystr_ref(self, vm: &VirtualMachine) -> PyRef { - PyStr::from(self).into_ref(vm) + PyStr::from(self).into_ref(&vm.ctx) } } impl IntoPyStrRef for &str { #[inline] fn into_pystr_ref(self, vm: &VirtualMachine) -> PyRef { - PyStr::from(self).into_ref(vm) + PyStr::from(self).into_ref(&vm.ctx) } } impl IntoPyStrRef for &'static crate::intern::PyStrInterned { #[inline] fn into_pystr_ref(self, _vm: &VirtualMachine) -> PyRef { - self.to_str() + self.to_owned() } } @@ -241,8 +241,9 @@ pub struct PyStrIterator { } impl PyPayload for PyStrIterator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.str_iterator_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.str_iterator_type } } @@ -358,10 +359,6 @@ impl PyStr { Self::new_str_unchecked(bytes, PyStrKind::Ascii) } - pub fn new_ref(s: impl Into, ctx: &Context) -> PyRef { - PyRef::new_ref(s.into(), ctx.types.str_type.clone(), None) - } - fn new_substr(&self, s: String) -> Self { let kind = if self.kind.kind() == PyStrKind::Ascii || s.is_ascii() { PyStrKind::Ascii @@ -445,7 +442,7 @@ impl PyStr { SequenceIndex::Int(i) => self.get_item_by_index(vm, i).map(|x| x.to_string()), SequenceIndex::Slice(slice) => self.get_item_by_slice(vm, slice), } - .map(|x| self.new_substr(x).into_ref(vm).into()) + .map(|x| self.new_substr(x).into_ref(&vm.ctx).into()) } #[pymethod(magic)] @@ -522,12 +519,12 @@ impl PyStr { #[pymethod(name = "__rmul__")] #[pymethod(magic)] fn mul(zelf: PyRef, value: isize, vm: &VirtualMachine) -> PyResult> { - if value == 0 && zelf.class().is(&vm.ctx.types.str_type) { + if value == 0 && zelf.class().is(vm.ctx.types.str_type) { // Special case: when some `str` is multiplied by `0`, // returns the empty `str`. return Ok(vm.ctx.empty_str.clone()); } - if (value == 1 || zelf.is_empty()) && zelf.class().is(&vm.ctx.types.str_type) { + if (value == 1 || zelf.is_empty()) && zelf.class().is(vm.ctx.types.str_type) { // Special case: when some `str` is multiplied by `1` or is the empty `str`, // nothing really happens, we need to return an object itself // with the same `id()` to be compatible with CPython. @@ -537,7 +534,7 @@ impl PyStr { zelf.as_str() .as_bytes() .mul(vm, value) - .map(|x| Self::from(unsafe { String::from_utf8_unchecked(x) }).into_ref(vm)) + .map(|x| Self::from(unsafe { String::from_utf8_unchecked(x) }).into_ref(&vm.ctx)) } #[pymethod(magic)] @@ -1264,7 +1261,7 @@ impl PyStrRef { let mut s = String::with_capacity(self.byte_len() + other.len()); s.push_str(self.as_ref()); s.push_str(other); - *self = PyStr::from(s).into_ref(vm); + *self = PyStr::from(s).into_ref(&vm.ctx); } } @@ -1336,7 +1333,7 @@ impl PyStr { item: Some(|seq, i, vm| { let zelf = Self::sequence_downcast(seq); zelf.get_item_by_index(vm, i) - .map(|x| zelf.new_substr(x.to_string()).into_ref(vm).into()) + .map(|x| zelf.new_substr(x.to_string()).into_ref(&vm.ctx).into()) }), contains: Some(|seq, needle, vm| Self::sequence_downcast(seq)._contains(needle, vm)), ..*PySequenceMethods::not_implemented() @@ -1364,8 +1361,9 @@ pub(crate) fn encode_string( } impl PyPayload for PyStr { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.str_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.str_type } } @@ -1425,9 +1423,9 @@ impl FindArgs { } pub fn init(ctx: &Context) { - PyStr::extend_class(ctx, &ctx.types.str_type); + PyStr::extend_class(ctx, ctx.types.str_type); - PyStrIterator::extend_class(ctx, &ctx.types.str_iterator_type); + PyStrIterator::extend_class(ctx, ctx.types.str_iterator_type); } impl SliceableSequenceOp for PyStr { diff --git a/vm/src/builtins/super.rs b/vm/src/builtins/super.rs index fb566f4777..908a036436 100644 --- a/vm/src/builtins/super.rs +++ b/vm/src/builtins/super.rs @@ -19,8 +19,9 @@ pub struct PySuper { } impl PyPayload for PySuper { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.super_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.super_type } } @@ -182,7 +183,7 @@ impl GetDescriptor for PySuper { return Ok(zelf.into()); } let zelf_class = zelf.as_object().class(); - if zelf_class.is(&vm.ctx.types.super_type) { + if zelf_class.is(vm.ctx.types.super_type) { Ok(PySuper::new(zelf.typ.clone(), obj, vm)?.into_pyobject(vm)) } else { let obj = vm.unwrap_or_none(zelf.obj.clone().map(|(o, _)| o)); diff --git a/vm/src/builtins/traceback.rs b/vm/src/builtins/traceback.rs index ffd247a301..5062284ee2 100644 --- a/vm/src/builtins/traceback.rs +++ b/vm/src/builtins/traceback.rs @@ -1,5 +1,5 @@ -use super::PyTypeRef; -use crate::{class::PyClassImpl, frame::FrameRef, Context, PyPayload, PyRef, VirtualMachine}; +use super::PyType; +use crate::{class::PyClassImpl, frame::FrameRef, Context, Py, PyPayload, PyRef}; #[pyclass(module = false, name = "traceback")] #[derive(Debug)] @@ -13,8 +13,9 @@ pub struct PyTraceback { pub type PyTracebackRef = PyRef; impl PyPayload for PyTraceback { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.traceback_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.traceback_type } } @@ -57,7 +58,7 @@ impl PyTracebackRef { } pub fn init(context: &Context) { - PyTraceback::extend_class(context, &context.types.traceback_type); + PyTraceback::extend_class(context, context.types.traceback_type); } impl serde::Serialize for PyTraceback { diff --git a/vm/src/builtins/tuple.rs b/vm/src/builtins/tuple.rs index 13052b30b1..898cbacec9 100644 --- a/vm/src/builtins/tuple.rs +++ b/vm/src/builtins/tuple.rs @@ -1,4 +1,4 @@ -use super::{PositionIterInternal, PyGenericAlias, PyTypeRef}; +use super::{PositionIterInternal, PyGenericAlias, PyType, PyTypeRef}; use crate::common::{hash::PyHash, lock::PyMutex}; use crate::{ class::PyClassImpl, @@ -15,7 +15,7 @@ use crate::{ }, utils::collection_repr, vm::VirtualMachine, - AsObject, Context, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, + AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, }; use std::{borrow::Cow, fmt, marker::PhantomData}; @@ -36,8 +36,9 @@ impl fmt::Debug for PyTuple { } impl PyPayload for PyTuple { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.tuple_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.tuple_type } } @@ -94,7 +95,7 @@ impl Constructor for PyTuple { fn py_new(cls: PyTypeRef, iterable: Self::Args, vm: &VirtualMachine) -> PyResult { let elements = if let OptionalArg::Present(iterable) = iterable { - let iterable = if cls.is(&vm.ctx.types.tuple_type) { + let iterable = if cls.is(vm.ctx.types.tuple_type) { match iterable.downcast_exact::(vm) { Ok(tuple) => return Ok(tuple.into()), Err(iterable) => iterable, @@ -107,7 +108,7 @@ impl Constructor for PyTuple { vec![] }; // Return empty tuple only for exact tuple types if the iterable is empty. - if elements.is_empty() && cls.is(&vm.ctx.types.tuple_type) { + if elements.is_empty() && cls.is(vm.ctx.types.tuple_type) { Ok(vm.ctx.empty_tuple.clone().into()) } else { Self { @@ -156,7 +157,7 @@ impl PyTuple { ctx.empty_tuple.clone() } else { let elements = elements.into_boxed_slice(); - PyRef::new_ref(Self { elements }, ctx.types.tuple_type.clone(), None) + PyRef::new_ref(Self { elements }, ctx.types.tuple_type.to_owned(), None) } } @@ -184,9 +185,9 @@ impl PyTuple { vm: &VirtualMachine, ) -> PyArithmeticValue> { let added = other.downcast::().map(|other| { - if other.elements.is_empty() && zelf.class().is(&vm.ctx.types.tuple_type) { + if other.elements.is_empty() && zelf.class().is(vm.ctx.types.tuple_type) { zelf - } else if zelf.elements.is_empty() && other.class().is(&vm.ctx.types.tuple_type) { + } else if zelf.elements.is_empty() && other.class().is(vm.ctx.types.tuple_type) { other } else { let elements = zelf @@ -194,7 +195,7 @@ impl PyTuple { .chain(other.as_slice()) .cloned() .collect::>(); - Self { elements }.into_ref(vm) + Self { elements }.into_ref(&vm.ctx) } }); PyArithmeticValue::from_option(added.ok()) @@ -248,7 +249,7 @@ impl PyTuple { fn mul(zelf: PyRef, value: isize, vm: &VirtualMachine) -> PyResult> { Ok(if zelf.elements.is_empty() || value == 0 { vm.ctx.empty_tuple.clone() - } else if value == 1 && zelf.class().is(&vm.ctx.types.tuple_type) { + } else if value == 1 && zelf.class().is(vm.ctx.types.tuple_type) { // Special case: when some `tuple` is multiplied by `1`, // nothing really happens, we need to return an object itself // with the same `id()` to be compatible with CPython. @@ -257,7 +258,7 @@ impl PyTuple { } else { let v = zelf.elements.mul(vm, value)?; let elements = v.into_boxed_slice(); - Self { elements }.into_ref(vm) + Self { elements }.into_ref(&vm.ctx) }) } @@ -331,7 +332,7 @@ impl PyTuple { // the arguments to pass to tuple() is just one tuple - so we'll be doing tuple(tup), which // should just return tup, or tuplesubclass(tup), which'll copy/validate (e.g. for a // structseq) - let tup_arg = if zelf.class().is(&vm.ctx.types.tuple_type) { + let tup_arg = if zelf.class().is(vm.ctx.types.tuple_type) { zelf } else { PyTuple::new_ref(zelf.elements.clone().into_vec(), &vm.ctx) @@ -435,8 +436,9 @@ pub(crate) struct PyTupleIterator { } impl PyPayload for PyTupleIterator { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.tuple_iterator_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.tuple_iterator_type } } @@ -475,8 +477,8 @@ impl IterNext for PyTupleIterator { } pub(crate) fn init(context: &Context) { - PyTuple::extend_class(context, &context.types.tuple_type); - PyTupleIterator::extend_class(context, &context.types.tuple_iterator_type); + PyTuple::extend_class(context, context.types.tuple_type); + PyTupleIterator::extend_class(context, context.types.tuple_iterator_type); } pub struct PyTupleTyped { diff --git a/vm/src/builtins/type.rs b/vm/src/builtins/type.rs index 3395a05e3e..fb6f87ba9b 100644 --- a/vm/src/builtins/type.rs +++ b/vm/src/builtins/type.rs @@ -50,8 +50,9 @@ impl fmt::Debug for PyType { } impl PyPayload for PyType { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.type_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.type_type } } @@ -62,7 +63,7 @@ impl PyType { vec![base.clone()], Default::default(), Default::default(), - Self::static_type().clone(), + Self::static_type().to_owned(), ) } pub fn new_ref( @@ -125,7 +126,7 @@ impl PyType { base.subclasses.write().push( new_type .as_object() - .downgrade_with_weakref_typ_opt(None, weakref_type.clone()) + .downgrade_with_weakref_typ_opt(None, weakref_type.to_owned()) .unwrap(), ); } @@ -334,7 +335,7 @@ impl PyType { .cloned() // We need to exclude this method from going into recursion: .and_then(|found| { - if found.fast_isinstance(&vm.ctx.types.getset_type) { + if found.fast_isinstance(vm.ctx.types.getset_type) { None } else { Some(found) @@ -351,7 +352,7 @@ impl PyType { .cloned() // We need to exclude this method from going into recursion: .and_then(|found| { - if found.fast_isinstance(&vm.ctx.types.getset_type) { + if found.fast_isinstance(vm.ctx.types.getset_type) { None } else { Some(found) @@ -410,7 +411,7 @@ impl PyType { fn slot_new(metatype: PyTypeRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult { vm_trace!("type.__new__ {:?}", args); - let is_type_type = metatype.is(&vm.ctx.types.type_type); + let is_type_type = metatype.is(vm.ctx.types.type_type); if is_type_type && args.args.len() == 1 && args.kwargs.is_empty() { return Ok(args.args[0].class().clone().into()); } @@ -434,7 +435,7 @@ impl PyType { } let (metatype, base, bases) = if bases.is_empty() { - let base = vm.ctx.types.object_type.clone(); + let base = vm.ctx.types.object_type.to_owned(); (metatype, base.clone(), vec![base]) } else { let bases = bases @@ -473,19 +474,19 @@ impl PyType { let mut attributes = dict.to_attributes(); if let Some(f) = attributes.get_mut("__new__") { - if f.class().is(&vm.ctx.types.function_type) { + if f.class().is(vm.ctx.types.function_type) { *f = PyStaticMethod::from(f.clone()).into_pyobject(vm); } } if let Some(f) = attributes.get_mut("__init_subclass__") { - if f.class().is(&vm.ctx.types.function_type) { + if f.class().is(vm.ctx.types.function_type) { *f = PyClassMethod::from(f.clone()).into_pyobject(vm); } } if let Some(f) = attributes.get_mut("__class_getitem__") { - if f.class().is(&vm.ctx.types.function_type) { + if f.class().is(vm.ctx.types.function_type) { *f = PyClassMethod::from(f.clone()).into_pyobject(vm); } } @@ -510,7 +511,7 @@ impl PyType { vm.ctx .new_getset( "__dict__", - vm.ctx.types.object_type.clone(), + vm.ctx.types.object_type, subtype_get_dict, subtype_set_dict, ) @@ -533,7 +534,13 @@ impl PyType { .iter() .filter_map(|(name, obj)| { vm.get_method(obj.clone(), "__set_name__").map(|res| { - res.map(|meth| (obj.clone(), PyStr::from(name.clone()).into_ref(vm), meth)) + res.map(|meth| { + ( + obj.clone(), + PyStr::from(name.clone()).into_ref(&vm.ctx), + meth, + ) + }) }) }) .collect::>>()?; @@ -694,7 +701,7 @@ impl SetAttr for PyType { let prev_value = attributes.remove(attr_name.as_str()); if prev_value.is_none() { return Err(vm.new_exception( - vm.ctx.exceptions.attribute_error.clone(), + vm.ctx.exceptions.attribute_error.to_owned(), vec![attr_name.into()], )); } @@ -713,8 +720,7 @@ impl Callable for PyType { vm_trace!("type_call: {:?}", zelf); let obj = call_slot_new(zelf.to_owned(), zelf.to_owned(), args.clone(), vm)?; - if (zelf.is(&vm.ctx.types.type_type) && args.kwargs.is_empty()) - || !obj.fast_isinstance(zelf) + if (zelf.is(vm.ctx.types.type_type) && args.kwargs.is_empty()) || !obj.fast_isinstance(zelf) { return Ok(obj); } @@ -730,7 +736,7 @@ fn find_base_dict_descr(cls: &PyTypeRef, vm: &VirtualMachine) -> Option &PyTypeRef { - &vm.ctx.types.union_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.union_type } } @@ -99,10 +100,10 @@ impl PyUnion { } pub fn is_unionable(obj: PyObjectRef, vm: &VirtualMachine) -> bool { - obj.class().is(&vm.ctx.types.none_type) - || obj.class().is(&vm.ctx.types.type_type) - || obj.class().is(&vm.ctx.types.generic_alias_type) - || obj.class().is(&vm.ctx.types.union_type) + obj.class().is(vm.ctx.types.none_type) + || obj.class().is(vm.ctx.types.type_type) + || obj.class().is(vm.ctx.types.generic_alias_type) + || obj.class().is(vm.ctx.types.union_type) } fn is_typevar(obj: &PyObjectRef) -> bool { @@ -171,8 +172,8 @@ fn dedup_and_flatten_args(args: PyTupleRef, vm: &VirtualMachine) -> PyTupleRef { PyTypeRef::try_from_object(vm, arg.clone()), ) { (Ok(a), Ok(b)) - if a.is(&vm.ctx.types.generic_alias_type) - && b.is(&vm.ctx.types.generic_alias_type) => + if a.is(vm.ctx.types.generic_alias_type) + && b.is(vm.ctx.types.generic_alias_type) => { param .rich_compare_bool(arg, PyComparisonOp::Eq, vm) @@ -258,7 +259,7 @@ impl Hashable for PyUnion { fn hash(zelf: &crate::Py, vm: &VirtualMachine) -> PyResult { let it = PyTuple::iter(zelf.args.clone(), vm); let set = PyFrozenSet::from_iter(vm, it)?; - PyFrozenSet::hash(&set.into_ref(vm), vm) + PyFrozenSet::hash(&set.into_ref(&vm.ctx), vm) } } diff --git a/vm/src/builtins/weakproxy.rs b/vm/src/builtins/weakproxy.rs index 1d92b0ea7b..d8db4736fe 100644 --- a/vm/src/builtins/weakproxy.rs +++ b/vm/src/builtins/weakproxy.rs @@ -1,9 +1,9 @@ -use super::{PyStrRef, PyTypeRef, PyWeak}; +use super::{PyStrRef, PyType, PyTypeRef, PyWeak}; use crate::{ class::PyClassImpl, function::OptionalArg, types::{Constructor, SetAttr}, - Context, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; #[pyclass(module = false, name = "weakproxy")] @@ -13,8 +13,9 @@ pub struct PyWeakProxy { } impl PyPayload for PyWeakProxy { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.weakproxy_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.weakproxy_type } } @@ -40,7 +41,7 @@ impl Constructor for PyWeakProxy { vm.ctx.new_class( None, "__weakproxy", - &vm.ctx.types.weakref_type, + vm.ctx.types.weakref_type.to_owned(), super::PyWeak::make_slots(), ) }); @@ -76,7 +77,7 @@ impl PyWeakProxy { fn new_reference_error(vm: &VirtualMachine) -> PyRef { vm.new_exception_msg( - vm.ctx.exceptions.reference_error.clone(), + vm.ctx.exceptions.reference_error.to_owned(), "weakly-referenced object no longer exists".to_owned(), ) } @@ -91,7 +92,7 @@ impl SetAttr for PyWeakProxy { match zelf.weak.upgrade() { Some(obj) => obj.call_set_attr(vm, attr_name, value), None => Err(vm.new_exception_msg( - vm.ctx.exceptions.reference_error.clone(), + vm.ctx.exceptions.reference_error.to_owned(), "weakly-referenced object no longer exists".to_owned(), )), } @@ -99,5 +100,5 @@ impl SetAttr for PyWeakProxy { } pub fn init(context: &Context) { - PyWeakProxy::extend_class(context, &context.types.weakproxy_type); + PyWeakProxy::extend_class(context, context.types.weakproxy_type); } diff --git a/vm/src/builtins/weakref.rs b/vm/src/builtins/weakref.rs index 750025c3e4..1cb29bbd42 100644 --- a/vm/src/builtins/weakref.rs +++ b/vm/src/builtins/weakref.rs @@ -1,4 +1,4 @@ -use super::{PyGenericAlias, PyTypeRef}; +use super::{PyGenericAlias, PyType, PyTypeRef}; use crate::common::{ atomic::{Ordering, Radium}, hash::{self, PyHash}, @@ -7,7 +7,7 @@ use crate::{ class::PyClassImpl, function::OptionalArg, types::{Callable, Comparable, Constructor, Hashable, PyComparisonOp}, - AsObject, Context, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; pub use crate::object::PyWeak; @@ -21,8 +21,9 @@ pub struct WeakNewArgs { } impl PyPayload for PyWeak { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.weakref_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.weakref_type } } @@ -115,5 +116,5 @@ impl Comparable for PyWeak { } pub fn init(context: &Context) { - PyWeak::extend_class(context, &context.types.weakref_type); + PyWeak::extend_class(context, context.types.weakref_type); } diff --git a/vm/src/builtins/zip.rs b/vm/src/builtins/zip.rs index 2b223a7f4f..2b5775c2b9 100644 --- a/vm/src/builtins/zip.rs +++ b/vm/src/builtins/zip.rs @@ -1,11 +1,11 @@ -use super::PyTypeRef; +use super::{PyType, PyTypeRef}; use crate::{ builtins::PyTupleRef, class::PyClassImpl, function::{ArgIntoBool, OptionalArg, PosArgs}, protocol::{PyIter, PyIterReturn}, types::{Constructor, IterNext, IterNextIterable}, - AsObject, Context, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, + AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, }; use rustpython_common::atomic::{self, PyAtomic, Radium}; @@ -17,8 +17,9 @@ pub struct PyZip { } impl PyPayload for PyZip { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.zip_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.zip_type } } @@ -109,6 +110,6 @@ impl IterNext for PyZip { } } -pub fn init(context: &Context) { - PyZip::extend_class(context, &context.types.zip_type); +pub fn init(ctx: &Context) { + PyZip::extend_class(ctx, ctx.types.zip_type); } diff --git a/vm/src/bytesinner.rs b/vm/src/bytesinner.rs index 8e9613747b..458c179001 100644 --- a/vm/src/bytesinner.rs +++ b/vm/src/bytesinner.rs @@ -75,7 +75,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)) { + let obj = if cls.is(vm.ctx.types.bytes_type) { match obj.downcast_exact::(vm) { Ok(b) => { return Ok(b); @@ -90,7 +90,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 = vm.invoke(&bytes_method?, ())?; - let bytes = if cls.is(PyBytes::class(vm)) { + 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/cformat.rs b/vm/src/cformat.rs index fd2486fedd..be5556a684 100644 --- a/vm/src/cformat.rs +++ b/vm/src/cformat.rs @@ -448,7 +448,7 @@ impl CFormatSpec { CFormatType::Float(_) => { let type_name = obj.class().name().to_string(); let value = ArgIntoFloat::try_from_object(vm, obj).map_err(|e| { - if e.fast_isinstance(&vm.ctx.exceptions.type_error) { + if e.fast_isinstance(vm.ctx.exceptions.type_error) { // formatfloat in bytesobject.c generates its own specific exception // text in this case, mirror it here. vm.new_type_error(format!("float argument required, not {}", type_name)) @@ -690,9 +690,9 @@ impl CFormatBytes { let mut result = vec![]; let is_mapping = values_obj.class().has_attr("__getitem__") - && !values_obj.fast_isinstance(&vm.ctx.types.tuple_type) - && !values_obj.fast_isinstance(&vm.ctx.types.bytes_type) - && !values_obj.fast_isinstance(&vm.ctx.types.bytearray_type); + && !values_obj.fast_isinstance(vm.ctx.types.tuple_type) + && !values_obj.fast_isinstance(vm.ctx.types.bytes_type) + && !values_obj.fast_isinstance(vm.ctx.types.bytearray_type); if num_specifiers == 0 { // literal only @@ -842,8 +842,8 @@ impl CFormatString { let mut result = String::new(); let is_mapping = values_obj.class().has_attr("__getitem__") - && !values_obj.fast_isinstance(&vm.ctx.types.tuple_type) - && !values_obj.fast_isinstance(&vm.ctx.types.str_type); + && !values_obj.fast_isinstance(vm.ctx.types.tuple_type) + && !values_obj.fast_isinstance(vm.ctx.types.str_type); if num_specifiers == 0 { // literal only diff --git a/vm/src/class.rs b/vm/src/class.rs index c6e057929c..8f36be74d2 100644 --- a/vm/src/class.rs +++ b/vm/src/class.rs @@ -2,33 +2,39 @@ use crate::{ builtins::{PyBaseObject, PyBoundMethod, PyType, PyTypeRef}, - object::{PyObjectPayload, PyObjectRef, PyRef}, + object::{Py, PyObjectPayload, PyObjectRef, PyRef}, types::{PyTypeFlags, PyTypeSlots}, vm::Context, + PyPayload, }; use rustpython_common::{lock::PyRwLock, static_cell}; pub trait StaticType { // Ideally, saving PyType is better than PyTypeRef fn static_cell() -> &'static static_cell::StaticCell; - fn static_metaclass() -> &'static PyTypeRef { + #[inline] + fn static_metaclass() -> &'static Py { PyType::static_type() } - fn static_baseclass() -> &'static PyTypeRef { + #[inline] + fn static_baseclass() -> &'static Py { PyBaseObject::static_type() } - fn static_type() -> &'static PyTypeRef { - Self::static_cell() - .get() - .expect("static type has not been initialized") + #[inline] + fn static_type() -> &'static Py { + #[cold] + fn fail() -> ! { + panic!("static type has not been initialized"); + } + Self::static_cell().get().unwrap_or_else(|| fail()) } - fn init_manually(typ: PyTypeRef) -> &'static PyTypeRef { + fn init_manually(typ: PyTypeRef) -> &'static Py { let cell = Self::static_cell(); cell.set(typ) .unwrap_or_else(|_| panic!("double initialization from init_manually")); cell.get().unwrap() } - fn init_bare_type() -> &'static PyTypeRef + fn init_bare_type() -> &'static Py where Self: PyClassImpl, { @@ -44,10 +50,10 @@ pub trait StaticType { { PyType::new_ref( Self::NAME, - vec![Self::static_baseclass().clone()], + vec![Self::static_baseclass().to_owned()], Default::default(), Self::make_slots(), - Self::static_metaclass().clone(), + Self::static_metaclass().to_owned(), ) .unwrap() } @@ -75,9 +81,9 @@ where pub trait PyClassImpl: PyClassDef { const TP_FLAGS: PyTypeFlags = PyTypeFlags::DEFAULT; - fn impl_extend_class(ctx: &Context, class: &PyTypeRef); + fn impl_extend_class(ctx: &Context, class: &'static Py); - fn extend_class(ctx: &Context, class: &PyTypeRef) { + fn extend_class(ctx: &Context, class: &'static Py) { #[cfg(debug_assertions)] { assert!(class.slots.flags.is_created_with_flags()); @@ -87,7 +93,7 @@ pub trait PyClassImpl: PyClassDef { "__dict__", ctx.new_getset( "__dict__", - class.clone(), + class, crate::builtins::object::object_get_dict, crate::builtins::object::object_set_dict, ), @@ -102,7 +108,8 @@ pub trait PyClassImpl: PyClassDef { } if class.slots.new.load().is_some() { let bound: PyObjectRef = - PyBoundMethod::new_ref(class.clone().into(), ctx.slot_new_wrapper.clone(), ctx) + PyBoundMethod::new(class.to_owned().into(), ctx.slot_new_wrapper.clone()) + .into_ref(ctx) .into(); class.set_str_attr("__new__", bound); } @@ -112,13 +119,16 @@ pub trait PyClassImpl: PyClassDef { where Self: StaticType, { - Self::static_cell() - .get_or_init(|| { - let typ = Self::create_bare_type(); - Self::extend_class(ctx, &typ); - typ - }) - .clone() + (*Self::static_cell().get_or_init(|| { + let typ = Self::create_bare_type(); + Self::extend_class(ctx, unsafe { + // typ will be saved in static_cell + let r: &Py = &typ; + &*(r as *const _) + }); + typ + })) + .to_owned() } fn extend_slots(slots: &mut PyTypeSlots); diff --git a/vm/src/codecs.rs b/vm/src/codecs.rs index a82e9f6bb7..e84ab925cb 100644 --- a/vm/src/codecs.rs +++ b/vm/src/codecs.rs @@ -218,7 +218,7 @@ impl CodecsRegistry { } let search_path = inner.search_path.clone(); drop(inner); // don't want to deadlock - let encoding = PyStr::from(encoding.into_owned()).into_ref(vm); + let encoding = PyStr::from(encoding.into_owned()).into_ref(&vm.ctx); for func in search_path { let res = vm.invoke(&func, (encoding.clone(),))?; let res: Option = res.try_into_value(vm)?; @@ -359,12 +359,12 @@ fn extract_unicode_error_range(err: &PyObject, vm: &VirtualMachine) -> PyResult< #[inline] fn is_decode_err(err: &PyObject, vm: &VirtualMachine) -> bool { - err.fast_isinstance(&vm.ctx.exceptions.unicode_decode_error) + err.fast_isinstance(vm.ctx.exceptions.unicode_decode_error) } #[inline] fn is_encode_ish_err(err: &PyObject, vm: &VirtualMachine) -> bool { - err.fast_isinstance(&vm.ctx.exceptions.unicode_encode_error) - || err.fast_isinstance(&vm.ctx.exceptions.unicode_translate_error) + err.fast_isinstance(vm.ctx.exceptions.unicode_encode_error) + || err.fast_isinstance(vm.ctx.exceptions.unicode_translate_error) } fn bad_err_type(err: PyObjectRef, vm: &VirtualMachine) -> PyBaseExceptionRef { @@ -393,12 +393,12 @@ fn ignore_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(PyObjectRef fn replace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(String, usize)> { // char::REPLACEMENT_CHARACTER as a str let replacement_char = "\u{FFFD}"; - let replace = if err.fast_isinstance(&vm.ctx.exceptions.unicode_encode_error) { + let replace = if err.fast_isinstance(vm.ctx.exceptions.unicode_encode_error) { "?" - } else if err.fast_isinstance(&vm.ctx.exceptions.unicode_decode_error) { + } else if err.fast_isinstance(vm.ctx.exceptions.unicode_decode_error) { let range = extract_unicode_error_range(&err, vm)?; return Ok((replacement_char.to_owned(), range.end)); - } else if err.fast_isinstance(&vm.ctx.exceptions.unicode_translate_error) { + } else if err.fast_isinstance(vm.ctx.exceptions.unicode_translate_error) { replacement_char } else { return Err(bad_err_type(err, vm)); @@ -456,7 +456,7 @@ fn backslashreplace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(S } fn namereplace_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(String, usize)> { - if err.fast_isinstance(&vm.ctx.exceptions.unicode_encode_error) { + if err.fast_isinstance(vm.ctx.exceptions.unicode_encode_error) { let range = extract_unicode_error_range(&err, vm)?; let s = PyStrRef::try_from_object(vm, err.get_attr("object", vm)?)?; let s_after_start = @@ -550,7 +550,7 @@ fn get_standard_encoding(encoding: &str) -> (usize, StandardEncoding) { } fn surrogatepass_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(String, usize)> { - if err.fast_isinstance(&vm.ctx.exceptions.unicode_encode_error) { + if err.fast_isinstance(vm.ctx.exceptions.unicode_encode_error) { let range = extract_unicode_error_range(&err, vm)?; let s = PyStrRef::try_from_object(vm, err.get_attr("object", vm)?)?; let s_encoding = PyStrRef::try_from_object(vm, err.get_attr("encoding", vm)?)?; @@ -662,7 +662,7 @@ fn surrogatepass_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(Stri } fn surrogateescape_errors(err: PyObjectRef, vm: &VirtualMachine) -> PyResult<(String, usize)> { - if err.fast_isinstance(&vm.ctx.exceptions.unicode_encode_error) { + if err.fast_isinstance(vm.ctx.exceptions.unicode_encode_error) { let range = extract_unicode_error_range(&err, vm)?; let s = PyStrRef::try_from_object(vm, err.get_attr("object", vm)?)?; let s_after_start = diff --git a/vm/src/convert/transmute_from.rs b/vm/src/convert/transmute_from.rs index 5931e106bb..908188f0d1 100644 --- a/vm/src/convert/transmute_from.rs +++ b/vm/src/convert/transmute_from.rs @@ -15,7 +15,7 @@ pub unsafe trait TransmuteFromObject: Sized { unsafe impl TransmuteFromObject for PyRef { fn check(vm: &VirtualMachine, obj: &PyObject) -> PyResult<()> { - let class = T::class(vm); + let class = T::class(&vm.ctx); if obj.fast_isinstance(class) { if obj.payload_is::() { Ok(()) diff --git a/vm/src/convert/try_from.rs b/vm/src/convert/try_from.rs index cd14896953..9a3a1f4bb7 100644 --- a/vm/src/convert/try_from.rs +++ b/vm/src/convert/try_from.rs @@ -43,7 +43,7 @@ impl PyObject { T: PyPayload, F: Fn(&T) -> PyResult, { - let class = T::class(vm); + let class = T::class(&vm.ctx); let special; let py_ref = if self.fast_isinstance(class) { self.downcast_ref() @@ -69,7 +69,7 @@ where { #[inline] fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { - let class = T::class(vm); + let class = T::class(&vm.ctx); if obj.fast_isinstance(class) { obj.downcast() .map_err(|obj| vm.new_downcast_runtime_error(class, &obj)) diff --git a/vm/src/coroutine.rs b/vm/src/coroutine.rs index 801fe5c834..6d6b743310 100644 --- a/vm/src/coroutine.rs +++ b/vm/src/coroutine.rs @@ -38,9 +38,9 @@ pub struct Coro { fn gen_name(gen: &PyObject, vm: &VirtualMachine) -> &'static str { let typ = gen.class(); - if typ.is(&vm.ctx.types.coroutine_type) { + if typ.is(vm.ctx.types.coroutine_type) { "coroutine" - } else if typ.is(&vm.ctx.types.async_generator) { + } else if typ.is(vm.ctx.types.async_generator) { "async generator" } else { "generator" @@ -112,13 +112,13 @@ impl Coro { match result { Ok(exec_res) => Ok(exec_res.into_iter_return(vm)), Err(e) => { - if e.fast_isinstance(&vm.ctx.exceptions.stop_iteration) { + if e.fast_isinstance(vm.ctx.exceptions.stop_iteration) { let err = vm.new_runtime_error(format!("{} raised StopIteration", gen_name(gen, vm))); err.set_cause(Some(e)); Err(err) - } else if gen.class().is(&vm.ctx.types.async_generator) - && e.fast_isinstance(&vm.ctx.exceptions.stop_async_iteration) + } else if gen.class().is(vm.ctx.types.async_generator) + && e.fast_isinstance(vm.ctx.exceptions.stop_async_iteration) { let err = vm .new_runtime_error("async generator raised StopAsyncIteration".to_owned()); @@ -153,7 +153,7 @@ impl Coro { let result = self.run_with_context(gen, vm, |f| { f.gen_throw( vm, - vm.ctx.exceptions.generator_exit.clone().into(), + vm.ctx.exceptions.generator_exit.to_owned().into(), vm.ctx.none(), vm.ctx.none(), ) @@ -194,5 +194,5 @@ impl Coro { } pub fn is_gen_exit(exc: &PyBaseExceptionRef, vm: &VirtualMachine) -> bool { - exc.fast_isinstance(&vm.ctx.exceptions.generator_exit) + exc.fast_isinstance(vm.ctx.exceptions.generator_exit) } diff --git a/vm/src/dictdatatype.rs b/vm/src/dictdatatype.rs index 487207e880..29e7d2d340 100644 --- a/vm/src/dictdatatype.rs +++ b/vm/src/dictdatatype.rs @@ -870,7 +870,7 @@ impl DictKey for usize { } fn str_exact<'a>(obj: &'a PyObject, vm: &VirtualMachine) -> Option<&'a PyStr> { - if obj.class().is(&vm.ctx.types.str_type) { + if obj.class().is(vm.ctx.types.str_type) { obj.payload::() } else { None diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 91bf73f160..e3b04f6b42 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -10,7 +10,7 @@ use crate::{ py_io::{self, Write}, stdlib::sys, suggestion::offer_suggestions, - AsObject, Context, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, + AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, }; use crossbeam_utils::atomic::AtomicCell; use itertools::Itertools; @@ -28,8 +28,9 @@ impl std::fmt::Debug for PyBaseException { } impl PyPayload for PyBaseException { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.exceptions.base_exception_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.exceptions.base_exception_type } } @@ -158,20 +159,20 @@ impl VirtualMachine { let args0_repr = if str_single { varargs[0] .str(vm) - .unwrap_or_else(|_| PyStr::from("").into_ref(vm)) + .unwrap_or_else(|_| PyStr::from("").into_ref(&vm.ctx)) } else { - varargs[0] - .repr(vm) - .unwrap_or_else(|_| PyStr::from("").into_ref(vm)) + varargs[0].repr(vm).unwrap_or_else(|_| { + PyStr::from("").into_ref(&vm.ctx) + }) }; vec![args0_repr] } _ => varargs .iter() .map(|vararg| { - vararg - .repr(vm) - .unwrap_or_else(|_| PyStr::from("").into_ref(vm)) + vararg.repr(vm).unwrap_or_else(|_| { + PyStr::from("").into_ref(&vm.ctx) + }) }) .collect(), } @@ -264,7 +265,7 @@ impl TryFromObject for ExceptionCtor { fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { obj.downcast::() .and_then(|cls| { - if cls.fast_issubclass(&vm.ctx.exceptions.base_exception_type) { + if cls.fast_issubclass(vm.ctx.exceptions.base_exception_type) { Ok(Self::Class(cls)) } else { Err(cls.into()) @@ -320,75 +321,75 @@ impl ExceptionCtor { #[derive(Debug, Clone)] pub struct ExceptionZoo { - pub base_exception_type: PyTypeRef, - pub system_exit: PyTypeRef, - pub keyboard_interrupt: PyTypeRef, - pub generator_exit: PyTypeRef, - pub exception_type: PyTypeRef, - pub stop_iteration: PyTypeRef, - pub stop_async_iteration: PyTypeRef, - pub arithmetic_error: PyTypeRef, - pub floating_point_error: PyTypeRef, - pub overflow_error: PyTypeRef, - pub zero_division_error: PyTypeRef, - pub assertion_error: PyTypeRef, - pub attribute_error: PyTypeRef, - pub buffer_error: PyTypeRef, - pub eof_error: PyTypeRef, - pub import_error: PyTypeRef, - pub module_not_found_error: PyTypeRef, - pub lookup_error: PyTypeRef, - pub index_error: PyTypeRef, - pub key_error: PyTypeRef, - pub memory_error: PyTypeRef, - pub name_error: PyTypeRef, - pub unbound_local_error: PyTypeRef, - pub os_error: PyTypeRef, - pub blocking_io_error: PyTypeRef, - pub child_process_error: PyTypeRef, - pub connection_error: PyTypeRef, - pub broken_pipe_error: PyTypeRef, - pub connection_aborted_error: PyTypeRef, - pub connection_refused_error: PyTypeRef, - pub connection_reset_error: PyTypeRef, - pub file_exists_error: PyTypeRef, - pub file_not_found_error: PyTypeRef, - pub interrupted_error: PyTypeRef, - pub is_a_directory_error: PyTypeRef, - pub not_a_directory_error: PyTypeRef, - pub permission_error: PyTypeRef, - pub process_lookup_error: PyTypeRef, - pub timeout_error: PyTypeRef, - pub reference_error: PyTypeRef, - pub runtime_error: PyTypeRef, - pub not_implemented_error: PyTypeRef, - pub recursion_error: PyTypeRef, - pub syntax_error: PyTypeRef, - pub indentation_error: PyTypeRef, - pub tab_error: PyTypeRef, - pub system_error: PyTypeRef, - pub type_error: PyTypeRef, - pub value_error: PyTypeRef, - pub unicode_error: PyTypeRef, - pub unicode_decode_error: PyTypeRef, - pub unicode_encode_error: PyTypeRef, - pub unicode_translate_error: PyTypeRef, + pub base_exception_type: &'static Py, + pub system_exit: &'static Py, + pub keyboard_interrupt: &'static Py, + pub generator_exit: &'static Py, + pub exception_type: &'static Py, + pub stop_iteration: &'static Py, + pub stop_async_iteration: &'static Py, + pub arithmetic_error: &'static Py, + pub floating_point_error: &'static Py, + pub overflow_error: &'static Py, + pub zero_division_error: &'static Py, + pub assertion_error: &'static Py, + pub attribute_error: &'static Py, + pub buffer_error: &'static Py, + pub eof_error: &'static Py, + pub import_error: &'static Py, + pub module_not_found_error: &'static Py, + pub lookup_error: &'static Py, + pub index_error: &'static Py, + pub key_error: &'static Py, + pub memory_error: &'static Py, + pub name_error: &'static Py, + pub unbound_local_error: &'static Py, + pub os_error: &'static Py, + pub blocking_io_error: &'static Py, + pub child_process_error: &'static Py, + pub connection_error: &'static Py, + pub broken_pipe_error: &'static Py, + pub connection_aborted_error: &'static Py, + pub connection_refused_error: &'static Py, + pub connection_reset_error: &'static Py, + pub file_exists_error: &'static Py, + pub file_not_found_error: &'static Py, + pub interrupted_error: &'static Py, + pub is_a_directory_error: &'static Py, + pub not_a_directory_error: &'static Py, + pub permission_error: &'static Py, + pub process_lookup_error: &'static Py, + pub timeout_error: &'static Py, + pub reference_error: &'static Py, + pub runtime_error: &'static Py, + pub not_implemented_error: &'static Py, + pub recursion_error: &'static Py, + pub syntax_error: &'static Py, + pub indentation_error: &'static Py, + pub tab_error: &'static Py, + pub system_error: &'static Py, + pub type_error: &'static Py, + pub value_error: &'static Py, + pub unicode_error: &'static Py, + pub unicode_decode_error: &'static Py, + pub unicode_encode_error: &'static Py, + pub unicode_translate_error: &'static Py, #[cfg(feature = "jit")] - pub jit_error: PyTypeRef, - - pub warning: PyTypeRef, - pub deprecation_warning: PyTypeRef, - pub pending_deprecation_warning: PyTypeRef, - pub runtime_warning: PyTypeRef, - pub syntax_warning: PyTypeRef, - pub user_warning: PyTypeRef, - pub future_warning: PyTypeRef, - pub import_warning: PyTypeRef, - pub unicode_warning: PyTypeRef, - pub bytes_warning: PyTypeRef, - pub resource_warning: PyTypeRef, - pub encoding_warning: PyTypeRef, + pub jit_error: &'static Py, + + pub warning: &'static Py, + pub deprecation_warning: &'static Py, + pub pending_deprecation_warning: &'static Py, + pub runtime_warning: &'static Py, + pub syntax_warning: &'static Py, + pub user_warning: &'static Py, + pub future_warning: &'static Py, + pub import_warning: &'static Py, + pub unicode_warning: &'static Py, + pub bytes_warning: &'static Py, + pub resource_warning: &'static Py, + pub encoding_warning: &'static Py, } macro_rules! extend_exception { @@ -509,7 +510,7 @@ impl PyBaseException { match str_args.into_iter().exactly_one() { Err(i) if i.len() == 0 => vm.ctx.empty_str.clone(), Ok(s) => s, - Err(i) => PyStr::from(format!("({})", i.format(", "))).into_ref(vm), + Err(i) => PyStr::from(format!("({})", i.format(", "))).into_ref(&vm.ctx), } } @@ -534,91 +535,91 @@ impl ExceptionZoo { pub(crate) fn init() -> Self { use self::types::*; - let base_exception_type = PyBaseException::init_bare_type().clone(); + let base_exception_type = PyBaseException::init_bare_type(); // Sorted By Hierarchy then alphabetized. - let system_exit = PySystemExit::init_bare_type().clone(); - let keyboard_interrupt = PyKeyboardInterrupt::init_bare_type().clone(); - let generator_exit = PyGeneratorExit::init_bare_type().clone(); + let system_exit = PySystemExit::init_bare_type(); + let keyboard_interrupt = PyKeyboardInterrupt::init_bare_type(); + let generator_exit = PyGeneratorExit::init_bare_type(); - let exception_type = PyException::init_bare_type().clone(); - let stop_iteration = PyStopIteration::init_bare_type().clone(); - let stop_async_iteration = PyStopAsyncIteration::init_bare_type().clone(); - let arithmetic_error = PyArithmeticError::init_bare_type().clone(); - let floating_point_error = PyFloatingPointError::init_bare_type().clone(); - let overflow_error = PyOverflowError::init_bare_type().clone(); - let zero_division_error = PyZeroDivisionError::init_bare_type().clone(); + let exception_type = PyException::init_bare_type(); + let stop_iteration = PyStopIteration::init_bare_type(); + let stop_async_iteration = PyStopAsyncIteration::init_bare_type(); + let arithmetic_error = PyArithmeticError::init_bare_type(); + let floating_point_error = PyFloatingPointError::init_bare_type(); + let overflow_error = PyOverflowError::init_bare_type(); + let zero_division_error = PyZeroDivisionError::init_bare_type(); - let assertion_error = PyAssertionError::init_bare_type().clone(); - let attribute_error = PyAttributeError::init_bare_type().clone(); - let buffer_error = PyBufferError::init_bare_type().clone(); - let eof_error = PyEOFError::init_bare_type().clone(); + let assertion_error = PyAssertionError::init_bare_type(); + let attribute_error = PyAttributeError::init_bare_type(); + let buffer_error = PyBufferError::init_bare_type(); + let eof_error = PyEOFError::init_bare_type(); - let import_error = PyImportError::init_bare_type().clone(); - let module_not_found_error = PyModuleNotFoundError::init_bare_type().clone(); + let import_error = PyImportError::init_bare_type(); + let module_not_found_error = PyModuleNotFoundError::init_bare_type(); - let lookup_error = PyLookupError::init_bare_type().clone(); - let index_error = PyIndexError::init_bare_type().clone(); - let key_error = PyKeyError::init_bare_type().clone(); + let lookup_error = PyLookupError::init_bare_type(); + let index_error = PyIndexError::init_bare_type(); + let key_error = PyKeyError::init_bare_type(); - let memory_error = PyMemoryError::init_bare_type().clone(); + let memory_error = PyMemoryError::init_bare_type(); - let name_error = PyNameError::init_bare_type().clone(); - let unbound_local_error = PyUnboundLocalError::init_bare_type().clone(); + let name_error = PyNameError::init_bare_type(); + let unbound_local_error = PyUnboundLocalError::init_bare_type(); // os errors - let os_error = PyOSError::init_bare_type().clone(); - let blocking_io_error = PyBlockingIOError::init_bare_type().clone(); - let child_process_error = PyChildProcessError::init_bare_type().clone(); - - let connection_error = PyConnectionError::init_bare_type().clone(); - let broken_pipe_error = PyBrokenPipeError::init_bare_type().clone(); - let connection_aborted_error = PyConnectionAbortedError::init_bare_type().clone(); - let connection_refused_error = PyConnectionRefusedError::init_bare_type().clone(); - let connection_reset_error = PyConnectionResetError::init_bare_type().clone(); - - let file_exists_error = PyFileExistsError::init_bare_type().clone(); - let file_not_found_error = PyFileNotFoundError::init_bare_type().clone(); - let interrupted_error = PyInterruptedError::init_bare_type().clone(); - let is_a_directory_error = PyIsADirectoryError::init_bare_type().clone(); - let not_a_directory_error = PyNotADirectoryError::init_bare_type().clone(); - let permission_error = PyPermissionError::init_bare_type().clone(); - let process_lookup_error = PyProcessLookupError::init_bare_type().clone(); - let timeout_error = PyTimeoutError::init_bare_type().clone(); - - let reference_error = PyReferenceError::init_bare_type().clone(); - - let runtime_error = PyRuntimeError::init_bare_type().clone(); - let not_implemented_error = PyNotImplementedError::init_bare_type().clone(); - let recursion_error = PyRecursionError::init_bare_type().clone(); - - let syntax_error = PySyntaxError::init_bare_type().clone(); - let indentation_error = PyIndentationError::init_bare_type().clone(); - let tab_error = PyTabError::init_bare_type().clone(); - - let system_error = PySystemError::init_bare_type().clone(); - let type_error = PyTypeError::init_bare_type().clone(); - let value_error = PyValueError::init_bare_type().clone(); - let unicode_error = PyUnicodeError::init_bare_type().clone(); - let unicode_decode_error = PyUnicodeDecodeError::init_bare_type().clone(); - let unicode_encode_error = PyUnicodeEncodeError::init_bare_type().clone(); - let unicode_translate_error = PyUnicodeTranslateError::init_bare_type().clone(); + let os_error = PyOSError::init_bare_type(); + let blocking_io_error = PyBlockingIOError::init_bare_type(); + let child_process_error = PyChildProcessError::init_bare_type(); + + let connection_error = PyConnectionError::init_bare_type(); + let broken_pipe_error = PyBrokenPipeError::init_bare_type(); + let connection_aborted_error = PyConnectionAbortedError::init_bare_type(); + let connection_refused_error = PyConnectionRefusedError::init_bare_type(); + let connection_reset_error = PyConnectionResetError::init_bare_type(); + + let file_exists_error = PyFileExistsError::init_bare_type(); + let file_not_found_error = PyFileNotFoundError::init_bare_type(); + let interrupted_error = PyInterruptedError::init_bare_type(); + let is_a_directory_error = PyIsADirectoryError::init_bare_type(); + let not_a_directory_error = PyNotADirectoryError::init_bare_type(); + let permission_error = PyPermissionError::init_bare_type(); + let process_lookup_error = PyProcessLookupError::init_bare_type(); + let timeout_error = PyTimeoutError::init_bare_type(); + + let reference_error = PyReferenceError::init_bare_type(); + + let runtime_error = PyRuntimeError::init_bare_type(); + let not_implemented_error = PyNotImplementedError::init_bare_type(); + let recursion_error = PyRecursionError::init_bare_type(); + + let syntax_error = PySyntaxError::init_bare_type(); + let indentation_error = PyIndentationError::init_bare_type(); + let tab_error = PyTabError::init_bare_type(); + + let system_error = PySystemError::init_bare_type(); + let type_error = PyTypeError::init_bare_type(); + let value_error = PyValueError::init_bare_type(); + let unicode_error = PyUnicodeError::init_bare_type(); + let unicode_decode_error = PyUnicodeDecodeError::init_bare_type(); + let unicode_encode_error = PyUnicodeEncodeError::init_bare_type(); + let unicode_translate_error = PyUnicodeTranslateError::init_bare_type(); #[cfg(feature = "jit")] - let jit_error = PyJitError::init_bare_type().clone(); - - let warning = PyWarning::init_bare_type().clone(); - let deprecation_warning = PyDeprecationWarning::init_bare_type().clone(); - let pending_deprecation_warning = PyPendingDeprecationWarning::init_bare_type().clone(); - let runtime_warning = PyRuntimeWarning::init_bare_type().clone(); - let syntax_warning = PySyntaxWarning::init_bare_type().clone(); - let user_warning = PyUserWarning::init_bare_type().clone(); - let future_warning = PyFutureWarning::init_bare_type().clone(); - let import_warning = PyImportWarning::init_bare_type().clone(); - let unicode_warning = PyUnicodeWarning::init_bare_type().clone(); - let bytes_warning = PyBytesWarning::init_bare_type().clone(); - let resource_warning = PyResourceWarning::init_bare_type().clone(); - let encoding_warning = PyEncodingWarning::init_bare_type().clone(); + let jit_error = PyJitError::init_bare_type(); + + let warning = PyWarning::init_bare_type(); + let deprecation_warning = PyDeprecationWarning::init_bare_type(); + let pending_deprecation_warning = PyPendingDeprecationWarning::init_bare_type(); + let runtime_warning = PyRuntimeWarning::init_bare_type(); + let syntax_warning = PySyntaxWarning::init_bare_type(); + let user_warning = PyUserWarning::init_bare_type(); + let future_warning = PyFutureWarning::init_bare_type(); + let import_warning = PyImportWarning::init_bare_type(); + let unicode_warning = PyUnicodeWarning::init_bare_type(); + let bytes_warning = PyBytesWarning::init_bare_type(); + let resource_warning = PyResourceWarning::init_bare_type(); + let encoding_warning = PyEncodingWarning::init_bare_type(); Self { base_exception_type, @@ -700,160 +701,152 @@ impl ExceptionZoo { let excs = &ctx.exceptions; - PyBaseException::extend_class(ctx, &excs.base_exception_type); + PyBaseException::extend_class(ctx, excs.base_exception_type); // Sorted By Hierarchy then alphabetized. - extend_exception!(PySystemExit, ctx, &excs.system_exit, { - "code" => ctx.new_readonly_getset("code", excs.system_exit.clone(), system_exit_code), + extend_exception!(PySystemExit, ctx, excs.system_exit, { + "code" => ctx.new_readonly_getset("code", excs.system_exit, system_exit_code), }); - extend_exception!(PyKeyboardInterrupt, ctx, &excs.keyboard_interrupt); - extend_exception!(PyGeneratorExit, ctx, &excs.generator_exit); + extend_exception!(PyKeyboardInterrupt, ctx, excs.keyboard_interrupt); + extend_exception!(PyGeneratorExit, ctx, excs.generator_exit); - extend_exception!(PyException, ctx, &excs.exception_type); + extend_exception!(PyException, ctx, excs.exception_type); - extend_exception!(PyStopIteration, ctx, &excs.stop_iteration, { - "value" => ctx.new_readonly_getset("value", excs.stop_iteration.clone(), make_arg_getter(0)), + extend_exception!(PyStopIteration, ctx, excs.stop_iteration, { + "value" => ctx.new_readonly_getset("value", excs.stop_iteration, make_arg_getter(0)), }); - extend_exception!(PyStopAsyncIteration, ctx, &excs.stop_async_iteration); + extend_exception!(PyStopAsyncIteration, ctx, excs.stop_async_iteration); - extend_exception!(PyArithmeticError, ctx, &excs.arithmetic_error); - extend_exception!(PyFloatingPointError, ctx, &excs.floating_point_error); - extend_exception!(PyOverflowError, ctx, &excs.overflow_error); - extend_exception!(PyZeroDivisionError, ctx, &excs.zero_division_error); + extend_exception!(PyArithmeticError, ctx, excs.arithmetic_error); + extend_exception!(PyFloatingPointError, ctx, excs.floating_point_error); + extend_exception!(PyOverflowError, ctx, excs.overflow_error); + extend_exception!(PyZeroDivisionError, ctx, excs.zero_division_error); - extend_exception!(PyAssertionError, ctx, &excs.assertion_error); - extend_exception!(PyAttributeError, ctx, &excs.attribute_error, { + extend_exception!(PyAssertionError, ctx, excs.assertion_error); + extend_exception!(PyAttributeError, ctx, excs.attribute_error, { "name" => ctx.none(), "obj" => ctx.none(), }); - extend_exception!(PyBufferError, ctx, &excs.buffer_error); - extend_exception!(PyEOFError, ctx, &excs.eof_error); + extend_exception!(PyBufferError, ctx, excs.buffer_error); + extend_exception!(PyEOFError, ctx, excs.eof_error); - extend_exception!(PyImportError, ctx, &excs.import_error, { - "msg" => ctx.new_readonly_getset("msg", excs.import_error.clone(), make_arg_getter(0)), + extend_exception!(PyImportError, ctx, excs.import_error, { + "msg" => ctx.new_readonly_getset("msg", excs.import_error, make_arg_getter(0)), }); - extend_exception!(PyModuleNotFoundError, ctx, &excs.module_not_found_error); + extend_exception!(PyModuleNotFoundError, ctx, excs.module_not_found_error); - extend_exception!(PyLookupError, ctx, &excs.lookup_error); - extend_exception!(PyIndexError, ctx, &excs.index_error); - extend_exception!(PyKeyError, ctx, &excs.key_error, { - "__str__" => ctx.new_method("__str__", excs.key_error.clone(), key_error_str), + extend_exception!(PyLookupError, ctx, excs.lookup_error); + extend_exception!(PyIndexError, ctx, excs.index_error); + extend_exception!(PyKeyError, ctx, excs.key_error, { + "__str__" => ctx.new_method("__str__", excs.key_error, key_error_str), }); - extend_exception!(PyMemoryError, ctx, &excs.memory_error); - extend_exception!(PyNameError, ctx, &excs.name_error, { + extend_exception!(PyMemoryError, ctx, excs.memory_error); + extend_exception!(PyNameError, ctx, excs.name_error, { "name" => ctx.none(), }); - extend_exception!(PyUnboundLocalError, ctx, &excs.unbound_local_error); + extend_exception!(PyUnboundLocalError, ctx, excs.unbound_local_error); // os errors: let errno_getter = - ctx.new_readonly_getset("errno", excs.os_error.clone(), |exc: PyBaseExceptionRef| { + ctx.new_readonly_getset("errno", excs.os_error, |exc: PyBaseExceptionRef| { let args = exc.args(); args.get(0).filter(|_| args.len() > 1).cloned() }); - extend_exception!(PyOSError, ctx, &excs.os_error, { + extend_exception!(PyOSError, ctx, excs.os_error, { // POSIX exception code "errno" => errno_getter.clone(), // exception strerror - "strerror" => ctx.new_readonly_getset("strerror", excs.os_error.clone(), make_arg_getter(1)), + "strerror" => ctx.new_readonly_getset("strerror", excs.os_error, make_arg_getter(1)), // exception filename "filename" => ctx.none(), // second exception filename "filename2" => ctx.none(), - "__str__" => ctx.new_method("__str__", excs.os_error.clone(), os_error_str), + "__str__" => ctx.new_method("__str__", excs.os_error, os_error_str), }); // TODO: this isn't really accurate #[cfg(windows)] - excs.os_error.set_str_attr("winerror", errno_getter.clone()); - - extend_exception!(PyBlockingIOError, ctx, &excs.blocking_io_error); - extend_exception!(PyChildProcessError, ctx, &excs.child_process_error); - - extend_exception!(PyConnectionError, ctx, &excs.connection_error); - extend_exception!(PyBrokenPipeError, ctx, &excs.broken_pipe_error); - extend_exception!( - PyConnectionAbortedError, - ctx, - &excs.connection_aborted_error - ); - extend_exception!( - PyConnectionRefusedError, - ctx, - &excs.connection_refused_error - ); - extend_exception!(PyConnectionResetError, ctx, &excs.connection_reset_error); - - extend_exception!(PyFileExistsError, ctx, &excs.file_exists_error); - extend_exception!(PyFileNotFoundError, ctx, &excs.file_not_found_error); - extend_exception!(PyInterruptedError, ctx, &excs.interrupted_error); - extend_exception!(PyIsADirectoryError, ctx, &excs.is_a_directory_error); - extend_exception!(PyNotADirectoryError, ctx, &excs.not_a_directory_error); - extend_exception!(PyPermissionError, ctx, &excs.permission_error); - extend_exception!(PyProcessLookupError, ctx, &excs.process_lookup_error); - extend_exception!(PyTimeoutError, ctx, &excs.timeout_error); - - extend_exception!(PyReferenceError, ctx, &excs.reference_error); - extend_exception!(PyRuntimeError, ctx, &excs.runtime_error); - extend_exception!(PyNotImplementedError, ctx, &excs.not_implemented_error); - extend_exception!(PyRecursionError, ctx, &excs.recursion_error); - - extend_exception!(PySyntaxError, ctx, &excs.syntax_error, { - "msg" => ctx.new_readonly_getset("msg", excs.syntax_error.clone(), make_arg_getter(0)), + excs.os_error.set_str_attr("winerror", errno_getter); + + extend_exception!(PyBlockingIOError, ctx, excs.blocking_io_error); + extend_exception!(PyChildProcessError, ctx, excs.child_process_error); + + extend_exception!(PyConnectionError, ctx, excs.connection_error); + extend_exception!(PyBrokenPipeError, ctx, excs.broken_pipe_error); + extend_exception!(PyConnectionAbortedError, ctx, excs.connection_aborted_error); + extend_exception!(PyConnectionRefusedError, ctx, excs.connection_refused_error); + extend_exception!(PyConnectionResetError, ctx, excs.connection_reset_error); + + extend_exception!(PyFileExistsError, ctx, excs.file_exists_error); + extend_exception!(PyFileNotFoundError, ctx, excs.file_not_found_error); + extend_exception!(PyInterruptedError, ctx, excs.interrupted_error); + extend_exception!(PyIsADirectoryError, ctx, excs.is_a_directory_error); + extend_exception!(PyNotADirectoryError, ctx, excs.not_a_directory_error); + extend_exception!(PyPermissionError, ctx, excs.permission_error); + extend_exception!(PyProcessLookupError, ctx, excs.process_lookup_error); + extend_exception!(PyTimeoutError, ctx, excs.timeout_error); + + extend_exception!(PyReferenceError, ctx, excs.reference_error); + extend_exception!(PyRuntimeError, ctx, excs.runtime_error); + extend_exception!(PyNotImplementedError, ctx, excs.not_implemented_error); + extend_exception!(PyRecursionError, ctx, excs.recursion_error); + + extend_exception!(PySyntaxError, ctx, excs.syntax_error, { + "msg" => ctx.new_readonly_getset("msg", excs.syntax_error, make_arg_getter(0)), // TODO: members "filename" => ctx.none(), "lineno" => ctx.none(), "offset" => ctx.none(), "text" => ctx.none(), }); - extend_exception!(PyIndentationError, ctx, &excs.indentation_error); - extend_exception!(PyTabError, ctx, &excs.tab_error); - - extend_exception!(PySystemError, ctx, &excs.system_error); - extend_exception!(PyTypeError, ctx, &excs.type_error); - extend_exception!(PyValueError, ctx, &excs.value_error); - extend_exception!(PyUnicodeError, ctx, &excs.unicode_error); - extend_exception!(PyUnicodeDecodeError, ctx, &excs.unicode_decode_error, { - "encoding" => ctx.new_readonly_getset("encoding", excs.unicode_decode_error.clone(), make_arg_getter(0)), - "object" => ctx.new_readonly_getset("object", excs.unicode_decode_error.clone(), make_arg_getter(1)), - "start" => ctx.new_readonly_getset("start", excs.unicode_decode_error.clone(), make_arg_getter(2)), - "end" => ctx.new_readonly_getset("end", excs.unicode_decode_error.clone(), make_arg_getter(3)), - "reason" => ctx.new_readonly_getset("reason", excs.unicode_decode_error.clone(), make_arg_getter(4)), + extend_exception!(PyIndentationError, ctx, excs.indentation_error); + extend_exception!(PyTabError, ctx, excs.tab_error); + + extend_exception!(PySystemError, ctx, excs.system_error); + extend_exception!(PyTypeError, ctx, excs.type_error); + extend_exception!(PyValueError, ctx, excs.value_error); + extend_exception!(PyUnicodeError, ctx, excs.unicode_error); + extend_exception!(PyUnicodeDecodeError, ctx, excs.unicode_decode_error, { + "encoding" => ctx.new_readonly_getset("encoding", excs.unicode_decode_error, make_arg_getter(0)), + "object" => ctx.new_readonly_getset("object", excs.unicode_decode_error, make_arg_getter(1)), + "start" => ctx.new_readonly_getset("start", excs.unicode_decode_error, make_arg_getter(2)), + "end" => ctx.new_readonly_getset("end", excs.unicode_decode_error, make_arg_getter(3)), + "reason" => ctx.new_readonly_getset("reason", excs.unicode_decode_error, make_arg_getter(4)), }); - extend_exception!(PyUnicodeEncodeError, ctx, &excs.unicode_encode_error, { - "encoding" => ctx.new_readonly_getset("encoding", excs.unicode_encode_error.clone(), make_arg_getter(0)), - "object" => ctx.new_readonly_getset("object", excs.unicode_encode_error.clone(), make_arg_getter(1)), - "start" => ctx.new_readonly_getset("start", excs.unicode_encode_error.clone(), make_arg_getter(2), ), - "end" => ctx.new_readonly_getset("end", excs.unicode_encode_error.clone(), make_arg_getter(3)), - "reason" => ctx.new_readonly_getset("reason", excs.unicode_encode_error.clone(), make_arg_getter(4)), + extend_exception!(PyUnicodeEncodeError, ctx, excs.unicode_encode_error, { + "encoding" => ctx.new_readonly_getset("encoding", excs.unicode_encode_error, make_arg_getter(0)), + "object" => ctx.new_readonly_getset("object", excs.unicode_encode_error, make_arg_getter(1)), + "start" => ctx.new_readonly_getset("start", excs.unicode_encode_error, make_arg_getter(2), ), + "end" => ctx.new_readonly_getset("end", excs.unicode_encode_error, make_arg_getter(3)), + "reason" => ctx.new_readonly_getset("reason", excs.unicode_encode_error, make_arg_getter(4)), }); - extend_exception!(PyUnicodeTranslateError, ctx, &excs.unicode_translate_error, { - "encoding" => ctx.new_readonly_getset("encoding", excs.unicode_translate_error.clone(), none_getter), - "object" => ctx.new_readonly_getset("object", excs.unicode_translate_error.clone(), make_arg_getter(0)), - "start" => ctx.new_readonly_getset("start", excs.unicode_translate_error.clone(), make_arg_getter(1)), - "end" => ctx.new_readonly_getset("end", excs.unicode_translate_error.clone(), make_arg_getter(2)), - "reason" => ctx.new_readonly_getset("reason", excs.unicode_translate_error.clone(), make_arg_getter(3)), + extend_exception!(PyUnicodeTranslateError, ctx, excs.unicode_translate_error, { + "encoding" => ctx.new_readonly_getset("encoding", excs.unicode_translate_error, none_getter), + "object" => ctx.new_readonly_getset("object", excs.unicode_translate_error, make_arg_getter(0)), + "start" => ctx.new_readonly_getset("start", excs.unicode_translate_error, make_arg_getter(1)), + "end" => ctx.new_readonly_getset("end", excs.unicode_translate_error, make_arg_getter(2)), + "reason" => ctx.new_readonly_getset("reason", excs.unicode_translate_error, make_arg_getter(3)), }); #[cfg(feature = "jit")] - extend_exception!(PyJitError, ctx, &excs.jit_error); + extend_exception!(PyJitError, ctx, excs.jit_error); - extend_exception!(PyWarning, ctx, &excs.warning); - extend_exception!(PyDeprecationWarning, ctx, &excs.deprecation_warning); + extend_exception!(PyWarning, ctx, excs.warning); + extend_exception!(PyDeprecationWarning, ctx, excs.deprecation_warning); extend_exception!( PyPendingDeprecationWarning, ctx, - &excs.pending_deprecation_warning + excs.pending_deprecation_warning ); - extend_exception!(PyRuntimeWarning, ctx, &excs.runtime_warning); - extend_exception!(PySyntaxWarning, ctx, &excs.syntax_warning); - extend_exception!(PyUserWarning, ctx, &excs.user_warning); - extend_exception!(PyFutureWarning, ctx, &excs.future_warning); - extend_exception!(PyImportWarning, ctx, &excs.import_warning); - extend_exception!(PyUnicodeWarning, ctx, &excs.unicode_warning); - extend_exception!(PyBytesWarning, ctx, &excs.bytes_warning); - extend_exception!(PyResourceWarning, ctx, &excs.resource_warning); - extend_exception!(PyEncodingWarning, ctx, &excs.encoding_warning); + extend_exception!(PyRuntimeWarning, ctx, excs.runtime_warning); + extend_exception!(PySyntaxWarning, ctx, excs.syntax_warning); + extend_exception!(PyUserWarning, ctx, excs.user_warning); + extend_exception!(PyFutureWarning, ctx, excs.future_warning); + extend_exception!(PyImportWarning, ctx, excs.import_warning); + extend_exception!(PyUnicodeWarning, ctx, excs.unicode_warning); + extend_exception!(PyBytesWarning, ctx, excs.bytes_warning); + extend_exception!(PyResourceWarning, ctx, excs.resource_warning); + extend_exception!(PyEncodingWarning, ctx, excs.encoding_warning); } } @@ -1006,35 +999,41 @@ impl ToPyException for widestring::NulError { } #[cfg(any(unix, windows, target_os = "wasi"))] -pub(crate) fn raw_os_error_to_exc_type(errno: i32, vm: &VirtualMachine) -> Option { +pub(crate) fn raw_os_error_to_exc_type( + errno: i32, + vm: &VirtualMachine, +) -> Option<&'static Py> { use crate::stdlib::errno::errors; let excs = &vm.ctx.exceptions; match errno { - errors::EWOULDBLOCK => Some(excs.blocking_io_error.clone()), - errors::EALREADY => Some(excs.blocking_io_error.clone()), - errors::EINPROGRESS => Some(excs.blocking_io_error.clone()), - errors::EPIPE => Some(excs.broken_pipe_error.clone()), + errors::EWOULDBLOCK => Some(excs.blocking_io_error), + errors::EALREADY => Some(excs.blocking_io_error), + errors::EINPROGRESS => Some(excs.blocking_io_error), + errors::EPIPE => Some(excs.broken_pipe_error), #[cfg(not(target_os = "wasi"))] - errors::ESHUTDOWN => Some(excs.broken_pipe_error.clone()), - errors::ECHILD => Some(excs.child_process_error.clone()), - errors::ECONNABORTED => Some(excs.connection_aborted_error.clone()), - errors::ECONNREFUSED => Some(excs.connection_refused_error.clone()), - errors::ECONNRESET => Some(excs.connection_reset_error.clone()), - errors::EEXIST => Some(excs.file_exists_error.clone()), - errors::ENOENT => Some(excs.file_not_found_error.clone()), - errors::EISDIR => Some(excs.is_a_directory_error.clone()), - errors::ENOTDIR => Some(excs.not_a_directory_error.clone()), - errors::EINTR => Some(excs.interrupted_error.clone()), - errors::EACCES => Some(excs.permission_error.clone()), - errors::EPERM => Some(excs.permission_error.clone()), - errors::ESRCH => Some(excs.process_lookup_error.clone()), - errors::ETIMEDOUT => Some(excs.timeout_error.clone()), + errors::ESHUTDOWN => Some(excs.broken_pipe_error), + errors::ECHILD => Some(excs.child_process_error), + errors::ECONNABORTED => Some(excs.connection_aborted_error), + errors::ECONNREFUSED => Some(excs.connection_refused_error), + errors::ECONNRESET => Some(excs.connection_reset_error), + errors::EEXIST => Some(excs.file_exists_error), + errors::ENOENT => Some(excs.file_not_found_error), + errors::EISDIR => Some(excs.is_a_directory_error), + errors::ENOTDIR => Some(excs.not_a_directory_error), + errors::EINTR => Some(excs.interrupted_error), + errors::EACCES => Some(excs.permission_error), + errors::EPERM => Some(excs.permission_error), + errors::ESRCH => Some(excs.process_lookup_error), + errors::ETIMEDOUT => Some(excs.timeout_error), _ => None, } } #[cfg(all(target_arch = "wasm32", not(target_os = "wasi")))] -pub(crate) fn raw_os_error_to_exc_type(_errno: i32, _vm: &VirtualMachine) -> Option { +pub(crate) fn raw_os_error_to_exc_type( + _errno: i32, + _vm: &VirtualMachine, +) -> Option<&'static Py> { None } @@ -1252,7 +1251,7 @@ pub(super) mod types { .payload_if_subclass::(vm) .and_then(|errno| errno.try_to_primitive::(vm).ok()) .and_then(|errno| super::raw_os_error_to_exc_type(errno, vm)) - .and_then(|typ| vm.invoke_exception(typ, args.to_vec()).ok()) + .and_then(|typ| vm.invoke_exception(typ.to_owned(), args.to_vec()).ok()) } else { None } diff --git a/vm/src/frame.rs b/vm/src/frame.rs index a0d49b41b5..05a1ea0327 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -5,7 +5,7 @@ use crate::{ function::{PyCell, PyCellRef, PyFunction}, tuple::{PyTuple, PyTupleTyped}, PyBaseExceptionRef, PyCode, PyCoroutine, PyDict, PyDictRef, PyGenerator, PyList, PySet, - PySlice, PyStr, PyStrRef, PyTraceback, PyTypeRef, + PySlice, PyStr, PyStrRef, PyTraceback, PyType, }, bytecode, convert::{IntoObject, ToPyResult}, @@ -16,7 +16,7 @@ use crate::{ protocol::{PyIter, PyIterReturn}, scope::Scope, stdlib::builtins, - vm::PyMethod, + vm::{Context, PyMethod}, AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, }; use indexmap::IndexMap; @@ -114,8 +114,9 @@ pub struct Frame { } impl PyPayload for Frame { - fn class(vm: &VirtualMachine) -> &PyTypeRef { - &vm.ctx.types.frame_type + #[inline] + fn class(ctx: &Context) -> &'static Py { + ctx.types.frame_type } } @@ -136,7 +137,7 @@ impl Frame { closure: &[PyCellRef], vm: &VirtualMachine, ) -> Frame { - let cells_frees = std::iter::repeat_with(|| PyCell::default().into_ref(vm)) + let cells_frees = std::iter::repeat_with(|| PyCell::default().into_ref(&vm.ctx)) .take(code.cellvars.len()) .chain(closure.iter().cloned()) .collect(); @@ -190,7 +191,7 @@ impl FrameRef { for (k, v) in itertools::zip(&map[..j], &**fastlocals) { match locals.mapping().ass_subscript(k, v.clone(), vm) { Ok(()) => {} - Err(e) if e.fast_isinstance(&vm.ctx.exceptions.key_error) => {} + Err(e) if e.fast_isinstance(vm.ctx.exceptions.key_error) => {} Err(e) => return Err(e), } } @@ -203,7 +204,7 @@ impl FrameRef { } else { match locals.mapping().ass_subscript(k, None, vm) { Ok(()) => {} - Err(e) if e.fast_isinstance(&vm.ctx.exceptions.key_error) => {} + Err(e) if e.fast_isinstance(vm.ctx.exceptions.key_error) => {} Err(e) => return Err(e), } } @@ -346,7 +347,7 @@ impl ExecutingFrame<'_> { let new_traceback = PyTraceback::new(next, self.object.clone(), self.lasti(), loc.row()); vm_trace!("Adding to traceback: {:?} {:?}", new_traceback, loc.row()); - exception.set_traceback(Some(new_traceback.into_ref(vm))); + exception.set_traceback(Some(new_traceback.into_ref(&vm.ctx))); vm.contextualize_exception(&exception); @@ -404,7 +405,7 @@ impl ExecutingFrame<'_> { return ret.map(ExecutionResult::Yield).or_else(|err| { self.pop_value(); self.update_lasti(|i| *i += 1); - if err.fast_isinstance(&vm.ctx.exceptions.stop_iteration) { + if err.fast_isinstance(vm.ctx.exceptions.stop_iteration) { let val = vm.unwrap_or_none(err.get_arg(0)); self.push_value(val); self.run(vm) @@ -426,7 +427,7 @@ impl ExecutingFrame<'_> { fn unbound_cell_exception(&self, i: usize, vm: &VirtualMachine) -> PyBaseExceptionRef { if let Some(name) = self.code.cellvars.get(i) { vm.new_exception_msg( - vm.ctx.exceptions.unbound_local_error.clone(), + vm.ctx.exceptions.unbound_local_error.to_owned(), format!("local variable '{}' referenced before assignment", name), ) } else { @@ -484,7 +485,7 @@ impl ExecutingFrame<'_> { let idx = *idx as usize; let x = self.fastlocals.lock()[idx].clone().ok_or_else(|| { vm.new_exception_msg( - vm.ctx.exceptions.unbound_local_error.clone(), + vm.ctx.exceptions.unbound_local_error.to_owned(), format!( "local variable '{}' referenced before assignment", self.code.varnames[idx] @@ -561,7 +562,7 @@ impl ExecutingFrame<'_> { match res { Ok(()) => {} - Err(e) if e.fast_isinstance(&vm.ctx.exceptions.key_error) => { + Err(e) if e.fast_isinstance(vm.ctx.exceptions.key_error) => { return Err( vm.new_name_error(format!("name '{}' is not defined", name), name) ) @@ -574,7 +575,7 @@ impl ExecutingFrame<'_> { let name = &self.code.names[*idx as usize]; match self.globals.del_item(&**name, vm) { Ok(()) => {} - Err(e) if e.fast_isinstance(&vm.ctx.exceptions.key_error) => { + Err(e) if e.fast_isinstance(vm.ctx.exceptions.key_error) => { return Err( vm.new_name_error(format!("name '{}' is not defined", name), name) ) @@ -898,7 +899,7 @@ impl ExecutingFrame<'_> { bytecode::Instruction::EndAsyncFor => { let exc = self.pop_value(); self.pop_value(); // async iterator we were calling __anext__ on - if exc.fast_isinstance(&vm.ctx.exceptions.stop_async_iteration) { + if exc.fast_isinstance(vm.ctx.exceptions.stop_async_iteration) { vm.take_exception().expect("Should have exception in stack"); Ok(None) } else { @@ -1015,7 +1016,7 @@ impl ExecutingFrame<'_> { bytecode::Instruction::UnpackSequence { size } => { let value = self.pop_value(); let elements: Vec<_> = value.try_to_value(vm).map_err(|e| { - if e.class().is(&vm.ctx.exceptions.type_error) { + if e.class().is(vm.ctx.exceptions.type_error) { vm.new_type_error(format!( "cannot unpack non-iterable {} object", value.class().name() @@ -1320,7 +1321,7 @@ impl ExecutingFrame<'_> { stop, step, } - .into_ref(vm); + .into_ref(&vm.ctx); self.push_value(obj.into()); Ok(None) } diff --git a/vm/src/import.rs b/vm/src/import.rs index da37c6517b..c7c48dfb54 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -183,7 +183,7 @@ fn remove_importlib_frames_inner( traceback.lasti, traceback.lineno, ) - .into_ref(vm), + .into_ref(&vm.ctx), ), now_in_importlib, ) @@ -195,7 +195,7 @@ pub fn remove_importlib_frames( vm: &VirtualMachine, exc: &PyBaseExceptionRef, ) -> PyBaseExceptionRef { - let always_trim = exc.fast_isinstance(&vm.ctx.exceptions.import_error); + let always_trim = exc.fast_isinstance(vm.ctx.exceptions.import_error); if let Some(tb) = exc.traceback() { let trimmed_tb = remove_importlib_frames_inner(vm, Some(tb), always_trim).0; diff --git a/vm/src/intern.rs b/vm/src/intern.rs index c07828a82d..817871a194 100644 --- a/vm/src/intern.rs +++ b/vm/src/intern.rs @@ -2,7 +2,7 @@ use crate::{ builtins::{PyStr, PyTypeRef}, common::lock::PyRwLock, convert::ToPyObject, - Py, PyExact, PyObject, PyObjectRef, PyRef, PyRefExact, + AsObject, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, VirtualMachine, }; use std::{ borrow::{Borrow, ToOwned}, @@ -43,14 +43,17 @@ impl StringPool { let inserted = zelf.inner.write().insert(cache.clone()); if inserted { let interned = unsafe { PyStrInterned::borrow_cache(&cache) }; - // unsafe { interned.as_object().mark_intern() }; + unsafe { interned.as_object().mark_intern() }; interned } else { - zelf.inner - .read() - .get(cache.as_str()) - .map(|cached| unsafe { PyStrInterned::borrow_cache(cached) }) - .expect("") + unsafe { + PyStrInterned::borrow_cache( + zelf.inner + .read() + .get(cache.as_ref()) + .expect("inserted is false"), + ) + } } } let str_ref = s.into_pyref_exact(typ); @@ -110,83 +113,96 @@ impl CachedPyStrRef { } } -/// The unique reference of interned PyStr -/// Always intended to be used as a static reference -pub struct PyStrInterned { - inner: Py, +pub struct PyInterned +where + T: PyPayload, +{ + inner: Py, } -impl PyStrInterned { - /// # Safety - /// the given cache must be alive while returned reference is alive +impl PyInterned { #[inline] - unsafe fn borrow_cache(cache: &CachedPyStrRef) -> &'static Self { - std::mem::transmute_copy(cache) + pub fn leak(cache: PyRef) -> &'static Self { + unsafe { std::mem::transmute(cache) } } #[inline] - fn as_ptr(&self) -> *const Py { + fn as_ptr(&self) -> *const Py { self as *const _ as *const _ } #[inline] - pub fn to_owned(&'static self) -> PyRefExact { - unsafe { (*(&self as *const _ as *const PyRefExact)).clone() } - } - - #[inline] - pub fn to_str(&'static self) -> PyRef { - self.to_owned().into_pyref() + pub fn to_owned(&'static self) -> PyRef { + unsafe { (*(&self as *const _ as *const PyRef)).clone() } } #[inline] pub fn to_object(&'static self) -> PyObjectRef { - self.to_str().into() + self.to_owned().into() } } -impl Borrow for PyStrInterned { +impl Borrow for PyInterned { #[inline(always)] fn borrow(&self) -> &PyObject { self.inner.borrow() } } -impl Deref for PyStrInterned { - type Target = Py; +// NOTE: std::hash::Hash of Self and Self::Borrowed *must* be the same +// This is ok only because PyObject doesn't implement Hash +impl std::hash::Hash for PyInterned { #[inline(always)] - fn deref(&self) -> &Self::Target { - &self.inner + fn hash(&self, state: &mut H) { + self.get_id().hash(state) } } -impl std::hash::Hash for PyStrInterned { +impl Deref for PyInterned { + type Target = Py; #[inline(always)] - fn hash(&self, state: &mut H) { - std::hash::Hash::hash(&(self as *const _), state) + fn deref(&self) -> &Self::Target { + &self.inner } } -impl PartialEq for PyStrInterned { +impl PartialEq for PyInterned { #[inline(always)] fn eq(&self, other: &Self) -> bool { std::ptr::eq(self, other) } } -impl Eq for PyStrInterned {} +impl Eq for PyInterned {} -impl AsRef for PyStrInterned { - #[inline] - fn as_ref(&self) -> &str { - self.as_str() +impl std::fmt::Debug for PyInterned { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Debug::fmt(&**self, f)?; + write!(f, "@{:p}", self.as_ptr()) } } -impl std::fmt::Debug for PyStrInterned { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Debug::fmt(self.as_str(), f)?; - write!(f, "@{:p}", self.as_ptr()) +impl ToPyObject for &'static PyInterned { + fn to_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef { + self.to_owned().into() + } +} + +/// The unique reference of interned PyStr +/// Always intended to be used as a static reference +pub type PyStrInterned = PyInterned; + +impl PyStrInterned { + /// # Safety + /// the given cache must be alive while returned reference is alive + #[inline] + unsafe fn borrow_cache(cache: &CachedPyStrRef) -> &'static Self { + std::mem::transmute_copy(cache) + } + + #[inline] + pub fn to_exact(&'static self) -> PyRefExact { + unsafe { PyRefExact::new_unchecked(self.to_owned()) } } } @@ -196,6 +212,13 @@ impl std::fmt::Display for PyStrInterned { } } +impl AsRef for PyStrInterned { + #[inline(always)] + fn as_ref(&self) -> &str { + self.as_str() + } +} + mod sealed { use crate::{ builtins::PyStr, @@ -216,8 +239,12 @@ mod sealed { } /// A sealed marker trait for `DictKey` types that always become an exact instance of `str` -pub trait Internable: sealed::SealedInternable + ToPyObject + AsRef { - type Interned: ?Sized + MaybeInterned; +pub trait Internable +where + Self: sealed::SealedInternable + ToPyObject + AsRef, + Self::Interned: MaybeInterned, +{ + type Interned: ?Sized; fn into_pyref_exact(self, str_type: PyTypeRef) -> PyRefExact; } @@ -269,6 +296,24 @@ impl MaybeInterned for PyExact { impl MaybeInterned for Py { #[inline(always)] fn as_interned(&self) -> Option<&'static PyStrInterned> { - None + if self.as_object().is_interned() { + Some(unsafe { std::mem::transmute(self) }) + } else { + None + } + } +} + +impl PyObject { + #[inline] + pub fn as_interned_str(&self, vm: &crate::VirtualMachine) -> Option<&'static PyStrInterned> { + let s: Option<&Py> = self.downcast_ref(); + if self.is_interned() { + s.unwrap().as_interned() + } else if let Some(s) = s { + vm.ctx.interned_str(s.as_str()) + } else { + None + } } } diff --git a/vm/src/object/core.rs b/vm/src/object/core.rs index 19c7aa47ec..3f7e013482 100644 --- a/vm/src/object/core.rs +++ b/vm/src/object/core.rs @@ -555,7 +555,7 @@ impl PyObjectRef { self, vm: &VirtualMachine, ) -> Result, Self> { - if self.class().is(T::class(vm)) { + if self.class().is(T::class(&vm.ctx)) { // TODO: is this always true? assert!( self.payload_is::(), @@ -600,7 +600,7 @@ impl PyObject { } else { None }; - let cls_is_weakref = typ.is(&vm.ctx.types.weakref_type); + let cls_is_weakref = typ.is(vm.ctx.types.weakref_type); self.weak_ref_list() .map(|wrl| wrl.add(self, typ, cls_is_weakref, callback, dict)) .ok_or_else(|| { @@ -616,7 +616,7 @@ impl PyObject { callback: Option, vm: &VirtualMachine, ) -> PyResult> { - self.downgrade_with_typ(callback, vm.ctx.types.weakref_type.clone(), vm) + self.downgrade_with_typ(callback, vm.ctx.types.weakref_type.to_owned(), vm) } pub fn get_weak_references(&self) -> Option>> { @@ -650,7 +650,7 @@ impl PyObject { &self, vm: &VirtualMachine, ) -> Option<&T> { - if self.class().is(T::class(vm)) { + if self.class().is(T::class(&vm.ctx)) { self.payload() } else { None @@ -681,7 +681,7 @@ impl PyObject { #[inline(always)] pub fn payload_if_subclass(&self, vm: &VirtualMachine) -> Option<&T> { - if self.class().fast_issubclass(T::class(vm)) { + if self.class().fast_issubclass(T::class(&vm.ctx)) { self.payload() } else { None @@ -705,7 +705,7 @@ impl PyObject { vm: &VirtualMachine, ) -> Option<&Py> { self.class() - .is(T::class(vm)) + .is(T::class(&vm.ctx)) .then(|| unsafe { self.downcast_unchecked_ref::() }) } @@ -783,6 +783,16 @@ impl PyObject { // call drop only when there are no references in scope - stacked borrows stuff drop_dealloc(ptr.as_ptr()) } + + /// # Safety + /// This call will make the object live forever. + pub(crate) unsafe fn mark_intern(&self) { + self.0.ref_count.leak(); + } + + pub(crate) fn is_interned(&self) -> bool { + self.0.ref_count.is_leaked() + } } impl Borrow for PyObjectRef { @@ -958,6 +968,12 @@ impl PyRef { ptr: unsafe { NonNull::new_unchecked(inner.cast::>()) }, } } + + pub fn leak(pyref: Self) -> &'static Py { + let ptr = pyref.ptr; + std::mem::forget(pyref); + unsafe { &*ptr.as_ptr() } + } } impl Borrow for PyRef diff --git a/vm/src/object/ext.rs b/vm/src/object/ext.rs index 47b7b91d67..5214a0b505 100644 --- a/vm/src/object/ext.rs +++ b/vm/src/object/ext.rs @@ -143,7 +143,7 @@ impl Clone for PyRefExact { impl TryFromObject for PyRefExact { fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { - let target_cls = T::class(vm); + let target_cls = T::class(&vm.ctx); let cls = obj.class(); if cls.is(target_cls) { drop(cls); diff --git a/vm/src/object/payload.rs b/vm/src/object/payload.rs index 44b4f1174d..74b83e6592 100644 --- a/vm/src/object/payload.rs +++ b/vm/src/object/payload.rs @@ -1,8 +1,8 @@ -use super::{PyObject, PyObjectRef, PyRef, PyResult}; +use super::{Py, PyObject, PyObjectRef, PyRef, PyResult}; use crate::{ - builtins::{PyBaseExceptionRef, PyTypeRef}, + builtins::{PyBaseExceptionRef, PyType, PyTypeRef}, types::PyTypeFlags, - vm::VirtualMachine, + vm::{Context, VirtualMachine}, }; cfg_if::cfg_if! { @@ -16,11 +16,16 @@ cfg_if::cfg_if! { } pub trait PyPayload: std::fmt::Debug + PyThreadingConstraint + Sized + 'static { - fn class(vm: &VirtualMachine) -> &PyTypeRef; + fn class(ctx: &Context) -> &'static Py; + + #[inline] + fn new_ref(data: impl Into, ctx: &Context) -> PyRef { + PyRef::new_ref(data.into(), Self::class(ctx).to_owned(), None) + } #[inline] fn into_pyobject(self, vm: &VirtualMachine) -> PyObjectRef { - self.into_ref(vm).into() + self.into_ref(&vm.ctx).into() } #[inline(always)] @@ -29,9 +34,9 @@ pub trait PyPayload: std::fmt::Debug + PyThreadingConstraint + Sized + 'static { } #[inline] - fn _into_ref(self, cls: PyTypeRef, vm: &VirtualMachine) -> PyRef { + fn _into_ref(self, cls: PyTypeRef, ctx: &Context) -> PyRef { let dict = if cls.slots.flags.has_feature(PyTypeFlags::HAS_DICT) { - Some(vm.ctx.new_dict()) + Some(ctx.new_dict()) } else { None }; @@ -39,23 +44,23 @@ pub trait PyPayload: std::fmt::Debug + PyThreadingConstraint + Sized + 'static { } #[inline] - fn into_ref(self, vm: &VirtualMachine) -> PyRef { - let cls = Self::class(vm); - self._into_ref(cls.clone(), vm) + fn into_ref(self, ctx: &Context) -> PyRef { + let cls = Self::class(ctx); + self._into_ref(cls.to_owned(), ctx) } #[inline] fn into_ref_with_type(self, vm: &VirtualMachine, cls: PyTypeRef) -> PyResult> { - let exact_class = Self::class(vm); + let exact_class = Self::class(&vm.ctx); if cls.fast_issubclass(exact_class) { - Ok(self._into_ref(cls, vm)) + Ok(self._into_ref(cls, &vm.ctx)) } else { #[cold] #[inline(never)] fn _into_ref_with_type_error( vm: &VirtualMachine, cls: &PyTypeRef, - exact_class: &PyTypeRef, + exact_class: &Py, ) -> PyBaseExceptionRef { vm.new_type_error(format!( "'{}' is not a subtype of '{}'", diff --git a/vm/src/protocol/iter.rs b/vm/src/protocol/iter.rs index deef0c37ea..94371c74bd 100644 --- a/vm/src/protocol/iter.rs +++ b/vm/src/protocol/iter.rs @@ -153,7 +153,7 @@ impl PyIterReturn { pub fn from_pyresult(result: PyResult, vm: &VirtualMachine) -> PyResult { match result { Ok(obj) => Ok(Self::Return(obj)), - Err(err) if err.fast_isinstance(&vm.ctx.exceptions.stop_iteration) => { + Err(err) if err.fast_isinstance(vm.ctx.exceptions.stop_iteration) => { let args = err.get_arg(0); Ok(Self::StopIteration(args)) } @@ -164,10 +164,10 @@ impl PyIterReturn { pub fn from_getitem_result(result: PyResult, vm: &VirtualMachine) -> PyResult { match result { Ok(obj) => Ok(Self::Return(obj)), - Err(err) if err.fast_isinstance(&vm.ctx.exceptions.index_error) => { + Err(err) if err.fast_isinstance(vm.ctx.exceptions.index_error) => { Ok(Self::StopIteration(None)) } - Err(err) if err.fast_isinstance(&vm.ctx.exceptions.stop_iteration) => { + Err(err) if err.fast_isinstance(vm.ctx.exceptions.stop_iteration) => { let args = err.get_arg(0); Ok(Self::StopIteration(args)) } @@ -180,7 +180,7 @@ impl PyIterReturn { Self::Return(obj) => Ok(obj), Self::StopIteration(v) => Err({ let args = if let Some(v) = v { vec![v] } else { Vec::new() }; - vm.new_exception(vm.ctx.exceptions.stop_async_iteration.clone(), args) + vm.new_exception(vm.ctx.exceptions.stop_async_iteration.to_owned(), args) }), } } diff --git a/vm/src/protocol/mapping.rs b/vm/src/protocol/mapping.rs index f8ec7437d4..8ed06c4e5e 100644 --- a/vm/src/protocol/mapping.rs +++ b/vm/src/protocol/mapping.rs @@ -157,7 +157,7 @@ impl PyMapping<'_> { fn method_output_as_list(&self, method_name: &str, vm: &VirtualMachine) -> PyResult { let meth_output = vm.call_method(self.obj, method_name, ())?; - if meth_output.is(&vm.ctx.types.list_type) { + if meth_output.is(vm.ctx.types.list_type) { return Ok(meth_output); } diff --git a/vm/src/protocol/object.rs b/vm/src/protocol/object.rs index 5023eca11f..4861132a87 100644 --- a/vm/src/protocol/object.rs +++ b/vm/src/protocol/object.rs @@ -33,11 +33,11 @@ impl PyObjectRef { } pub fn bytes(self, vm: &VirtualMachine) -> PyResult { - let bytes_type = &vm.ctx.types.bytes_type; + let bytes_type = vm.ctx.types.bytes_type; match self.downcast_exact::(vm) { Ok(int) => Err(vm.new_downcast_type_error(bytes_type, &int)), Err(obj) => PyBytes::py_new( - bytes_type.clone(), + bytes_type.to_owned(), ByteInnerNewOptions { source: OptionalArg::Present(obj), encoding: OptionalArg::Missing, @@ -156,7 +156,7 @@ impl PyObject { dict.set_item(&*attr_name, value, vm)?; } else { dict.del_item(&*attr_name, vm).map_err(|e| { - if e.fast_isinstance(&vm.ctx.exceptions.key_error) { + if e.fast_isinstance(vm.ctx.exceptions.key_error) { vm.new_attribute_error(format!( "'{}' object has no attribute '{}'", self.class().name(), @@ -323,7 +323,7 @@ impl PyObject { // Container of the virtual machine state: pub fn str(&self, vm: &VirtualMachine) -> PyResult { - if self.class().is(&vm.ctx.types.str_type) { + if self.class().is(vm.ctx.types.str_type) { Ok(self.to_owned().downcast().unwrap()) } else { let s = vm.call_special_method(self.to_owned(), "__str__", ())?; @@ -339,7 +339,7 @@ impl PyObject { { cls.to_owned().get_attr("__bases__", vm).map_err(|e| { // Only mask AttributeErrors. - if e.class().is(&vm.ctx.exceptions.attribute_error) { + if e.class().is(vm.ctx.exceptions.attribute_error) { vm.new_type_error(msg()) } else { e @@ -404,7 +404,7 @@ impl PyObject { /// Determines if `self` is a subclass of `cls`, either directly, indirectly or virtually /// via the __subclasscheck__ magic method. pub fn is_subclass(&self, cls: &PyObject, vm: &VirtualMachine) -> PyResult { - if cls.class().is(&vm.ctx.types.type_type) { + if cls.class().is(vm.ctx.types.type_type) { if self.is(cls) { return Ok(true); } @@ -472,7 +472,7 @@ impl PyObject { return Ok(true); } - if cls.class().is(&vm.ctx.types.type_type) { + if cls.class().is(vm.ctx.types.type_type) { return self.abstract_isinstance(cls, vm); } @@ -532,8 +532,8 @@ impl PyObject { let i = needle.key_as_isize(vm)?; seq.get_item(i, vm) } else { - if self.class().fast_issubclass(&vm.ctx.types.type_type) { - if self.is(&vm.ctx.types.type_type) { + if self.class().fast_issubclass(vm.ctx.types.type_type) { + if self.is(vm.ctx.types.type_type) { return PyGenericAlias::new(self.class().clone(), needle, vm).to_pyresult(vm); } diff --git a/vm/src/protocol/sequence.rs b/vm/src/protocol/sequence.rs index 94f3b1fa40..ac15be3e06 100644 --- a/vm/src/protocol/sequence.rs +++ b/vm/src/protocol/sequence.rs @@ -96,7 +96,7 @@ impl PySequence<'_> { pub fn methods_cow(&self, vm: &VirtualMachine) -> &Cow<'static, PySequenceMethods> { self.methods.get_or_init(|| { let cls = self.obj.class(); - if !cls.is(&vm.ctx.types.dict_type) { + if !cls.is(vm.ctx.types.dict_type) { if let Some(f) = cls.mro_find_map(|x| x.slots.as_sequence.load()) { return f(self.obj, vm); } diff --git a/vm/src/py_io.rs b/vm/src/py_io.rs index b705765841..8091b75afc 100644 --- a/vm/src/py_io.rs +++ b/vm/src/py_io.rs @@ -64,7 +64,7 @@ pub fn file_readline(obj: &PyObject, size: Option, vm: &VirtualMachine) - let ret = vm.call_method(obj, "readline", args)?; let eof_err = || { vm.new_exception( - vm.ctx.exceptions.eof_error.clone(), + vm.ctx.exceptions.eof_error.to_owned(), vec![vm.ctx.new_str(ascii!("EOF when reading a line")).into()], ) }; diff --git a/vm/src/py_serde.rs b/vm/src/py_serde.rs index 7491c0064c..9a7fb3c92a 100644 --- a/vm/src/py_serde.rs +++ b/vm/src/py_serde.rs @@ -64,11 +64,11 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> { }; if let Some(s) = self.pyobject.payload::() { serializer.serialize_str(s.as_ref()) - } else if self.pyobject.fast_isinstance(&self.vm.ctx.types.float_type) { + } else if self.pyobject.fast_isinstance(self.vm.ctx.types.float_type) { serializer.serialize_f64(float::get_value(self.pyobject)) - } else if self.pyobject.fast_isinstance(&self.vm.ctx.types.bool_type) { + } else if self.pyobject.fast_isinstance(self.vm.ctx.types.bool_type) { serializer.serialize_bool(bool_::get_value(self.pyobject)) - } else if self.pyobject.fast_isinstance(&self.vm.ctx.types.int_type) { + } else if self.pyobject.fast_isinstance(self.vm.ctx.types.int_type) { let v = int::get_value(self.pyobject); let int_too_large = || serde::ser::Error::custom("int too large to serialize"); // TODO: serialize BigInt when it does not fit into i64 @@ -84,7 +84,7 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> { serialize_seq_elements(serializer, &list.borrow_vec()) } else if let Some(tuple) = self.pyobject.payload_if_subclass::(self.vm) { serialize_seq_elements(serializer, tuple) - } else if self.pyobject.fast_isinstance(&self.vm.ctx.types.dict_type) { + } else if self.pyobject.fast_isinstance(self.vm.ctx.types.dict_type) { let dict: PyDictRef = self.pyobject.to_owned().downcast().unwrap(); let pairs: Vec<_> = dict.into_iter().collect(); let mut map = serializer.serialize_map(Some(pairs.len()))?; diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs index 329bbd7a67..07c5f78ef0 100644 --- a/vm/src/stdlib/ast.rs +++ b/vm/src/stdlib/ast.rs @@ -6,9 +6,10 @@ mod gen; use crate::{ - builtins::{self, PyStrRef, PyTypeRef}, + builtins::{self, PyStrRef, PyType}, class::{PyClassImpl, StaticType}, - AsObject, Context, PyObject, PyObjectRef, PyPayload, PyResult, TryFromObject, VirtualMachine, + AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, TryFromObject, + VirtualMachine, }; use num_complex::Complex64; use num_traits::{ToPrimitive, Zero}; @@ -213,7 +214,7 @@ impl Node for ast::Constant { let constant = match_class!(match object { ref i @ builtins::int::PyInt => { let value = i.as_bigint(); - if object.class().is(&vm.ctx.types.bool_type) { + if object.class().is(vm.ctx.types.bool_type) { ast::Constant::Bool(!value.is_zero()) } else { ast::Constant::Int(value.clone()) diff --git a/vm/src/stdlib/ast/gen.rs b/vm/src/stdlib/ast/gen.rs index e094ee738d..80ccc774a8 100644 --- a/vm/src/stdlib/ast/gen.rs +++ b/vm/src/stdlib/ast/gen.rs @@ -14,7 +14,7 @@ struct NodeModule; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeModule { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -30,7 +30,7 @@ struct NodeInteractive; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeInteractive { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("body")).into()]), @@ -43,7 +43,7 @@ struct NodeExpression; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeExpression { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("body")).into()]), @@ -56,7 +56,7 @@ struct NodeFunctionType; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeFunctionType { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -76,7 +76,7 @@ struct NodeFunctionDef; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeFunctionDef { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -104,7 +104,7 @@ struct NodeAsyncFunctionDef; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeAsyncFunctionDef { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -132,7 +132,7 @@ struct NodeClassDef; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeClassDef { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -159,7 +159,7 @@ struct NodeReturn; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeReturn { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("value")).into()]), @@ -180,7 +180,7 @@ struct NodeDelete; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeDelete { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("targets")).into()]), @@ -201,7 +201,7 @@ struct NodeAssign; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeAssign { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -226,7 +226,7 @@ struct NodeAugAssign; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeAugAssign { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -251,7 +251,7 @@ struct NodeAnnAssign; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeAnnAssign { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -277,7 +277,7 @@ struct NodeFor; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeFor { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -304,7 +304,7 @@ struct NodeAsyncFor; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeAsyncFor { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -331,7 +331,7 @@ struct NodeWhile; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeWhile { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -356,7 +356,7 @@ struct NodeIf; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeIf { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -381,7 +381,7 @@ struct NodeWith; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeWith { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -406,7 +406,7 @@ struct NodeAsyncWith; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeAsyncWith { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -431,7 +431,7 @@ struct NodeRaise; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeRaise { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -455,7 +455,7 @@ struct NodeTry; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeTry { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -481,7 +481,7 @@ struct NodeAssert; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeAssert { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -505,7 +505,7 @@ struct NodeImport; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeImport { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("names")).into()]), @@ -526,7 +526,7 @@ struct NodeImportFrom; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeImportFrom { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -551,7 +551,7 @@ struct NodeGlobal; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeGlobal { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("names")).into()]), @@ -572,7 +572,7 @@ struct NodeNonlocal; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeNonlocal { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("names")).into()]), @@ -593,7 +593,7 @@ struct NodeExpr; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeExpr { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("value")).into()]), @@ -614,7 +614,7 @@ struct NodePass; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodePass { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr( "_attributes", @@ -632,7 +632,7 @@ struct NodeBreak; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeBreak { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr( "_attributes", @@ -650,7 +650,7 @@ struct NodeContinue; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeContinue { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr( "_attributes", @@ -672,7 +672,7 @@ struct NodeBoolOp; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeBoolOp { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -696,7 +696,7 @@ struct NodeNamedExpr; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeNamedExpr { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -720,7 +720,7 @@ struct NodeBinOp; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeBinOp { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -745,7 +745,7 @@ struct NodeUnaryOp; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeUnaryOp { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -769,7 +769,7 @@ struct NodeLambda; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeLambda { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -793,7 +793,7 @@ struct NodeIfExp; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeIfExp { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -818,7 +818,7 @@ struct NodeDict; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeDict { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -842,7 +842,7 @@ struct NodeSet; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeSet { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("elts")).into()]), @@ -863,7 +863,7 @@ struct NodeListComp; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeListComp { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -887,7 +887,7 @@ struct NodeSetComp; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeSetComp { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -911,7 +911,7 @@ struct NodeDictComp; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeDictComp { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -936,7 +936,7 @@ struct NodeGeneratorExp; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeGeneratorExp { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -960,7 +960,7 @@ struct NodeAwait; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeAwait { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("value")).into()]), @@ -981,7 +981,7 @@ struct NodeYield; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeYield { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("value")).into()]), @@ -1002,7 +1002,7 @@ struct NodeYieldFrom; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeYieldFrom { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("value")).into()]), @@ -1023,7 +1023,7 @@ struct NodeCompare; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeCompare { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1048,7 +1048,7 @@ struct NodeCall; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeCall { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1073,7 +1073,7 @@ struct NodeFormattedValue; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeFormattedValue { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1098,7 +1098,7 @@ struct NodeJoinedStr; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeJoinedStr { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ctx.new_str(ascii!("values")).into()]), @@ -1119,7 +1119,7 @@ struct NodeConstant; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeConstant { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1143,7 +1143,7 @@ struct NodeAttribute; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeAttribute { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1168,7 +1168,7 @@ struct NodeSubscript; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeSubscript { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1193,7 +1193,7 @@ struct NodeStarred; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeStarred { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1217,7 +1217,7 @@ struct NodeName; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeName { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1241,7 +1241,7 @@ struct NodeList; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeList { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1265,7 +1265,7 @@ struct NodeTuple; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeTuple { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1289,7 +1289,7 @@ struct NodeSlice; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeSlice { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1318,7 +1318,7 @@ struct NodeLoad; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeLoad { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1328,7 +1328,7 @@ struct NodeStore; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeStore { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1338,7 +1338,7 @@ struct NodeDel; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeDel { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1352,7 +1352,7 @@ struct NodeAnd; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeAnd { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1362,7 +1362,7 @@ struct NodeOr; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeOr { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1376,7 +1376,7 @@ struct NodeAdd; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeAdd { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1386,7 +1386,7 @@ struct NodeSub; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeSub { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1396,7 +1396,7 @@ struct NodeMult; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeMult { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1406,7 +1406,7 @@ struct NodeMatMult; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeMatMult { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1416,7 +1416,7 @@ struct NodeDiv; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeDiv { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1426,7 +1426,7 @@ struct NodeMod; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeMod { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1436,7 +1436,7 @@ struct NodePow; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodePow { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1446,7 +1446,7 @@ struct NodeLShift; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeLShift { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1456,7 +1456,7 @@ struct NodeRShift; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeRShift { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1466,7 +1466,7 @@ struct NodeBitOr; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeBitOr { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1476,7 +1476,7 @@ struct NodeBitXor; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeBitXor { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1486,7 +1486,7 @@ struct NodeBitAnd; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeBitAnd { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1496,7 +1496,7 @@ struct NodeFloorDiv; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeFloorDiv { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1510,7 +1510,7 @@ struct NodeInvert; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeInvert { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1520,7 +1520,7 @@ struct NodeNot; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeNot { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1530,7 +1530,7 @@ struct NodeUAdd; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeUAdd { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1540,7 +1540,7 @@ struct NodeUSub; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeUSub { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1554,7 +1554,7 @@ struct NodeEq; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeEq { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1564,7 +1564,7 @@ struct NodeNotEq; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeNotEq { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1574,7 +1574,7 @@ struct NodeLt; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeLt { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1584,7 +1584,7 @@ struct NodeLtE; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeLtE { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1594,7 +1594,7 @@ struct NodeGt; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeGt { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1604,7 +1604,7 @@ struct NodeGtE; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeGtE { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1614,7 +1614,7 @@ struct NodeIs; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeIs { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1624,7 +1624,7 @@ struct NodeIsNot; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeIsNot { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1634,7 +1634,7 @@ struct NodeIn; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeIn { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1644,7 +1644,7 @@ struct NodeNotIn; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeNotIn { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr("_fields", ctx.new_list(vec![])); class.set_str_attr("_attributes", ctx.new_list(vec![])); } @@ -1654,7 +1654,7 @@ struct Nodecomprehension; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl Nodecomprehension { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1680,7 +1680,7 @@ struct NodeExceptHandler; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeExceptHandler { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1705,7 +1705,7 @@ struct Nodearguments; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl Nodearguments { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1726,7 +1726,7 @@ struct Nodearg; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl Nodearg { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1751,7 +1751,7 @@ struct Nodekeyword; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl Nodekeyword { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1775,7 +1775,7 @@ struct Nodealias; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl Nodealias { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1791,7 +1791,7 @@ struct Nodewithitem; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl Nodewithitem { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1811,7 +1811,7 @@ struct NodeTypeIgnore; #[pyimpl(flags(HAS_DICT, BASETYPE))] impl NodeTypeIgnore { #[extend_class] - fn extend_class_with_fields(ctx: &Context, class: &PyTypeRef) { + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { class.set_str_attr( "_fields", ctx.new_list(vec![ @@ -1831,7 +1831,7 @@ impl Node for ast::Mod { match self { ast::Mod::Module { body, type_ignores } => { let _node = AstNode - .into_ref_with_type(_vm, NodeModule::static_type().clone()) + .into_ref_with_type(_vm, NodeModule::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -1844,7 +1844,7 @@ impl Node for ast::Mod { } ast::Mod::Interactive { body } => { let _node = AstNode - .into_ref_with_type(_vm, NodeInteractive::static_type().clone()) + .into_ref_with_type(_vm, NodeInteractive::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -1854,7 +1854,7 @@ impl Node for ast::Mod { } ast::Mod::Expression { body } => { let _node = AstNode - .into_ref_with_type(_vm, NodeExpression::static_type().clone()) + .into_ref_with_type(_vm, NodeExpression::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -1864,7 +1864,7 @@ impl Node for ast::Mod { } ast::Mod::FunctionType { argtypes, returns } => { let _node = AstNode - .into_ref_with_type(_vm, NodeFunctionType::static_type().clone()) + .into_ref_with_type(_vm, NodeFunctionType::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -1929,7 +1929,7 @@ impl Node for ast::StmtKind { type_comment, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeFunctionDef::static_type().clone()) + .into_ref_with_type(_vm, NodeFunctionDef::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -1961,7 +1961,7 @@ impl Node for ast::StmtKind { type_comment, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeAsyncFunctionDef::static_type().clone()) + .into_ref_with_type(_vm, NodeAsyncFunctionDef::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -1992,7 +1992,7 @@ impl Node for ast::StmtKind { decorator_list, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeClassDef::static_type().clone()) + .into_ref_with_type(_vm, NodeClassDef::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2014,7 +2014,7 @@ impl Node for ast::StmtKind { } ast::StmtKind::Return { value } => { let _node = AstNode - .into_ref_with_type(_vm, NodeReturn::static_type().clone()) + .into_ref_with_type(_vm, NodeReturn::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2024,7 +2024,7 @@ impl Node for ast::StmtKind { } ast::StmtKind::Delete { targets } => { let _node = AstNode - .into_ref_with_type(_vm, NodeDelete::static_type().clone()) + .into_ref_with_type(_vm, NodeDelete::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2038,7 +2038,7 @@ impl Node for ast::StmtKind { type_comment, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeAssign::static_type().clone()) + .into_ref_with_type(_vm, NodeAssign::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2054,7 +2054,7 @@ impl Node for ast::StmtKind { } ast::StmtKind::AugAssign { target, op, value } => { let _node = AstNode - .into_ref_with_type(_vm, NodeAugAssign::static_type().clone()) + .into_ref_with_type(_vm, NodeAugAssign::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2073,7 +2073,7 @@ impl Node for ast::StmtKind { simple, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeAnnAssign::static_type().clone()) + .into_ref_with_type(_vm, NodeAnnAssign::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2098,7 +2098,7 @@ impl Node for ast::StmtKind { type_comment, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeFor::static_type().clone()) + .into_ref_with_type(_vm, NodeFor::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2126,7 +2126,7 @@ impl Node for ast::StmtKind { type_comment, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeAsyncFor::static_type().clone()) + .into_ref_with_type(_vm, NodeAsyncFor::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2148,7 +2148,7 @@ impl Node for ast::StmtKind { } ast::StmtKind::While { test, body, orelse } => { let _node = AstNode - .into_ref_with_type(_vm, NodeWhile::static_type().clone()) + .into_ref_with_type(_vm, NodeWhile::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2164,7 +2164,7 @@ impl Node for ast::StmtKind { } ast::StmtKind::If { test, body, orelse } => { let _node = AstNode - .into_ref_with_type(_vm, NodeIf::static_type().clone()) + .into_ref_with_type(_vm, NodeIf::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2184,7 +2184,7 @@ impl Node for ast::StmtKind { type_comment, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeWith::static_type().clone()) + .into_ref_with_type(_vm, NodeWith::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2204,7 +2204,7 @@ impl Node for ast::StmtKind { type_comment, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeAsyncWith::static_type().clone()) + .into_ref_with_type(_vm, NodeAsyncWith::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2220,7 +2220,7 @@ impl Node for ast::StmtKind { } ast::StmtKind::Raise { exc, cause } => { let _node = AstNode - .into_ref_with_type(_vm, NodeRaise::static_type().clone()) + .into_ref_with_type(_vm, NodeRaise::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("exc", exc.ast_to_object(_vm), _vm).unwrap(); @@ -2236,7 +2236,7 @@ impl Node for ast::StmtKind { finalbody, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeTry::static_type().clone()) + .into_ref_with_type(_vm, NodeTry::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2255,7 +2255,7 @@ impl Node for ast::StmtKind { } ast::StmtKind::Assert { test, msg } => { let _node = AstNode - .into_ref_with_type(_vm, NodeAssert::static_type().clone()) + .into_ref_with_type(_vm, NodeAssert::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2266,7 +2266,7 @@ impl Node for ast::StmtKind { } ast::StmtKind::Import { names } => { let _node = AstNode - .into_ref_with_type(_vm, NodeImport::static_type().clone()) + .into_ref_with_type(_vm, NodeImport::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2280,7 +2280,7 @@ impl Node for ast::StmtKind { level, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeImportFrom::static_type().clone()) + .into_ref_with_type(_vm, NodeImportFrom::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2296,7 +2296,7 @@ impl Node for ast::StmtKind { } ast::StmtKind::Global { names } => { let _node = AstNode - .into_ref_with_type(_vm, NodeGlobal::static_type().clone()) + .into_ref_with_type(_vm, NodeGlobal::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2306,7 +2306,7 @@ impl Node for ast::StmtKind { } ast::StmtKind::Nonlocal { names } => { let _node = AstNode - .into_ref_with_type(_vm, NodeNonlocal::static_type().clone()) + .into_ref_with_type(_vm, NodeNonlocal::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2316,7 +2316,7 @@ impl Node for ast::StmtKind { } ast::StmtKind::Expr { value } => { let _node = AstNode - .into_ref_with_type(_vm, NodeExpr::static_type().clone()) + .into_ref_with_type(_vm, NodeExpr::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2326,19 +2326,19 @@ impl Node for ast::StmtKind { } ast::StmtKind::Pass {} => { let _node = AstNode - .into_ref_with_type(_vm, NodePass::static_type().clone()) + .into_ref_with_type(_vm, NodePass::static_type().to_owned()) .unwrap(); _node.into() } ast::StmtKind::Break {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeBreak::static_type().clone()) + .into_ref_with_type(_vm, NodeBreak::static_type().to_owned()) .unwrap(); _node.into() } ast::StmtKind::Continue {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeContinue::static_type().clone()) + .into_ref_with_type(_vm, NodeContinue::static_type().to_owned()) .unwrap(); _node.into() } @@ -2591,7 +2591,7 @@ impl Node for ast::ExprKind { match self { ast::ExprKind::BoolOp { op, values } => { let _node = AstNode - .into_ref_with_type(_vm, NodeBoolOp::static_type().clone()) + .into_ref_with_type(_vm, NodeBoolOp::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("op", op.ast_to_object(_vm), _vm).unwrap(); @@ -2602,7 +2602,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::NamedExpr { target, value } => { let _node = AstNode - .into_ref_with_type(_vm, NodeNamedExpr::static_type().clone()) + .into_ref_with_type(_vm, NodeNamedExpr::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2615,7 +2615,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::BinOp { left, op, right } => { let _node = AstNode - .into_ref_with_type(_vm, NodeBinOp::static_type().clone()) + .into_ref_with_type(_vm, NodeBinOp::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2629,7 +2629,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::UnaryOp { op, operand } => { let _node = AstNode - .into_ref_with_type(_vm, NodeUnaryOp::static_type().clone()) + .into_ref_with_type(_vm, NodeUnaryOp::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("op", op.ast_to_object(_vm), _vm).unwrap(); @@ -2640,7 +2640,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::Lambda { args, body } => { let _node = AstNode - .into_ref_with_type(_vm, NodeLambda::static_type().clone()) + .into_ref_with_type(_vm, NodeLambda::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2653,7 +2653,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::IfExp { test, body, orelse } => { let _node = AstNode - .into_ref_with_type(_vm, NodeIfExp::static_type().clone()) + .into_ref_with_type(_vm, NodeIfExp::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2669,7 +2669,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::Dict { keys, values } => { let _node = AstNode - .into_ref_with_type(_vm, NodeDict::static_type().clone()) + .into_ref_with_type(_vm, NodeDict::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2682,7 +2682,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::Set { elts } => { let _node = AstNode - .into_ref_with_type(_vm, NodeSet::static_type().clone()) + .into_ref_with_type(_vm, NodeSet::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2692,7 +2692,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::ListComp { elt, generators } => { let _node = AstNode - .into_ref_with_type(_vm, NodeListComp::static_type().clone()) + .into_ref_with_type(_vm, NodeListComp::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("elt", elt.ast_to_object(_vm), _vm).unwrap(); @@ -2703,7 +2703,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::SetComp { elt, generators } => { let _node = AstNode - .into_ref_with_type(_vm, NodeSetComp::static_type().clone()) + .into_ref_with_type(_vm, NodeSetComp::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("elt", elt.ast_to_object(_vm), _vm).unwrap(); @@ -2718,7 +2718,7 @@ impl Node for ast::ExprKind { generators, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeDictComp::static_type().clone()) + .into_ref_with_type(_vm, NodeDictComp::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("key", key.ast_to_object(_vm), _vm).unwrap(); @@ -2732,7 +2732,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::GeneratorExp { elt, generators } => { let _node = AstNode - .into_ref_with_type(_vm, NodeGeneratorExp::static_type().clone()) + .into_ref_with_type(_vm, NodeGeneratorExp::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("elt", elt.ast_to_object(_vm), _vm).unwrap(); @@ -2743,7 +2743,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::Await { value } => { let _node = AstNode - .into_ref_with_type(_vm, NodeAwait::static_type().clone()) + .into_ref_with_type(_vm, NodeAwait::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2753,7 +2753,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::Yield { value } => { let _node = AstNode - .into_ref_with_type(_vm, NodeYield::static_type().clone()) + .into_ref_with_type(_vm, NodeYield::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2763,7 +2763,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::YieldFrom { value } => { let _node = AstNode - .into_ref_with_type(_vm, NodeYieldFrom::static_type().clone()) + .into_ref_with_type(_vm, NodeYieldFrom::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2777,7 +2777,7 @@ impl Node for ast::ExprKind { comparators, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeCompare::static_type().clone()) + .into_ref_with_type(_vm, NodeCompare::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2795,7 +2795,7 @@ impl Node for ast::ExprKind { keywords, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeCall::static_type().clone()) + .into_ref_with_type(_vm, NodeCall::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2815,7 +2815,7 @@ impl Node for ast::ExprKind { format_spec, } => { let _node = AstNode - .into_ref_with_type(_vm, NodeFormattedValue::static_type().clone()) + .into_ref_with_type(_vm, NodeFormattedValue::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2831,7 +2831,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::JoinedStr { values } => { let _node = AstNode - .into_ref_with_type(_vm, NodeJoinedStr::static_type().clone()) + .into_ref_with_type(_vm, NodeJoinedStr::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2841,7 +2841,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::Constant { value, kind } => { let _node = AstNode - .into_ref_with_type(_vm, NodeConstant::static_type().clone()) + .into_ref_with_type(_vm, NodeConstant::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2854,7 +2854,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::Attribute { value, attr, ctx } => { let _node = AstNode - .into_ref_with_type(_vm, NodeAttribute::static_type().clone()) + .into_ref_with_type(_vm, NodeAttribute::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2868,7 +2868,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::Subscript { value, slice, ctx } => { let _node = AstNode - .into_ref_with_type(_vm, NodeSubscript::static_type().clone()) + .into_ref_with_type(_vm, NodeSubscript::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2882,7 +2882,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::Starred { value, ctx } => { let _node = AstNode - .into_ref_with_type(_vm, NodeStarred::static_type().clone()) + .into_ref_with_type(_vm, NodeStarred::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2893,7 +2893,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::Name { id, ctx } => { let _node = AstNode - .into_ref_with_type(_vm, NodeName::static_type().clone()) + .into_ref_with_type(_vm, NodeName::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("id", id.ast_to_object(_vm), _vm).unwrap(); @@ -2902,7 +2902,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::List { elts, ctx } => { let _node = AstNode - .into_ref_with_type(_vm, NodeList::static_type().clone()) + .into_ref_with_type(_vm, NodeList::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2913,7 +2913,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::Tuple { elts, ctx } => { let _node = AstNode - .into_ref_with_type(_vm, NodeTuple::static_type().clone()) + .into_ref_with_type(_vm, NodeTuple::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -2924,7 +2924,7 @@ impl Node for ast::ExprKind { } ast::ExprKind::Slice { lower, upper, step } => { let _node = AstNode - .into_ref_with_type(_vm, NodeSlice::static_type().clone()) + .into_ref_with_type(_vm, NodeSlice::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -3151,19 +3151,19 @@ impl Node for ast::ExprContext { match self { ast::ExprContext::Load {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeLoad::static_type().clone()) + .into_ref_with_type(_vm, NodeLoad::static_type().to_owned()) .unwrap(); _node.into() } ast::ExprContext::Store {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeStore::static_type().clone()) + .into_ref_with_type(_vm, NodeStore::static_type().to_owned()) .unwrap(); _node.into() } ast::ExprContext::Del {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeDel::static_type().clone()) + .into_ref_with_type(_vm, NodeDel::static_type().to_owned()) .unwrap(); _node.into() } @@ -3193,13 +3193,13 @@ impl Node for ast::Boolop { match self { ast::Boolop::And {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeAnd::static_type().clone()) + .into_ref_with_type(_vm, NodeAnd::static_type().to_owned()) .unwrap(); _node.into() } ast::Boolop::Or {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeOr::static_type().clone()) + .into_ref_with_type(_vm, NodeOr::static_type().to_owned()) .unwrap(); _node.into() } @@ -3227,79 +3227,79 @@ impl Node for ast::Operator { match self { ast::Operator::Add {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeAdd::static_type().clone()) + .into_ref_with_type(_vm, NodeAdd::static_type().to_owned()) .unwrap(); _node.into() } ast::Operator::Sub {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeSub::static_type().clone()) + .into_ref_with_type(_vm, NodeSub::static_type().to_owned()) .unwrap(); _node.into() } ast::Operator::Mult {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeMult::static_type().clone()) + .into_ref_with_type(_vm, NodeMult::static_type().to_owned()) .unwrap(); _node.into() } ast::Operator::MatMult {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeMatMult::static_type().clone()) + .into_ref_with_type(_vm, NodeMatMult::static_type().to_owned()) .unwrap(); _node.into() } ast::Operator::Div {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeDiv::static_type().clone()) + .into_ref_with_type(_vm, NodeDiv::static_type().to_owned()) .unwrap(); _node.into() } ast::Operator::Mod {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeMod::static_type().clone()) + .into_ref_with_type(_vm, NodeMod::static_type().to_owned()) .unwrap(); _node.into() } ast::Operator::Pow {} => { let _node = AstNode - .into_ref_with_type(_vm, NodePow::static_type().clone()) + .into_ref_with_type(_vm, NodePow::static_type().to_owned()) .unwrap(); _node.into() } ast::Operator::LShift {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeLShift::static_type().clone()) + .into_ref_with_type(_vm, NodeLShift::static_type().to_owned()) .unwrap(); _node.into() } ast::Operator::RShift {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeRShift::static_type().clone()) + .into_ref_with_type(_vm, NodeRShift::static_type().to_owned()) .unwrap(); _node.into() } ast::Operator::BitOr {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeBitOr::static_type().clone()) + .into_ref_with_type(_vm, NodeBitOr::static_type().to_owned()) .unwrap(); _node.into() } ast::Operator::BitXor {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeBitXor::static_type().clone()) + .into_ref_with_type(_vm, NodeBitXor::static_type().to_owned()) .unwrap(); _node.into() } ast::Operator::BitAnd {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeBitAnd::static_type().clone()) + .into_ref_with_type(_vm, NodeBitAnd::static_type().to_owned()) .unwrap(); _node.into() } ast::Operator::FloorDiv {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeFloorDiv::static_type().clone()) + .into_ref_with_type(_vm, NodeFloorDiv::static_type().to_owned()) .unwrap(); _node.into() } @@ -3349,25 +3349,25 @@ impl Node for ast::Unaryop { match self { ast::Unaryop::Invert {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeInvert::static_type().clone()) + .into_ref_with_type(_vm, NodeInvert::static_type().to_owned()) .unwrap(); _node.into() } ast::Unaryop::Not {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeNot::static_type().clone()) + .into_ref_with_type(_vm, NodeNot::static_type().to_owned()) .unwrap(); _node.into() } ast::Unaryop::UAdd {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeUAdd::static_type().clone()) + .into_ref_with_type(_vm, NodeUAdd::static_type().to_owned()) .unwrap(); _node.into() } ast::Unaryop::USub {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeUSub::static_type().clone()) + .into_ref_with_type(_vm, NodeUSub::static_type().to_owned()) .unwrap(); _node.into() } @@ -3399,61 +3399,61 @@ impl Node for ast::Cmpop { match self { ast::Cmpop::Eq {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeEq::static_type().clone()) + .into_ref_with_type(_vm, NodeEq::static_type().to_owned()) .unwrap(); _node.into() } ast::Cmpop::NotEq {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeNotEq::static_type().clone()) + .into_ref_with_type(_vm, NodeNotEq::static_type().to_owned()) .unwrap(); _node.into() } ast::Cmpop::Lt {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeLt::static_type().clone()) + .into_ref_with_type(_vm, NodeLt::static_type().to_owned()) .unwrap(); _node.into() } ast::Cmpop::LtE {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeLtE::static_type().clone()) + .into_ref_with_type(_vm, NodeLtE::static_type().to_owned()) .unwrap(); _node.into() } ast::Cmpop::Gt {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeGt::static_type().clone()) + .into_ref_with_type(_vm, NodeGt::static_type().to_owned()) .unwrap(); _node.into() } ast::Cmpop::GtE {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeGtE::static_type().clone()) + .into_ref_with_type(_vm, NodeGtE::static_type().to_owned()) .unwrap(); _node.into() } ast::Cmpop::Is {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeIs::static_type().clone()) + .into_ref_with_type(_vm, NodeIs::static_type().to_owned()) .unwrap(); _node.into() } ast::Cmpop::IsNot {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeIsNot::static_type().clone()) + .into_ref_with_type(_vm, NodeIsNot::static_type().to_owned()) .unwrap(); _node.into() } ast::Cmpop::In {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeIn::static_type().clone()) + .into_ref_with_type(_vm, NodeIn::static_type().to_owned()) .unwrap(); _node.into() } ast::Cmpop::NotIn {} => { let _node = AstNode - .into_ref_with_type(_vm, NodeNotIn::static_type().clone()) + .into_ref_with_type(_vm, NodeNotIn::static_type().to_owned()) .unwrap(); _node.into() } @@ -3501,7 +3501,7 @@ impl Node for ast::Comprehension { is_async, } = self; let _node = AstNode - .into_ref_with_type(_vm, Nodecomprehension::static_type().clone()) + .into_ref_with_type(_vm, Nodecomprehension::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -3545,7 +3545,7 @@ impl Node for ast::ExcepthandlerKind { match self { ast::ExcepthandlerKind::ExceptHandler { type_, name, body } => { let _node = AstNode - .into_ref_with_type(_vm, NodeExceptHandler::static_type().clone()) + .into_ref_with_type(_vm, NodeExceptHandler::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -3609,7 +3609,7 @@ impl Node for ast::Arguments { defaults, } = self; let _node = AstNode - .into_ref_with_type(_vm, Nodearguments::static_type().clone()) + .into_ref_with_type(_vm, Nodearguments::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -3674,7 +3674,7 @@ impl Node for ast::ArgData { type_comment, } = self; let _node = AstNode - .into_ref_with_type(_vm, Nodearg::static_type().clone()) + .into_ref_with_type(_vm, Nodearg::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("arg", arg.ast_to_object(_vm), _vm).unwrap(); @@ -3709,7 +3709,7 @@ impl Node for ast::KeywordData { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::KeywordData { arg, value } = self; let _node = AstNode - .into_ref_with_type(_vm, Nodekeyword::static_type().clone()) + .into_ref_with_type(_vm, Nodekeyword::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("arg", arg.ast_to_object(_vm), _vm).unwrap(); @@ -3738,7 +3738,7 @@ impl Node for ast::Alias { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::Alias { name, asname } = self; let _node = AstNode - .into_ref_with_type(_vm, Nodealias::static_type().clone()) + .into_ref_with_type(_vm, Nodealias::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -3768,7 +3768,7 @@ impl Node for ast::Withitem { optional_vars, } = self; let _node = AstNode - .into_ref_with_type(_vm, Nodewithitem::static_type().clone()) + .into_ref_with_type(_vm, Nodewithitem::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict @@ -3799,7 +3799,7 @@ impl Node for ast::TypeIgnore { match self { ast::TypeIgnore::TypeIgnore { lineno, tag } => { let _node = AstNode - .into_ref_with_type(_vm, NodeTypeIgnore::static_type().clone()) + .into_ref_with_type(_vm, NodeTypeIgnore::static_type().to_owned()) .unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict diff --git a/vm/src/stdlib/atexit.rs b/vm/src/stdlib/atexit.rs index 37127deeae..1359f461b2 100644 --- a/vm/src/stdlib/atexit.rs +++ b/vm/src/stdlib/atexit.rs @@ -37,7 +37,7 @@ mod atexit { let funcs: Vec<_> = std::mem::take(&mut *vm.state.atexit_funcs.lock()); for (func, args) in funcs.into_iter().rev() { if let Err(e) = vm.invoke(&func, args) { - let exit = e.fast_isinstance(&vm.ctx.exceptions.system_exit); + let exit = e.fast_isinstance(vm.ctx.exceptions.system_exit); vm.run_unraisable(e, Some("Error in atexit._run_exitfuncs".to_owned()), func); if exit { break; diff --git a/vm/src/stdlib/builtins.rs b/vm/src/stdlib/builtins.rs index e1e785c73f..1c1a4f2f89 100644 --- a/vm/src/stdlib/builtins.rs +++ b/vm/src/stdlib/builtins.rs @@ -374,10 +374,10 @@ mod builtins { match readline.readline(prompt) { ReadlineResult::Line(s) => Ok(vm.ctx.new_str(s).into()), ReadlineResult::Eof => { - Err(vm.new_exception_empty(vm.ctx.exceptions.eof_error.clone())) + Err(vm.new_exception_empty(vm.ctx.exceptions.eof_error.to_owned())) } ReadlineResult::Interrupt => { - Err(vm.new_exception_empty(vm.ctx.exceptions.keyboard_interrupt.clone())) + Err(vm.new_exception_empty(vm.ctx.exceptions.keyboard_interrupt.to_owned())) } ReadlineResult::Io(e) => Err(vm.new_os_error(e.to_string())), ReadlineResult::EncodingError => { @@ -413,7 +413,7 @@ mod builtins { if let OptionalArg::Present(sentinel) = sentinel { let callable = ArgCallable::try_from_object(vm, iter_target)?; let iterator = PyCallableIterator::new(callable, sentinel) - .into_ref(vm) + .into_ref(&vm.ctx) .into(); Ok(PyIter::new(iterator)) } else { @@ -630,7 +630,7 @@ mod builtins { #[pyfunction] pub fn exit(exit_code_arg: OptionalArg, vm: &VirtualMachine) -> PyResult { let code = exit_code_arg.unwrap_or_else(|| vm.ctx.new_int(0).into()); - Err(vm.new_exception(vm.ctx.exceptions.system_exit.clone(), vec![code])) + Err(vm.new_exception(vm.ctx.exceptions.system_exit.to_owned(), vec![code])) } #[derive(Debug, Default, FromArgs)] @@ -653,7 +653,9 @@ mod builtins { }; let write = |obj: PyStrRef| vm.call_method(&file, "write", (obj,)); - let sep = options.sep.unwrap_or_else(|| PyStr::from(" ").into_ref(vm)); + let sep = options + .sep + .unwrap_or_else(|| PyStr::from(" ").into_ref(&vm.ctx)); let mut first = true; for object in objects { @@ -668,7 +670,7 @@ mod builtins { let end = options .end - .unwrap_or_else(|| PyStr::from("\n").into_ref(vm)); + .unwrap_or_else(|| PyStr::from("\n").into_ref(&vm.ctx)); write(end)?; if *options.flush { @@ -815,7 +817,7 @@ mod builtins { let mut new_bases: Option> = None; let bases = PyTuple::new_ref(bases.into_vec(), &vm.ctx); for (i, base) in bases.iter().enumerate() { - if base.fast_isinstance(&vm.ctx.types.type_type) { + if base.fast_isinstance(vm.ctx.types.type_type) { if let Some(bases) = &mut new_bases { bases.push(base.clone()); } @@ -848,7 +850,7 @@ mod builtins { let metaclass = kwargs .pop_kwarg("metaclass") .map(|metaclass| metaclass.downcast_exact::(vm)) - .unwrap_or_else(|| Ok(vm.ctx.types.type_type.clone())); + .unwrap_or_else(|| Ok(vm.ctx.types.type_type.to_owned())); let (metaclass, meta_name) = match metaclass { Ok(mut metaclass) => { @@ -926,31 +928,31 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef) { extend_module!(vm, module, { "__debug__" => ctx.new_bool(debug_mode), - "bool" => ctx.types.bool_type.clone(), - "bytearray" => ctx.types.bytearray_type.clone(), - "bytes" => ctx.types.bytes_type.clone(), - "classmethod" => ctx.types.classmethod_type.clone(), - "complex" => ctx.types.complex_type.clone(), - "dict" => ctx.types.dict_type.clone(), - "enumerate" => ctx.types.enumerate_type.clone(), - "float" => ctx.types.float_type.clone(), - "frozenset" => ctx.types.frozenset_type.clone(), - "filter" => ctx.types.filter_type.clone(), - "int" => ctx.types.int_type.clone(), - "list" => ctx.types.list_type.clone(), - "map" => ctx.types.map_type.clone(), - "memoryview" => ctx.types.memoryview_type.clone(), - "object" => ctx.types.object_type.clone(), - "property" => ctx.types.property_type.clone(), - "range" => ctx.types.range_type.clone(), - "set" => ctx.types.set_type.clone(), - "slice" => ctx.types.slice_type.clone(), - "staticmethod" => ctx.types.staticmethod_type.clone(), - "str" => ctx.types.str_type.clone(), - "super" => ctx.types.super_type.clone(), - "tuple" => ctx.types.tuple_type.clone(), - "type" => ctx.types.type_type.clone(), - "zip" => ctx.types.zip_type.clone(), + "bool" => ctx.types.bool_type.to_owned(), + "bytearray" => ctx.types.bytearray_type.to_owned(), + "bytes" => ctx.types.bytes_type.to_owned(), + "classmethod" => ctx.types.classmethod_type.to_owned(), + "complex" => ctx.types.complex_type.to_owned(), + "dict" => ctx.types.dict_type.to_owned(), + "enumerate" => ctx.types.enumerate_type.to_owned(), + "float" => ctx.types.float_type.to_owned(), + "frozenset" => ctx.types.frozenset_type.to_owned(), + "filter" => ctx.types.filter_type.to_owned(), + "int" => ctx.types.int_type.to_owned(), + "list" => ctx.types.list_type.to_owned(), + "map" => ctx.types.map_type.to_owned(), + "memoryview" => ctx.types.memoryview_type.to_owned(), + "object" => ctx.types.object_type.to_owned(), + "property" => ctx.types.property_type.to_owned(), + "range" => ctx.types.range_type.to_owned(), + "set" => ctx.types.set_type.to_owned(), + "slice" => ctx.types.slice_type.to_owned(), + "staticmethod" => ctx.types.staticmethod_type.to_owned(), + "str" => ctx.types.str_type.to_owned(), + "super" => ctx.types.super_type.to_owned(), + "tuple" => ctx.types.tuple_type.to_owned(), + "type" => ctx.types.type_type.to_owned(), + "zip" => ctx.types.zip_type.to_owned(), // Constants "None" => ctx.none(), @@ -961,80 +963,80 @@ pub fn make_module(vm: &VirtualMachine, module: PyObjectRef) { // ordered by exception_hierarachy.txt // Exceptions: - "BaseException" => ctx.exceptions.base_exception_type.clone(), - "SystemExit" => ctx.exceptions.system_exit.clone(), - "KeyboardInterrupt" => ctx.exceptions.keyboard_interrupt.clone(), - "GeneratorExit" => ctx.exceptions.generator_exit.clone(), - "Exception" => ctx.exceptions.exception_type.clone(), - "StopIteration" => ctx.exceptions.stop_iteration.clone(), - "StopAsyncIteration" => ctx.exceptions.stop_async_iteration.clone(), - "ArithmeticError" => ctx.exceptions.arithmetic_error.clone(), - "FloatingPointError" => ctx.exceptions.floating_point_error.clone(), - "OverflowError" => ctx.exceptions.overflow_error.clone(), - "ZeroDivisionError" => ctx.exceptions.zero_division_error.clone(), - "AssertionError" => ctx.exceptions.assertion_error.clone(), - "AttributeError" => ctx.exceptions.attribute_error.clone(), - "BufferError" => ctx.exceptions.buffer_error.clone(), - "EOFError" => ctx.exceptions.eof_error.clone(), - "ImportError" => ctx.exceptions.import_error.clone(), - "ModuleNotFoundError" => ctx.exceptions.module_not_found_error.clone(), - "LookupError" => ctx.exceptions.lookup_error.clone(), - "IndexError" => ctx.exceptions.index_error.clone(), - "KeyError" => ctx.exceptions.key_error.clone(), - "MemoryError" => ctx.exceptions.memory_error.clone(), - "NameError" => ctx.exceptions.name_error.clone(), - "UnboundLocalError" => ctx.exceptions.unbound_local_error.clone(), - "OSError" => ctx.exceptions.os_error.clone(), + "BaseException" => ctx.exceptions.base_exception_type.to_owned(), + "SystemExit" => ctx.exceptions.system_exit.to_owned(), + "KeyboardInterrupt" => ctx.exceptions.keyboard_interrupt.to_owned(), + "GeneratorExit" => ctx.exceptions.generator_exit.to_owned(), + "Exception" => ctx.exceptions.exception_type.to_owned(), + "StopIteration" => ctx.exceptions.stop_iteration.to_owned(), + "StopAsyncIteration" => ctx.exceptions.stop_async_iteration.to_owned(), + "ArithmeticError" => ctx.exceptions.arithmetic_error.to_owned(), + "FloatingPointError" => ctx.exceptions.floating_point_error.to_owned(), + "OverflowError" => ctx.exceptions.overflow_error.to_owned(), + "ZeroDivisionError" => ctx.exceptions.zero_division_error.to_owned(), + "AssertionError" => ctx.exceptions.assertion_error.to_owned(), + "AttributeError" => ctx.exceptions.attribute_error.to_owned(), + "BufferError" => ctx.exceptions.buffer_error.to_owned(), + "EOFError" => ctx.exceptions.eof_error.to_owned(), + "ImportError" => ctx.exceptions.import_error.to_owned(), + "ModuleNotFoundError" => ctx.exceptions.module_not_found_error.to_owned(), + "LookupError" => ctx.exceptions.lookup_error.to_owned(), + "IndexError" => ctx.exceptions.index_error.to_owned(), + "KeyError" => ctx.exceptions.key_error.to_owned(), + "MemoryError" => ctx.exceptions.memory_error.to_owned(), + "NameError" => ctx.exceptions.name_error.to_owned(), + "UnboundLocalError" => ctx.exceptions.unbound_local_error.to_owned(), + "OSError" => ctx.exceptions.os_error.to_owned(), // OSError alias - "IOError" => ctx.exceptions.os_error.clone(), - "EnvironmentError" => ctx.exceptions.os_error.clone(), - "BlockingIOError" => ctx.exceptions.blocking_io_error.clone(), - "ChildProcessError" => ctx.exceptions.child_process_error.clone(), - "ConnectionError" => ctx.exceptions.connection_error.clone(), - "BrokenPipeError" => ctx.exceptions.broken_pipe_error.clone(), - "ConnectionAbortedError" => ctx.exceptions.connection_aborted_error.clone(), - "ConnectionRefusedError" => ctx.exceptions.connection_refused_error.clone(), - "ConnectionResetError" => ctx.exceptions.connection_reset_error.clone(), - "FileExistsError" => ctx.exceptions.file_exists_error.clone(), - "FileNotFoundError" => ctx.exceptions.file_not_found_error.clone(), - "InterruptedError" => ctx.exceptions.interrupted_error.clone(), - "IsADirectoryError" => ctx.exceptions.is_a_directory_error.clone(), - "NotADirectoryError" => ctx.exceptions.not_a_directory_error.clone(), - "PermissionError" => ctx.exceptions.permission_error.clone(), - "ProcessLookupError" => ctx.exceptions.process_lookup_error.clone(), - "TimeoutError" => ctx.exceptions.timeout_error.clone(), - "ReferenceError" => ctx.exceptions.reference_error.clone(), - "RuntimeError" => ctx.exceptions.runtime_error.clone(), - "NotImplementedError" => ctx.exceptions.not_implemented_error.clone(), - "RecursionError" => ctx.exceptions.recursion_error.clone(), - "SyntaxError" => ctx.exceptions.syntax_error.clone(), - "IndentationError" => ctx.exceptions.indentation_error.clone(), - "TabError" => ctx.exceptions.tab_error.clone(), - "SystemError" => ctx.exceptions.system_error.clone(), - "TypeError" => ctx.exceptions.type_error.clone(), - "ValueError" => ctx.exceptions.value_error.clone(), - "UnicodeError" => ctx.exceptions.unicode_error.clone(), - "UnicodeDecodeError" => ctx.exceptions.unicode_decode_error.clone(), - "UnicodeEncodeError" => ctx.exceptions.unicode_encode_error.clone(), - "UnicodeTranslateError" => ctx.exceptions.unicode_translate_error.clone(), + "IOError" => ctx.exceptions.os_error.to_owned(), + "EnvironmentError" => ctx.exceptions.os_error.to_owned(), + "BlockingIOError" => ctx.exceptions.blocking_io_error.to_owned(), + "ChildProcessError" => ctx.exceptions.child_process_error.to_owned(), + "ConnectionError" => ctx.exceptions.connection_error.to_owned(), + "BrokenPipeError" => ctx.exceptions.broken_pipe_error.to_owned(), + "ConnectionAbortedError" => ctx.exceptions.connection_aborted_error.to_owned(), + "ConnectionRefusedError" => ctx.exceptions.connection_refused_error.to_owned(), + "ConnectionResetError" => ctx.exceptions.connection_reset_error.to_owned(), + "FileExistsError" => ctx.exceptions.file_exists_error.to_owned(), + "FileNotFoundError" => ctx.exceptions.file_not_found_error.to_owned(), + "InterruptedError" => ctx.exceptions.interrupted_error.to_owned(), + "IsADirectoryError" => ctx.exceptions.is_a_directory_error.to_owned(), + "NotADirectoryError" => ctx.exceptions.not_a_directory_error.to_owned(), + "PermissionError" => ctx.exceptions.permission_error.to_owned(), + "ProcessLookupError" => ctx.exceptions.process_lookup_error.to_owned(), + "TimeoutError" => ctx.exceptions.timeout_error.to_owned(), + "ReferenceError" => ctx.exceptions.reference_error.to_owned(), + "RuntimeError" => ctx.exceptions.runtime_error.to_owned(), + "NotImplementedError" => ctx.exceptions.not_implemented_error.to_owned(), + "RecursionError" => ctx.exceptions.recursion_error.to_owned(), + "SyntaxError" => ctx.exceptions.syntax_error.to_owned(), + "IndentationError" => ctx.exceptions.indentation_error.to_owned(), + "TabError" => ctx.exceptions.tab_error.to_owned(), + "SystemError" => ctx.exceptions.system_error.to_owned(), + "TypeError" => ctx.exceptions.type_error.to_owned(), + "ValueError" => ctx.exceptions.value_error.to_owned(), + "UnicodeError" => ctx.exceptions.unicode_error.to_owned(), + "UnicodeDecodeError" => ctx.exceptions.unicode_decode_error.to_owned(), + "UnicodeEncodeError" => ctx.exceptions.unicode_encode_error.to_owned(), + "UnicodeTranslateError" => ctx.exceptions.unicode_translate_error.to_owned(), // Warnings - "Warning" => ctx.exceptions.warning.clone(), - "DeprecationWarning" => ctx.exceptions.deprecation_warning.clone(), - "PendingDeprecationWarning" => ctx.exceptions.pending_deprecation_warning.clone(), - "RuntimeWarning" => ctx.exceptions.runtime_warning.clone(), - "SyntaxWarning" => ctx.exceptions.syntax_warning.clone(), - "UserWarning" => ctx.exceptions.user_warning.clone(), - "FutureWarning" => ctx.exceptions.future_warning.clone(), - "ImportWarning" => ctx.exceptions.import_warning.clone(), - "UnicodeWarning" => ctx.exceptions.unicode_warning.clone(), - "BytesWarning" => ctx.exceptions.bytes_warning.clone(), - "ResourceWarning" => ctx.exceptions.resource_warning.clone(), - "EncodingWarning" => ctx.exceptions.encoding_warning.clone(), + "Warning" => ctx.exceptions.warning.to_owned(), + "DeprecationWarning" => ctx.exceptions.deprecation_warning.to_owned(), + "PendingDeprecationWarning" => ctx.exceptions.pending_deprecation_warning.to_owned(), + "RuntimeWarning" => ctx.exceptions.runtime_warning.to_owned(), + "SyntaxWarning" => ctx.exceptions.syntax_warning.to_owned(), + "UserWarning" => ctx.exceptions.user_warning.to_owned(), + "FutureWarning" => ctx.exceptions.future_warning.to_owned(), + "ImportWarning" => ctx.exceptions.import_warning.to_owned(), + "UnicodeWarning" => ctx.exceptions.unicode_warning.to_owned(), + "BytesWarning" => ctx.exceptions.bytes_warning.to_owned(), + "ResourceWarning" => ctx.exceptions.resource_warning.to_owned(), + "EncodingWarning" => ctx.exceptions.encoding_warning.to_owned(), }); #[cfg(feature = "jit")] extend_module!(vm, module, { - "JitError" => ctx.exceptions.jit_error.clone(), + "JitError" => ctx.exceptions.jit_error.to_owned(), }); } diff --git a/vm/src/stdlib/codecs.rs b/vm/src/stdlib/codecs.rs index 0702226e41..9de8fd1a4f 100644 --- a/vm/src/stdlib/codecs.rs +++ b/vm/src/stdlib/codecs.rs @@ -121,7 +121,7 @@ mod _codecs { let vm = self.vm; let data_str = vm.ctx.new_str(data).into(); let encode_exc = vm.new_exception( - vm.ctx.exceptions.unicode_encode_error.clone(), + vm.ctx.exceptions.unicode_encode_error.to_owned(), vec![ vm.ctx.new_str(self.encoding).into(), data_str, @@ -164,7 +164,7 @@ mod _codecs { let vm = self.vm; let data_bytes: PyObjectRef = vm.ctx.new_bytes(data.to_vec()).into(); let decode_exc = vm.new_exception( - vm.ctx.exceptions.unicode_decode_error.clone(), + vm.ctx.exceptions.unicode_decode_error.to_owned(), vec![ vm.ctx.new_str(self.encoding).into(), data_bytes.clone(), @@ -222,7 +222,7 @@ mod _codecs { ) -> Self::Error { let vm = self.vm; vm.new_exception( - vm.ctx.exceptions.unicode_encode_error.clone(), + vm.ctx.exceptions.unicode_encode_error.to_owned(), vec![ vm.ctx.new_str(self.encoding).into(), vm.ctx.new_str(data).into(), diff --git a/vm/src/stdlib/collections.rs b/vm/src/stdlib/collections.rs index 508f1b4119..eafdfe565d 100644 --- a/vm/src/stdlib/collections.rs +++ b/vm/src/stdlib/collections.rs @@ -532,12 +532,12 @@ mod _collections { concat: Some(|seq, other, vm| { Self::sequence_downcast(seq) .concat(other, vm) - .map(|x| x.into_ref(vm).into()) + .map(|x| x.into_ref(&vm.ctx).into()) }), repeat: Some(|seq, n, vm| { Self::sequence_downcast(seq) .mul(n as isize, vm) - .map(|x| x.into_ref(vm).into()) + .map(|x| x.into_ref(&vm.ctx).into()) }), item: Some(|seq, i, vm| Self::sequence_downcast(seq).getitem(i, vm)), ass_item: Some(|seq, i, value, vm| { @@ -642,7 +642,7 @@ mod _collections { let internal = zelf.internal.lock(); let deque = match &internal.status { Active(obj) => obj.clone(), - Exhausted => PyDeque::default().into_ref(vm), + Exhausted => PyDeque::default().into_ref(&vm.ctx), }; ( zelf.class().clone(), @@ -708,7 +708,7 @@ mod _collections { let internal = zelf.internal.lock(); let deque = match &internal.status { Active(obj) => obj.clone(), - Exhausted => PyDeque::default().into_ref(vm), + Exhausted => PyDeque::default().into_ref(&vm.ctx), }; Ok(( zelf.class().clone(), diff --git a/vm/src/stdlib/functools.rs b/vm/src/stdlib/functools.rs index fc53c5aaa7..9d653288a7 100644 --- a/vm/src/stdlib/functools.rs +++ b/vm/src/stdlib/functools.rs @@ -16,7 +16,7 @@ mod _functools { val } else { iter.next().transpose()?.ok_or_else(|| { - let exc_type = vm.ctx.exceptions.type_error.clone(); + let exc_type = vm.ctx.exceptions.type_error.to_owned(); vm.new_exception_msg( exc_type, "reduce() of empty sequence with no initial value".to_owned(), diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index 6233c27d65..caa96a351a 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -29,18 +29,18 @@ impl ToPyException for &'_ std::io::Error { let excs = &vm.ctx.exceptions; #[allow(unreachable_patterns)] // some errors are just aliases of each other let exc_type = match self.kind() { - ErrorKind::NotFound => excs.file_not_found_error.clone(), - ErrorKind::PermissionDenied => excs.permission_error.clone(), - ErrorKind::AlreadyExists => excs.file_exists_error.clone(), - ErrorKind::WouldBlock => excs.blocking_io_error.clone(), + ErrorKind::NotFound => excs.file_not_found_error, + ErrorKind::PermissionDenied => excs.permission_error, + ErrorKind::AlreadyExists => excs.file_exists_error, + ErrorKind::WouldBlock => excs.blocking_io_error, _ => self .raw_os_error() .and_then(|errno| crate::exceptions::raw_os_error_to_exc_type(errno, vm)) - .unwrap_or_else(|| excs.os_error.clone()), + .unwrap_or(excs.os_error), }; let errno = self.raw_os_error().to_pyobject(vm); let msg = vm.ctx.new_str(self.to_string()).into(); - vm.new_exception(exc_type, vec![errno, msg]) + vm.new_exception(exc_type.to_owned(), vec![errno, msg]) } } @@ -57,7 +57,7 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef { .clone(); extend_module!(vm, module, { "UnsupportedOperation" => unsupported_operation, - "BlockingIOError" => ctx.exceptions.blocking_io_error.clone(), + "BlockingIOError" => ctx.exceptions.blocking_io_error.to_owned(), }); module @@ -121,7 +121,7 @@ mod _io { recursion::ReprGuard, types::{Constructor, DefaultConstructor, Destructor, Initializer, IterNext, Iterable}, vm::VirtualMachine, - AsObject, Context, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, + AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromBorrowedObject, TryFromObject, }; use bstr::ByteSlice; @@ -593,7 +593,7 @@ mod _io { fn read(instance: PyObjectRef, size: OptionalSize, vm: &VirtualMachine) -> PyResult { if let Some(size) = size.to_usize() { // FIXME: unnecessary zero-init - let b = PyByteArray::from(vec![0; size]).into_ref(vm); + let b = PyByteArray::from(vec![0; size]).into_ref(&vm.ctx); let n = >::try_from_object( vm, vm.call_method(&instance, "readinto", (b.clone(),))?, @@ -808,7 +808,7 @@ mod _io { self.raw_write(None, self.write_pos as usize..self.write_end as usize, vm)?; let n = n.ok_or_else(|| { vm.new_exception_msg( - vm.ctx.exceptions.blocking_io_error.clone(), + vm.ctx.exceptions.blocking_io_error.to_owned(), "write could not complete without blocking".to_owned(), ) })?; @@ -912,13 +912,13 @@ mod _io { vm.call_method(self.raw.as_ref().unwrap(), "write", (memobj,))? } else { let v = std::mem::take(&mut self.buffer); - let writebuf = VecBuffer::from(v).into_ref(vm); + let writebuf = VecBuffer::from(v).into_ref(&vm.ctx); let memobj = PyMemoryView::from_buffer_range( writebuf.clone().into_pybuffer(true), buf_range, vm, )? - .into_ref(vm); + .into_ref(&vm.ctx); // TODO: loop if write() raises an interrupt let res = vm.call_method(self.raw.as_ref().unwrap(), "write", (memobj.clone(),)); @@ -1006,7 +1006,7 @@ mod _io { // TODO: BlockingIOError(errno, msg, written) // written += self.buffer.len(); return Err(vm.new_exception_msg( - vm.ctx.exceptions.blocking_io_error.clone(), + vm.ctx.exceptions.blocking_io_error.to_owned(), "write could not complete without blocking".to_owned(), )); } else { @@ -1137,13 +1137,13 @@ mod _io { let res = match v { Either::A(v) => { let v = v.unwrap_or(&mut self.buffer); - let readbuf = VecBuffer::from(std::mem::take(v)).into_ref(vm); + let readbuf = VecBuffer::from(std::mem::take(v)).into_ref(&vm.ctx); let memobj = PyMemoryView::from_buffer_range( readbuf.clone().into_pybuffer(false), buf_range, vm, )? - .into_ref(vm); + .into_ref(&vm.ctx); // TODO: loop if readinto() raises an interrupt let res = @@ -1201,7 +1201,7 @@ mod _io { if let Some(bytes) = res { data.extend_from_slice(bytes.as_bytes()); } - Some(PyBytes::from(data).into_ref(vm)) + Some(PyBytes::from(data).into_ref(&vm.ctx)) } else { res }; @@ -1233,7 +1233,7 @@ mod _io { for bytes in &chunks { data.extend_from_slice(bytes.as_bytes()) } - Some(PyBytes::from(data).into_ref(vm)) + Some(PyBytes::from(data).into_ref(&vm.ctx)) }; break Ok(ret); } @@ -1343,8 +1343,8 @@ mod _io { let name = match obj.to_owned().get_attr("name", vm) { Ok(name) => Some(name), Err(e) - if e.fast_isinstance(&vm.ctx.exceptions.attribute_error) - || e.fast_isinstance(&vm.ctx.exceptions.value_error) => + if e.fast_isinstance(vm.ctx.exceptions.attribute_error) + || e.fast_isinstance(vm.ctx.exceptions.value_error) => { None } @@ -1596,7 +1596,7 @@ mod _io { match n.to_usize() { Some(n) => data .read_generic(n, vm) - .map(|x| x.map(|b| PyBytes::from(b).into_ref(vm))), + .map(|x| x.map(|b| PyBytes::from(b).into_ref(&vm.ctx))), None => data.read_all(vm), } } @@ -2097,7 +2097,7 @@ mod _io { }; let mut buf = Vec::with_capacity(num_bytes); writes_iter.for_each(|chunk| buf.extend_from_slice(chunk.as_bytes())); - PyBytes::from(buf).into_ref(vm) + PyBytes::from(buf).into_ref(&vm.ctx) } } @@ -2206,13 +2206,13 @@ mod _io { Some(enc) => enc, None => { // TODO: try os.device_encoding(fileno) and then locale.getpreferredencoding() - PyStr::from(crate::codecs::DEFAULT_ENCODING).into_ref(vm) + PyStr::from(crate::codecs::DEFAULT_ENCODING).into_ref(&vm.ctx) } }; let errors = args .errors - .unwrap_or_else(|| PyStr::from("strict").into_ref(vm)); + .unwrap_or_else(|| PyStr::from("strict").into_ref(&vm.ctx)); let buffer = args.buffer; @@ -2434,7 +2434,7 @@ mod _io { } textio.decoded_chars_used = cookie.num_to_skip(); } else { - textio.snapshot = Some((cookie.dec_flags, PyBytes::from(vec![]).into_ref(vm))) + textio.snapshot = Some((cookie.dec_flags, PyBytes::from(vec![]).into_ref(&vm.ctx))) } if let Some((encoder, _)) = &textio.encoder { let start_of_stream = cookie.start_pos == 0 && cookie.dec_flags == 0; @@ -2610,7 +2610,7 @@ mod _io { for chunk in chunks { ret.push_str(chunk.as_str()) } - PyStr::from(ret).into_ref(vm) + PyStr::from(ret).into_ref(&vm.ctx) } } else { let bytes = vm.call_method(&textio.buffer, "read", ())?; @@ -2650,7 +2650,7 @@ mod _io { let flush = textio.line_buffering && (has_lf || data.contains('\r')); let chunk = if let Some(replace_nl) = replace_nl { if has_lf { - PyStr::from(data.replace('\n', replace_nl)).into_ref(vm) + PyStr::from(data.replace('\n', replace_nl)).into_ref(&vm.ctx) } else { obj } @@ -2744,7 +2744,7 @@ mod _io { self.0 } else { // TODO: try to use Arc::get_mut() on the str? - PyStr::from(self.slice()).into_ref(vm) + PyStr::from(self.slice()).into_ref(&vm.ctx) } } fn utf8_len(&self) -> Utf8size { @@ -2798,7 +2798,7 @@ mod _io { String::with_capacity(remaining.len() + decoded_chars.len()); s.push_str(remaining); s.push_str(decoded_chars); - PyStr::from(s).into_ref(vm) + PyStr::from(s).into_ref(&vm.ctx) }; start = Utf8size::default(); line @@ -2860,7 +2860,7 @@ mod _io { for chunk in chunks { s.push_str(chunk.slice()) } - PyStr::from(s).into_ref(vm) + PyStr::from(s).into_ref(&vm.ctx) } else if let Some(cur_line) = cur_line { cur_line.slice_pystr(vm) } else { @@ -2972,7 +2972,7 @@ mod _io { // TODO: inplace append to bytes when refcount == 1 let mut next_input = dec_buffer.as_bytes().to_vec(); next_input.extend_from_slice(&*buf.borrow_buf()); - self.snapshot = Some((dec_flags, PyBytes::from(next_input).into_ref(vm))); + self.snapshot = Some((dec_flags, PyBytes::from(next_input).into_ref(&vm.ctx))); } Ok(eof) @@ -3002,11 +3002,11 @@ mod _io { if self.decoded_chars_used.bytes == 0 { (decoded_chars.clone(), avail_chars) } else { - (PyStr::from(avail).into_ref(vm), avail_chars) + (PyStr::from(avail).into_ref(&vm.ctx), avail_chars) } } else { let s = crate::common::str::get_chars(avail, 0..n); - (PyStr::from(s).into_ref(vm), n) + (PyStr::from(s).into_ref(&vm.ctx), n) }; self.decoded_chars_used += Utf8size { bytes: chars.byte_len(), @@ -3041,7 +3041,7 @@ mod _io { if let Some(append) = append { s.push_str(append.as_str()) } - PyStr::from(s).into_ref(vm) + PyStr::from(s).into_ref(&vm.ctx) } } @@ -3561,7 +3561,7 @@ mod _io { // Construct a FileIO (subclass of RawIOBase) // This is subsequently consumed by a Buffered Class. - let file_io_class = { + let file_io_class: &'static Py = { cfg_if::cfg_if! { if #[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))] { Some(super::fileio::FileIO::static_type()) @@ -3569,8 +3569,8 @@ mod _io { None } } - }; - let file_io_class: &PyTypeRef = file_io_class.ok_or_else(|| { + } + .ok_or_else(|| { new_unsupported_operation( vm, "Couldn't get FileIO, io.open likely isn't supported on your platform".to_owned(), @@ -3641,12 +3641,12 @@ mod _io { PyType::new_ref( "UnsupportedOperation", vec![ - ctx.exceptions.os_error.clone(), - ctx.exceptions.value_error.clone(), + ctx.exceptions.os_error.to_owned(), + ctx.exceptions.value_error.to_owned(), ], Default::default(), Default::default(), - ctx.types.type_type.clone(), + ctx.types.type_type.to_owned(), ) .unwrap() } @@ -3857,7 +3857,9 @@ mod fileio { type Args = FileIOArgs; fn init(zelf: PyRef, args: Self::Args, vm: &VirtualMachine) -> PyResult<()> { - let mode_obj = args.mode.unwrap_or_else(|| PyStr::from("rb").into_ref(vm)); + let mode_obj = args + .mode + .unwrap_or_else(|| PyStr::from("rb").into_ref(&vm.ctx)); let mode_str = mode_obj.as_str(); let name = args.name; let (mode, flags) = @@ -3865,7 +3867,7 @@ mod fileio { zelf.mode.store(mode); let fd = if let Some(opener) = args.opener { let fd = vm.invoke(&opener, (name.clone(), flags))?; - if !fd.fast_isinstance(&vm.ctx.types.int_type) { + if !fd.fast_isinstance(vm.ctx.types.int_type) { return Err(vm.new_type_error("expected integer from opener".to_owned())); } let fd = i32::try_from_object(vm, fd)?; diff --git a/vm/src/stdlib/itertools.rs b/vm/src/stdlib/itertools.rs index bd4de3ce0a..98191cfe2f 100644 --- a/vm/src/stdlib/itertools.rs +++ b/vm/src/stdlib/itertools.rs @@ -650,7 +650,7 @@ mod decl { let grouper = PyItertoolsGrouper { groupby: zelf.to_owned(), } - .into_ref(vm); + .into_ref(&vm.ctx); state.grouper = Some(grouper.downgrade(None, vm).unwrap()); Ok(PyIterReturn::Return( @@ -720,7 +720,7 @@ mod decl { name: &'static str, vm: &VirtualMachine, ) -> PyResult { - let is_int = obj.fast_isinstance(&vm.ctx.types.int_type); + let is_int = obj.fast_isinstance(vm.ctx.types.int_type); if is_int { let value = int::get_value(&obj).to_usize(); if let Some(value) = value { @@ -1037,15 +1037,15 @@ mod decl { #[pyimpl(with(IterNext, Constructor))] impl PyItertoolsTee { fn from_iter(iterator: PyIter, vm: &VirtualMachine) -> PyResult { - let class = PyItertoolsTee::class(vm); - if iterator.class().is(PyItertoolsTee::class(vm)) { + let class = PyItertoolsTee::class(&vm.ctx); + if iterator.class().is(PyItertoolsTee::class(&vm.ctx)) { return vm.call_method(&iterator, "__copy__", ()); } Ok(PyItertoolsTee { tee_data: PyItertoolsTeeData::new(iterator, vm)?, index: AtomicCell::new(0), } - .into_ref_with_type(vm, class.clone())? + .into_ref_with_type(vm, class.to_owned())? .into()) } diff --git a/vm/src/stdlib/marshal.rs b/vm/src/stdlib/marshal.rs index 81d5bbeeb2..88c39f012a 100644 --- a/vm/src/stdlib/marshal.rs +++ b/vm/src/stdlib/marshal.rs @@ -60,7 +60,7 @@ mod decl { fn _dumps(value: PyObjectRef, vm: &VirtualMachine) -> PyResult> { let r = match_class!(match value { pyint @ PyInt => { - if pyint.class().is(&vm.ctx.types.bool_type) { + if pyint.class().is(vm.ctx.types.bool_type) { let (_, mut bool_bytes) = pyint.as_bigint().to_bytes_le(); bool_bytes.push(BOOL_BYTE); bool_bytes @@ -213,7 +213,7 @@ mod decl { })?; let (type_indicator, buf) = full_buff.split_last().ok_or_else(|| { vm.new_exception_msg( - vm.ctx.exceptions.eof_error.clone(), + vm.ctx.exceptions.eof_error.to_owned(), "EOF where object expected.".to_owned(), ) })?; @@ -300,7 +300,7 @@ mod decl { // If prefix is not identifiable, assume CodeObject, error out if it doesn't match. let code = bytecode::CodeObject::from_bytes(&full_buff).map_err(|e| match e { bytecode::CodeDeserializeError::Eof => vm.new_exception_msg( - vm.ctx.exceptions.eof_error.clone(), + vm.ctx.exceptions.eof_error.to_owned(), "End of file while deserializing bytecode".to_owned(), ), _ => vm.new_value_error("Couldn't deserialize python bytecode".to_owned()), diff --git a/vm/src/stdlib/operator.rs b/vm/src/stdlib/operator.rs index ac72893c30..67ae0fdf31 100644 --- a/vm/src/stdlib/operator.rs +++ b/vm/src/stdlib/operator.rs @@ -196,7 +196,7 @@ mod _operator { #[pyfunction] fn concat(a: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult { // Best attempt at checking that a is sequence-like. - if !a.class().has_attr("__getitem__") || a.fast_isinstance(&vm.ctx.types.dict_type) { + if !a.class().has_attr("__getitem__") || a.fast_isinstance(vm.ctx.types.dict_type) { return Err( vm.new_type_error(format!("{} object can't be concatenated", a.class().name())) ); @@ -269,7 +269,7 @@ mod _operator { fn length_hint(obj: PyObjectRef, default: OptionalArg, vm: &VirtualMachine) -> PyResult { let default: usize = default .map(|v| { - if !v.fast_isinstance(&vm.ctx.types.int_type) { + if !v.fast_isinstance(vm.ctx.types.int_type) { return Err(vm.new_type_error(format!( "'{}' type cannot be interpreted as an integer", v.class().name() @@ -299,7 +299,7 @@ mod _operator { #[pyfunction] fn iconcat(a: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult { // Best attempt at checking that a is sequence-like. - if !a.class().has_attr("__getitem__") || a.fast_isinstance(&vm.ctx.types.dict_type) { + if !a.class().has_attr("__getitem__") || a.fast_isinstance(vm.ctx.types.dict_type) { return Err( vm.new_type_error(format!("{} object can't be concatenated", a.class().name())) ); diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index a0ee7c509a..20035885b8 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -830,8 +830,8 @@ pub(super) mod _os { let name = match zelf.get_attr("name", vm) { Ok(name) => Some(name), Err(e) - if e.fast_isinstance(&vm.ctx.exceptions.attribute_error) - || e.fast_isinstance(&vm.ctx.exceptions.value_error) => + if e.fast_isinstance(vm.ctx.exceptions.attribute_error) + || e.fast_isinstance(vm.ctx.exceptions.value_error) => { None } @@ -902,7 +902,7 @@ pub(super) mod _os { #[cfg(not(unix))] ino: AtomicCell::new(None), } - .into_ref(vm) + .into_ref(&vm.ctx) .into(), )), Err(err) => Err(err.to_pyexception(vm)), @@ -924,7 +924,7 @@ pub(super) mod _os { exhausted: AtomicCell::new(false), mode: path.mode, } - .into_ref(vm) + .into_ref(&vm.ctx) .into()) } @@ -1783,9 +1783,9 @@ pub fn extend_module(vm: &VirtualMachine, module: &PyObject) { _os::extend_module(vm, module); let support_funcs = _os::support_funcs(); - let supports_fd = PySet::default().into_ref(vm); - let supports_dir_fd = PySet::default().into_ref(vm); - let supports_follow_symlinks = PySet::default().into_ref(vm); + let supports_fd = PySet::default().into_ref(&vm.ctx); + let supports_dir_fd = PySet::default().into_ref(&vm.ctx); + let supports_follow_symlinks = PySet::default().into_ref(&vm.ctx); for support in support_funcs { let func_obj = module.to_owned().get_attr(support.name, vm).unwrap(); if support.fd.unwrap_or(false) { @@ -1803,7 +1803,7 @@ pub fn extend_module(vm: &VirtualMachine, module: &PyObject) { "supports_fd" => supports_fd, "supports_dir_fd" => supports_dir_fd, "supports_follow_symlinks" => supports_follow_symlinks, - "error" => vm.ctx.exceptions.os_error.clone(), + "error" => vm.ctx.exceptions.os_error.to_owned(), }); } pub(crate) use _os::os_open as open; diff --git a/vm/src/stdlib/signal.rs b/vm/src/stdlib/signal.rs index 5ed656f0d4..7dd4cb6395 100644 --- a/vm/src/stdlib/signal.rs +++ b/vm/src/stdlib/signal.rs @@ -176,7 +176,7 @@ pub(crate) mod _signal { _arg: PyObjectRef, vm: &VirtualMachine, ) -> PyResult { - Err(vm.new_exception_empty(vm.ctx.exceptions.keyboard_interrupt.clone())) + Err(vm.new_exception_empty(vm.ctx.exceptions.keyboard_interrupt.to_owned())) } #[derive(FromArgs)] diff --git a/vm/src/stdlib/sre.rs b/vm/src/stdlib/sre.rs index 9c0abd1c69..2e18158e88 100644 --- a/vm/src/stdlib/sre.rs +++ b/vm/src/stdlib/sre.rs @@ -180,9 +180,9 @@ mod _sre { vm, |mut state| { state = state.pymatch(); - Ok(state - .has_matched - .then(|| Match::new(&state, zelf.clone(), string_args.string).into_ref(vm))) + Ok(state.has_matched.then(|| { + Match::new(&state, zelf.clone(), string_args.string).into_ref(&vm.ctx) + })) }, ) } @@ -201,9 +201,9 @@ mod _sre { |mut state| { state.match_all = true; state = state.pymatch(); - Ok(state - .has_matched - .then(|| Match::new(&state, zelf.clone(), string_args.string).into_ref(vm))) + Ok(state.has_matched.then(|| { + Match::new(&state, zelf.clone(), string_args.string).into_ref(&vm.ctx) + })) }, ) } @@ -221,9 +221,9 @@ mod _sre { vm, |mut state| { state = state.search(); - Ok(state - .has_matched - .then(|| Match::new(&state, zelf.clone(), string_args.string).into_ref(vm))) + Ok(state.has_matched.then(|| { + Match::new(&state, zelf.clone(), string_args.string).into_ref(&vm.ctx) + })) }, ) } @@ -281,7 +281,7 @@ mod _sre { end: string_args.endpos, must_advance: AtomicCell::new(false), } - .into_ref(vm); + .into_ref(&vm.ctx); let search = vm.get_method(scanner.into(), "search").unwrap()?; let search = ArgCallable::try_from_object(vm, search)?; let iterator = PyCallableIterator::new(search, vm.ctx.none()); @@ -301,7 +301,7 @@ mod _sre { end: string_args.endpos, must_advance: AtomicCell::new(false), } - .into_ref(vm) + .into_ref(&vm.ctx) } #[pymethod] @@ -467,7 +467,7 @@ mod _sre { if is_callable { let m = Match::new(&state, zelf.clone(), string.clone()); - let ret = vm.invoke(&filter, (m.into_ref(vm),))?; + let ret = vm.invoke(&filter, (m.into_ref(&vm.ctx),))?; sublist.push(ret); } else { sublist.push(filter.clone()); @@ -832,7 +832,8 @@ mod _sre { self.start.store(state.string_position); Ok(state.has_matched.then(|| { - Match::new(&state, self.pattern.clone(), self.string.clone()).into_ref(vm) + Match::new(&state, self.pattern.clone(), self.string.clone()) + .into_ref(&vm.ctx) })) }, ) @@ -857,7 +858,8 @@ mod _sre { self.start.store(state.string_position); Ok(state.has_matched.then(|| { - Match::new(&state, self.pattern.clone(), self.string.clone()).into_ref(vm) + Match::new(&state, self.pattern.clone(), self.string.clone()) + .into_ref(&vm.ctx) })) }, ) diff --git a/vm/src/stdlib/symtable.rs b/vm/src/stdlib/symtable.rs index 404ad430e0..437c800a3e 100644 --- a/vm/src/stdlib/symtable.rs +++ b/vm/src/stdlib/symtable.rs @@ -27,7 +27,7 @@ mod symtable { .map_err(|err| vm.new_syntax_error(&err))?; let py_symbol_table = to_py_symbol_table(symtable); - Ok(py_symbol_table.into_ref(vm)) + Ok(py_symbol_table.into_ref(&vm.ctx)) } fn to_py_symbol_table(symtable: SymbolTable) -> PySymbolTable { @@ -91,7 +91,7 @@ mod symtable { .cloned() .collect(), } - .into_ref(vm)) + .into_ref(&vm.ctx)) } else { Err(vm.new_key_error(vm.ctx.new_str(format!("lookup {} failed", name)).into())) } @@ -125,7 +125,7 @@ mod symtable { .cloned() .collect(), }) - .into_ref(vm) + .into_ref(&vm.ctx) .into() }) .collect(); @@ -244,7 +244,7 @@ mod symtable { ); } Ok(to_py_symbol_table(self.namespaces.first().unwrap().clone()) - .into_ref(vm) + .into_ref(&vm.ctx) .into()) } } diff --git a/vm/src/stdlib/sys.rs b/vm/src/stdlib/sys.rs index c94df5e689..8228838f92 100644 --- a/vm/src/stdlib/sys.rs +++ b/vm/src/stdlib/sys.rs @@ -132,7 +132,7 @@ mod sys { } else { "unknown" }) - .to_str() + .to_owned() } #[pyattr] @@ -279,7 +279,7 @@ mod sys { #[pyfunction] fn exit(code: OptionalArg, vm: &VirtualMachine) -> PyResult { let code = code.unwrap_or_none(vm); - Err(vm.new_exception(vm.ctx.exceptions.system_exit.clone(), vec![code])) + Err(vm.new_exception(vm.ctx.exceptions.system_exit.to_owned(), vec![code])) } #[pyfunction(name = "__displayhook__")] @@ -479,7 +479,7 @@ mod sys { } assert!(unraisable .exc_type - .fast_issubclass(&vm.ctx.exceptions.exception_type)); + .fast_issubclass(vm.ctx.exceptions.exception_type)); // TODO: print module name and qualname @@ -513,7 +513,7 @@ mod sys { #[pyfunction] fn intern(s: PyRefExact, vm: &VirtualMachine) -> PyRefExact { - vm.ctx.intern_str(s).to_owned() + vm.ctx.intern_str(s).to_exact() } #[pyattr] diff --git a/vm/src/stdlib/thread.rs b/vm/src/stdlib/thread.rs index 8e8fbb6121..7c1a39a923 100644 --- a/vm/src/stdlib/thread.rs +++ b/vm/src/stdlib/thread.rs @@ -31,7 +31,7 @@ pub(crate) mod _thread { #[pyattr] fn error(vm: &VirtualMachine) -> PyTypeRef { - vm.ctx.exceptions.runtime_error.clone() + vm.ctx.exceptions.runtime_error.to_owned() } #[derive(FromArgs)] @@ -269,7 +269,7 @@ pub(crate) mod _thread { fn run_thread(func: ArgCallable, args: FuncArgs, vm: &VirtualMachine) { match func.invoke(args, vm) { Ok(_obj) => {} - Err(e) if e.fast_isinstance(&vm.ctx.exceptions.system_exit) => {} + Err(e) if e.fast_isinstance(vm.ctx.exceptions.system_exit) => {} Err(exc) => { vm.run_unraisable( exc, @@ -290,14 +290,14 @@ pub(crate) mod _thread { #[pyfunction] fn exit(vm: &VirtualMachine) -> PyResult { - Err(vm.new_exception_empty(vm.ctx.exceptions.system_exit.clone())) + Err(vm.new_exception_empty(vm.ctx.exceptions.system_exit.to_owned())) } thread_local!(static SENTINELS: RefCell>> = RefCell::default()); #[pyfunction] fn _set_sentinel(vm: &VirtualMachine) -> PyRef { - let lock = Lock { mu: RawMutex::INIT }.into_ref(vm); + let lock = Lock { mu: RawMutex::INIT }.into_ref(&vm.ctx); SENTINELS.with(|sents| sents.borrow_mut().push(lock.clone())); lock } diff --git a/vm/src/stdlib/warnings.rs b/vm/src/stdlib/warnings.rs index 829880852b..edc3b108e1 100644 --- a/vm/src/stdlib/warnings.rs +++ b/vm/src/stdlib/warnings.rs @@ -24,7 +24,7 @@ mod _warnings { // TODO: Implement correctly let level = args.stacklevel.unwrap_or(1); let category = if let OptionalArg::Present(category) = args.category { - if !category.fast_issubclass(&vm.ctx.exceptions.warning) { + if !category.fast_issubclass(vm.ctx.exceptions.warning) { return Err(vm.new_type_error(format!( "category must be a Warning subclass, not '{}'", category.class().name() @@ -32,7 +32,7 @@ mod _warnings { } category } else { - vm.ctx.exceptions.user_warning.clone() + vm.ctx.exceptions.user_warning.to_owned() }; let stderr = PyStderr(vm); writeln!( diff --git a/vm/src/stdlib/weakref.rs b/vm/src/stdlib/weakref.rs index 372c746e64..3ef0de6155 100644 --- a/vm/src/stdlib/weakref.rs +++ b/vm/src/stdlib/weakref.rs @@ -15,23 +15,23 @@ mod _weakref { #[pyattr(name = "ref")] fn ref_(vm: &VirtualMachine) -> PyTypeRef { - vm.ctx.types.weakref_type.clone() + vm.ctx.types.weakref_type.to_owned() } #[pyattr] fn proxy(vm: &VirtualMachine) -> PyTypeRef { - vm.ctx.types.weakproxy_type.clone() + vm.ctx.types.weakproxy_type.to_owned() } #[pyattr(name = "ReferenceType")] fn reference_type(vm: &VirtualMachine) -> PyTypeRef { - vm.ctx.types.weakref_type.clone() + vm.ctx.types.weakref_type.to_owned() } #[pyattr(name = "ProxyType")] fn proxy_type(vm: &VirtualMachine) -> PyTypeRef { - vm.ctx.types.weakproxy_type.clone() + vm.ctx.types.weakproxy_type.to_owned() } #[pyattr(name = "CallableProxyType")] fn callable_proxy_type(vm: &VirtualMachine) -> PyTypeRef { - vm.ctx.types.weakproxy_type.clone() + vm.ctx.types.weakproxy_type.to_owned() } #[pyfunction] diff --git a/vm/src/suggestion.rs b/vm/src/suggestion.rs index 7d69bde2ef..b23f9c447b 100644 --- a/vm/src/suggestion.rs +++ b/vm/src/suggestion.rs @@ -45,12 +45,12 @@ fn calculate_suggestions<'a>( } pub fn offer_suggestions(exc: &PyBaseExceptionRef, vm: &VirtualMachine) -> Option { - if exc.class().is(&vm.ctx.exceptions.attribute_error) { + if exc.class().is(vm.ctx.exceptions.attribute_error) { let name = exc.as_object().to_owned().get_attr("name", vm).unwrap(); let obj = exc.as_object().to_owned().get_attr("obj", vm).unwrap(); calculate_suggestions(vm.dir(Some(obj)).ok()?.borrow_vec().iter(), &name) - } else if exc.class().is(&vm.ctx.exceptions.name_error) { + } else if exc.class().is(vm.ctx.exceptions.name_error) { let name = exc.as_object().to_owned().get_attr("name", vm).unwrap(); let mut tb = exc.traceback().unwrap(); while let Some(traceback) = tb.next.clone() { diff --git a/vm/src/types/structseq.rs b/vm/src/types/structseq.rs index 01ab762eb1..b74ea34c5e 100644 --- a/vm/src/types/structseq.rs +++ b/vm/src/types/structseq.rs @@ -1,8 +1,8 @@ use crate::{ - builtins::{PyTuple, PyTupleRef, PyTypeRef}, + builtins::{PyTuple, PyTupleRef, PyType}, class::{PyClassImpl, StaticType}, vm::Context, - AsObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, + AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; #[pyimpl] @@ -13,7 +13,7 @@ pub trait PyStructSequence: StaticType + PyClassImpl + Sized + 'static { fn into_struct_sequence(self, vm: &VirtualMachine) -> PyTupleRef { self.into_tuple(vm) - .into_ref_with_type(vm, Self::static_type().clone()) + .into_ref_with_type(vm, Self::static_type().to_owned()) .unwrap() } @@ -73,14 +73,14 @@ pub trait PyStructSequence: StaticType + PyClassImpl + Sized + 'static { } #[extend_class] - fn extend_pyclass(ctx: &Context, class: &PyTypeRef) { + fn extend_pyclass(ctx: &Context, class: &'static Py) { for (i, &name) in Self::FIELD_NAMES.iter().enumerate() { // cast i to a u8 so there's less to store in the getter closure. // Hopefully there's not struct sequences with >=256 elements :P let i = i as u8; class.set_str_attr( name, - ctx.new_readonly_getset(name, class.clone(), move |zelf: &PyTuple| { + ctx.new_readonly_getset(name, class, move |zelf: &PyTuple| { zelf.fast_getitem(i.into()) }), ); diff --git a/vm/src/types/zoo.rs b/vm/src/types/zoo.rs index bd7af4d4b3..66a6617e6e 100644 --- a/vm/src/types/zoo.rs +++ b/vm/src/types/zoo.rs @@ -4,89 +4,90 @@ use crate::{ coroutine, dict, enumerate, filter, float, frame, function, generator, genericalias, getset, int, iter, list, map, mappingproxy, memory, module, namespace, object, property, pystr, range, set, singletons, slice, staticmethod, super_, traceback, tuple, - type_::{self, PyTypeRef}, + type_::{self, PyType}, union_, weakproxy, weakref, zip, }, class::StaticType, vm::Context, + Py, }; /// Holder of references to builtin types. #[derive(Debug, Clone)] #[non_exhaustive] pub struct TypeZoo { - pub async_generator: PyTypeRef, - pub async_generator_asend: PyTypeRef, - pub async_generator_athrow: PyTypeRef, - pub async_generator_wrapped_value: PyTypeRef, - pub bytes_type: PyTypeRef, - pub bytes_iterator_type: PyTypeRef, - pub bytearray_type: PyTypeRef, - pub bytearray_iterator_type: PyTypeRef, - pub bool_type: PyTypeRef, - pub callable_iterator: PyTypeRef, - pub cell_type: PyTypeRef, - pub classmethod_type: PyTypeRef, - pub code_type: PyTypeRef, - pub coroutine_type: PyTypeRef, - pub coroutine_wrapper_type: PyTypeRef, - pub dict_type: PyTypeRef, - pub enumerate_type: PyTypeRef, - pub filter_type: PyTypeRef, - pub float_type: PyTypeRef, - pub frame_type: PyTypeRef, - pub frozenset_type: PyTypeRef, - pub generator_type: PyTypeRef, - pub int_type: PyTypeRef, - pub iter_type: PyTypeRef, - pub reverse_iter_type: PyTypeRef, - pub complex_type: PyTypeRef, - pub list_type: PyTypeRef, - pub list_iterator_type: PyTypeRef, - pub list_reverseiterator_type: PyTypeRef, - pub str_iterator_type: PyTypeRef, - pub dict_keyiterator_type: PyTypeRef, - pub dict_reversekeyiterator_type: PyTypeRef, - pub dict_valueiterator_type: PyTypeRef, - pub dict_reversevalueiterator_type: PyTypeRef, - pub dict_itemiterator_type: PyTypeRef, - pub dict_reverseitemiterator_type: PyTypeRef, - pub dict_keys_type: PyTypeRef, - pub dict_values_type: PyTypeRef, - pub dict_items_type: PyTypeRef, - pub map_type: PyTypeRef, - pub memoryview_type: PyTypeRef, - pub tuple_type: PyTypeRef, - pub tuple_iterator_type: PyTypeRef, - pub set_type: PyTypeRef, - pub set_iterator_type: PyTypeRef, - pub staticmethod_type: PyTypeRef, - pub super_type: PyTypeRef, - pub str_type: PyTypeRef, - pub range_type: PyTypeRef, - pub range_iterator_type: PyTypeRef, - pub longrange_iterator_type: PyTypeRef, - pub slice_type: PyTypeRef, - pub type_type: PyTypeRef, - pub zip_type: PyTypeRef, - pub function_type: PyTypeRef, - pub builtin_function_or_method_type: PyTypeRef, - pub method_descriptor_type: PyTypeRef, - pub property_type: PyTypeRef, - pub getset_type: PyTypeRef, - pub module_type: PyTypeRef, - pub namespace_type: PyTypeRef, - pub bound_method_type: PyTypeRef, - pub weakref_type: PyTypeRef, - pub weakproxy_type: PyTypeRef, - pub mappingproxy_type: PyTypeRef, - pub traceback_type: PyTypeRef, - pub object_type: PyTypeRef, - pub ellipsis_type: PyTypeRef, - pub none_type: PyTypeRef, - pub not_implemented_type: PyTypeRef, - pub generic_alias_type: PyTypeRef, - pub union_type: PyTypeRef, + pub async_generator: &'static Py, + pub async_generator_asend: &'static Py, + pub async_generator_athrow: &'static Py, + pub async_generator_wrapped_value: &'static Py, + pub bytes_type: &'static Py, + pub bytes_iterator_type: &'static Py, + pub bytearray_type: &'static Py, + pub bytearray_iterator_type: &'static Py, + pub bool_type: &'static Py, + pub callable_iterator: &'static Py, + pub cell_type: &'static Py, + pub classmethod_type: &'static Py, + pub code_type: &'static Py, + pub coroutine_type: &'static Py, + pub coroutine_wrapper_type: &'static Py, + pub dict_type: &'static Py, + pub enumerate_type: &'static Py, + pub filter_type: &'static Py, + pub float_type: &'static Py, + pub frame_type: &'static Py, + pub frozenset_type: &'static Py, + pub generator_type: &'static Py, + pub int_type: &'static Py, + pub iter_type: &'static Py, + pub reverse_iter_type: &'static Py, + pub complex_type: &'static Py, + pub list_type: &'static Py, + pub list_iterator_type: &'static Py, + pub list_reverseiterator_type: &'static Py, + pub str_iterator_type: &'static Py, + pub dict_keyiterator_type: &'static Py, + pub dict_reversekeyiterator_type: &'static Py, + pub dict_valueiterator_type: &'static Py, + pub dict_reversevalueiterator_type: &'static Py, + pub dict_itemiterator_type: &'static Py, + pub dict_reverseitemiterator_type: &'static Py, + pub dict_keys_type: &'static Py, + pub dict_values_type: &'static Py, + pub dict_items_type: &'static Py, + pub map_type: &'static Py, + pub memoryview_type: &'static Py, + pub tuple_type: &'static Py, + pub tuple_iterator_type: &'static Py, + pub set_type: &'static Py, + pub set_iterator_type: &'static Py, + pub staticmethod_type: &'static Py, + pub super_type: &'static Py, + pub str_type: &'static Py, + pub range_type: &'static Py, + pub range_iterator_type: &'static Py, + pub longrange_iterator_type: &'static Py, + pub slice_type: &'static Py, + pub type_type: &'static Py, + pub zip_type: &'static Py, + pub function_type: &'static Py, + pub builtin_function_or_method_type: &'static Py, + pub method_descriptor_type: &'static Py, + pub property_type: &'static Py, + pub getset_type: &'static Py, + pub module_type: &'static Py, + pub namespace_type: &'static Py, + pub bound_method_type: &'static Py, + pub weakref_type: &'static Py, + pub weakproxy_type: &'static Py, + pub mappingproxy_type: &'static Py, + pub traceback_type: &'static Py, + pub object_type: &'static Py, + pub ellipsis_type: &'static Py, + pub none_type: &'static Py, + pub not_implemented_type: &'static Py, + pub generic_alias_type: &'static Py, + pub union_type: &'static Py, } impl TypeZoo { @@ -95,86 +96,82 @@ impl TypeZoo { let (type_type, object_type, weakref_type) = crate::object::init_type_hierarchy(); Self { // the order matters for type, object, weakref, and int - type_type: type_::PyType::init_manually(type_type).clone(), - object_type: object::PyBaseObject::init_manually(object_type).clone(), - weakref_type: weakref::PyWeak::init_manually(weakref_type).clone(), - int_type: int::PyInt::init_bare_type().clone(), + type_type: type_::PyType::init_manually(type_type), + object_type: object::PyBaseObject::init_manually(object_type), + weakref_type: weakref::PyWeak::init_manually(weakref_type), + int_type: int::PyInt::init_bare_type(), // types exposed as builtins - bool_type: bool_::PyBool::init_bare_type().clone(), - bytearray_type: bytearray::PyByteArray::init_bare_type().clone(), - bytes_type: bytes::PyBytes::init_bare_type().clone(), - classmethod_type: classmethod::PyClassMethod::init_bare_type().clone(), - complex_type: complex::PyComplex::init_bare_type().clone(), - dict_type: dict::PyDict::init_bare_type().clone(), - enumerate_type: enumerate::PyEnumerate::init_bare_type().clone(), - float_type: float::PyFloat::init_bare_type().clone(), - frozenset_type: set::PyFrozenSet::init_bare_type().clone(), - filter_type: filter::PyFilter::init_bare_type().clone(), - list_type: list::PyList::init_bare_type().clone(), - map_type: map::PyMap::init_bare_type().clone(), - memoryview_type: memory::PyMemoryView::init_bare_type().clone(), - property_type: property::PyProperty::init_bare_type().clone(), - range_type: range::PyRange::init_bare_type().clone(), - set_type: set::PySet::init_bare_type().clone(), - slice_type: slice::PySlice::init_bare_type().clone(), - staticmethod_type: staticmethod::PyStaticMethod::init_bare_type().clone(), - str_type: pystr::PyStr::init_bare_type().clone(), - super_type: super_::PySuper::init_bare_type().clone(), - tuple_type: tuple::PyTuple::init_bare_type().clone(), - zip_type: zip::PyZip::init_bare_type().clone(), + bool_type: bool_::PyBool::init_bare_type(), + bytearray_type: bytearray::PyByteArray::init_bare_type(), + bytes_type: bytes::PyBytes::init_bare_type(), + classmethod_type: classmethod::PyClassMethod::init_bare_type(), + complex_type: complex::PyComplex::init_bare_type(), + dict_type: dict::PyDict::init_bare_type(), + enumerate_type: enumerate::PyEnumerate::init_bare_type(), + float_type: float::PyFloat::init_bare_type(), + frozenset_type: set::PyFrozenSet::init_bare_type(), + filter_type: filter::PyFilter::init_bare_type(), + list_type: list::PyList::init_bare_type(), + map_type: map::PyMap::init_bare_type(), + memoryview_type: memory::PyMemoryView::init_bare_type(), + property_type: property::PyProperty::init_bare_type(), + range_type: range::PyRange::init_bare_type(), + set_type: set::PySet::init_bare_type(), + slice_type: slice::PySlice::init_bare_type(), + staticmethod_type: staticmethod::PyStaticMethod::init_bare_type(), + str_type: pystr::PyStr::init_bare_type(), + super_type: super_::PySuper::init_bare_type(), + tuple_type: tuple::PyTuple::init_bare_type(), + zip_type: zip::PyZip::init_bare_type(), // hidden internal types. is this really need to be cached here? - async_generator: asyncgenerator::PyAsyncGen::init_bare_type().clone(), - async_generator_asend: asyncgenerator::PyAsyncGenASend::init_bare_type().clone(), - async_generator_athrow: asyncgenerator::PyAsyncGenAThrow::init_bare_type().clone(), - async_generator_wrapped_value: asyncgenerator::PyAsyncGenWrappedValue::init_bare_type() - .clone(), - bound_method_type: function::PyBoundMethod::init_bare_type().clone(), - builtin_function_or_method_type: builtinfunc::PyBuiltinFunction::init_bare_type() - .clone(), - bytearray_iterator_type: bytearray::PyByteArrayIterator::init_bare_type().clone(), - bytes_iterator_type: bytes::PyBytesIterator::init_bare_type().clone(), - callable_iterator: iter::PyCallableIterator::init_bare_type().clone(), - cell_type: function::PyCell::init_bare_type().clone(), - code_type: code::PyCode::init_bare_type().clone(), - coroutine_type: coroutine::PyCoroutine::init_bare_type().clone(), - coroutine_wrapper_type: coroutine::PyCoroutineWrapper::init_bare_type().clone(), - dict_keys_type: dict::PyDictKeys::init_bare_type().clone(), - dict_values_type: dict::PyDictValues::init_bare_type().clone(), - dict_items_type: dict::PyDictItems::init_bare_type().clone(), - dict_keyiterator_type: dict::PyDictKeyIterator::init_bare_type().clone(), - dict_reversekeyiterator_type: dict::PyDictReverseKeyIterator::init_bare_type().clone(), - dict_valueiterator_type: dict::PyDictValueIterator::init_bare_type().clone(), - dict_reversevalueiterator_type: dict::PyDictReverseValueIterator::init_bare_type() - .clone(), - dict_itemiterator_type: dict::PyDictItemIterator::init_bare_type().clone(), - dict_reverseitemiterator_type: dict::PyDictReverseItemIterator::init_bare_type() - .clone(), - ellipsis_type: slice::PyEllipsis::init_bare_type().clone(), - frame_type: crate::frame::Frame::init_bare_type().clone(), - function_type: function::PyFunction::init_bare_type().clone(), - generator_type: generator::PyGenerator::init_bare_type().clone(), - getset_type: getset::PyGetSet::init_bare_type().clone(), - iter_type: iter::PySequenceIterator::init_bare_type().clone(), - reverse_iter_type: enumerate::PyReverseSequenceIterator::init_bare_type().clone(), - list_iterator_type: list::PyListIterator::init_bare_type().clone(), - list_reverseiterator_type: list::PyListReverseIterator::init_bare_type().clone(), - mappingproxy_type: mappingproxy::PyMappingProxy::init_bare_type().clone(), - module_type: module::PyModule::init_bare_type().clone(), - namespace_type: namespace::PyNamespace::init_bare_type().clone(), - range_iterator_type: range::PyRangeIterator::init_bare_type().clone(), - longrange_iterator_type: range::PyLongRangeIterator::init_bare_type().clone(), - set_iterator_type: set::PySetIterator::init_bare_type().clone(), - str_iterator_type: pystr::PyStrIterator::init_bare_type().clone(), - traceback_type: traceback::PyTraceback::init_bare_type().clone(), - tuple_iterator_type: tuple::PyTupleIterator::init_bare_type().clone(), - weakproxy_type: weakproxy::PyWeakProxy::init_bare_type().clone(), - method_descriptor_type: builtinfunc::PyBuiltinMethod::init_bare_type().clone(), - none_type: singletons::PyNone::init_bare_type().clone(), - not_implemented_type: singletons::PyNotImplemented::init_bare_type().clone(), - generic_alias_type: genericalias::PyGenericAlias::init_bare_type().clone(), - union_type: union_::PyUnion::init_bare_type().clone(), + async_generator: asyncgenerator::PyAsyncGen::init_bare_type(), + async_generator_asend: asyncgenerator::PyAsyncGenASend::init_bare_type(), + async_generator_athrow: asyncgenerator::PyAsyncGenAThrow::init_bare_type(), + async_generator_wrapped_value: asyncgenerator::PyAsyncGenWrappedValue::init_bare_type(), + bound_method_type: function::PyBoundMethod::init_bare_type(), + builtin_function_or_method_type: builtinfunc::PyBuiltinFunction::init_bare_type(), + bytearray_iterator_type: bytearray::PyByteArrayIterator::init_bare_type(), + bytes_iterator_type: bytes::PyBytesIterator::init_bare_type(), + callable_iterator: iter::PyCallableIterator::init_bare_type(), + cell_type: function::PyCell::init_bare_type(), + code_type: code::PyCode::init_bare_type(), + coroutine_type: coroutine::PyCoroutine::init_bare_type(), + coroutine_wrapper_type: coroutine::PyCoroutineWrapper::init_bare_type(), + dict_keys_type: dict::PyDictKeys::init_bare_type(), + dict_values_type: dict::PyDictValues::init_bare_type(), + dict_items_type: dict::PyDictItems::init_bare_type(), + dict_keyiterator_type: dict::PyDictKeyIterator::init_bare_type(), + dict_reversekeyiterator_type: dict::PyDictReverseKeyIterator::init_bare_type(), + dict_valueiterator_type: dict::PyDictValueIterator::init_bare_type(), + dict_reversevalueiterator_type: dict::PyDictReverseValueIterator::init_bare_type(), + dict_itemiterator_type: dict::PyDictItemIterator::init_bare_type(), + dict_reverseitemiterator_type: dict::PyDictReverseItemIterator::init_bare_type(), + ellipsis_type: slice::PyEllipsis::init_bare_type(), + frame_type: crate::frame::Frame::init_bare_type(), + function_type: function::PyFunction::init_bare_type(), + generator_type: generator::PyGenerator::init_bare_type(), + getset_type: getset::PyGetSet::init_bare_type(), + iter_type: iter::PySequenceIterator::init_bare_type(), + reverse_iter_type: enumerate::PyReverseSequenceIterator::init_bare_type(), + list_iterator_type: list::PyListIterator::init_bare_type(), + list_reverseiterator_type: list::PyListReverseIterator::init_bare_type(), + mappingproxy_type: mappingproxy::PyMappingProxy::init_bare_type(), + module_type: module::PyModule::init_bare_type(), + namespace_type: namespace::PyNamespace::init_bare_type(), + range_iterator_type: range::PyRangeIterator::init_bare_type(), + longrange_iterator_type: range::PyLongRangeIterator::init_bare_type(), + set_iterator_type: set::PySetIterator::init_bare_type(), + str_iterator_type: pystr::PyStrIterator::init_bare_type(), + traceback_type: traceback::PyTraceback::init_bare_type(), + tuple_iterator_type: tuple::PyTupleIterator::init_bare_type(), + weakproxy_type: weakproxy::PyWeakProxy::init_bare_type(), + method_descriptor_type: builtinfunc::PyBuiltinMethod::init_bare_type(), + none_type: singletons::PyNone::init_bare_type(), + not_implemented_type: singletons::PyNotImplemented::init_bare_type(), + generic_alias_type: genericalias::PyGenericAlias::init_bare_type(), + union_type: union_::PyUnion::init_bare_type(), } } diff --git a/vm/src/vm/context.rs b/vm/src/vm/context.rs index 1e362c3c5e..6392e3787e 100644 --- a/vm/src/vm/context.rs +++ b/vm/src/vm/context.rs @@ -1,20 +1,19 @@ use crate::{ builtins::{ builtinfunc::{PyBuiltinFunction, PyBuiltinMethod, PyNativeFuncDef}, - bytes, code::{self, PyCode}, getset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet}, object, pystr, type_::PyAttributes, - PyBaseException, PyComplex, PyDict, PyDictRef, PyEllipsis, PyFloat, PyFrozenSet, PyInt, - PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented, PyStr, PyTuple, PyTupleRef, PyType, - PyTypeRef, + PyBaseException, PyByteArray, PyBytes, PyComplex, PyDict, PyDictRef, PyEllipsis, PyFloat, + PyFrozenSet, PyInt, PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented, PyStr, PyTuple, + PyTupleRef, PyType, PyTypeRef, }, class::{PyClassImpl, StaticType}, exceptions, function::IntoPyNativeFunc, - intern::{Internable, PyStrInterned, StringPool}, - object::{PyObjectPayload, PyObjectRef, PyPayload, PyRef}, + intern::{Internable, MaybeInterned, PyStrInterned, StringPool}, + object::{Py, PyObjectPayload, PyObjectRef, PyPayload, PyRef}, types::{PyTypeFlags, PyTypeSlots, TypeZoo}, }; use num_bigint::BigInt; @@ -54,8 +53,11 @@ impl Context { let exceptions = exceptions::ExceptionZoo::init(); #[inline] - fn create_object(payload: T, cls: &PyTypeRef) -> PyRef { - PyRef::new_ref(payload, cls.clone(), None) + fn create_object( + payload: T, + cls: &'static Py, + ) -> PyRef { + PyRef::new_ref(payload, cls.to_owned(), None) } let none = create_object(PyNone, PyNone::static_type()); @@ -63,32 +65,40 @@ impl Context { let not_implemented = create_object(PyNotImplemented, PyNotImplemented::static_type()); let int_cache_pool = (Self::INT_CACHE_POOL_MIN..=Self::INT_CACHE_POOL_MAX) - .map(|v| PyRef::new_ref(PyInt::from(BigInt::from(v)), types.int_type.clone(), None)) + .map(|v| { + PyRef::new_ref( + PyInt::from(BigInt::from(v)), + types.int_type.to_owned(), + None, + ) + }) .collect(); - let true_value = create_object(PyInt::from(1), &types.bool_type); - let false_value = create_object(PyInt::from(0), &types.bool_type); + let true_value = create_object(PyInt::from(1), types.bool_type); + let false_value = create_object(PyInt::from(0), types.bool_type); let empty_tuple = create_object( PyTuple::new_unchecked(Vec::new().into_boxed_slice()), - &types.tuple_type, + types.tuple_type, + ); + let empty_frozenset = PyRef::new_ref( + PyFrozenSet::default(), + types.frozenset_type.to_owned(), + None, ); - let empty_frozenset = - PyRef::new_ref(PyFrozenSet::default(), types.frozenset_type.clone(), None); let string_pool = StringPool::default(); - let new_str = unsafe { string_pool.intern("__new__", types.str_type.clone()) }; + let new_str = unsafe { string_pool.intern("__new__", types.str_type.to_owned()) }; let slot_new_wrapper = create_object( - PyNativeFuncDef::new(PyType::__new__.into_func(), new_str.to_owned().into_pyref()) - .into_function(), - &types.builtin_function_or_method_type, + PyNativeFuncDef::new(PyType::__new__.into_func(), new_str.to_owned()).into_function(), + types.builtin_function_or_method_type, ) .into(); - let true_str = unsafe { string_pool.intern("True", types.str_type.clone()) }; - let false_str = unsafe { string_pool.intern("False", types.str_type.clone()) }; - let empty_str = unsafe { string_pool.intern("", types.str_type.clone()) }.to_str(); + let true_str = unsafe { string_pool.intern("True", types.str_type.to_owned()) }; + let false_str = unsafe { string_pool.intern("False", types.str_type.to_owned()) }; + let empty_str = unsafe { string_pool.intern("", types.str_type.to_owned()) }.to_owned(); let context = Context { true_value, @@ -116,7 +126,11 @@ impl Context { } pub fn intern_str(&self, s: S) -> &'static PyStrInterned { - unsafe { self.string_pool.intern(s, self.types.str_type.clone()) } + unsafe { self.string_pool.intern(s, self.types.str_type.to_owned()) } + } + + pub fn interned_str(&self, s: &S) -> Option<&'static PyStrInterned> { + self.string_pool.interned(s) } #[inline(always)] @@ -144,7 +158,7 @@ impl Context { return self.int_cache_pool[inner_idx].clone(); } } - PyRef::new_ref(PyInt::from(i), self.types.int_type.clone(), None) + PyRef::new_ref(PyInt::from(i), self.types.int_type.to_owned(), None) } #[inline] @@ -155,19 +169,19 @@ impl Context { return self.int_cache_pool[inner_idx].clone(); } } - PyRef::new_ref(PyInt::from(i.clone()), self.types.int_type.clone(), None) + PyRef::new_ref(PyInt::from(i.clone()), self.types.int_type.to_owned(), None) } #[inline] pub fn new_float(&self, value: f64) -> PyRef { - PyRef::new_ref(PyFloat::from(value), self.types.float_type.clone(), None) + PyRef::new_ref(PyFloat::from(value), self.types.float_type.to_owned(), None) } #[inline] pub fn new_complex(&self, value: Complex64) -> PyRef { PyRef::new_ref( PyComplex::from(value), - self.types.complex_type.clone(), + self.types.complex_type.to_owned(), None, ) } @@ -178,8 +192,17 @@ 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::new_ref(data, self) + } + + #[inline] + pub fn new_bytearray(&self, data: Vec) -> PyRef { + PyRef::new_ref( + PyByteArray::from(data), + self.types.bytearray_type.to_owned(), + None, + ) } #[inline(always)] @@ -204,14 +227,14 @@ impl Context { #[inline(always)] pub fn new_dict(&self) -> PyDictRef { - PyDict::new_ref(self) + PyDict::default().into_ref(self) } pub fn new_class( &self, module: Option<&str>, name: &str, - base: &PyTypeRef, + base: PyTypeRef, slots: PyTypeSlots, ) -> PyTypeRef { let mut attrs = PyAttributes::default(); @@ -220,10 +243,10 @@ impl Context { }; PyType::new_ref( name, - vec![base.clone()], + vec![base], attrs, slots, - self.types.type_type.clone(), + self.types.type_type.to_owned(), ) .unwrap() } @@ -237,7 +260,7 @@ impl Context { let bases = if let Some(bases) = bases { bases } else { - vec![self.exceptions.exception_type.clone()] + vec![self.exceptions.exception_type.to_owned()] }; let mut attrs = PyAttributes::default(); attrs.insert("__module__".to_owned(), self.new_str(module).into()); @@ -247,7 +270,7 @@ impl Context { bases, attrs, PyBaseException::make_slots(), - self.types.type_type.clone(), + self.types.type_type.to_owned(), ) .unwrap() } @@ -271,7 +294,7 @@ impl Context { pub fn new_method( &self, name: impl Into, - class: PyTypeRef, + class: &'static Py, f: F, ) -> PyRef where @@ -283,7 +306,7 @@ impl Context { pub fn new_readonly_getset( &self, name: impl Into, - class: PyTypeRef, + class: &'static Py, f: F, ) -> PyRef where @@ -291,7 +314,7 @@ impl Context { { PyRef::new_ref( PyGetSet::new(name.into(), class).with_get(f), - self.types.getset_type.clone(), + self.types.getset_type.to_owned(), None, ) } @@ -299,7 +322,7 @@ impl Context { pub fn new_getset( &self, name: impl Into, - class: PyTypeRef, + class: &'static Py, g: G, s: S, ) -> PyRef @@ -309,7 +332,7 @@ impl Context { { PyRef::new_ref( PyGetSet::new(name.into(), class).with_get(g).with_set(s), - self.types.getset_type.clone(), + self.types.getset_type.to_owned(), None, ) } @@ -324,7 +347,7 @@ impl Context { pub fn new_code(&self, code: impl code::IntoCodeObject) -> PyRef { let code = code.into_codeobj(self); - PyRef::new_ref(PyCode { code }, self.types.code_type.clone(), None) + PyRef::new_ref(PyCode { code }, self.types.code_type.to_owned(), None) } } diff --git a/vm/src/vm/mod.rs b/vm/src/vm/mod.rs index 87e4ac22d8..a8c0cd8b7c 100644 --- a/vm/src/vm/mod.rs +++ b/vm/src/vm/mod.rs @@ -99,7 +99,7 @@ impl VirtualMachine { let new_module = || { PyRef::new_ref( PyModule {}, - ctx.types.module_type.clone(), + ctx.types.module_type.to_owned(), Some(ctx.new_dict()), ) }; @@ -271,7 +271,7 @@ impl VirtualMachine { } pub fn run_code_obj(&self, code: PyRef, scope: Scope) -> PyResult { - let frame = Frame::new(code, scope, self.builtins.dict(), &[], self).into_ref(self); + let frame = Frame::new(code, scope, self.builtins.dict(), &[], self).into_ref(&self.ctx); self.run_frame(frame) } @@ -455,9 +455,9 @@ impl VirtualMachine { // Extract elements from item, if possible: let cls = value.class(); let list_borrow; - let slice = if cls.is(&self.ctx.types.tuple_type) { + let slice = if cls.is(self.ctx.types.tuple_type) { value.payload::().unwrap().as_slice() - } else if cls.is(&self.ctx.types.list_type) { + } else if cls.is(self.ctx.types.list_type) { list_borrow = value.payload::().unwrap().borrow_vec(); &list_borrow } else { @@ -506,7 +506,7 @@ impl VirtualMachine { { let iter = value.to_owned().get_iter(self)?; let cap = match self.length_hint_opt(value.to_owned()) { - Err(e) if e.class().is(&self.ctx.exceptions.runtime_error) => return Err(e), + Err(e) if e.class().is(self.ctx.exceptions.runtime_error) => return Err(e), Ok(Some(value)) => Some(value), // Use a power of 2 as a default capacity. _ => None, @@ -536,7 +536,7 @@ impl VirtualMachine { { match obj.get_attr(attr_name, self) { Ok(attr) => Ok(Some(attr)), - Err(e) if e.fast_isinstance(&self.ctx.exceptions.attribute_error) => Ok(None), + Err(e) if e.fast_isinstance(self.ctx.exceptions.attribute_error) => Ok(None), Err(e) => Err(e), } } @@ -547,7 +547,7 @@ impl VirtualMachine { obj: PyObjectRef, name: PyStrRef, ) { - if exc.class().is(&self.ctx.exceptions.attribute_error) { + if exc.class().is(self.ctx.exceptions.attribute_error) { let exc = exc.as_object(); exc.set_attr("name", name, self).unwrap(); exc.set_attr("obj", obj, self).unwrap(); @@ -654,7 +654,7 @@ impl VirtualMachine { } pub fn handle_exit_exception(&self, exc: PyBaseExceptionRef) -> i32 { - if exc.fast_isinstance(&self.ctx.exceptions.system_exit) { + if exc.fast_isinstance(self.ctx.exceptions.system_exit) { let args = exc.args(); let msg = match args.as_slice() { [] => return 0, @@ -764,7 +764,7 @@ fn get_importer(path: &str, vm: &VirtualMachine) -> PyResult importer = Some(imp); break; } - Err(e) if e.fast_isinstance(&vm.ctx.exceptions.import_error) => continue, + Err(e) if e.fast_isinstance(vm.ctx.exceptions.import_error) => continue, Err(e) => return Err(e), } } diff --git a/vm/src/vm/thread.rs b/vm/src/vm/thread.rs index 54c72e6976..015c2453f4 100644 --- a/vm/src/vm/thread.rs +++ b/vm/src/vm/thread.rs @@ -22,7 +22,7 @@ where let vm_owns_obj = |intp: NonNull| { // SAFETY: all references in VM_STACK should be valid let vm = unsafe { intp.as_ref() }; - obj.fast_isinstance(&vm.ctx.types.object_type) + obj.fast_isinstance(vm.ctx.types.object_type) }; VM_STACK.with(|vms| { let intp = match vms.borrow().iter().copied().exactly_one() { diff --git a/vm/src/vm/vm_new.rs b/vm/src/vm/vm_new.rs index 5d4c7d1059..9f6922d290 100644 --- a/vm/src/vm/vm_new.rs +++ b/vm/src/vm/vm_new.rs @@ -4,12 +4,12 @@ use crate::{ builtins::{ pystr::IntoPyStrRef, tuple::{IntoPyTuple, PyTupleRef}, - PyBaseException, PyBaseExceptionRef, PyDictRef, PyModule, PyStrRef, PyTypeRef, + PyBaseException, PyBaseExceptionRef, PyDictRef, PyModule, PyStrRef, PyType, PyTypeRef, }, convert::ToPyObject, scope::Scope, vm::VirtualMachine, - AsObject, PyObject, PyObjectRef, PyPayload, PyRef, + AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, }; /// Collection of object creation helpers @@ -24,7 +24,7 @@ impl VirtualMachine { T: Into

, P: PyPayload, { - value.into().into_ref(self) + value.into().into_ref(&self.ctx) } pub fn new_tuple(&self, value: impl IntoPyTuple) -> PyTupleRef { @@ -32,7 +32,11 @@ impl VirtualMachine { } pub fn new_module(&self, name: &str, dict: PyDictRef, doc: Option<&str>) -> PyObjectRef { - let module = PyRef::new_ref(PyModule {}, self.ctx.types.module_type.clone(), Some(dict)); + let module = PyRef::new_ref( + PyModule {}, + self.ctx.types.module_type.to_owned(), + Some(dict), + ); module.init_module_dict( self.new_pyobj(name.to_owned()), doc.map(|doc| self.new_pyobj(doc.to_owned())) @@ -83,22 +87,22 @@ impl VirtualMachine { } pub fn new_lookup_error(&self, msg: String) -> PyBaseExceptionRef { - let lookup_error = self.ctx.exceptions.lookup_error.clone(); + let lookup_error = self.ctx.exceptions.lookup_error.to_owned(); self.new_exception_msg(lookup_error, msg) } pub fn new_attribute_error(&self, msg: String) -> PyBaseExceptionRef { - let attribute_error = self.ctx.exceptions.attribute_error.clone(); + let attribute_error = self.ctx.exceptions.attribute_error.to_owned(); self.new_exception_msg(attribute_error, msg) } pub fn new_type_error(&self, msg: String) -> PyBaseExceptionRef { - let type_error = self.ctx.exceptions.type_error.clone(); + let type_error = self.ctx.exceptions.type_error.to_owned(); self.new_exception_msg(type_error, msg) } pub fn new_name_error(&self, msg: String, name: &PyStrRef) -> PyBaseExceptionRef { - let name_error_type = self.ctx.exceptions.name_error.clone(); + let name_error_type = self.ctx.exceptions.name_error.to_owned(); let name_error = self.new_exception_msg(name_error_type, msg); name_error .as_object() @@ -146,60 +150,60 @@ impl VirtualMachine { } pub fn new_os_error(&self, msg: String) -> PyBaseExceptionRef { - let os_error = self.ctx.exceptions.os_error.clone(); + let os_error = self.ctx.exceptions.os_error.to_owned(); self.new_exception_msg(os_error, msg) } pub fn new_unicode_decode_error(&self, msg: String) -> PyBaseExceptionRef { - let unicode_decode_error = self.ctx.exceptions.unicode_decode_error.clone(); + let unicode_decode_error = self.ctx.exceptions.unicode_decode_error.to_owned(); self.new_exception_msg(unicode_decode_error, msg) } pub fn new_unicode_encode_error(&self, msg: String) -> PyBaseExceptionRef { - let unicode_encode_error = self.ctx.exceptions.unicode_encode_error.clone(); + let unicode_encode_error = self.ctx.exceptions.unicode_encode_error.to_owned(); self.new_exception_msg(unicode_encode_error, msg) } /// Create a new python ValueError object. Useful for raising errors from /// python functions implemented in rust. pub fn new_value_error(&self, msg: String) -> PyBaseExceptionRef { - let value_error = self.ctx.exceptions.value_error.clone(); + let value_error = self.ctx.exceptions.value_error.to_owned(); self.new_exception_msg(value_error, msg) } pub fn new_buffer_error(&self, msg: String) -> PyBaseExceptionRef { - let buffer_error = self.ctx.exceptions.buffer_error.clone(); + let buffer_error = self.ctx.exceptions.buffer_error.to_owned(); self.new_exception_msg(buffer_error, msg) } // TODO: don't take ownership should make the success path faster pub fn new_key_error(&self, obj: PyObjectRef) -> PyBaseExceptionRef { - let key_error = self.ctx.exceptions.key_error.clone(); + let key_error = self.ctx.exceptions.key_error.to_owned(); self.new_exception(key_error, vec![obj]) } pub fn new_index_error(&self, msg: String) -> PyBaseExceptionRef { - let index_error = self.ctx.exceptions.index_error.clone(); + let index_error = self.ctx.exceptions.index_error.to_owned(); self.new_exception_msg(index_error, msg) } pub fn new_not_implemented_error(&self, msg: String) -> PyBaseExceptionRef { - let not_implemented_error = self.ctx.exceptions.not_implemented_error.clone(); + let not_implemented_error = self.ctx.exceptions.not_implemented_error.to_owned(); self.new_exception_msg(not_implemented_error, msg) } pub fn new_recursion_error(&self, msg: String) -> PyBaseExceptionRef { - let recursion_error = self.ctx.exceptions.recursion_error.clone(); + let recursion_error = self.ctx.exceptions.recursion_error.to_owned(); self.new_exception_msg(recursion_error, msg) } pub fn new_zero_division_error(&self, msg: String) -> PyBaseExceptionRef { - let zero_division_error = self.ctx.exceptions.zero_division_error.clone(); + let zero_division_error = self.ctx.exceptions.zero_division_error.to_owned(); self.new_exception_msg(zero_division_error, msg) } pub fn new_overflow_error(&self, msg: String) -> PyBaseExceptionRef { - let overflow_error = self.ctx.exceptions.overflow_error.clone(); + let overflow_error = self.ctx.exceptions.overflow_error.to_owned(); self.new_exception_msg(overflow_error, msg) } @@ -207,11 +211,12 @@ impl VirtualMachine { pub fn new_syntax_error(&self, error: &CompileError) -> PyBaseExceptionRef { let syntax_error_type = match &error.error { CompileErrorType::Parse(p) if p.is_indentation_error() => { - self.ctx.exceptions.indentation_error.clone() + self.ctx.exceptions.indentation_error } - CompileErrorType::Parse(p) if p.is_tab_error() => self.ctx.exceptions.tab_error.clone(), - _ => self.ctx.exceptions.syntax_error.clone(), - }; + CompileErrorType::Parse(p) if p.is_tab_error() => self.ctx.exceptions.tab_error, + _ => self.ctx.exceptions.syntax_error, + } + .to_owned(); let syntax_error = self.new_exception_msg(syntax_error_type, error.to_string()); let lineno = self.ctx.new_int(error.location.row()); let offset = self.ctx.new_int(error.location.column()); @@ -239,7 +244,7 @@ impl VirtualMachine { } pub fn new_import_error(&self, msg: String, name: impl IntoPyStrRef) -> PyBaseExceptionRef { - let import_error = self.ctx.exceptions.import_error.clone(); + let import_error = self.ctx.exceptions.import_error.to_owned(); let exc = self.new_exception_msg(import_error, msg); exc.as_object() .set_attr("name", name.into_pystr_ref(self), self) @@ -248,12 +253,12 @@ impl VirtualMachine { } pub fn new_runtime_error(&self, msg: String) -> PyBaseExceptionRef { - let runtime_error = self.ctx.exceptions.runtime_error.clone(); + let runtime_error = self.ctx.exceptions.runtime_error.to_owned(); self.new_exception_msg(runtime_error, msg) } pub fn new_memory_error(&self, msg: String) -> PyBaseExceptionRef { - let memory_error_type = self.ctx.exceptions.memory_error.clone(); + let memory_error_type = self.ctx.exceptions.memory_error.to_owned(); self.new_exception_msg(memory_error_type, msg) } @@ -263,31 +268,31 @@ impl VirtualMachine { } else { Vec::new() }; - self.new_exception(self.ctx.exceptions.stop_iteration.clone(), args) + self.new_exception(self.ctx.exceptions.stop_iteration.to_owned(), args) } fn new_downcast_error( &self, msg: &'static str, - error_type: &PyTypeRef, - class: &PyTypeRef, + error_type: &'static Py, + class: &Py, obj: &PyObject, // the impl Borrow allows to pass PyObjectRef or &PyObject ) -> PyBaseExceptionRef { let actual_class = obj.class(); let actual_type = &*actual_class.name(); let expected_type = &*class.name(); let msg = format!("Expected {msg} '{expected_type}' but '{actual_type}' found"); - self.new_exception_msg(error_type.clone(), msg) + self.new_exception_msg(error_type.to_owned(), msg) } pub(crate) fn new_downcast_runtime_error( &self, - class: &PyTypeRef, + class: &Py, obj: &impl AsObject, ) -> PyBaseExceptionRef { self.new_downcast_error( "payload", - &self.ctx.exceptions.runtime_error, + self.ctx.exceptions.runtime_error, class, obj.as_object(), ) @@ -295,12 +300,12 @@ impl VirtualMachine { pub(crate) fn new_downcast_type_error( &self, - class: &PyTypeRef, + class: &Py, obj: &impl AsObject, ) -> PyBaseExceptionRef { self.new_downcast_error( "type", - &self.ctx.exceptions.type_error, + self.ctx.exceptions.type_error, class, obj.as_object(), ) diff --git a/vm/src/vm/vm_object.rs b/vm/src/vm/vm_object.rs index 4c98a4c08e..44250f96e0 100644 --- a/vm/src/vm/vm_object.rs +++ b/vm/src/vm/vm_object.rs @@ -120,7 +120,7 @@ impl VirtualMachine { PyMethod::get( obj.to_owned(), - PyStr::from(method_name).into_ref(self), + PyStr::from(method_name).into_ref(&self.ctx), self, )? .invoke(args, self) diff --git a/vm/src/vm/vm_ops.rs b/vm/src/vm/vm_ops.rs index dc10479a24..f244841921 100644 --- a/vm/src/vm/vm_ops.rs +++ b/vm/src/vm/vm_ops.rs @@ -72,7 +72,7 @@ impl VirtualMachine { match iter.length(self) { Ok(len) => return Ok(Some(len)), Err(e) => { - if !e.fast_isinstance(&self.ctx.exceptions.type_error) { + if !e.fast_isinstance(self.ctx.exceptions.type_error) { return Err(e); } } @@ -89,7 +89,7 @@ impl VirtualMachine { res } Err(e) => { - return if e.fast_isinstance(&self.ctx.exceptions.type_error) { + return if e.fast_isinstance(self.ctx.exceptions.type_error) { Ok(None) } else { Err(e) @@ -176,7 +176,7 @@ impl VirtualMachine { if let Some((lop, rop)) = lop.zip(rop) { if !lop.is(&rop) { if let Ok(r) = self.call_or_unsupported(rhs, lhs, reflection, |vm, _, _| { - Err(vm.new_exception_empty(vm.ctx.exceptions.exception_type.clone())) + Err(vm.new_exception_empty(vm.ctx.exceptions.exception_type.to_owned())) }) { return Ok(r); } diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs index edb002a219..db07750534 100644 --- a/wasm/lib/src/convert.rs +++ b/wasm/lib/src/convert.rs @@ -62,16 +62,16 @@ pub fn js_err_to_py_err(vm: &VirtualMachine, js_err: &JsValue) -> PyBaseExceptio match js_err.dyn_ref::() { Some(err) => { let exc_type = match String::from(err.name()).as_str() { - "TypeError" => &vm.ctx.exceptions.type_error, - "ReferenceError" => &vm.ctx.exceptions.name_error, - "SyntaxError" => &vm.ctx.exceptions.syntax_error, - _ => &vm.ctx.exceptions.exception_type, + "TypeError" => vm.ctx.exceptions.type_error, + "ReferenceError" => vm.ctx.exceptions.name_error, + "SyntaxError" => vm.ctx.exceptions.syntax_error, + _ => vm.ctx.exceptions.exception_type, } - .clone(); + .to_owned(); vm.new_exception_msg(exc_type, err.message().into()) } None => vm.new_exception_msg( - vm.ctx.exceptions.exception_type.clone(), + vm.ctx.exceptions.exception_type.to_owned(), format!("{:?}", js_err), ), } @@ -79,7 +79,7 @@ pub fn js_err_to_py_err(vm: &VirtualMachine, js_err: &JsValue) -> PyBaseExceptio pub fn py_to_js(vm: &VirtualMachine, py_obj: PyObjectRef) -> JsValue { if let Some(ref wasm_id) = vm.wasm_id { - if py_obj.fast_isinstance(&vm.ctx.types.function_type) { + if py_obj.fast_isinstance(vm.ctx.types.function_type) { let wasm_vm = WASMVirtualMachine { id: wasm_id.clone(), }; @@ -174,7 +174,7 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef { // the browser module might not be injected if vm.try_class("browser", "Promise").is_ok() { return js_module::PyPromise::new(promise.clone()) - .into_ref(vm) + .into_ref(&vm.ctx) .into(); } } diff --git a/wasm/lib/src/js_module.rs b/wasm/lib/src/js_module.rs index aaa3f2d309..bae5d05462 100644 --- a/wasm/lib/src/js_module.rs +++ b/wasm/lib/src/js_module.rs @@ -1,8 +1,5 @@ pub(crate) use _js::{PyJsValue, PyPromise}; -use rustpython_vm::{ - builtins::{PyBaseExceptionRef, PyType}, - PyObjectRef, VirtualMachine, -}; +use rustpython_vm::VirtualMachine; #[pymodule] mod _js { @@ -13,7 +10,7 @@ mod _js { }; use js_sys::{Array, Object, Promise, Reflect}; use rustpython_vm::{ - builtins::{PyBaseExceptionRef, PyFloat, PyStrRef, PyTypeRef}, + builtins::{PyBaseExceptionRef, PyFloat, PyStrRef, PyType, PyTypeRef}, convert::{IntoObject, ToPyObject}, function::{ArgCallable, OptionalArg, OptionalOption, PosArgs}, protocol::PyIterReturn, @@ -336,7 +333,7 @@ mod _js { } else { Closure::once(Box::new(f)) }; - let wrapped = PyJsValue::new(wrap_closure(closure.as_ref())).into_ref(vm); + let wrapped = PyJsValue::new(wrap_closure(closure.as_ref())).into_ref(&vm.ctx); Ok(JsClosure { closure: Some((closure, wrapped)).into(), destroyed: false.into(), @@ -617,24 +614,23 @@ mod _js { vec![PyJsValue::new(err).to_pyobject(vm)], ) } -} - -pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { - let module = _js::make_module(vm); - - let ctx = &vm.ctx; - let js_error = PyType::new_simple_ref("JSError", &vm.ctx.exceptions.exception_type).unwrap(); - extend_class!(ctx, &js_error, { - "value" => ctx.new_readonly_getset("value", js_error.clone(), |exc: PyBaseExceptionRef| exc.get_arg(0)), - }); - extend_module!(vm, module, { - "JSError" => js_error, - }); - - module + #[pyattr(name = "JSError", once)] + fn js_error(vm: &VirtualMachine) -> PyTypeRef { + let ctx = &vm.ctx; + let js_error = PyRef::leak( + PyType::new_simple_ref("JSError", &vm.ctx.exceptions.exception_type.to_owned()) + .unwrap(), + ); + extend_class!(ctx, js_error, { + "value" => ctx.new_readonly_getset("value", js_error, |exc: PyBaseExceptionRef| exc.get_arg(0)), + }); + js_error.to_owned() + } } +pub(crate) use _js::make_module; + pub fn setup_js_module(vm: &mut VirtualMachine) { vm.add_native_module("_js".to_owned(), Box::new(make_module)); } diff --git a/wasm/lib/src/vm_class.rs b/wasm/lib/src/vm_class.rs index a82d44bd6a..327db6685e 100644 --- a/wasm/lib/src/vm_class.rs +++ b/wasm/lib/src/vm_class.rs @@ -32,7 +32,7 @@ fn init_window_module(vm: &VirtualMachine) -> PyObjectRef { let module = _window::make_module(vm); extend_module!(vm, module, { - "window" => js_module::PyJsValue::new(wasm_builtins::window()).into_ref(vm), + "window" => js_module::PyJsValue::new(wasm_builtins::window()).into_ref(&vm.ctx), }); module diff --git a/wasm/lib/src/wasm_builtins.rs b/wasm/lib/src/wasm_builtins.rs index a64316ef3c..6cf86ea570 100644 --- a/wasm/lib/src/wasm_builtins.rs +++ b/wasm/lib/src/wasm_builtins.rs @@ -4,12 +4,9 @@ //! desktop. //! Implements functions listed here: https://docs.python.org/3/library/builtins.html. +use rustpython_vm::{builtins::PyStrRef, PyObjectRef, PyRef, PyResult, VirtualMachine}; use web_sys::{self, console}; -use rustpython_vm::builtins::PyStrRef; -use rustpython_vm::VirtualMachine; -use rustpython_vm::{PyObjectRef, PyResult}; - pub(crate) fn window() -> web_sys::Window { web_sys::window().expect("Window to be available") } @@ -26,18 +23,23 @@ pub fn make_stdout_object( let ctx = &vm.ctx; // there's not really any point to storing this class so that there's a consistent type object, // we just want a half-decent repr() output - let cls = py_class!(ctx, "JSStdout", &vm.ctx.types.object_type, {}); + let cls = PyRef::leak(py_class!( + ctx, + "JSStdout", + vm.ctx.types.object_type.to_owned(), + {} + )); let write_method = ctx.new_method( "write", - cls.clone(), + cls, move |_self: PyObjectRef, data: PyStrRef, vm: &VirtualMachine| -> PyResult<()> { write_f(data.as_str(), vm) }, ); - let flush_method = ctx.new_method("flush", cls.clone(), |_self: PyObjectRef| {}); + let flush_method = ctx.new_method("flush", cls, |_self: PyObjectRef| {}); extend_class!(ctx, cls, { "write" => write_method, "flush" => flush_method, }); - ctx.new_base_object(cls, None) + ctx.new_base_object(cls.to_owned(), None) }