From fa889f3652dcbad8ed72b210334f7390938084d5 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 19 Sep 2020 08:20:11 +0900 Subject: [PATCH 01/11] move ellipsis to objslice by following cpython --- vm/src/obj/mod.rs | 1 - vm/src/obj/objellipsis.rs | 42 --------------------------------------- vm/src/obj/objslice.rs | 36 ++++++++++++++++++++++++++++++--- vm/src/pyobject.rs | 2 +- vm/src/types.rs | 4 +--- 5 files changed, 35 insertions(+), 50 deletions(-) delete mode 100644 vm/src/obj/objellipsis.rs diff --git a/vm/src/obj/mod.rs b/vm/src/obj/mod.rs index b06f4d47f..3528f7e24 100644 --- a/vm/src/obj/mod.rs +++ b/vm/src/obj/mod.rs @@ -11,7 +11,6 @@ pub mod objcomplex; pub mod objcoroinner; pub mod objcoroutine; pub mod objdict; -pub mod objellipsis; pub mod objenumerate; pub mod objfilter; pub mod objfloat; diff --git a/vm/src/obj/objellipsis.rs b/vm/src/obj/objellipsis.rs deleted file mode 100644 index 57164bc32..000000000 --- a/vm/src/obj/objellipsis.rs +++ /dev/null @@ -1,42 +0,0 @@ -use super::objtype::{issubclass, PyClassRef}; -use crate::pyobject::{PyClassImpl, PyContext, PyResult, PyValue}; -use crate::vm::VirtualMachine; - -pub(crate) fn init(context: &PyContext) { - PyEllipsis::extend_class(context, &context.types.ellipsis_type); -} - -#[pyclass(module = false, name = "EllipsisType")] -#[derive(Debug)] -pub struct PyEllipsis; - -impl PyValue for PyEllipsis { - fn class(vm: &VirtualMachine) -> PyClassRef { - vm.ctx.types.ellipsis_type.clone() - } -} - -#[pyimpl] -impl PyEllipsis { - #[pyslot] - fn tp_new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult { - if issubclass(&cls, &vm.ctx.types.ellipsis_type) { - Ok(vm.ctx.ellipsis()) - } else { - Err(vm.new_type_error(format!( - "ellipsis.__new__({ty}): {ty} is not a subtype of ellipsis", - ty = cls, - ))) - } - } - - #[pymethod(magic)] - fn repr(&self) -> String { - "Ellipsis".to_owned() - } - - #[pymethod(magic)] - fn reduce(&self) -> String { - "Ellipsis".to_owned() - } -} diff --git a/vm/src/obj/objslice.rs b/vm/src/obj/objslice.rs index c74b91007..ca56c6358 100644 --- a/vm/src/obj/objslice.rs +++ b/vm/src/obj/objslice.rs @@ -1,3 +1,5 @@ +// sliceobject.{h,c} in CPython + use super::objint::PyInt; use super::objtype::PyClassRef; use crate::function::{OptionalArg, PyFuncArgs}; @@ -333,7 +335,35 @@ fn to_index_value(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult PyClassRef { + vm.ctx.types.ellipsis_type.clone() + } +} + +#[pyimpl] +impl PyEllipsis { + #[pyslot] + fn tp_new(_cls: PyClassRef, vm: &VirtualMachine) -> PyRef { + vm.ctx.ellipsis.clone() + } + + #[pymethod(magic)] + fn repr(&self) -> String { + "Ellipsis".to_owned() + } + + #[pymethod(magic)] + fn reduce(&self) -> String { + "Ellipsis".to_owned() + } +} + +pub fn init(context: &PyContext) { + PySlice::extend_class(context, &context.types.slice_type); + PyEllipsis::extend_class(context, &context.types.ellipsis_type); } diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index ee3499095..ac0f9718c 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -20,7 +20,6 @@ use crate::obj::objcode; use crate::obj::objcode::PyCodeRef; use crate::obj::objcomplex::PyComplex; use crate::obj::objdict::{PyDict, PyDictRef}; -use crate::obj::objellipsis::PyEllipsis; use crate::obj::objfloat::PyFloat; use crate::obj::objfunction::{PyBoundMethod, PyFunction}; use crate::obj::objgetset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet}; @@ -31,6 +30,7 @@ use crate::obj::objnamespace::PyNamespace; use crate::obj::objnone::{PyNone, PyNoneRef}; use crate::obj::objobject; use crate::obj::objset::PySet; +use crate::obj::objslice::PyEllipsis; use crate::obj::objstaticmethod::PyStaticMethod; use crate::obj::objstr; use crate::obj::objtuple::{PyTuple, PyTupleRef}; diff --git a/vm/src/types.rs b/vm/src/types.rs index e834101b3..a8ce11dcc 100644 --- a/vm/src/types.rs +++ b/vm/src/types.rs @@ -8,7 +8,6 @@ use crate::obj::objcode; use crate::obj::objcomplex; use crate::obj::objcoroutine; use crate::obj::objdict; -use crate::obj::objellipsis; use crate::obj::objenumerate; use crate::obj::objfilter; use crate::obj::objfloat; @@ -166,7 +165,7 @@ impl TypeZoo { dict_reversevalueiterator_type: create_type!(objdict::PyDictReverseValueIterator), dict_itemiterator_type: create_type!(objdict::PyDictItemIterator), dict_reverseitemiterator_type: create_type!(objdict::PyDictReverseItemIterator), - ellipsis_type: create_type!(objellipsis::PyEllipsis), + ellipsis_type: create_type!(objslice::PyEllipsis), enumerate_type: create_type!(objenumerate::PyEnumerate), filter_type: create_type!(objfilter::PyFilter), float_type: create_type!(objfloat::PyFloat), @@ -361,7 +360,6 @@ pub fn initialize_types(context: &PyContext) { objslice::init(&context); objsuper::init(&context); objiter::init(&context); - objellipsis::init(&context); objenumerate::init(&context); objfilter::init(&context); objmap::init(&context); From b5db221c5a843aff822622d5490066c0cb5da109 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 19 Sep 2020 08:20:57 +0900 Subject: [PATCH 02/11] replace get_property_value with into_pyobject --- vm/src/obj/objslice.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/vm/src/obj/objslice.rs b/vm/src/obj/objslice.rs index ca56c6358..e8bd5190d 100644 --- a/vm/src/obj/objslice.rs +++ b/vm/src/obj/objslice.rs @@ -5,7 +5,7 @@ use super::objtype::PyClassRef; use crate::function::{OptionalArg, PyFuncArgs}; use crate::pyobject::{ BorrowValue, IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, - TryIntoRef, + TryIntoRef, IntoPyObject, }; use crate::vm::VirtualMachine; use num_bigint::{BigInt, ToBigInt}; @@ -27,19 +27,11 @@ impl PyValue for PySlice { pub type PySliceRef = PyRef; -fn get_property_value(vm: &VirtualMachine, value: &Option) -> PyObjectRef { - if let Some(value) = value { - value.clone() - } else { - vm.get_none() - } -} - #[pyimpl] impl PySlice { #[pyproperty(name = "start")] fn start(&self, vm: &VirtualMachine) -> PyObjectRef { - get_property_value(vm, &self.start) + self.start.clone().into_pyobject(vm) } #[pyproperty(name = "stop")] @@ -49,7 +41,7 @@ impl PySlice { #[pyproperty(name = "step")] fn step(&self, vm: &VirtualMachine) -> PyObjectRef { - get_property_value(vm, &self.step) + self.step.clone().into_pyobject(vm) } #[pymethod(name = "__repr__")] From f14ec5d4c8dd629891fc3dc50117c9b647140424 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 19 Sep 2020 08:26:52 +0900 Subject: [PATCH 03/11] objsingletons --- vm/src/bytesinner.rs | 2 +- vm/src/exceptions.rs | 2 +- vm/src/obj/mod.rs | 2 +- vm/src/obj/objsequence.rs | 2 +- vm/src/obj/{objnone.rs => objsingletons.rs} | 11 +++++++++++ vm/src/obj/objslice.rs | 4 ++-- vm/src/pyobject.rs | 13 +------------ vm/src/types.rs | 4 ++-- 8 files changed, 20 insertions(+), 20 deletions(-) rename vm/src/obj/{objnone.rs => objsingletons.rs} (88%) diff --git a/vm/src/bytesinner.rs b/vm/src/bytesinner.rs index 607457630..74267d2ac 100644 --- a/vm/src/bytesinner.rs +++ b/vm/src/bytesinner.rs @@ -10,10 +10,10 @@ use crate::obj::objbytes::PyBytes; use crate::obj::objint::{self, PyInt, PyIntRef}; use crate::obj::objlist::PyList; use crate::obj::objmemory::PyMemoryView; -use crate::obj::objnone::PyNoneRef; use crate::obj::objsequence::{ get_saturated_pos, PySliceableSequence, PySliceableSequenceMut, SequenceIndex, }; +use crate::obj::objsingletons::PyNoneRef; use crate::obj::objslice::PySliceRef; use crate::obj::objstr::{self, PyString, PyStringRef}; use crate::pyobject::{ diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index d2cb2f766..4a152b568 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -1,6 +1,6 @@ use crate::common::cell::PyRwLock; use crate::function::PyFuncArgs; -use crate::obj::objnone::PyNone; +use crate::obj::objsingletons::PyNone; use crate::obj::objstr::{PyString, PyStringRef}; use crate::obj::objtraceback::PyTracebackRef; use crate::obj::objtuple::{PyTuple, PyTupleRef}; diff --git a/vm/src/obj/mod.rs b/vm/src/obj/mod.rs index 3528f7e24..7e6e1e629 100644 --- a/vm/src/obj/mod.rs +++ b/vm/src/obj/mod.rs @@ -26,12 +26,12 @@ pub mod objmappingproxy; pub mod objmemory; pub mod objmodule; pub mod objnamespace; -pub mod objnone; pub mod objobject; pub mod objproperty; pub mod objrange; pub mod objsequence; pub mod objset; +pub mod objsingletons; pub mod objslice; pub mod objstaticmethod; pub mod objstr; diff --git a/vm/src/obj/objsequence.rs b/vm/src/obj/objsequence.rs index 2dd47eb0a..1bb6a5568 100644 --- a/vm/src/obj/objsequence.rs +++ b/vm/src/obj/objsequence.rs @@ -5,7 +5,7 @@ use num_traits::{One, Signed, ToPrimitive, Zero}; use super::objint::{PyInt, PyIntRef}; use super::objlist::PyList; -use super::objnone::PyNone; +use super::objsingletons::PyNone; use super::objslice::{PySlice, PySliceRef}; use super::objtuple::PyTuple; use crate::function::OptionalArg; diff --git a/vm/src/obj/objnone.rs b/vm/src/obj/objsingletons.rs similarity index 88% rename from vm/src/obj/objnone.rs rename to vm/src/obj/objsingletons.rs index 450ca9fd6..7867631d1 100644 --- a/vm/src/obj/objnone.rs +++ b/vm/src/obj/objsingletons.rs @@ -68,6 +68,17 @@ impl PyNone { } } +pub type PyNotImplementedRef = PyRef; + +#[derive(Debug)] +pub struct PyNotImplemented; + +impl PyValue for PyNotImplemented { + fn class(vm: &VirtualMachine) -> PyClassRef { + vm.ctx.not_implemented().class() + } +} + pub fn init(context: &PyContext) { PyNone::extend_class(context, &context.none.class()); } diff --git a/vm/src/obj/objslice.rs b/vm/src/obj/objslice.rs index e8bd5190d..5e80afd3f 100644 --- a/vm/src/obj/objslice.rs +++ b/vm/src/obj/objslice.rs @@ -4,8 +4,8 @@ use super::objint::PyInt; use super::objtype::PyClassRef; use crate::function::{OptionalArg, PyFuncArgs}; use crate::pyobject::{ - BorrowValue, IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, - TryIntoRef, IntoPyObject, + BorrowValue, IdProtocol, IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, + PyValue, TryIntoRef, }; use crate::vm::VirtualMachine; use num_bigint::{BigInt, ToBigInt}; diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index ac0f9718c..cee0f5086 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -27,9 +27,9 @@ use crate::obj::objint::{PyInt, PyIntRef}; use crate::obj::objiter; use crate::obj::objlist::PyList; use crate::obj::objnamespace::PyNamespace; -use crate::obj::objnone::{PyNone, PyNoneRef}; use crate::obj::objobject; use crate::obj::objset::PySet; +use crate::obj::objsingletons::{PyNone, PyNoneRef, PyNotImplemented, PyNotImplementedRef}; use crate::obj::objslice::PyEllipsis; use crate::obj::objstaticmethod::PyStaticMethod; use crate::obj::objstr; @@ -106,17 +106,6 @@ pub struct PyContext { tp_new_wrapper: PyObjectRef, } -pub type PyNotImplementedRef = PyRef; - -#[derive(Debug)] -pub struct PyNotImplemented; - -impl PyValue for PyNotImplemented { - fn class(vm: &VirtualMachine) -> PyClassRef { - vm.ctx.not_implemented().class() - } -} - // Basic objects: impl PyContext { pub const INT_CACHE_POOL_MIN: i32 = -5; diff --git a/vm/src/types.rs b/vm/src/types.rs index a8ce11dcc..818ff606a 100644 --- a/vm/src/types.rs +++ b/vm/src/types.rs @@ -23,11 +23,11 @@ use crate::obj::objmappingproxy; use crate::obj::objmemory; use crate::obj::objmodule; use crate::obj::objnamespace; -use crate::obj::objnone; use crate::obj::objobject; use crate::obj::objproperty; use crate::obj::objrange; use crate::obj::objset; +use crate::obj::objsingletons; use crate::obj::objslice; use crate::obj::objstaticmethod; use crate::obj::objstr; @@ -369,7 +369,7 @@ pub fn initialize_types(context: &PyContext) { objframe::init(&context); objweakref::init(&context); objweakproxy::init(&context); - objnone::init(&context); + objsingletons::init(&context); objmodule::init(&context); objnamespace::init(&context); objmappingproxy::init(&context); From 5642299f4f7d9928ffbe2c07f083ece797b48c58 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 19 Sep 2020 08:31:49 +0900 Subject: [PATCH 04/11] pyclass for NotImplementedType --- vm/src/obj/objsingletons.rs | 8 ++++++-- vm/src/pyobject.rs | 9 +++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/vm/src/obj/objsingletons.rs b/vm/src/obj/objsingletons.rs index 7867631d1..9d6f8596d 100644 --- a/vm/src/obj/objsingletons.rs +++ b/vm/src/obj/objsingletons.rs @@ -68,10 +68,10 @@ impl PyNone { } } -pub type PyNotImplementedRef = PyRef; - +#[pyclass(module = false, name = "NotImplementedType")] #[derive(Debug)] pub struct PyNotImplemented; +pub type PyNotImplementedRef = PyRef; impl PyValue for PyNotImplemented { fn class(vm: &VirtualMachine) -> PyClassRef { @@ -79,6 +79,10 @@ impl PyValue for PyNotImplemented { } } +#[pyimpl] +impl PyNotImplemented {} + pub fn init(context: &PyContext) { PyNone::extend_class(context, &context.none.class()); + PyNotImplemented::extend_class(context, &context.not_implemented.class()); } diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index cee0f5086..8a4b1a514 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -38,7 +38,7 @@ use crate::obj::objtype::{self, PyClass, PyClassRef}; pub use crate::pyobjectrc::{PyObjectRc, PyObjectWeak}; use crate::scope::Scope; use crate::slots::{PyClassSlots, PyTpFlags}; -use crate::types::{create_type, create_type_with_slots, initialize_types, TypeZoo}; +use crate::types::{create_type_with_slots, initialize_types, TypeZoo}; use crate::vm::VirtualMachine; use rustpython_common::cell::{PyRwLock, PyRwLockReadGuard}; use rustpython_common::rc::PyRc; @@ -125,11 +125,8 @@ impl PyContext { let ellipsis = create_object(PyEllipsis, &types.ellipsis_type); - let not_implemented_type = create_type( - "NotImplementedType", - &types.type_type, - types.object_type.clone(), - ); + let not_implemented_type = + PyNotImplemented::create_bare_type(&types.type_type, types.object_type.clone()); let not_implemented = create_object(PyNotImplemented, ¬_implemented_type); let int_cache_pool = (Self::INT_CACHE_POOL_MIN..=Self::INT_CACHE_POOL_MAX) From 1bd6cd98148c1bf304b09aedab8ed0b5b94d73d5 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 19 Sep 2020 08:41:10 +0900 Subject: [PATCH 05/11] Remove elleipsis_type from TypeZoo --- vm/src/obj/objsingletons.rs | 4 ++-- vm/src/obj/objslice.rs | 6 +++--- vm/src/pyobject.rs | 4 +++- vm/src/types.rs | 2 -- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/vm/src/obj/objsingletons.rs b/vm/src/obj/objsingletons.rs index 9d6f8596d..c73e6efd1 100644 --- a/vm/src/obj/objsingletons.rs +++ b/vm/src/obj/objsingletons.rs @@ -11,7 +11,7 @@ pub type PyNoneRef = PyRef; impl PyValue for PyNone { fn class(vm: &VirtualMachine) -> PyClassRef { - vm.ctx.none().class() + vm.ctx.none.class() } } @@ -75,7 +75,7 @@ pub type PyNotImplementedRef = PyRef; impl PyValue for PyNotImplemented { fn class(vm: &VirtualMachine) -> PyClassRef { - vm.ctx.not_implemented().class() + vm.ctx.not_implemented.class() } } diff --git a/vm/src/obj/objslice.rs b/vm/src/obj/objslice.rs index 5e80afd3f..e20495698 100644 --- a/vm/src/obj/objslice.rs +++ b/vm/src/obj/objslice.rs @@ -5,7 +5,7 @@ use super::objtype::PyClassRef; use crate::function::{OptionalArg, PyFuncArgs}; use crate::pyobject::{ BorrowValue, IdProtocol, IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, - PyValue, TryIntoRef, + PyValue, TryIntoRef, TypeProtocol, }; use crate::vm::VirtualMachine; use num_bigint::{BigInt, ToBigInt}; @@ -333,7 +333,7 @@ pub struct PyEllipsis; impl PyValue for PyEllipsis { fn class(vm: &VirtualMachine) -> PyClassRef { - vm.ctx.types.ellipsis_type.clone() + vm.ctx.ellipsis.class() } } @@ -357,5 +357,5 @@ impl PyEllipsis { pub fn init(context: &PyContext) { PySlice::extend_class(context, &context.types.slice_type); - PyEllipsis::extend_class(context, &context.types.ellipsis_type); + PyEllipsis::extend_class(context, &context.ellipsis.class()); } diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index 8a4b1a514..13aaeee4a 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -123,7 +123,9 @@ impl PyContext { let none_type = PyNone::create_bare_type(&types.type_type, types.object_type.clone()); let none = create_object(PyNone, &none_type); - let ellipsis = create_object(PyEllipsis, &types.ellipsis_type); + let ellipsis_type = + PyEllipsis::create_bare_type(&types.type_type, types.object_type.clone()); + let ellipsis = create_object(PyEllipsis, &ellipsis_type); let not_implemented_type = PyNotImplemented::create_bare_type(&types.type_type, types.object_type.clone()); diff --git a/vm/src/types.rs b/vm/src/types.rs index 818ff606a..d8e567efe 100644 --- a/vm/src/types.rs +++ b/vm/src/types.rs @@ -65,7 +65,6 @@ pub struct TypeZoo { pub coroutine_wrapper_type: PyClassRef, pub dict_type: PyClassRef, pub enumerate_type: PyClassRef, - pub ellipsis_type: PyClassRef, pub filter_type: PyClassRef, pub float_type: PyClassRef, pub frame_type: PyClassRef, @@ -165,7 +164,6 @@ impl TypeZoo { dict_reversevalueiterator_type: create_type!(objdict::PyDictReverseValueIterator), dict_itemiterator_type: create_type!(objdict::PyDictItemIterator), dict_reverseitemiterator_type: create_type!(objdict::PyDictReverseItemIterator), - ellipsis_type: create_type!(objslice::PyEllipsis), enumerate_type: create_type!(objenumerate::PyEnumerate), filter_type: create_type!(objfilter::PyFilter), float_type: create_type!(objfloat::PyFloat), From 3d908dc754ac862211c0daca127a2659ef31d00d Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 19 Sep 2020 08:52:28 +0900 Subject: [PATCH 06/11] Fix wrong use of None cloning --- vm/src/obj/objproperty.rs | 4 ++-- vm/src/obj/objslice.rs | 6 +++--- vm/src/vm.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/vm/src/obj/objproperty.rs b/vm/src/obj/objproperty.rs index f319399a2..5af26b89d 100644 --- a/vm/src/obj/objproperty.rs +++ b/vm/src/obj/objproperty.rs @@ -6,7 +6,7 @@ use crate::common::cell::PyRwLock; use super::objtype::PyClassRef; use crate::function::OptionalArg; use crate::pyobject::{ - IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, + PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, }; use crate::slots::SlotDescriptor; use crate::vm::VirtualMachine; @@ -198,7 +198,7 @@ impl PyProperty { /// Take a python object and turn it into an option object, where python None maps to rust None. fn py_none_to_option(vm: &VirtualMachine, value: &PyObjectRef) -> Option { - if vm.ctx.none().is(value) { + if vm.is_none(value) { None } else { Some(value.clone()) diff --git a/vm/src/obj/objslice.rs b/vm/src/obj/objslice.rs index e20495698..ff3a93987 100644 --- a/vm/src/obj/objslice.rs +++ b/vm/src/obj/objslice.rs @@ -4,8 +4,8 @@ use super::objint::PyInt; use super::objtype::PyClassRef; use crate::function::{OptionalArg, PyFuncArgs}; use crate::pyobject::{ - BorrowValue, IdProtocol, IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, - PyValue, TryIntoRef, TypeProtocol, + BorrowValue, IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, + TryIntoRef, TypeProtocol, }; use crate::vm::VirtualMachine; use num_bigint::{BigInt, ToBigInt}; @@ -315,7 +315,7 @@ impl PySlice { } fn to_index_value(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult> { - if obj.is(&vm.ctx.none) { + if vm.is_none(obj) { return Ok(None); } diff --git a/vm/src/vm.rs b/vm/src/vm.rs index a3357540d..8bec0fa13 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -669,7 +669,7 @@ impl VirtualMachine { /// Test whether a python object is `None`. pub fn is_none(&self, obj: &PyObjectRef) -> bool { - obj.is(&self.get_none()) + obj.is(&self.ctx.none) } pub fn option_if_none(&self, obj: PyObjectRef) -> Option { if self.is_none(&obj) { From 0f7ed21eda30a51385fccbc10352c17196c8a552 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 19 Sep 2020 10:10:43 +0900 Subject: [PATCH 07/11] remove vm.get_none and clean up its use cases --- vm/src/exceptions.rs | 35 +++++-------- vm/src/frame.rs | 19 +++---- vm/src/function.rs | 6 +++ vm/src/obj/objasyncgenerator.rs | 26 +++++----- vm/src/obj/objbuiltinfunc.rs | 6 +-- vm/src/obj/objcoroinner.rs | 4 +- vm/src/obj/objcoroutine.rs | 8 +-- vm/src/obj/objdict.rs | 6 +-- vm/src/obj/objfilter.rs | 4 +- vm/src/obj/objframe.rs | 2 +- vm/src/obj/objfunction.rs | 6 +-- vm/src/obj/objgenerator.rs | 8 +-- vm/src/obj/objint.rs | 2 +- vm/src/obj/objiter.rs | 6 +-- vm/src/obj/objmappingproxy.rs | 13 +++-- vm/src/obj/objmodule.rs | 12 ++--- vm/src/obj/objrange.rs | 4 +- vm/src/obj/objset.rs | 8 +-- vm/src/obj/objstr.rs | 4 +- vm/src/obj/objsuper.rs | 4 +- vm/src/obj/objtype.rs | 2 +- vm/src/obj/objweakref.rs | 2 +- vm/src/py_serde.rs | 6 +-- vm/src/pyobject.rs | 2 +- vm/src/slots.rs | 2 +- vm/src/stdlib/ast.rs | 4 +- vm/src/stdlib/dis.rs | 2 +- vm/src/stdlib/hashlib.rs | 87 ++++++++++++++++----------------- vm/src/stdlib/imp.rs | 4 +- vm/src/stdlib/io.rs | 20 ++------ vm/src/stdlib/itertools.rs | 18 +++---- vm/src/stdlib/json.rs | 8 ++- vm/src/stdlib/os.rs | 9 ++-- vm/src/stdlib/re.rs | 20 ++++---- vm/src/stdlib/signal.rs | 4 +- vm/src/stdlib/socket.rs | 7 +-- vm/src/stdlib/ssl.rs | 5 +- vm/src/stdlib/winreg.rs | 2 +- vm/src/sysmodule.rs | 8 +-- vm/src/vm.rs | 33 +++++-------- wasm/lib/src/browser_module.rs | 17 +++---- wasm/lib/src/convert.rs | 4 +- 42 files changed, 194 insertions(+), 255 deletions(-) diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 4a152b568..79ff62495 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -1,14 +1,14 @@ use crate::common::cell::PyRwLock; use crate::function::PyFuncArgs; -use crate::obj::objsingletons::PyNone; +use crate::obj::objsingletons::{PyNone, PyNoneRef}; use crate::obj::objstr::{PyString, PyStringRef}; use crate::obj::objtraceback::PyTracebackRef; use crate::obj::objtuple::{PyTuple, PyTupleRef}; use crate::obj::objtype::{self, PyClass, PyClassRef}; use crate::py_io::{self, Write}; use crate::pyobject::{ - BorrowValue, PyClassDef, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef, PyResult, - PyValue, TryFromObject, TypeProtocol, + BorrowValue, IntoPyObject, PyClassDef, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef, + PyResult, PyValue, TryFromObject, TypeProtocol, }; use crate::types::create_type_with_slots; use crate::VirtualMachine; @@ -371,7 +371,7 @@ pub fn split( exc: PyBaseExceptionRef, vm: &VirtualMachine, ) -> (PyObjectRef, PyObjectRef, PyObjectRef) { - let tb = exc.traceback().map_or(vm.get_none(), |tb| tb.into_object()); + let tb = exc.traceback().into_pyobject(vm); (exc.class().into_object(), exc.into_object(), tb) } @@ -626,35 +626,22 @@ fn import_error_init(exc_self: PyObjectRef, args: PyFuncArgs, vm: &VirtualMachin vm.set_attr( &exc_self, "name", - args.kwargs - .get("name") - .cloned() - .unwrap_or_else(|| vm.get_none()), + vm.unwrap_or_none(args.kwargs.get("name").cloned()), )?; vm.set_attr( &exc_self, "path", - args.kwargs - .get("path") - .cloned() - .unwrap_or_else(|| vm.get_none()), + vm.unwrap_or_none(args.kwargs.get("path").cloned()), )?; Ok(()) } -fn none_getter(_obj: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef { - vm.get_none() +fn none_getter(_obj: PyObjectRef, vm: &VirtualMachine) -> PyNoneRef { + vm.ctx.none.clone() } -fn make_arg_getter(idx: usize) -> impl Fn(PyBaseExceptionRef, &VirtualMachine) -> PyObjectRef { - move |exc, vm| { - exc.args - .read() - .borrow_value() - .get(idx) - .cloned() - .unwrap_or_else(|| vm.get_none()) - } +fn make_arg_getter(idx: usize) -> impl Fn(PyBaseExceptionRef) -> Option { + move |exc| exc.args.read().borrow_value().get(idx).cloned() } fn key_error_str(exc: PyBaseExceptionRef, vm: &VirtualMachine) -> PyStringRef { @@ -678,7 +665,7 @@ fn system_exit_code(exc: PyBaseExceptionRef, vm: &VirtualMachine) -> PyObjectRef }, other => other.clone(), }), - None => vm.get_none(), + None => vm.ctx.none(), } } diff --git a/vm/src/frame.rs b/vm/src/frame.rs index d90e59318..8ed0de00d 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -170,7 +170,7 @@ impl Frame { stack: Vec::new(), blocks: Vec::new(), }), - trace: PyMutex::new(vm.get_none()), + trace: PyMutex::new(vm.ctx.none()), } } } @@ -540,14 +540,11 @@ impl ExecutingFrame<'_> { let exit = self.pop_value(); let args = if let Some(exc) = exc { - let exc_type = exc.class().into_object(); - let exc_val = exc.clone(); - let exc_tb = exc.traceback().map_or(vm.get_none(), |tb| tb.into_object()); - vec![exc_type, exc_val.into_object(), exc_tb] + exceptions::split(exc, vm) } else { - vec![vm.ctx.none(), vm.ctx.none(), vm.ctx.none()] + (vm.ctx.none(), vm.ctx.none(), vm.ctx.none()) }; - let exit_res = vm.invoke(&exit, args)?; + let exit_res = vm.invoke(&exit, vec![args.0, args.1, args.2])?; self.push_value(exit_res); Ok(None) @@ -1287,7 +1284,7 @@ impl ExecutingFrame<'_> { .ctx .new_pyfunction(code_obj, scope, defaults, kw_only_defaults); - vm.set_attr(&func_obj, "__doc__", vm.get_none())?; + vm.set_attr(&func_obj, "__doc__", vm.ctx.none())?; let name = qualified_name .borrow_value() @@ -1296,11 +1293,7 @@ impl ExecutingFrame<'_> { .unwrap(); vm.set_attr(&func_obj, "__name__", vm.ctx.new_str(name))?; vm.set_attr(&func_obj, "__qualname__", qualified_name)?; - let module = self - .scope - .globals - .get_item_option("__name__", vm)? - .unwrap_or_else(|| vm.get_none()); + let module = vm.unwrap_or_none(self.scope.globals.get_item_option("__name__", vm)?); vm.set_attr(&func_obj, "__module__", module)?; vm.set_attr(&func_obj, "__annotations__", annotations)?; diff --git a/vm/src/function.rs b/vm/src/function.rs index a020e5280..cf2eb485f 100644 --- a/vm/src/function.rs +++ b/vm/src/function.rs @@ -394,6 +394,12 @@ pub enum OptionalArg { impl_option_like!(OptionalArg, Present, Missing); +impl OptionalArg { + pub fn unwrap_or_none(self, vm: &VirtualMachine) -> PyObjectRef { + self.unwrap_or_else(|| vm.ctx.none()) + } +} + pub type OptionalOption = OptionalArg>; impl OptionalOption { diff --git a/vm/src/obj/objasyncgenerator.rs b/vm/src/obj/objasyncgenerator.rs index 2dd744ade..935714100 100644 --- a/vm/src/obj/objasyncgenerator.rs +++ b/vm/src/obj/objasyncgenerator.rs @@ -39,9 +39,7 @@ impl PyAsyncGen { // TODO: fix function names situation #[pyproperty(magic)] - fn name(&self, vm: &VirtualMachine) -> PyObjectRef { - vm.get_none() - } + fn name(&self) {} #[pymethod(name = "__aiter__")] fn aiter(zelf: PyRef, _vm: &VirtualMachine) -> PyRef { @@ -50,7 +48,7 @@ impl PyAsyncGen { #[pymethod(name = "__anext__")] fn anext(zelf: PyRef, vm: &VirtualMachine) -> PyAsyncGenASend { - Self::asend(zelf, vm.get_none(), vm) + Self::asend(zelf, vm.ctx.none(), vm) } #[pymethod] @@ -76,8 +74,8 @@ impl PyAsyncGen { state: AtomicCell::new(AwaitableState::Init), value: ( exc_type, - exc_val.unwrap_or_else(|| vm.get_none()), - exc_tb.unwrap_or_else(|| vm.get_none()), + exc_val.unwrap_or_none(vm), + exc_tb.unwrap_or_none(vm), ), } } @@ -90,8 +88,8 @@ impl PyAsyncGen { state: AtomicCell::new(AwaitableState::Init), value: ( vm.ctx.exceptions.generator_exit.clone().into_object(), - vm.get_none(), - vm.get_none(), + vm.ctx.none(), + vm.ctx.none(), ), } } @@ -185,7 +183,7 @@ impl PyAsyncGenASend { #[pymethod(name = "__next__")] fn next(&self, vm: &VirtualMachine) -> PyResult { - self.send(vm.get_none(), vm) + self.send(vm.ctx.none(), vm) } #[pymethod] @@ -236,8 +234,8 @@ impl PyAsyncGenASend { let res = self.ag.inner.throw( exc_type, - exc_val.unwrap_or_else(|| vm.get_none()), - exc_tb.unwrap_or_else(|| vm.get_none()), + exc_val.unwrap_or_none(vm), + exc_tb.unwrap_or_none(vm), vm, ); let res = PyAsyncGenWrappedValue::unbox(&self.ag, res, vm); @@ -281,7 +279,7 @@ impl PyAsyncGenAThrow { #[pymethod(name = "__next__")] fn next(&self, vm: &VirtualMachine) -> PyResult { - self.send(vm.get_none(), vm) + self.send(vm.ctx.none(), vm) } #[pymethod] @@ -353,8 +351,8 @@ impl PyAsyncGenAThrow { ) -> PyResult { let ret = self.ag.inner.throw( exc_type, - exc_val.unwrap_or_else(|| vm.get_none()), - exc_tb.unwrap_or_else(|| vm.get_none()), + exc_val.unwrap_or_none(vm), + exc_tb.unwrap_or_none(vm), vm, ); let res = if self.aclose { diff --git a/vm/src/obj/objbuiltinfunc.rs b/vm/src/obj/objbuiltinfunc.rs index a9b6df70b..be66d7193 100644 --- a/vm/src/obj/objbuiltinfunc.rs +++ b/vm/src/obj/objbuiltinfunc.rs @@ -3,9 +3,7 @@ use std::fmt; use crate::function::{OptionalArg, PyFuncArgs, PyNativeFunc}; use crate::obj::objstr::PyStringRef; use crate::obj::objtype::PyClassRef; -use crate::pyobject::{ - IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyResult, PyValue, TypeProtocol, -}; +use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyResult, PyValue, TypeProtocol}; use crate::slots::{SlotCall, SlotDescriptor}; use crate::vm::VirtualMachine; @@ -118,7 +116,7 @@ impl SlotDescriptor for PyBuiltinMethod { Ok(obj) => obj, Err(result) => return result, }; - if obj.is(&vm.get_none()) && !Self::_cls_is(&cls, &obj.class()) { + if vm.is_none(&obj) && !Self::_cls_is(&cls, &obj.class()) { Ok(zelf.into_object()) } else { Ok(vm.ctx.new_bound_method(zelf.into_object(), obj)) diff --git a/vm/src/obj/objcoroinner.rs b/vm/src/obj/objcoroinner.rs index 11d4515ab..fa52b3657 100644 --- a/vm/src/obj/objcoroinner.rs +++ b/vm/src/obj/objcoroinner.rs @@ -139,8 +139,8 @@ impl Coro { f.gen_throw( vm, vm.ctx.exceptions.generator_exit.clone().into_object(), - vm.get_none(), - vm.get_none(), + vm.ctx.none(), + vm.ctx.none(), ) }); self.closed.store(true); diff --git a/vm/src/obj/objcoroutine.rs b/vm/src/obj/objcoroutine.rs index 35cc43a61..313fcb1a6 100644 --- a/vm/src/obj/objcoroutine.rs +++ b/vm/src/obj/objcoroutine.rs @@ -37,7 +37,7 @@ impl PyCoroutine { // TODO: fix function names situation #[pyproperty(magic)] fn name(&self, vm: &VirtualMachine) -> PyObjectRef { - vm.get_none() + vm.ctx.none() } #[pymethod] @@ -55,8 +55,8 @@ impl PyCoroutine { ) -> PyResult { self.inner.throw( exc_type, - exc_val.unwrap_or_else(|| vm.get_none()), - exc_tb.unwrap_or_else(|| vm.get_none()), + exc_val.unwrap_or_none(vm), + exc_tb.unwrap_or_none(vm), vm, ) } @@ -116,7 +116,7 @@ impl PyCoroutineWrapper { #[pymethod(name = "__next__")] fn next(&self, vm: &VirtualMachine) -> PyResult { - self.coro.send(vm.get_none(), vm) + self.coro.send(vm.ctx.none(), vm) } #[pymethod] diff --git a/vm/src/obj/objdict.rs b/vm/src/obj/objdict.rs index 83f779f9c..fb332c96f 100644 --- a/vm/src/obj/objdict.rs +++ b/vm/src/obj/objdict.rs @@ -136,7 +136,7 @@ impl PyDict { vm: &VirtualMachine, ) -> PyResult> { let dict = DictContentType::default(); - let value = value.unwrap_or_else(|| vm.ctx.none()); + let value = value.unwrap_or_none(vm); for elem in iterable.iter(vm)? { let elem = elem?; dict.insert(vm, elem, value.clone())?; @@ -314,7 +314,7 @@ impl PyDict { ) -> PyResult { match self.entries.get(vm, &key)? { Some(value) => Ok(value), - None => Ok(default.unwrap_or_else(|| vm.ctx.none())), + None => Ok(default.unwrap_or_none(vm)), } } @@ -328,7 +328,7 @@ impl PyDict { match self.entries.get(vm, &key)? { Some(value) => Ok(value), None => { - let set_value = default.unwrap_or_else(|| vm.ctx.none()); + let set_value = default.unwrap_or_none(vm); self.entries.insert(vm, key, set_value.clone())?; Ok(set_value) } diff --git a/vm/src/obj/objfilter.rs b/vm/src/obj/objfilter.rs index a1c97e74a..1402f9298 100644 --- a/vm/src/obj/objfilter.rs +++ b/vm/src/obj/objfilter.rs @@ -1,7 +1,7 @@ use super::objbool; use super::objiter; use super::objtype::PyClassRef; -use crate::pyobject::{IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue}; +use crate::pyobject::{PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue}; use crate::vm::VirtualMachine; pub type PyFilterRef = PyRef; @@ -47,7 +47,7 @@ impl PyFilter { let iterator = &self.iterator; loop { let next_obj = objiter::call_next(vm, iterator)?; - let predicate_value = if predicate.is(&vm.get_none()) { + let predicate_value = if vm.is_none(predicate) { next_obj.clone() } else { // the predicate itself can raise StopIteration which does stop the filter diff --git a/vm/src/obj/objframe.rs b/vm/src/obj/objframe.rs index 376c68dcc..b8392b827 100644 --- a/vm/src/obj/objframe.rs +++ b/vm/src/obj/objframe.rs @@ -30,7 +30,7 @@ impl FrameRef { // CPython' Frame.f_trace is set to None when deleted. // The strange behavior is mimicked here make bdb.py happy about it. if value.to_string() == "f_trace" { - self.set_f_trace(vm.get_none()); + self.set_f_trace(vm.ctx.none()); }; } diff --git a/vm/src/obj/objfunction.rs b/vm/src/obj/objfunction.rs index 4e42f2e5b..752ec4846 100644 --- a/vm/src/obj/objfunction.rs +++ b/vm/src/obj/objfunction.rs @@ -15,8 +15,8 @@ use crate::obj::objgenerator::PyGenerator; #[cfg(feature = "jit")] use crate::pyobject::IntoPyObject; use crate::pyobject::{ - BorrowValue, IdProtocol, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, - PyValue, TypeProtocol, + BorrowValue, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, + TypeProtocol, }; use crate::scope::Scope; use crate::slots::{SlotCall, SlotDescriptor}; @@ -48,7 +48,7 @@ impl SlotDescriptor for PyFunction { cls: OptionalArg, ) -> PyResult { let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?; - if obj.is(&vm.get_none()) && !Self::_cls_is(&cls, &obj.class()) { + if vm.is_none(&obj) && !Self::_cls_is(&cls, &obj.class()) { Ok(zelf.into_object()) } else { Ok(vm.ctx.new_bound_method(zelf.into_object(), obj)) diff --git a/vm/src/obj/objgenerator.rs b/vm/src/obj/objgenerator.rs index 824c57210..8698d1b75 100644 --- a/vm/src/obj/objgenerator.rs +++ b/vm/src/obj/objgenerator.rs @@ -40,7 +40,7 @@ impl PyGenerator { // TODO: fix function names situation #[pyproperty(magic)] fn name(&self, vm: &VirtualMachine) -> PyObjectRef { - vm.get_none() + vm.ctx.none() } #[pymethod(name = "__iter__")] @@ -50,7 +50,7 @@ impl PyGenerator { #[pymethod(name = "__next__")] fn next(&self, vm: &VirtualMachine) -> PyResult { - self.send(vm.get_none(), vm) + self.send(vm.ctx.none(), vm) } #[pymethod] @@ -68,8 +68,8 @@ impl PyGenerator { ) -> PyResult { self.inner.throw( exc_type, - exc_val.unwrap_or_else(|| vm.get_none()), - exc_tb.unwrap_or_else(|| vm.get_none()), + exc_val.unwrap_or_none(vm), + exc_tb.unwrap_or_none(vm), vm, ) } diff --git a/vm/src/obj/objint.rs b/vm/src/obj/objint.rs index ed7d5d7d5..082e780aa 100644 --- a/vm/src/obj/objint.rs +++ b/vm/src/obj/objint.rs @@ -494,7 +494,7 @@ impl PyInt { match precision { OptionalArg::Missing => (), OptionalArg::Present(ref value) => { - if !vm.get_none().is(value) { + if !vm.is_none(value) { // Only accept int type ndigits let _ndigits = value.payload_if_subclass::(vm).ok_or_else(|| { vm.new_type_error(format!( diff --git a/vm/src/obj/objiter.rs b/vm/src/obj/objiter.rs index 5ec96e084..e9b370f9a 100644 --- a/vm/src/obj/objiter.rs +++ b/vm/src/obj/objiter.rs @@ -98,11 +98,7 @@ pub fn stop_iter_with_value(val: PyObjectRef, vm: &VirtualMachine) -> PyBaseExce pub fn stop_iter_value(vm: &VirtualMachine, exc: &PyBaseExceptionRef) -> PyResult { let args = exc.args(); - let val = args - .borrow_value() - .first() - .cloned() - .unwrap_or_else(|| vm.get_none()); + let val = vm.unwrap_or_none(args.borrow_value().first().cloned()); Ok(val) } diff --git a/vm/src/obj/objmappingproxy.rs b/vm/src/obj/objmappingproxy.rs index 2661ddd09..bf6e66eb0 100644 --- a/vm/src/obj/objmappingproxy.rs +++ b/vm/src/obj/objmappingproxy.rs @@ -57,12 +57,15 @@ impl PyMappingProxy { } #[pymethod] - fn get(&self, key: PyObjectRef, default: OptionalArg, vm: &VirtualMachine) -> PyResult { + fn get( + &self, + key: PyObjectRef, + default: OptionalArg, + vm: &VirtualMachine, + ) -> PyResult> { let default = default.into_option(); - Ok(self - .get_inner(key, vm)? - .or(default) - .unwrap_or_else(|| vm.get_none())) + let value = self.get_inner(key, vm)?.or(default); + Ok(value) } #[pymethod(name = "__getitem__")] diff --git a/vm/src/obj/objmodule.rs b/vm/src/obj/objmodule.rs index e156e424c..994c5fe0b 100644 --- a/vm/src/obj/objmodule.rs +++ b/vm/src/obj/objmodule.rs @@ -3,7 +3,8 @@ use super::objstr::{PyString, PyStringRef}; use super::objtype::PyClassRef; use crate::function::{OptionalOption, PyFuncArgs}; use crate::pyobject::{ - BorrowValue, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, + BorrowValue, IntoPyObject, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, + PyValue, }; use crate::vm::VirtualMachine; @@ -31,13 +32,13 @@ pub fn init_module_dict( .set_item("__doc__", doc, vm) .expect("Failed to set __doc__ on module"); module_dict - .set_item("__package__", vm.get_none(), vm) + .set_item("__package__", vm.ctx.none(), vm) .expect("Failed to set __package__ on module"); module_dict - .set_item("__loader__", vm.get_none(), vm) + .set_item("__loader__", vm.ctx.none(), vm) .expect("Failed to set __loader__ on module"); module_dict - .set_item("__spec__", vm.get_none(), vm) + .set_item("__spec__", vm.ctx.none(), vm) .expect("Failed to set __spec__ on module"); } @@ -63,8 +64,7 @@ impl PyModuleRef { vm, &self.as_object().dict().unwrap(), name.into_object(), - doc.flatten() - .map_or_else(|| vm.get_none(), PyRef::into_object), + doc.flatten().into_pyobject(vm), ); Ok(()) } diff --git a/vm/src/obj/objrange.rs b/vm/src/obj/objrange.rs index d8fe9a131..3a08bc90e 100644 --- a/vm/src/obj/objrange.rs +++ b/vm/src/obj/objrange.rs @@ -369,12 +369,12 @@ impl PyRange { fn hash(zelf: PyRef, vm: &VirtualMachine) -> PyResult { let length = zelf.length(); let elements = if length.is_zero() { - vec![vm.ctx.new_int(length), vm.get_none(), vm.get_none()] + vec![vm.ctx.new_int(length), vm.ctx.none(), vm.ctx.none()] } else if length.is_one() { vec![ vm.ctx.new_int(length), zelf.start().into_object(), - vm.get_none(), + vm.ctx.none(), ] } else { vec![ diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs index 7e6af132d..a4c341365 100644 --- a/vm/src/obj/objset.rs +++ b/vm/src/obj/objset.rs @@ -558,13 +558,13 @@ impl PySet { #[pymethod] fn update(&self, others: Args, vm: &VirtualMachine) -> PyResult { self.inner.update(others, vm)?; - Ok(vm.get_none()) + Ok(vm.ctx.none()) } #[pymethod] fn intersection_update(&self, others: Args, vm: &VirtualMachine) -> PyResult { self.inner.intersection_update(others, vm)?; - Ok(vm.get_none()) + Ok(vm.ctx.none()) } #[pymethod(name = "__iand__")] @@ -576,7 +576,7 @@ impl PySet { #[pymethod] fn difference_update(&self, others: Args, vm: &VirtualMachine) -> PyResult { self.inner.difference_update(others, vm)?; - Ok(vm.get_none()) + Ok(vm.ctx.none()) } #[pymethod(name = "__isub__")] @@ -592,7 +592,7 @@ impl PySet { vm: &VirtualMachine, ) -> PyResult { self.inner.symmetric_difference_update(others, vm)?; - Ok(vm.get_none()) + Ok(vm.ctx.none()) } #[pymethod(name = "__ixor__")] diff --git a/vm/src/obj/objstr.rs b/vm/src/obj/objstr.rs index 9faa2f188..a19986ff9 100644 --- a/vm/src/obj/objstr.rs +++ b/vm/src/obj/objstr.rs @@ -1011,7 +1011,7 @@ impl PyString { } if let OptionalArg::Present(none_str) = none_str { for c in none_str.value.chars() { - new_dict.set_item(vm.ctx.new_int(c as u32), vm.get_none(), vm)?; + new_dict.set_item(vm.ctx.new_int(c as u32), vm.ctx.none(), vm)?; } } Ok(new_dict.into_pyobject(vm)) @@ -1311,7 +1311,7 @@ mod tests { Interpreter::default().enter(|vm| { let table = vm.ctx.new_dict(); table.set_item("a", vm.ctx.new_str("🎅"), &vm).unwrap(); - table.set_item("b", vm.get_none(), &vm).unwrap(); + table.set_item("b", vm.ctx.none(), &vm).unwrap(); table.set_item("c", vm.ctx.new_str("xda"), &vm).unwrap(); let translated = PyString::maketrans( table.into_object(), diff --git a/vm/src/obj/objsuper.rs b/vm/src/obj/objsuper.rs index 01b07ef46..5438f2dcb 100644 --- a/vm/src/obj/objsuper.rs +++ b/vm/src/obj/objsuper.rs @@ -122,7 +122,7 @@ impl PySuper { vm.new_type_error(format!("super argument {} was not supplied", first_arg)) })? } else { - vm.get_none() + vm.ctx.none() } }; @@ -147,7 +147,7 @@ impl SlotDescriptor for PySuper { .into_ref(vm) .into_object()) } else { - let obj = zelf.obj.clone().map_or(vm.get_none(), |(o, _)| o); + let obj = vm.unwrap_or_none(zelf.obj.clone().map(|(o, _)| o)); vm.invoke( zelf_class.as_object(), vec![zelf.typ.clone().into_object(), obj], diff --git a/vm/src/obj/objtype.rs b/vm/src/obj/objtype.rs index a1708022b..542989424 100644 --- a/vm/src/obj/objtype.rs +++ b/vm/src/obj/objtype.rs @@ -194,7 +194,7 @@ impl PyClassRef { } else if let Some(ref descriptor) = attr_class.get_attr("__get__") { drop(mcl); // TODO: is this nessessary? - return vm.invoke(descriptor, vec![attr, vm.get_none(), self.into_object()]); + return vm.invoke(descriptor, vec![attr, vm.ctx.none(), self.into_object()]); } } diff --git a/vm/src/obj/objweakref.rs b/vm/src/obj/objweakref.rs index 3e89ea48a..7520245e2 100644 --- a/vm/src/obj/objweakref.rs +++ b/vm/src/obj/objweakref.rs @@ -41,7 +41,7 @@ pub type PyWeakRef = PyRef; impl SlotCall for PyWeak { fn call(&self, args: PyFuncArgs, vm: &VirtualMachine) -> PyResult { args.bind::<()>(vm)?; - Ok(self.upgrade().unwrap_or_else(|| vm.get_none())) + Ok(vm.unwrap_or_none(self.upgrade())) } } diff --git a/vm/src/py_serde.rs b/vm/src/py_serde.rs index 122f1b2e1..7ffd368a6 100644 --- a/vm/src/py_serde.rs +++ b/vm/src/py_serde.rs @@ -7,7 +7,7 @@ use crate::obj::{ objbool, objdict::PyDictRef, objfloat, objint, objlist::PyList, objstr, objtuple::PyTuple, objtype, }; -use crate::pyobject::{BorrowValue, IdProtocol, ItemProtocol, PyObjectRef, TypeProtocol}; +use crate::pyobject::{BorrowValue, ItemProtocol, PyObjectRef, TypeProtocol}; use crate::VirtualMachine; #[inline] @@ -96,7 +96,7 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> { map.serialize_entry(&self.clone_with_object(key), &self.clone_with_object(&e))?; } map.end() - } else if self.pyobject.is(&self.vm.get_none()) { + } else if self.vm.is_none(&self.pyobject) { serializer.serialize_none() } else { Err(serde::ser::Error::custom(format!( @@ -187,7 +187,7 @@ impl<'de> Visitor<'de> for PyObjectDeserializer<'de> { where E: serde::de::Error, { - Ok(self.vm.get_none()) + Ok(self.vm.ctx.none()) } fn visit_seq(self, mut access: A) -> Result diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs index 13aaeee4a..77ec56c91 100644 --- a/vm/src/pyobject.rs +++ b/vm/src/pyobject.rs @@ -939,7 +939,7 @@ impl TryFromObject for PyObjectRef { impl TryFromObject for Option { fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult { - if vm.get_none().is(&obj) { + if vm.is_none(&obj) { Ok(None) } else { T::try_from_object(vm, obj).map(Some) diff --git a/vm/src/slots.rs b/vm/src/slots.rs index 7a9152240..91afd0bc4 100644 --- a/vm/src/slots.rs +++ b/vm/src/slots.rs @@ -105,7 +105,7 @@ pub trait SlotDescriptor: PyValue { vm: &VirtualMachine, ) -> PyResult<(PyRef, PyObjectRef)> { let zelf = Self::_zelf(zelf, vm)?; - let obj = obj.unwrap_or_else(|| vm.get_none()); + let obj = vm.unwrap_or_none(obj); Ok((zelf, obj)) } diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs index 532ef25e9..3fee3b56d 100644 --- a/vm/src/stdlib/ast.rs +++ b/vm/src/stdlib/ast.rs @@ -559,8 +559,8 @@ fn parameters_to_ast(vm: &VirtualMachine, args: &ast::Parameters) -> PyResult PyResult { let py_node = match vararg { - ast::Varargs::None => vm.get_none(), - ast::Varargs::Unnamed => vm.get_none(), + ast::Varargs::None => vm.ctx.none(), + ast::Varargs::Unnamed => vm.ctx.none(), ast::Varargs::Named(parameter) => parameter_to_ast(vm, parameter)?.into_object(), }; Ok(py_node) diff --git a/vm/src/stdlib/dis.rs b/vm/src/stdlib/dis.rs index 4436d1093..d7ca945a4 100644 --- a/vm/src/stdlib/dis.rs +++ b/vm/src/stdlib/dis.rs @@ -37,7 +37,7 @@ mod decl { fn disassemble(co: PyObjectRef, vm: &VirtualMachine) -> PyResult { let code = &PyCodeRef::try_from_object(vm, co)?.code; print!("{}", code); - Ok(vm.get_none()) + Ok(vm.ctx.none()) } #[pyattr(name = "COMPILER_FLAG_NAMES")] diff --git a/vm/src/stdlib/hashlib.rs b/vm/src/stdlib/hashlib.rs index 913895d26..49233f1e4 100644 --- a/vm/src/stdlib/hashlib.rs +++ b/vm/src/stdlib/hashlib.rs @@ -67,9 +67,8 @@ impl PyHasher { } #[pymethod(name = "update")] - fn update(&self, data: PyBytesRef, vm: &VirtualMachine) -> PyResult { + fn update(&self, data: PyBytesRef) { self.borrow_value_mut().input(data.borrow_value()); - Ok(vm.get_none()) } #[pymethod(name = "digest")] @@ -94,74 +93,70 @@ fn hashlib_new( vm: &VirtualMachine, ) -> PyResult { match name.borrow_value() { - "md5" => md5(data, vm), - "sha1" => sha1(data, vm), - "sha224" => sha224(data, vm), - "sha256" => sha256(data, vm), - "sha384" => sha384(data, vm), - "sha512" => sha512(data, vm), - "sha3_224" => sha3_224(data, vm), - "sha3_256" => sha3_256(data, vm), - "sha3_384" => sha3_384(data, vm), - "sha3_512" => sha3_512(data, vm), - // TODO: "shake128" => shake128(data, vm), - // TODO: "shake256" => shake256(data, vm), - "blake2b" => blake2b(data, vm), - "blake2s" => blake2s(data, vm), + "md5" => md5(data), + "sha1" => sha1(data), + "sha224" => sha224(data), + "sha256" => sha256(data), + "sha384" => sha384(data), + "sha512" => sha512(data), + "sha3_224" => sha3_224(data), + "sha3_256" => sha3_256(data), + "sha3_384" => sha3_384(data), + "sha3_512" => sha3_512(data), + // TODO: "shake128" => shake128(data, ), + // TODO: "shake256" => shake256(data, ), + "blake2b" => blake2b(data), + "blake2s" => blake2s(data), other => Err(vm.new_value_error(format!("Unknown hashing algorithm: {}", other))), } } -fn init( - hasher: PyHasher, - data: OptionalArg, - vm: &VirtualMachine, -) -> PyResult { +fn init(hasher: PyHasher, data: OptionalArg) -> PyResult { if let OptionalArg::Present(data) = data { - hasher.update(data, vm)?; + hasher.update(data); } Ok(hasher) } -fn md5(data: OptionalArg, vm: &VirtualMachine) -> PyResult { - init(PyHasher::new("md5", HashWrapper::md5()), data, vm) +fn md5(data: OptionalArg) -> PyResult { + init(PyHasher::new("md5", HashWrapper::md5()), data) } -fn sha1(data: OptionalArg, vm: &VirtualMachine) -> PyResult { - init(PyHasher::new("sha1", HashWrapper::sha1()), data, vm) +fn sha1(data: OptionalArg) -> PyResult { + init(PyHasher::new("sha1", HashWrapper::sha1()), data) } -fn sha224(data: OptionalArg, vm: &VirtualMachine) -> PyResult { - init(PyHasher::new("sha224", HashWrapper::sha224()), data, vm) +fn sha224(data: OptionalArg) -> PyResult { + init(PyHasher::new("sha224", HashWrapper::sha224()), data) } -fn sha256(data: OptionalArg, vm: &VirtualMachine) -> PyResult { - init(PyHasher::new("sha256", HashWrapper::sha256()), data, vm) +fn sha256(data: OptionalArg) -> PyResult { + init(PyHasher::new("sha256", HashWrapper::sha256()), data) } -fn sha384(data: OptionalArg, vm: &VirtualMachine) -> PyResult { - init(PyHasher::new("sha384", HashWrapper::sha384()), data, vm) +fn sha384(data: OptionalArg) -> PyResult { + init(PyHasher::new("sha384", HashWrapper::sha384()), data) } -fn sha512(data: OptionalArg, vm: &VirtualMachine) -> PyResult { - init(PyHasher::new("sha512", HashWrapper::sha512()), data, vm) +fn sha512(data: OptionalArg) -> PyResult { + init(PyHasher::new("sha512", HashWrapper::sha512()), data) } -fn sha3_224(data: OptionalArg, vm: &VirtualMachine) -> PyResult { - init(PyHasher::new("sha3_224", HashWrapper::sha3_224()), data, vm) +fn sha3_224(data: OptionalArg) -> PyResult { + init(PyHasher::new("sha3_224", HashWrapper::sha3_224()), data) } -fn sha3_256(data: OptionalArg, vm: &VirtualMachine) -> PyResult { - init(PyHasher::new("sha3_256", HashWrapper::sha3_256()), data, vm) +fn sha3_256(data: OptionalArg) -> PyResult { + init(PyHasher::new("sha3_256", HashWrapper::sha3_256()), data) } -fn sha3_384(data: OptionalArg, vm: &VirtualMachine) -> PyResult { - init(PyHasher::new("sha3_384", HashWrapper::sha3_384()), data, vm) +fn sha3_384(data: OptionalArg) -> PyResult { + init(PyHasher::new("sha3_384", HashWrapper::sha3_384()), data) } -fn sha3_512(data: OptionalArg, vm: &VirtualMachine) -> PyResult { - init(PyHasher::new("sha3_512", HashWrapper::sha3_512()), data, vm) +fn sha3_512(data: OptionalArg) -> PyResult { + init(PyHasher::new("sha3_512", HashWrapper::sha3_512()), data) } fn shake128(_data: OptionalArg, vm: &VirtualMachine) -> PyResult { @@ -172,14 +167,14 @@ fn shake256(_data: OptionalArg, vm: &VirtualMachine) -> PyResult, vm: &VirtualMachine) -> PyResult { +fn blake2b(data: OptionalArg) -> PyResult { // TODO: handle parameters - init(PyHasher::new("blake2b", HashWrapper::blake2b()), data, vm) + init(PyHasher::new("blake2b", HashWrapper::blake2b()), data) } -fn blake2s(data: OptionalArg, vm: &VirtualMachine) -> PyResult { +fn blake2s(data: OptionalArg) -> PyResult { // TODO: handle parameters - init(PyHasher::new("blake2s", HashWrapper::blake2s()), data, vm) + init(PyHasher::new("blake2s", HashWrapper::blake2s()), data) } pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { diff --git a/vm/src/stdlib/imp.rs b/vm/src/stdlib/imp.rs index 50377706e..ac5fb4cdb 100644 --- a/vm/src/stdlib/imp.rs +++ b/vm/src/stdlib/imp.rs @@ -67,7 +67,7 @@ fn imp_create_builtin(spec: PyObjectRef, vm: &VirtualMachine) -> PyResult { } else if let Some(make_module_func) = vm.state.stdlib_inits.get(name) { Ok(make_module_func(vm)) } else { - Ok(vm.get_none()) + Ok(vm.ctx.none()) } } @@ -108,7 +108,7 @@ fn imp_fix_co_filename(_code: PyObjectRef, _path: PyStringRef) { fn imp_source_hash(_key: u64, _source: PyBytesRef, vm: &VirtualMachine) -> PyResult { // TODO: - Ok(vm.get_none()) + Ok(vm.ctx.none()) } pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index 93a3e4785..fc34d0317 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -963,11 +963,7 @@ fn text_io_wrapper_init( // let readuniversal = args.newline.map_or_else(true, |s| s.borrow_value().is_empty()); - vm.set_attr( - &instance, - "encoding", - self_encoding.map_or_else(|| vm.get_none(), |s| vm.ctx.new_str(s)), - )?; + vm.set_attr(&instance, "encoding", self_encoding.into_pyobject(vm))?; vm.set_attr(&instance, "errors", errors)?; vm.set_attr(&instance, "buffer", args.buffer)?; @@ -1022,11 +1018,7 @@ fn text_io_wrapper_read( return Err(vm.new_value_error("not readable".to_owned())); } - let bytes = vm.call_method( - &raw, - "read", - vec![size.flatten().unwrap_or_else(|| vm.get_none())], - )?; + let bytes = vm.call_method(&raw, "read", vec![vm.unwrap_or_none(size.flatten())])?; let bytes = PyBytesLike::try_from_object(vm, bytes)?; //format bytes into string let rust_string = String::from_utf8(bytes.to_cow().into_owned()).map_err(|e| { @@ -1079,11 +1071,7 @@ fn text_io_wrapper_readline( return Err(vm.new_value_error("not readable".to_owned())); } - let bytes = vm.call_method( - &raw, - "readline", - vec![size.flatten().unwrap_or_else(|| vm.get_none())], - )?; + let bytes = vm.call_method(&raw, "readline", vec![vm.unwrap_or_none(size.flatten())])?; let bytes = PyBytesLike::try_from_object(vm, bytes)?; //format bytes into string let rust_string = String::from_utf8(bytes.to_cow().into_owned()).map_err(|e| { @@ -1224,7 +1212,7 @@ pub fn io_open( Args::new(vec![file, vm.ctx.new_str(mode.clone())]), KwArgs::new(maplit::hashmap! { "closefd".to_owned() => vm.ctx.new_bool(opts.closefd), - "opener".to_owned() => opts.opener.unwrap_or_else(|| vm.get_none()), + "opener".to_owned() => vm.unwrap_or_none(opts.opener), }), )), )?; diff --git a/vm/src/stdlib/itertools.rs b/vm/src/stdlib/itertools.rs index 0e45de8aa..5ebb85448 100644 --- a/vm/src/stdlib/itertools.rs +++ b/vm/src/stdlib/itertools.rs @@ -732,7 +732,7 @@ mod decl { PyObjectRef, ) = args.bind(vm)?; - let start = if !start.is(&vm.get_none()) { + let start = if !vm.is_none(&start) { pyobject_to_opt_usize(start, &vm).ok_or_else(|| { vm.new_value_error( "Indices for islice() must be None or an integer: 0 <= x <= sys.maxsize.".to_owned(), @@ -742,7 +742,7 @@ mod decl { 0usize }; - let step = if !step.is(&vm.get_none()) { + let step = if !vm.is_none(&step) { pyobject_to_opt_usize(step, &vm).ok_or_else(|| { vm.new_value_error( "Step for islice() must be a positive integer or None.".to_owned(), @@ -756,7 +756,7 @@ mod decl { } }; - let stop = if !stop.is(&vm.get_none()) { + let stop = if !vm.is_none(&stop) { Some(pyobject_to_opt_usize(stop, &vm).ok_or_else(|| { vm.new_value_error( "Stop argument for islice() must be None or an integer: 0 <= x <= sys.maxsize." @@ -847,7 +847,7 @@ mod decl { loop { let obj = call_next(vm, iterable)?; - let pred_value = if predicate.is(&vm.get_none()) { + let pred_value = if vm.is_none(predicate) { obj.clone() } else { vm.invoke(predicate, vec![obj.clone()])? @@ -893,7 +893,7 @@ mod decl { PyItertoolsAccumulate { iterable: iter, - binop: binop.unwrap_or_else(|| vm.get_none()), + binop: binop.unwrap_or_none(vm), acc_value: PyRwLock::new(None), } .into_ref_with_type(vm, cls) @@ -909,7 +909,7 @@ mod decl { let next_acc_value = match acc_value { None => obj, Some(value) => { - if self.binop.is(&vm.get_none()) { + if vm.is_none(&self.binop) { vm._add(value, obj)? } else { vm.invoke(&self.binop, vec![value, obj])? @@ -1502,11 +1502,7 @@ mod decl { args: ZiplongestArgs, vm: &VirtualMachine, ) -> PyResult> { - let fillvalue = match args.fillvalue.into_option() { - Some(i) => i, - None => vm.get_none(), - }; - + let fillvalue = args.fillvalue.unwrap_or_none(vm); let iterators = iterables .into_iter() .map(|iterable| get_iter(vm, &iterable)) diff --git a/vm/src/stdlib/json.rs b/vm/src/stdlib/json.rs index 0e8a14612..17dc062d2 100644 --- a/vm/src/stdlib/json.rs +++ b/vm/src/stdlib/json.rs @@ -104,10 +104,8 @@ mod _json { .new_tuple(vec![pystr.into_object(), vm.ctx.new_int(next_idx)]), vm.ctx.new_bool(self.strict), scan_once, - self.object_hook.clone().unwrap_or_else(|| vm.get_none()), - self.object_pairs_hook - .clone() - .unwrap_or_else(|| vm.get_none()), + vm.unwrap_or_none(self.object_hook.clone()), + vm.unwrap_or_none(self.object_pairs_hook.clone()), ], ); } @@ -134,7 +132,7 @@ mod _json { }; } - parse_const!("null", vm.get_none()); + parse_const!("null", vm.ctx.none()); parse_const!("true", vm.ctx.new_bool(true)); parse_const!("false", vm.ctx.new_bool(false)); diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index 64870093c..d050eb25b 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -23,8 +23,8 @@ use crate::obj::objstr::{PyString, PyStringRef}; use crate::obj::objtuple::PyTupleRef; use crate::obj::objtype::PyClassRef; use crate::pyobject::{ - BorrowValue, Either, ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult, PyStructSequence, - PyValue, TryFromObject, TypeProtocol, + BorrowValue, Either, IntoPyObject, ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult, + PyStructSequence, PyValue, TryFromObject, TypeProtocol, }; use crate::vm::VirtualMachine; @@ -155,10 +155,7 @@ impl IntoPyException for io::Error { }, }; let os_error = vm.new_exception_msg(exc_type, self.to_string()); - let errno = match self.raw_os_error() { - Some(errno) => vm.ctx.new_int(errno), - None => vm.get_none(), - }; + let errno = self.raw_os_error().into_pyobject(vm); vm.set_attr(os_error.as_object(), "errno", errno).unwrap(); os_error } diff --git a/vm/src/stdlib/re.rs b/vm/src/stdlib/re.rs index 42cddf244..213fcccc1 100644 --- a/vm/src/stdlib/re.rs +++ b/vm/src/stdlib/re.rs @@ -172,14 +172,14 @@ fn do_match(vm: &VirtualMachine, pattern: &PyPattern, search_text: PyStringRef) let regex = Regex::new(®ex).unwrap(); match regex.captures(search_text.borrow_value().as_bytes()) { - None => Ok(vm.get_none()), + None => Ok(vm.ctx.none()), Some(captures) => Ok(create_match(vm, search_text.clone(), captures)), } } fn do_search(vm: &VirtualMachine, regex: &PyPattern, search_text: PyStringRef) -> PyResult { match regex.regex.captures(search_text.borrow_value().as_bytes()) { - None => Ok(vm.get_none()), + None => Ok(vm.ctx.none()), Some(captures) => Ok(create_match(vm, search_text.clone(), captures)), } } @@ -255,8 +255,7 @@ fn do_split( let split = output .into_iter() .map(|v| { - v.map(|v| vm.ctx.new_str(String::from_utf8_lossy(v).into_owned())) - .unwrap_or_else(|| vm.get_none()) + vm.unwrap_or_none(v.map(|v| vm.ctx.new_str(String::from_utf8_lossy(v).into_owned()))) }) .collect(); Ok(vm.ctx.new_list(split)) @@ -407,7 +406,7 @@ impl PyMatch { let bounds = self.get_bounds(id, vm)?; let group = match bounds { Some(bounds) => self.subgroup(bounds, vm), - None => vm.get_none(), + None => vm.ctx.none(), }; Ok(group) } @@ -435,11 +434,12 @@ impl PyMatch { .captures .iter() .map(|capture| { - capture - .as_ref() - .map(|bounds| self.subgroup(bounds.clone(), vm)) - .or_else(|| default.clone()) - .unwrap_or_else(|| vm.get_none()) + vm.unwrap_or_none( + capture + .as_ref() + .map(|bounds| self.subgroup(bounds.clone(), vm)) + .or_else(|| default.clone()), + ) }) .collect(); vm.ctx.new_tuple(groups) diff --git a/vm/src/stdlib/signal.rs b/vm/src/stdlib/signal.rs index a82c13ddf..60e4ef128 100644 --- a/vm/src/stdlib/signal.rs +++ b/vm/src/stdlib/signal.rs @@ -112,7 +112,7 @@ pub fn check_signals(vm: &VirtualMachine) -> PyResult<()> { if triggerd { let handler = &signal_handlers[signum]; if vm.is_callable(handler) { - vm.invoke(handler, vec![vm.ctx.new_int(signum), vm.get_none()])?; + vm.invoke(handler, vec![vm.ctx.new_int(signum), vm.ctx.none()])?; } } } @@ -156,7 +156,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { } else if handler == SIG_IGN { sig_ign.clone() } else { - vm.get_none() + vm.ctx.none() }; vm.signal_handlers.as_ref().unwrap().borrow_mut()[signum] = py_handler; } diff --git a/vm/src/stdlib/socket.rs b/vm/src/stdlib/socket.rs index cb0b87f45..5d98effb5 100644 --- a/vm/src/stdlib/socket.rs +++ b/vm/src/stdlib/socket.rs @@ -545,10 +545,7 @@ fn socket_getaddrinfo(opts: GAIOptions, vm: &VirtualMachine) -> PyResult { vm.ctx.new_int(ai.address), vm.ctx.new_int(ai.socktype), vm.ctx.new_int(ai.protocol), - match ai.canonname { - Some(s) => vm.ctx.new_str(s), - None => vm.get_none(), - }, + ai.canonname.into_pyobject(vm), get_addr_tuple(ai.sockaddr).into_pyobject(vm), ]) }) @@ -786,7 +783,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { "htons" => ctx.new_function(u16::to_be), "ntohl" => ctx.new_function(u32::from_be), "ntohs" => ctx.new_function(u16::from_be), - "getdefaulttimeout" => ctx.new_function(|vm: &VirtualMachine| vm.get_none()), + "getdefaulttimeout" => ctx.new_function(|vm: &VirtualMachine| vm.ctx.none()), "has_ipv6" => ctx.new_bool(false), "inet_pton" => ctx.new_function(socket_inet_pton), "inet_ntop" => ctx.new_function(socket_inet_ntop), diff --git a/vm/src/stdlib/ssl.rs b/vm/src/stdlib/ssl.rs index 60f50f217..426932d9a 100644 --- a/vm/src/stdlib/ssl.rs +++ b/vm/src/stdlib/ssl.rs @@ -668,10 +668,7 @@ fn cert_to_py(vm: &VirtualMachine, cert: &X509Ref, binary: bool) -> PyResult { let name_to_py = |name: &x509::X509NameRef| { name.entries() .map(|entry| { - let txt = match obj2txt(entry.object(), false) { - Some(s) => vm.ctx.new_str(s), - None => vm.get_none(), - }; + let txt = obj2txt(entry.object(), false).into_pyobject(vm); let data = vm.ctx.new_str(entry.data().as_utf8()?.to_owned()); Ok(vm.ctx.new_tuple(vec![vm.ctx.new_tuple(vec![txt, data])])) }) diff --git a/vm/src/stdlib/winreg.rs b/vm/src/stdlib/winreg.rs index 326a2b0f1..2fb46b9d2 100644 --- a/vm/src/stdlib/winreg.rs +++ b/vm/src/stdlib/winreg.rs @@ -239,7 +239,7 @@ fn reg_to_py(value: RegValue, vm: &VirtualMachine) -> PyResult { } RegType::REG_BINARY | _ => { if value.bytes.is_empty() { - Ok(vm.get_none()) + Ok(vm.ctx.none()) } else { Ok(vm.ctx.new_bytes(value.bytes)) } diff --git a/vm/src/sysmodule.rs b/vm/src/sysmodule.rs index f8dff4238..8e6b13ba9 100644 --- a/vm/src/sysmodule.rs +++ b/vm/src/sysmodule.rs @@ -215,7 +215,7 @@ fn sys_intern(value: PyStringRef) -> PyStringRef { fn sys_exc_info(vm: &VirtualMachine) -> PyObjectRef { let (ty, val, tb) = match vm.current_exception() { Some(exception) => exceptions::split(exception, vm), - None => (vm.get_none(), vm.get_none(), vm.get_none()), + None => (vm.ctx.none(), vm.ctx.none(), vm.ctx.none()), }; vm.ctx.new_tuple(vec![ty, val, tb]) } @@ -229,7 +229,7 @@ fn sys_git_info(vm: &VirtualMachine) -> PyObjectRef { } fn sys_exit(code: OptionalArg, vm: &VirtualMachine) -> PyResult { - let code = code.unwrap_or_else(|| vm.get_none()); + let code = code.unwrap_or_none(vm); Err(vm.new_exception(vm.ctx.exceptions.system_exit.clone(), vec![code])) } @@ -243,7 +243,7 @@ fn sys_displayhook(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { return Ok(()); } // set to none to avoid recursion while printing - vm.set_attr(&vm.builtins, "_", vm.get_none())?; + vm.set_attr(&vm.builtins, "_", vm.ctx.none())?; // TODO: catch encoding errors let repr = vm.to_repr(&obj)?.into_object(); builtins::builtin_print(Args::new(vec![repr]), Default::default(), vm)?; @@ -651,7 +651,7 @@ settrace() -- set the global debug tracing function "meta_path" => ctx.new_list(vec![]), "path_hooks" => ctx.new_list(vec![]), "path_importer_cache" => ctx.new_dict(), - "pycache_prefix" => vm.get_none(), + "pycache_prefix" => vm.ctx.none(), "dont_write_bytecode" => vm.ctx.new_bool(vm.state.settings.dont_write_bytecode), "setprofile" => ctx.new_function(sys_setprofile), "setrecursionlimit" => ctx.new_function(sys_setrecursionlimit), diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 8bec0fa13..bc7e44b95 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -268,9 +268,9 @@ impl VirtualMachine { &vm, &builtins_dict, vm.ctx.new_str("builtins"), - vm.get_none(), + vm.ctx.none(), ); - objmodule::init_module_dict(&vm, &sysmod_dict, vm.ctx.new_str("sys"), vm.get_none()); + objmodule::init_module_dict(&vm, &sysmod_dict, vm.ctx.new_str("sys"), vm.ctx.none()); vm } @@ -335,8 +335,8 @@ impl VirtualMachine { wasm_id: self.wasm_id.clone(), exceptions: RefCell::new(vec![]), import_func: self.import_func.clone(), - profile_func: RefCell::new(self.get_none()), - trace_func: RefCell::new(self.get_none()), + profile_func: RefCell::new(self.ctx.none()), + trace_func: RefCell::new(self.ctx.none()), use_tracing: Cell::new(false), recursion_limit: self.recursion_limit.clone(), signal_handlers: None, @@ -446,7 +446,7 @@ impl VirtualMachine { self, &dict, self.new_pyobj(name.to_owned()), - self.get_none(), + self.ctx.none(), ); PyObject::new(PyModule {}, self.ctx.types.module_type.clone(), Some(dict)) } @@ -663,10 +663,6 @@ impl VirtualMachine { Scope::with_builtins(None, self.ctx.new_dict(), self) } - pub fn get_none(&self) -> PyObjectRef { - self.ctx.none() - } - /// Test whether a python object is `None`. pub fn is_none(&self, obj: &PyObjectRef) -> bool { obj.is(&self.ctx.none) @@ -678,6 +674,9 @@ impl VirtualMachine { Some(obj) } } + pub fn unwrap_or_none(&self, obj: Option) -> PyObjectRef { + obj.unwrap_or_else(|| self.ctx.none()) + } pub fn get_locals(&self) -> PyDictRef { self.current_scope().get_locals() @@ -767,7 +766,7 @@ impl VirtualMachine { frame.scope.globals.clone().into_object(), ) } else { - (self.get_none(), self.get_none()) + (self.ctx.none(), self.ctx.none()) }; let from_list = self .ctx @@ -824,11 +823,7 @@ impl VirtualMachine { } else if let Some(ref descriptor) = descr_class.get_attr("__get__") { Some(self.invoke( descriptor, - vec![ - descr, - obj.unwrap_or_else(|| self.get_none()), - cls.unwrap_or_else(|| self.get_none()), - ], + vec![descr, self.unwrap_or_none(obj), self.unwrap_or_none(cls)], )) } else { None @@ -910,8 +905,7 @@ impl VirtualMachine { let frame = frame_ref.unwrap().as_object().clone(); let event = self.ctx.new_str(event.to_string()); - let arg = self.get_none(); - let args = vec![frame, event, arg]; + let args = vec![frame, event, self.ctx.none()]; // temporarily disable tracing, during the call to the // tracing function itself. @@ -1164,10 +1158,7 @@ impl VirtualMachine { ) -> PyResult { let codecsmodule = self.import("_codecs", &[], 0)?; let func = self.get_attribute(codecsmodule, func)?; - let mut args = vec![ - obj, - encoding.map_or_else(|| self.get_none(), |s| s.into_object()), - ]; + let mut args = vec![obj, encoding.into_pyobject(self)]; if let Some(errors) = errors { args.push(errors.into_object()); } diff --git a/wasm/lib/src/browser_module.rs b/wasm/lib/src/browser_module.rs index 484b042b0..e491edcce 100644 --- a/wasm/lib/src/browser_module.rs +++ b/wasm/lib/src/browser_module.rs @@ -9,7 +9,8 @@ use rustpython_vm::function::{OptionalArg, PyFuncArgs}; use rustpython_vm::import::import_file; use rustpython_vm::obj::{objdict::PyDictRef, objstr::PyStringRef, objtype::PyClassRef}; use rustpython_vm::pyobject::{ - BorrowValue, PyCallable, PyClassImpl, PyObject, PyObjectRef, PyRef, PyResult, PyValue, + BorrowValue, IntoPyObject, PyCallable, PyClassImpl, PyObject, PyObjectRef, PyRef, PyResult, + PyValue, }; use rustpython_vm::VirtualMachine; @@ -146,12 +147,12 @@ fn browser_request_animation_frame(func: PyCallable, vm: &VirtualMachine) -> PyR Ok(vm.ctx.new_int(id)) } -fn browser_cancel_animation_frame(id: i32, vm: &VirtualMachine) -> PyResult { +fn browser_cancel_animation_frame(id: i32, vm: &VirtualMachine) -> PyResult<()> { window() .cancel_animation_frame(id) .map_err(|err| convert::js_py_typeerror(vm, err))?; - Ok(vm.get_none()) + Ok(()) } #[pyclass(module = "browser", name = "Promise")] @@ -270,11 +271,9 @@ impl Document { let elem = self .doc .query_selector(query.borrow_value()) - .map_err(|err| convert::js_py_typeerror(vm, err))?; - let elem = match elem { - Some(elem) => Element { elem }.into_object(vm), - None => vm.get_none(), - }; + .map_err(|err| convert::js_py_typeerror(vm, err))? + .map(|elem| Element { elem }) + .into_pyobject(vm); Ok(elem) } } @@ -302,7 +301,7 @@ impl Element { ) -> PyObjectRef { match self.elem.get_attribute(attr.borrow_value()) { Some(s) => vm.ctx.new_str(s), - None => default.into_option().unwrap_or_else(|| vm.get_none()), + None => default.unwrap_or_none(vm), } } diff --git a/wasm/lib/src/convert.rs b/wasm/lib/src/convert.rs index 98862738e..2ef0f9158 100644 --- a/wasm/lib/src/convert.rs +++ b/wasm/lib/src/convert.rs @@ -216,10 +216,10 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef { js_err_to_py_err(vm, err).into_object() } else if js_val.is_undefined() { // Because `JSON.stringify(undefined)` returns undefined - vm.get_none() + vm.ctx.none() } else { py_serde::deserialize(vm, serde_wasm_bindgen::Deserializer::from(js_val)) - .unwrap_or_else(|_| vm.get_none()) + .unwrap_or_else(|_| vm.ctx.none()) } } From 90b3f7a24b71d7d35dfddc46eb8ff44229b70726 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 19 Sep 2020 10:46:39 +0900 Subject: [PATCH 08/11] builtins doc --- vm/src/builtins.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vm/src/builtins.rs b/vm/src/builtins.rs index 1159ba70b..85e2cbb12 100644 --- a/vm/src/builtins.rs +++ b/vm/src/builtins.rs @@ -4,6 +4,9 @@ use crate::pyobject::PyObjectRef; use crate::vm::VirtualMachine; +/// Built-in functions, exceptions, and other objects. +/// +/// Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices. #[pymodule(name = "builtins")] mod decl { use num_bigint::Sign; From b87662960610cd5fea8a80fe58e402908e661a2a Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 19 Sep 2020 10:58:03 +0900 Subject: [PATCH 09/11] Reduce direct usage of vm.ctx.none --- vm/src/exceptions.rs | 11 ++++---- vm/src/obj/objobject.rs | 8 ++---- vm/src/obj/objrange.rs | 8 +++--- vm/src/obj/objset.rs | 16 +++++------ vm/src/stdlib/ast.rs | 59 ++++++++++++++++------------------------- vm/src/stdlib/dis.rs | 41 +++++++++++++--------------- vm/src/sysmodule.rs | 14 +++++----- 7 files changed, 67 insertions(+), 90 deletions(-) diff --git a/vm/src/exceptions.rs b/vm/src/exceptions.rs index 79ff62495..6341ffe1b 100644 --- a/vm/src/exceptions.rs +++ b/vm/src/exceptions.rs @@ -656,17 +656,16 @@ fn key_error_str(exc: PyBaseExceptionRef, vm: &VirtualMachine) -> PyStringRef { } } -fn system_exit_code(exc: PyBaseExceptionRef, vm: &VirtualMachine) -> PyObjectRef { - match exc.args.read().borrow_value().first() { - Some(code) => match_class!(match code { +fn system_exit_code(exc: PyBaseExceptionRef) -> Option { + exc.args.read().borrow_value().first().map(|code| { + match_class!(match code { ref tup @ PyTuple => match tup.borrow_value() { [x] => x.clone(), _ => code.clone(), }, other => other.clone(), - }), - None => vm.ctx.none(), - } + }) + }) } pub fn init(ctx: &PyContext) { diff --git a/vm/src/obj/objobject.rs b/vm/src/obj/objobject.rs index b43a5880b..6a350cf0e 100644 --- a/vm/src/obj/objobject.rs +++ b/vm/src/obj/objobject.rs @@ -140,9 +140,7 @@ impl PyBaseObject { } #[pyclassmethod(magic)] - fn init_subclass(_cls: PyClassRef, vm: &VirtualMachine) -> PyResult { - Ok(vm.ctx.none()) - } + fn init_subclass(_cls: PyClassRef) {} #[pymethod(magic)] pub fn dir(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult { @@ -176,9 +174,7 @@ impl PyBaseObject { } #[pymethod(magic)] - fn init(_args: PyFuncArgs, vm: &VirtualMachine) -> PyResult { - Ok(vm.ctx.none()) - } + fn init(_args: PyFuncArgs) {} #[pyproperty(name = "__class__")] fn get_class(obj: PyObjectRef) -> PyObjectRef { diff --git a/vm/src/obj/objrange.rs b/vm/src/obj/objrange.rs index 3a08bc90e..6deea0ee9 100644 --- a/vm/src/obj/objrange.rs +++ b/vm/src/obj/objrange.rs @@ -369,21 +369,21 @@ impl PyRange { fn hash(zelf: PyRef, vm: &VirtualMachine) -> PyResult { let length = zelf.length(); let elements = if length.is_zero() { - vec![vm.ctx.new_int(length), vm.ctx.none(), vm.ctx.none()] + [vm.ctx.new_int(length), vm.ctx.none(), vm.ctx.none()] } else if length.is_one() { - vec![ + [ vm.ctx.new_int(length), zelf.start().into_object(), vm.ctx.none(), ] } else { - vec![ + [ vm.ctx.new_int(length), zelf.start().into_object(), zelf.step().into_object(), ] }; - pyobject::hash_iter(&elements, vm) + pyobject::hash_iter(elements.iter(), vm) } #[pyslot] diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs index a4c341365..6ec47fedd 100644 --- a/vm/src/obj/objset.rs +++ b/vm/src/obj/objset.rs @@ -556,15 +556,15 @@ impl PySet { } #[pymethod] - fn update(&self, others: Args, vm: &VirtualMachine) -> PyResult { + fn update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { self.inner.update(others, vm)?; - Ok(vm.ctx.none()) + Ok(()) } #[pymethod] - fn intersection_update(&self, others: Args, vm: &VirtualMachine) -> PyResult { + fn intersection_update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { self.inner.intersection_update(others, vm)?; - Ok(vm.ctx.none()) + Ok(()) } #[pymethod(name = "__iand__")] @@ -574,9 +574,9 @@ impl PySet { } #[pymethod] - fn difference_update(&self, others: Args, vm: &VirtualMachine) -> PyResult { + fn difference_update(&self, others: Args, vm: &VirtualMachine) -> PyResult<()> { self.inner.difference_update(others, vm)?; - Ok(vm.ctx.none()) + Ok(()) } #[pymethod(name = "__isub__")] @@ -590,9 +590,9 @@ impl PySet { &self, others: Args, vm: &VirtualMachine, - ) -> PyResult { + ) -> PyResult<()> { self.inner.symmetric_difference_update(others, vm)?; - Ok(vm.ctx.none()) + Ok(()) } #[pymethod(name = "__ixor__")] diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs index 3fee3b56d..6faa25285 100644 --- a/vm/src/stdlib/ast.rs +++ b/vm/src/stdlib/ast.rs @@ -11,7 +11,7 @@ use rustpython_parser::{ast, mode::Mode, parser}; use crate::obj::objlist::PyListRef; use crate::obj::objtype::PyClassRef; -use crate::pyobject::{PyObjectRef, PyRef, PyResult, PyValue}; +use crate::pyobject::{IntoPyObject, PyObjectRef, PyRef, PyResult, PyValue}; use crate::slots::PyTpFlags; use crate::vm::VirtualMachine; @@ -204,7 +204,7 @@ fn statement_to_ast(vm: &VirtualMachine, statement: &ast::Statement) -> PyResult names, } => node!(vm, ImportFrom, { level => vm.ctx.new_int(*level), - module => optional_string_to_py_obj(vm, module), + module => module.as_ref().into_pyobject(vm), names => map_ast(alias_to_ast, vm, names)? }), Nonlocal { names } => node!(vm, Nonlocal, { @@ -247,7 +247,7 @@ fn statement_to_ast(vm: &VirtualMachine, statement: &ast::Statement) -> PyResult fn alias_to_ast(vm: &VirtualMachine, alias: &ast::ImportSymbol) -> PyResult { Ok(node!(vm, alias, { name => vm.ctx.new_str(&alias.symbol), - asname => optional_string_to_py_obj(vm, &alias.alias) + asname => alias.alias.as_ref().into_pyobject(vm), })) } @@ -274,7 +274,7 @@ fn with_item_to_ast(vm: &VirtualMachine, with_item: &ast::WithItem) -> PyResult< fn handler_to_ast(vm: &VirtualMachine, handler: &ast::ExceptHandler) -> PyResult { let node = node!(vm, ExceptHandler, { typ => optional_expression_to_ast(vm, &handler.typ)?, - name => optional_string_to_py_obj(vm, &handler.name), + name => handler.name.as_ref().into_pyobject(vm), body => statements_to_ast(vm, &handler.body)?, }); Ok(node) @@ -297,12 +297,11 @@ fn optional_expressions_to_ast( } fn optional_expression_to_ast(vm: &VirtualMachine, value: &Option) -> PyResult { - let value = if let Some(value) = value { - expression_to_ast(vm, value)?.into_object() - } else { - vm.ctx.none() - }; - Ok(value) + let ast = value + .as_ref() + .map(|expr| expression_to_ast(vm, expr)) + .transpose()?; + Ok(ast.into_pyobject(vm)) } fn expressions_to_ast(vm: &VirtualMachine, expressions: &[ast::Expression]) -> PyResult { @@ -439,11 +438,8 @@ fn expression_to_ast(vm: &VirtualMachine, expression: &ast::Expression) -> PyRes let mut keys = Vec::new(); let mut values = Vec::new(); for (k, v) in elements { - if let Some(k) = k { - keys.push(expression_to_ast(vm, k)?.into_object()); - } else { - keys.push(vm.ctx.none()); - } + let k = k.as_ref().map(|k| expression_to_ast(vm, k)).transpose()?; + keys.push(k.into_pyobject(vm)); values.push(expression_to_ast(vm, v)?.into_object()); } @@ -484,13 +480,12 @@ fn expression_to_ast(vm: &VirtualMachine, expression: &ast::Expression) -> PyRes }) } Yield { value } => { - let py_value = if let Some(value) = value { - expression_to_ast(vm, value)?.into_object() - } else { - vm.ctx.none() - }; + let py_value = value + .as_ref() + .map(|v| expression_to_ast(vm, v)) + .transpose()?; node!(vm, Yield, { - value => py_value + value => py_value.into_pyobject(vm) }) } YieldFrom { value } => { @@ -567,12 +562,12 @@ fn vararg_to_ast(vm: &VirtualMachine, vararg: &ast::Varargs) -> PyResult { } fn parameter_to_ast(vm: &VirtualMachine, parameter: &ast::Parameter) -> PyResult { - let py_annotation = if let Some(annotation) = ¶meter.annotation { - expression_to_ast(vm, annotation)?.into_object() - } else { - vm.ctx.none() - }; - + let py_annotation = parameter + .annotation + .as_ref() + .map(|expr| expression_to_ast(vm, expr)) + .transpose()? + .into_pyobject(vm); let py_node = node!(vm, arg, { arg => vm.ctx.new_str(¶meter.arg), annotation => py_annotation @@ -584,17 +579,9 @@ fn parameter_to_ast(vm: &VirtualMachine, parameter: &ast::Parameter) -> PyResult Ok(py_node) } -fn optional_string_to_py_obj(vm: &VirtualMachine, name: &Option) -> PyObjectRef { - if let Some(name) = name { - vm.ctx.new_str(name) - } else { - vm.ctx.none() - } -} - fn keyword_to_ast(vm: &VirtualMachine, keyword: &ast::Keyword) -> PyResult { Ok(node!(vm, keyword, { - arg => optional_string_to_py_obj(vm, &keyword.name), + arg => keyword.name.as_ref().into_pyobject(vm), value => expression_to_ast(vm, &keyword.value)? })) } diff --git a/vm/src/stdlib/dis.rs b/vm/src/stdlib/dis.rs index d7ca945a4..d53eba879 100644 --- a/vm/src/stdlib/dis.rs +++ b/vm/src/stdlib/dis.rs @@ -11,33 +11,30 @@ mod decl { use rustpython_compiler::compile; #[pyfunction] - fn dis(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult { - // Method or function: - if let Ok(co) = vm.get_attribute(obj.clone(), "__code__") { - return disassemble(co, vm); - } - - // String: - if let Ok(co_str) = PyStringRef::try_from_object(vm, obj.clone()) { - let code = vm - .compile( - co_str.borrow_value(), - compile::Mode::Exec, - "".to_owned(), - ) - .map_err(|err| vm.new_syntax_error(&err))? - .into_object(); - return disassemble(code, vm); - } - - disassemble(obj, vm) + fn dis(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { + let co = if let Ok(co) = vm.get_attribute(obj.clone(), "__code__") { + // Method or function: + co + } else if let Ok(co_str) = PyStringRef::try_from_object(vm, obj.clone()) { + // String: + vm.compile( + co_str.borrow_value(), + compile::Mode::Exec, + "".to_owned(), + ) + .map_err(|err| vm.new_syntax_error(&err))? + .into_object() + } else { + obj + }; + disassemble(co, vm) } #[pyfunction] - fn disassemble(co: PyObjectRef, vm: &VirtualMachine) -> PyResult { + fn disassemble(co: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { let code = &PyCodeRef::try_from_object(vm, co)?.code; print!("{}", code); - Ok(vm.ctx.none()) + Ok(()) } #[pyattr(name = "COMPILER_FLAG_NAMES")] diff --git a/vm/src/sysmodule.rs b/vm/src/sysmodule.rs index 8e6b13ba9..56cb343e0 100644 --- a/vm/src/sysmodule.rs +++ b/vm/src/sysmodule.rs @@ -170,10 +170,9 @@ fn sys_gettrace(vm: &VirtualMachine) -> PyObjectRef { vm.trace_func.borrow().clone() } -fn sys_settrace(tracefunc: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef { +fn sys_settrace(tracefunc: PyObjectRef, vm: &VirtualMachine) { vm.trace_func.replace(tracefunc); update_use_tracing(vm); - vm.ctx.none() } fn update_use_tracing(vm: &VirtualMachine) { @@ -187,7 +186,7 @@ fn sys_getrecursionlimit(vm: &VirtualMachine) -> usize { vm.recursion_limit.get() } -fn sys_setrecursionlimit(recursion_limit: i32, vm: &VirtualMachine) -> PyResult { +fn sys_setrecursionlimit(recursion_limit: i32, vm: &VirtualMachine) -> PyResult<()> { let recursion_limit = recursion_limit .to_usize() .filter(|&u| u >= 1) @@ -198,7 +197,7 @@ fn sys_setrecursionlimit(recursion_limit: i32, vm: &VirtualMachine) -> PyResult if recursion_limit > recursion_depth + 1 { vm.recursion_limit.set(recursion_limit); - Ok(vm.ctx.none()) + Ok(()) } else { Err(vm.new_recursion_error(format!( "cannot set the recursion limit to {} at the recursion depth {}: the limit is too low", @@ -212,12 +211,11 @@ fn sys_intern(value: PyStringRef) -> PyStringRef { value } -fn sys_exc_info(vm: &VirtualMachine) -> PyObjectRef { - let (ty, val, tb) = match vm.current_exception() { +fn sys_exc_info(vm: &VirtualMachine) -> (PyObjectRef, PyObjectRef, PyObjectRef) { + match vm.current_exception() { Some(exception) => exceptions::split(exception, vm), None => (vm.ctx.none(), vm.ctx.none(), vm.ctx.none()), - }; - vm.ctx.new_tuple(vec![ty, val, tb]) + } } fn sys_git_info(vm: &VirtualMachine) -> PyObjectRef { From 5bfa5fa581f114944ecd43410da99673e927c99b Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 19 Sep 2020 11:11:31 +0900 Subject: [PATCH 10/11] re.rs with unflatten types --- vm/src/stdlib/re.rs | 94 ++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 48 deletions(-) diff --git a/vm/src/stdlib/re.rs b/vm/src/stdlib/re.rs index 213fcccc1..900fed702 100644 --- a/vm/src/stdlib/re.rs +++ b/vm/src/stdlib/re.rs @@ -13,7 +13,9 @@ use crate::function::{Args, OptionalArg}; use crate::obj::objint::{PyInt, PyIntRef}; use crate::obj::objstr::{PyString, PyStringRef}; use crate::obj::objtype::PyClassRef; -use crate::pyobject::{BorrowValue, PyClassImpl, PyObjectRef, PyResult, PyValue, TryFromObject}; +use crate::pyobject::{ + BorrowValue, IntoPyObject, PyClassImpl, PyObjectRef, PyResult, PyValue, TryFromObject, +}; use crate::vm::VirtualMachine; #[pyclass(module = "re", name = "Pattern")] @@ -95,10 +97,10 @@ fn re_match( string: PyStringRef, flags: OptionalArg, vm: &VirtualMachine, -) -> PyResult { +) -> PyResult> { let flags = extract_flags(flags); let regex = make_regex(vm, pattern.borrow_value(), flags)?; - do_match(vm, ®ex, string) + Ok(do_match(®ex, string)) } fn re_search( @@ -106,10 +108,10 @@ fn re_search( string: PyStringRef, flags: OptionalArg, vm: &VirtualMachine, -) -> PyResult { +) -> PyResult> { let flags = extract_flags(flags); let regex = make_regex(vm, pattern.borrow_value(), flags)?; - do_search(vm, ®ex, string) + Ok(do_search(®ex, string)) } fn re_sub( @@ -119,11 +121,11 @@ fn re_sub( count: OptionalArg, flags: OptionalArg, vm: &VirtualMachine, -) -> PyResult { +) -> PyResult { let flags = extract_flags(flags); let regex = make_regex(vm, pattern.borrow_value(), flags)?; let limit = count.unwrap_or(0); - do_sub(vm, ®ex, repl, string, limit) + Ok(do_sub(®ex, repl, string, limit)) } fn re_findall( @@ -150,38 +152,34 @@ fn re_split( } fn do_sub( - vm: &VirtualMachine, pattern: &PyPattern, repl: PyStringRef, search_text: PyStringRef, limit: usize, -) -> PyResult { +) -> String { let out = pattern.regex.replacen( search_text.borrow_value().as_bytes(), limit, repl.borrow_value().as_bytes(), ); - let out = String::from_utf8_lossy(&out).into_owned(); - Ok(vm.ctx.new_str(out)) + String::from_utf8_lossy(&out).into_owned() } -fn do_match(vm: &VirtualMachine, pattern: &PyPattern, search_text: PyStringRef) -> PyResult { +fn do_match(pattern: &PyPattern, search_text: PyStringRef) -> Option { // I really wish there was a better way to do this; I don't think there is - let mut regex = r"\A".to_owned(); - regex.push_str(pattern.regex.as_str()); - let regex = Regex::new(®ex).unwrap(); - - match regex.captures(search_text.borrow_value().as_bytes()) { - None => Ok(vm.ctx.none()), - Some(captures) => Ok(create_match(vm, search_text.clone(), captures)), - } + let mut regex_text = r"\A".to_owned(); + regex_text.push_str(pattern.regex.as_str()); + let regex = Regex::new(®ex_text).unwrap(); + regex + .captures(search_text.borrow_value().as_bytes()) + .map(|captures| create_match(search_text.clone(), captures)) } -fn do_search(vm: &VirtualMachine, regex: &PyPattern, search_text: PyStringRef) -> PyResult { - match regex.regex.captures(search_text.borrow_value().as_bytes()) { - None => Ok(vm.ctx.none()), - Some(captures) => Ok(create_match(vm, search_text.clone(), captures)), - } +fn do_search(regex: &PyPattern, search_text: PyStringRef) -> Option { + regex + .regex + .captures(search_text.borrow_value().as_bytes()) + .map(|captures| create_match(search_text.clone(), captures)) } fn do_findall(vm: &VirtualMachine, pattern: &PyPattern, search_text: PyStringRef) -> PyResult { @@ -285,12 +283,12 @@ fn make_regex(vm: &VirtualMachine, pattern: &str, flags: PyRegexFlags) -> PyResu } /// Take a found regular expression and convert it to proper match object. -fn create_match(vm: &VirtualMachine, haystack: PyStringRef, captures: Captures) -> PyObjectRef { +fn create_match(haystack: PyStringRef, captures: Captures) -> PyMatch { let captures = captures .iter() .map(|opt| opt.map(|m| m.start()..m.end())) .collect(); - PyMatch { haystack, captures }.into_object(vm) + PyMatch { haystack, captures } } fn extract_flags(flags: OptionalArg) -> PyRegexFlags { @@ -318,13 +316,13 @@ fn re_purge(_vm: &VirtualMachine) {} #[pyimpl] impl PyPattern { #[pymethod(name = "match")] - fn match_(&self, text: PyStringRef, vm: &VirtualMachine) -> PyResult { - do_match(vm, self, text) + fn match_(&self, text: PyStringRef) -> Option { + do_match(self, text) } #[pymethod(name = "search")] - fn search(&self, text: PyStringRef, vm: &VirtualMachine) -> PyResult { - do_search(vm, self, text) + fn search(&self, text: PyStringRef) -> Option { + do_search(self, text) } #[pymethod(name = "sub")] @@ -383,8 +381,8 @@ impl PyMatch { Ok(end) } - fn subgroup(&self, bounds: Range, vm: &VirtualMachine) -> PyObjectRef { - vm.ctx.new_str(&self.haystack.borrow_value()[bounds]) + fn subgroup(&self, bounds: Range) -> String { + self.haystack.borrow_value()[bounds].to_owned() } fn get_bounds(&self, id: PyObjectRef, vm: &VirtualMachine) -> PyResult>> { @@ -402,27 +400,27 @@ impl PyMatch { }) } - fn get_group(&self, id: PyObjectRef, vm: &VirtualMachine) -> PyResult { + fn get_group(&self, id: PyObjectRef, vm: &VirtualMachine) -> PyResult> { let bounds = self.get_bounds(id, vm)?; - let group = match bounds { - Some(bounds) => self.subgroup(bounds, vm), - None => vm.ctx.none(), - }; - Ok(group) + Ok(bounds.map(|b| self.subgroup(b))) } #[pymethod] fn group(&self, groups: Args, vm: &VirtualMachine) -> PyResult { let mut groups = groups.into_vec(); match groups.len() { - 0 => Ok(self.subgroup(self.captures[0].clone().unwrap(), vm)), - 1 => self.get_group(groups.pop().unwrap(), vm), - len => { - let mut output = Vec::with_capacity(len); - for id in groups { - output.push(self.get_group(id, vm)?); - } - Ok(vm.ctx.new_tuple(output)) + 0 => Ok(self + .subgroup(self.captures[0].clone().unwrap()) + .into_pyobject(vm)), + 1 => self + .get_group(groups.pop().unwrap(), vm) + .map(|g| g.into_pyobject(vm)), + _ => { + let output: Result, _> = groups + .into_iter() + .map(|id| self.get_group(id, vm).map(|g| g.into_pyobject(vm))) + .collect(); + Ok(vm.ctx.new_tuple(output?)) } } } @@ -437,7 +435,7 @@ impl PyMatch { vm.unwrap_or_none( capture .as_ref() - .map(|bounds| self.subgroup(bounds.clone(), vm)) + .map(|bounds| self.subgroup(bounds.clone()).into_pyobject(vm)) .or_else(|| default.clone()), ) }) From 8faa82538a5807fa7b607a89da86fd6e37c50463 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Sat, 19 Sep 2020 11:35:03 +0900 Subject: [PATCH 11/11] repr for NotImplemented and no eq/ne for None --- vm/src/obj/objsingletons.rs | 39 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/vm/src/obj/objsingletons.rs b/vm/src/obj/objsingletons.rs index c73e6efd1..f54dadfe6 100644 --- a/vm/src/obj/objsingletons.rs +++ b/vm/src/obj/objsingletons.rs @@ -1,6 +1,6 @@ use super::objtype::PyClassRef; use crate::pyobject::{ - IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, + IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyValue, TypeProtocol, }; use crate::vm::VirtualMachine; @@ -39,32 +39,14 @@ impl PyNone { vm.ctx.none.clone() } - #[pymethod(name = "__repr__")] - fn repr(&self) -> PyResult { - Ok("None".to_owned()) + #[pymethod(magic)] + fn repr(&self) -> String { + "None".to_owned() } - #[pymethod(name = "__bool__")] - fn bool(&self) -> PyResult { - Ok(false) - } - - #[pymethod(name = "__eq__")] - fn eq(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef { - if vm.is_none(&rhs) { - vm.ctx.new_bool(true) - } else { - vm.ctx.not_implemented() - } - } - - #[pymethod(name = "__ne__")] - fn ne(&self, rhs: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef { - if vm.is_none(&rhs) { - vm.ctx.new_bool(false) - } else { - vm.ctx.not_implemented() - } + #[pymethod(magic)] + fn bool(&self) -> bool { + false } } @@ -80,7 +62,12 @@ impl PyValue for PyNotImplemented { } #[pyimpl] -impl PyNotImplemented {} +impl PyNotImplemented { + #[pymethod(magic)] + fn repr(&self) -> String { + "PyNotImplemented".to_owned() + } +} pub fn init(context: &PyContext) { PyNone::extend_class(context, &context.none.class());