From 93d143834528f2b7b710cc044ad146cbaa2df350 Mon Sep 17 00:00:00 2001 From: Jeong Yunwon Date: Mon, 16 May 2022 02:04:58 +0900 Subject: [PATCH] PyObjBag refers Context instead of vm --- examples/freeze/main.rs | 2 +- examples/mini_repl.rs | 2 +- src/lib.rs | 2 +- vm/src/builtins/code.rs | 37 ++++++++++++++++++------------------- vm/src/frozen.rs | 2 +- vm/src/import.rs | 4 ++-- vm/src/stdlib/ast.rs | 2 +- vm/src/stdlib/marshal.rs | 5 +---- vm/src/vm/compile.rs | 2 +- vm/src/vm/context.rs | 24 ++++++++++++++++++++++-- vm/src/vm/mod.rs | 4 ---- vm/src/vm/vm_new.rs | 5 ----- 12 files changed, 49 insertions(+), 42 deletions(-) diff --git a/examples/freeze/main.rs b/examples/freeze/main.rs index 2395b3301d..4899112907 100644 --- a/examples/freeze/main.rs +++ b/examples/freeze/main.rs @@ -11,7 +11,7 @@ fn run(vm: &vm::VirtualMachine) -> vm::PyResult<()> { // https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates let module = vm::py_compile!(file = "examples/freeze/freeze.py"); - let res = vm.run_code_obj(vm.new_code_object(module), scope); + let res = vm.run_code_obj(vm.ctx.new_code(module), scope); if let Err(exc) = res { vm.print_exception(exc); diff --git a/examples/mini_repl.rs b/examples/mini_repl.rs index 19a4113e50..7ea4c2d746 100644 --- a/examples/mini_repl.rs +++ b/examples/mini_repl.rs @@ -15,7 +15,7 @@ macro_rules! add_python_function { // compile the code to bytecode let code = vm::py_compile!(source = $src); // convert the rustpython_bytecode::CodeObject to a PyRef - let code = $vm.new_code_object(code); + let code = $vm.ctx.new_code(code); // run the python code in the scope to store the function $vm.run_code_obj(code, $scope.clone()) diff --git a/src/lib.rs b/src/lib.rs index c6154f43d5..d30792ea0e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -506,7 +506,7 @@ __import__("io").TextIOWrapper( mode = "eval" ); eprintln!("downloading get-pip.py..."); - let getpip_code = vm.run_code_obj(vm.new_code_object(get_getpip), scope.clone())?; + let getpip_code = vm.run_code_obj(vm.ctx.new_code(get_getpip), scope.clone())?; let getpip_code: rustpython_vm::builtins::PyStrRef = getpip_code .downcast() .expect("TextIOWrapper.read() should return str"); diff --git a/vm/src/builtins/code.rs b/vm/src/builtins/code.rs index 310c6599a6..16a80ad025 100644 --- a/vm/src/builtins/code.rs +++ b/vm/src/builtins/code.rs @@ -71,24 +71,23 @@ impl Constant for PyConstant { } } -pub(crate) struct PyObjBag<'a>(pub &'a VirtualMachine); +pub(crate) struct PyObjBag<'a>(pub &'a Context); impl ConstantBag for PyObjBag<'_> { type Constant = PyConstant; fn make_constant(&self, constant: bytecode::ConstantData) -> Self::Constant { - let vm = self.0; - let ctx = &vm.ctx; + let ctx = self.0; let obj = match constant { bytecode::ConstantData::Integer { value } => ctx.new_int(value).into(), bytecode::ConstantData::Float { value } => ctx.new_float(value).into(), - bytecode::ConstantData::Complex { value } => vm.new_pyobj(value), + bytecode::ConstantData::Complex { value } => ctx.new_complex(value).into(), bytecode::ConstantData::Str { value } if value.len() <= 20 => { - vm.ctx.intern_string(value).into_pyref().into() + ctx.intern_string(value).into_pyref().into() } - bytecode::ConstantData::Str { value } => vm.ctx.new_str(value).into(), + bytecode::ConstantData::Str { value } => ctx.new_str(value).into(), bytecode::ConstantData::Bytes { value } => ctx.new_bytes(value.to_vec()).into(), bytecode::ConstantData::Boolean { value } => ctx.new_bool(value).into(), - bytecode::ConstantData::Code { code } => vm.new_code_object(code.map_bag(self)).into(), + bytecode::ConstantData::Code { code } => ctx.new_code(code.map_bag(self)).into(), bytecode::ConstantData::Tuple { elements } => { let elements = elements .into_iter() @@ -102,20 +101,19 @@ impl ConstantBag for PyObjBag<'_> { PyConstant(obj) } fn make_constant_borrowed(&self, constant: BorrowedConstant) -> Self::Constant { - let vm = self.0; - let ctx = &vm.ctx; + let ctx = &self.0; let obj = match constant { bytecode::BorrowedConstant::Integer { value } => ctx.new_bigint(value).into(), bytecode::BorrowedConstant::Float { value } => ctx.new_float(value).into(), - bytecode::BorrowedConstant::Complex { value } => vm.new_pyobj(value), + bytecode::BorrowedConstant::Complex { value } => ctx.new_complex(value).into(), bytecode::BorrowedConstant::Str { value } if value.len() <= 20 => { - vm.ctx.intern_string(value).into_pyref().into() + ctx.intern_string(value).into_pyref().into() } - bytecode::BorrowedConstant::Str { value } => vm.ctx.new_str(value).into(), + bytecode::BorrowedConstant::Str { value } => ctx.new_str(value).into(), bytecode::BorrowedConstant::Bytes { value } => ctx.new_bytes(value.to_vec()).into(), bytecode::BorrowedConstant::Boolean { value } => ctx.new_bool(value).into(), bytecode::BorrowedConstant::Code { code } => { - vm.new_code_object(code.map_clone_bag(self)).into() + ctx.new_code(code.map_clone_bag(self)).into() } bytecode::BorrowedConstant::Tuple { elements } => { let elements = elements @@ -130,10 +128,10 @@ impl ConstantBag for PyObjBag<'_> { PyConstant(obj) } fn make_name(&self, name: String) -> PyStrRef { - self.0.ctx.intern_string(name).into_pyref() + self.0.intern_string(name).into_pyref() } fn make_name_ref(&self, name: &str) -> PyStrRef { - self.0.ctx.intern_string(name).into_pyref() + self.0.intern_string(name).into_pyref() } } @@ -141,16 +139,17 @@ pub type CodeObject = bytecode::CodeObject; pub type FrozenModule = bytecode::FrozenModule; pub trait IntoCodeObject { - fn into_codeobj(self, vm: &VirtualMachine) -> CodeObject; + fn into_codeobj(self, ctx: &Context) -> CodeObject; } impl IntoCodeObject for CodeObject { - fn into_codeobj(self, _vm: &VirtualMachine) -> CodeObject { + fn into_codeobj(self, _ctx: &Context) -> CodeObject { self } } + impl IntoCodeObject for bytecode::CodeObject { - fn into_codeobj(self, vm: &VirtualMachine) -> CodeObject { - vm.map_codeobj(self) + fn into_codeobj(self, ctx: &Context) -> CodeObject { + self.map_bag(&PyObjBag(ctx)) } } diff --git a/vm/src/frozen.rs b/vm/src/frozen.rs index 160ae22aba..83aecde161 100644 --- a/vm/src/frozen.rs +++ b/vm/src/frozen.rs @@ -11,7 +11,7 @@ pub fn map_frozen<'a>( ( k, code::FrozenModule { - code: vm.map_codeobj(code), + code: vm.ctx.new_code_object(code), package, }, ) diff --git a/vm/src/import.rs b/vm/src/import.rs index ad68e2a27f..406dab2c68 100644 --- a/vm/src/import.rs +++ b/vm/src/import.rs @@ -123,9 +123,9 @@ pub fn import_file( file_path: String, content: String, ) -> PyResult { - let code_obj = compile::compile(&content, compile::Mode::Exec, file_path, vm.compile_opts()) + let code = compile::compile(&content, compile::Mode::Exec, file_path, vm.compile_opts()) .map_err(|err| vm.new_syntax_error(&err))?; - import_codeobj(vm, module_name, vm.map_codeobj(code_obj), true) + import_codeobj(vm, module_name, vm.ctx.new_code_object(code), true) } pub fn import_codeobj( diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs index ea44be9fe3..329bbd7a67 100644 --- a/vm/src/stdlib/ast.rs +++ b/vm/src/stdlib/ast.rs @@ -276,7 +276,7 @@ pub(crate) fn compile( let code = rustpython_compiler_core::compile::compile_top(&ast, filename.to_owned(), opts) // TODO: use vm.new_syntax_error() .map_err(|err| vm.new_value_error(err.to_string()))?; - Ok(vm.new_code_object(code).into()) + Ok(vm.ctx.new_code(code).into()) } // Required crate visibility for inclusion by gen.rs diff --git a/vm/src/stdlib/marshal.rs b/vm/src/stdlib/marshal.rs index b75c8b8506..707a465053 100644 --- a/vm/src/stdlib/marshal.rs +++ b/vm/src/stdlib/marshal.rs @@ -309,10 +309,7 @@ mod decl { ), _ => vm.new_value_error("Couldn't deserialize python bytecode".to_owned()), })?; - Ok(PyCode { - code: vm.map_codeobj(code), - } - .to_pyobject(vm)) + Ok(vm.ctx.new_code(code).into()) } } } diff --git a/vm/src/vm/compile.rs b/vm/src/vm/compile.rs index 61c8ab7623..fd5b25c9ee 100644 --- a/vm/src/vm/compile.rs +++ b/vm/src/vm/compile.rs @@ -30,6 +30,6 @@ impl VirtualMachine { opts: CompileOpts, ) -> Result, CompileError> { compile::compile(source, mode, source_path, opts) - .map(|code| PyCode::new(self.map_codeobj(code)).into_ref(self)) + .map(|code| PyCode::new(self.ctx.new_code_object(code)).into_ref(self)) } } diff --git a/vm/src/vm/context.rs b/vm/src/vm/context.rs index d3d69dcf2a..c3cb438644 100644 --- a/vm/src/vm/context.rs +++ b/vm/src/vm/context.rs @@ -2,11 +2,13 @@ use crate::{ builtins::{ builtinfunc::{PyBuiltinFunction, PyBuiltinMethod, PyNativeFuncDef}, bytes, + code::{self, PyCode}, getset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet}, object, pystr, type_::PyAttributes, - PyBaseException, PyDict, PyDictRef, PyEllipsis, PyFloat, PyFrozenSet, PyInt, PyIntRef, - PyList, PyListRef, PyNone, PyNotImplemented, PyStr, PyTuple, PyTupleRef, PyType, PyTypeRef, + PyBaseException, PyComplex, PyDict, PyDictRef, PyEllipsis, PyFloat, PyFrozenSet, PyInt, + PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented, PyStr, PyTuple, PyTupleRef, PyType, + PyTypeRef, }, class::{PyClassImpl, StaticType}, exceptions, @@ -16,6 +18,7 @@ use crate::{ types::{PyTypeFlags, PyTypeSlots, TypeZoo}, }; use num_bigint::BigInt; +use num_complex::Complex64; use num_traits::ToPrimitive; #[derive(Debug, Clone)] @@ -159,6 +162,15 @@ impl Context { PyRef::new_ref(PyFloat::from(value), self.types.float_type.clone(), None) } + #[inline] + pub fn new_complex(&self, value: Complex64) -> PyRef { + PyRef::new_ref( + PyComplex::from(value), + self.types.complex_type.clone(), + None, + ) + } + #[inline] pub fn new_str(&self, s: impl Into) -> PyRef { pystr::PyStr::new_ref(s, self) @@ -308,6 +320,14 @@ impl Context { ); PyRef::new_ref(object::PyBaseObject, class, dict).into() } + + pub fn new_code(&self, code: impl code::IntoCodeObject) -> PyRef { + PyCode::new_ref(code.into_codeobj(self), self) + } + + pub fn new_code_object(&self, code: crate::bytecode::CodeObject) -> code::CodeObject { + code.map_bag(&code::PyObjBag(self)) + } } impl Default for Context { diff --git a/vm/src/vm/mod.rs b/vm/src/vm/mod.rs index 98fd122810..865c5817a3 100644 --- a/vm/src/vm/mod.rs +++ b/vm/src/vm/mod.rs @@ -685,10 +685,6 @@ impl VirtualMachine { } } - pub fn map_codeobj(&self, code: bytecode::CodeObject) -> code::CodeObject { - code.map_bag(&code::PyObjBag(self)) - } - #[doc(hidden)] pub fn __module_set_attr( &self, diff --git a/vm/src/vm/vm_new.rs b/vm/src/vm/vm_new.rs index dd4a3ec3ef..5d4c7d1059 100644 --- a/vm/src/vm/vm_new.rs +++ b/vm/src/vm/vm_new.rs @@ -2,7 +2,6 @@ use crate::compile::{CompileError, CompileErrorType}; use crate::{ builtins::{ - code::{self, PyCode}, pystr::IntoPyStrRef, tuple::{IntoPyTuple, PyTupleRef}, PyBaseException, PyBaseExceptionRef, PyDictRef, PyModule, PyStrRef, PyTypeRef, @@ -32,10 +31,6 @@ impl VirtualMachine { value.into_pytuple(self) } - pub fn new_code_object(&self, code: impl code::IntoCodeObject) -> PyRef { - PyCode::new_ref(code.into_codeobj(self), &self.ctx) - } - 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)); module.init_module_dict(