diff --git a/vm/src/obj/objenumerate.rs b/vm/src/obj/objenumerate.rs index 76452e56c..fb7ae7c71 100644 --- a/vm/src/obj/objenumerate.rs +++ b/vm/src/obj/objenumerate.rs @@ -4,18 +4,20 @@ use std::ops::AddAssign; use num_bigint::BigInt; use num_traits::Zero; -use crate::function::PyFuncArgs; -use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol}; +use crate::function::{OptionalArg, PyFuncArgs}; +use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol}; use crate::vm::VirtualMachine; -use super::objint; +use super::objint::PyIntRef; use super::objiter; +use super::objtype::PyClassRef; #[derive(Debug)] pub struct PyEnumerate { counter: RefCell, iterator: PyObjectRef, } +type PyEnumerateRef = PyRef; impl PyValue for PyEnumerate { fn class(vm: &mut VirtualMachine) -> PyObjectRef { @@ -23,26 +25,23 @@ impl PyValue for PyEnumerate { } } -fn enumerate_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [(cls, Some(vm.ctx.type_type())), (iterable, None)], - optional = [(start, Some(vm.ctx.int_type()))] - ); - let counter = if let Some(x) = start { - objint::get_value(x).clone() - } else { - BigInt::zero() +fn enumerate_new( + cls: PyClassRef, + iterable: PyObjectRef, + start: OptionalArg, + vm: &mut VirtualMachine, +) -> PyResult { + let counter = match start { + OptionalArg::Present(start) => start.value.clone(), + OptionalArg::Missing => BigInt::zero(), }; - let iterator = objiter::get_iter(vm, iterable)?; - Ok(PyObject::new( - PyEnumerate { - counter: RefCell::new(counter), - iterator, - }, - cls.clone(), - )) + + let iterator = objiter::get_iter(vm, &iterable)?; + PyEnumerate { + counter: RefCell::new(counter.clone()), + iterator, + } + .into_ref_with_type(vm, cls) } fn enumerate_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { diff --git a/vm/src/obj/objgenerator.rs b/vm/src/obj/objgenerator.rs index 611b89150..2fe08c138 100644 --- a/vm/src/obj/objgenerator.rs +++ b/vm/src/obj/objgenerator.rs @@ -4,13 +4,14 @@ use crate::frame::{ExecutionResult, Frame}; use crate::function::PyFuncArgs; -use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol}; +use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol}; use crate::vm::VirtualMachine; #[derive(Debug)] pub struct PyGenerator { frame: PyObjectRef, } +type PyGeneratorRef = PyRef; impl PyValue for PyGenerator { fn class(vm: &mut VirtualMachine) -> PyObjectRef { @@ -37,11 +38,8 @@ pub fn init(context: &PyContext) { ); } -pub fn new_generator(vm: &mut VirtualMachine, frame: PyObjectRef) -> PyResult { - Ok(PyObject::new( - PyGenerator { frame }, - vm.ctx.generator_type.clone(), - )) +pub fn new_generator(frame: PyObjectRef, vm: &mut VirtualMachine) -> PyGeneratorRef { + PyGenerator { frame }.into_ref(vm) } fn generator_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { diff --git a/vm/src/obj/objlist.rs b/vm/src/obj/objlist.rs index 2780f7582..08d3ff2f4 100644 --- a/vm/src/obj/objlist.rs +++ b/vm/src/obj/objlist.rs @@ -119,14 +119,11 @@ impl PyListRef { ) } - fn iter(self, vm: &mut VirtualMachine) -> PyObjectRef { - PyObject::new( - PyIteratorValue { - position: Cell::new(0), - iterated_obj: self.into_object(), - }, - vm.ctx.iter_type(), - ) + fn iter(self, _vm: &mut VirtualMachine) -> PyIteratorValue { + PyIteratorValue { + position: Cell::new(0), + iterated_obj: self.into_object(), + } } fn setitem(self, key: PyObjectRef, value: PyObjectRef, vm: &mut VirtualMachine) -> PyResult { diff --git a/vm/src/obj/objmap.rs b/vm/src/obj/objmap.rs index 2de5bc5ef..029d3bae9 100644 --- a/vm/src/obj/objmap.rs +++ b/vm/src/obj/objmap.rs @@ -1,14 +1,16 @@ -use crate::function::PyFuncArgs; -use crate::pyobject::{PyContext, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol}; +use crate::function::{Args, PyFuncArgs}; +use crate::pyobject::{PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol}; use crate::vm::VirtualMachine; use super::objiter; +use super::objtype::PyClassRef; #[derive(Debug)] pub struct PyMap { mapper: PyObjectRef, iterators: Vec, } +type PyMapRef = PyRef; impl PyValue for PyMap { fn class(vm: &mut VirtualMachine) -> PyObjectRef { @@ -16,26 +18,21 @@ impl PyValue for PyMap { } } -fn map_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { - no_kwargs!(vm, args); - let cls = &args.args[0]; - if args.args.len() < 3 { - Err(vm.new_type_error("map() must have at least two arguments.".to_owned())) - } else { - let function = &args.args[1]; - let iterables = &args.args[2..]; - let iterators = iterables - .iter() - .map(|iterable| objiter::get_iter(vm, iterable)) - .collect::, _>>()?; - Ok(PyObject::new( - PyMap { - mapper: function.clone(), - iterators, - }, - cls.clone(), - )) +fn map_new( + cls: PyClassRef, + function: PyObjectRef, + iterables: Args, + vm: &mut VirtualMachine, +) -> PyResult { + let iterators = iterables + .into_iter() + .map(|iterable| objiter::get_iter(vm, &iterable)) + .collect::, _>>()?; + PyMap { + mapper: function.clone(), + iterators, } + .into_ref_with_type(vm, cls.clone()) } fn map_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs index 7f54c0d65..2b4626146 100644 --- a/vm/src/obj/objset.rs +++ b/vm/src/obj/objset.rs @@ -7,21 +7,22 @@ use std::collections::{hash_map::DefaultHasher, HashMap}; use std::fmt; use std::hash::{Hash, Hasher}; -use crate::function::PyFuncArgs; +use crate::function::{OptionalArg, PyFuncArgs}; use crate::pyobject::{ - PyContext, PyIteratorValue, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol, + PyContext, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, }; use crate::vm::{ReprGuard, VirtualMachine}; use super::objbool; use super::objint; use super::objiter; -use super::objtype; +use super::objtype::{self, PyClassRef}; #[derive(Default)] pub struct PySet { elements: RefCell>, } +pub type PySetRef = PyRef; impl fmt::Debug for PySet { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -151,23 +152,20 @@ fn set_clear(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { } /* Create a new object of sub-type of set */ -fn set_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [(cls, None)], - optional = [(iterable, None)] - ); - - if !objtype::issubclass(cls, &vm.ctx.set_type()) { +fn set_new( + cls: PyClassRef, + iterable: OptionalArg, + vm: &mut VirtualMachine, +) -> PyResult { + if !objtype::issubclass(cls.as_object(), &vm.ctx.set_type()) { return Err(vm.new_type_error(format!("{} is not a subtype of set", cls))); } let elements: HashMap = match iterable { - None => HashMap::new(), - Some(iterable) => { + OptionalArg::Missing => HashMap::new(), + OptionalArg::Present(iterable) => { let mut elements = HashMap::new(); - let iterator = objiter::get_iter(vm, iterable)?; + let iterator = objiter::get_iter(vm, &iterable)?; while let Ok(v) = vm.call_method(&iterator, "__next__", vec![]) { insert_into_set(vm, &mut elements, &v)?; } @@ -175,12 +173,10 @@ fn set_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { } }; - Ok(PyObject::new( - PySet { - elements: RefCell::new(elements), - }, - cls.clone(), - )) + PySet { + elements: RefCell::new(elements), + } + .into_ref_with_type(vm, cls) } fn set_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { @@ -190,16 +186,12 @@ fn set_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { Ok(vm.context().new_int(elements.len())) } -fn set_copy(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { - trace!("set.copy called with: {:?}", args); - arg_check!(vm, args, required = [(s, Some(vm.ctx.set_type()))]); - let elements = get_elements(s); - Ok(PyObject::new( - PySet { - elements: RefCell::new(elements), - }, - vm.ctx.set_type(), - )) +fn set_copy(obj: PySetRef, _vm: &mut VirtualMachine) -> PySet { + trace!("set.copy called with: {:?}", obj); + let elements = obj.elements.borrow().clone(); + PySet { + elements: RefCell::new(elements), + } } fn set_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { @@ -335,67 +327,47 @@ fn set_compare_inner( Ok(vm.new_bool(true)) } -fn set_union(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [ - (zelf, Some(vm.ctx.set_type())), - (other, Some(vm.ctx.set_type())) - ] - ); +fn set_union(zelf: PySetRef, other: PySetRef, _vm: &mut VirtualMachine) -> PySet { + let mut elements = zelf.elements.borrow().clone(); + elements.extend(other.elements.borrow().clone()); - let mut elements = get_elements(zelf).clone(); - elements.extend(get_elements(other).clone()); - - Ok(PyObject::new( - PySet { - elements: RefCell::new(elements), - }, - vm.ctx.set_type(), - )) + PySet { + elements: RefCell::new(elements), + } } -fn set_intersection(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { - set_combine_inner(vm, args, SetCombineOperation::Intersection) +fn set_intersection(zelf: PySetRef, other: PySetRef, vm: &mut VirtualMachine) -> PyResult { + set_combine_inner(zelf, other, vm, SetCombineOperation::Intersection) } -fn set_difference(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { - set_combine_inner(vm, args, SetCombineOperation::Difference) +fn set_difference(zelf: PySetRef, other: PySetRef, vm: &mut VirtualMachine) -> PyResult { + set_combine_inner(zelf, other, vm, SetCombineOperation::Difference) } -fn set_symmetric_difference(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!( - vm, - args, - required = [ - (zelf, Some(vm.ctx.set_type())), - (other, Some(vm.ctx.set_type())) - ] - ); - +fn set_symmetric_difference( + zelf: PySetRef, + other: PySetRef, + vm: &mut VirtualMachine, +) -> PyResult { let mut elements = HashMap::new(); - for element in get_elements(zelf).iter() { - let value = vm.call_method(other, "__contains__", vec![element.1.clone()])?; + for element in zelf.elements.borrow().iter() { + let value = vm.call_method(other.as_object(), "__contains__", vec![element.1.clone()])?; if !objbool::get_value(&value) { elements.insert(element.0.clone(), element.1.clone()); } } - for element in get_elements(other).iter() { - let value = vm.call_method(zelf, "__contains__", vec![element.1.clone()])?; + for element in other.elements.borrow().iter() { + let value = vm.call_method(zelf.as_object(), "__contains__", vec![element.1.clone()])?; if !objbool::get_value(&value) { elements.insert(element.0.clone(), element.1.clone()); } } - Ok(PyObject::new( - PySet { - elements: RefCell::new(elements), - }, - vm.ctx.set_type(), - )) + Ok(PySet { + elements: RefCell::new(elements), + }) } enum SetCombineOperation { @@ -404,23 +376,15 @@ enum SetCombineOperation { } fn set_combine_inner( + zelf: PySetRef, + other: PySetRef, vm: &mut VirtualMachine, - args: PyFuncArgs, op: SetCombineOperation, -) -> PyResult { - arg_check!( - vm, - args, - required = [ - (zelf, Some(vm.ctx.set_type())), - (other, Some(vm.ctx.set_type())) - ] - ); - +) -> PyResult { let mut elements = HashMap::new(); - for element in get_elements(zelf).iter() { - let value = vm.call_method(other, "__contains__", vec![element.1.clone()])?; + for element in zelf.elements.borrow().iter() { + let value = vm.call_method(other.as_object(), "__contains__", vec![element.1.clone()])?; let should_add = match op { SetCombineOperation::Intersection => objbool::get_value(&value), SetCombineOperation::Difference => !objbool::get_value(&value), @@ -430,12 +394,9 @@ fn set_combine_inner( } } - Ok(PyObject::new( - PySet { - elements: RefCell::new(elements), - }, - vm.ctx.set_type(), - )) + Ok(PySet { + elements: RefCell::new(elements), + }) } fn set_pop(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { @@ -557,20 +518,13 @@ fn set_ixor(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { Ok(zelf.clone()) } -fn set_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { - arg_check!(vm, args, required = [(zelf, Some(vm.ctx.set_type()))]); - - let items = get_elements(zelf).values().cloned().collect(); +fn set_iter(zelf: PySetRef, vm: &mut VirtualMachine) -> PyIteratorValue { + let items = zelf.elements.borrow().values().cloned().collect(); let set_list = vm.ctx.new_list(items); - let iter_obj = PyObject::new( - PyIteratorValue { - position: Cell::new(0), - iterated_obj: set_list, - }, - vm.ctx.iter_type(), - ); - - Ok(iter_obj) + PyIteratorValue { + position: Cell::new(0), + iterated_obj: set_list, + } } fn frozenset_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult { diff --git a/vm/src/obj/objtuple.rs b/vm/src/obj/objtuple.rs index 212005fdf..11d6a3694 100644 --- a/vm/src/obj/objtuple.rs +++ b/vm/src/obj/objtuple.rs @@ -4,7 +4,7 @@ use std::hash::{Hash, Hasher}; use crate::function::OptionalArg; use crate::pyobject::{ - IdProtocol, PyContext, PyIteratorValue, PyObject, PyObjectRef, PyRef, PyResult, PyValue, + IdProtocol, PyContext, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue, }; use crate::vm::{ReprGuard, VirtualMachine}; @@ -13,7 +13,7 @@ use super::objint; use super::objsequence::{ get_elements, get_item, seq_equal, seq_ge, seq_gt, seq_le, seq_lt, seq_mul, }; -use super::objtype; +use super::objtype::{self, PyClassRef}; #[derive(Default)] pub struct PyTuple { @@ -132,14 +132,11 @@ impl PyTupleRef { Ok(hasher.finish()) } - fn iter(self, vm: &mut VirtualMachine) -> PyObjectRef { - PyObject::new( - PyIteratorValue { - position: Cell::new(0), - iterated_obj: self.into_object(), - }, - vm.ctx.iter_type(), - ) + fn iter(self, _vm: &mut VirtualMachine) -> PyIteratorValue { + PyIteratorValue { + position: Cell::new(0), + iterated_obj: self.into_object(), + } } fn len(self, _vm: &mut VirtualMachine) -> usize { @@ -207,10 +204,10 @@ impl PyTupleRef { } fn tuple_new( - cls: PyRef, + cls: PyClassRef, iterable: OptionalArg, vm: &mut VirtualMachine, -) -> PyResult { +) -> PyResult { if !objtype::issubclass(cls.as_object(), &vm.ctx.tuple_type()) { return Err(vm.new_type_error(format!("{} is not a subtype of tuple", cls))); } @@ -221,7 +218,7 @@ fn tuple_new( vec![] }; - Ok(PyObject::new(PyTuple::from(elements), cls.into_object())) + PyTuple::from(elements).into_ref_with_type(vm, cls) } #[rustfmt::skip] // to avoid line splitting diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 49bc2f9e2..3b3799d0f 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -353,7 +353,7 @@ impl VirtualMachine { // If we have a generator, create a new generator if code_object.is_generator { - objgenerator::new_generator(self, frame) + Ok(objgenerator::new_generator(frame, self).into_object()) } else { self.run_frame_full(frame) }