mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-17 01:51:39 +09:00
Remove outer RefCell from PyObjectRef
This commit is contained in:
@@ -12,17 +12,17 @@ impl IntoPyObject for bool {
|
||||
}
|
||||
|
||||
pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> Result<bool, PyObjectRef> {
|
||||
let result = match obj.borrow().payload {
|
||||
let result = match obj.payload {
|
||||
PyObjectPayload::Integer { ref value } => !value.is_zero(),
|
||||
PyObjectPayload::Float { value } => value != 0.0,
|
||||
PyObjectPayload::Sequence { ref elements } => !elements.is_empty(),
|
||||
PyObjectPayload::Dict { ref elements } => !elements.is_empty(),
|
||||
PyObjectPayload::Sequence { ref elements } => !elements.borrow().is_empty(),
|
||||
PyObjectPayload::Dict { ref elements } => !elements.borrow().is_empty(),
|
||||
PyObjectPayload::String { ref value } => !value.is_empty(),
|
||||
PyObjectPayload::None { .. } => false,
|
||||
_ => {
|
||||
if let Ok(f) = vm.get_method(obj.clone(), "__bool__") {
|
||||
let bool_res = vm.invoke(f, PyFuncArgs::default())?;
|
||||
let v = match bool_res.borrow().payload {
|
||||
let v = match bool_res.payload {
|
||||
PyObjectPayload::Integer { ref value } => !value.is_zero(),
|
||||
_ => return Err(vm.new_type_error(String::from("TypeError"))),
|
||||
};
|
||||
@@ -60,7 +60,7 @@ pub fn not(vm: &mut VirtualMachine, obj: &PyObjectRef) -> PyResult {
|
||||
|
||||
// Retrieve inner int value:
|
||||
pub fn get_value(obj: &PyObjectRef) -> bool {
|
||||
if let PyObjectPayload::Integer { value } = &obj.borrow().payload {
|
||||
if let PyObjectPayload::Integer { value } = &obj.payload {
|
||||
!value.is_zero()
|
||||
} else {
|
||||
panic!("Inner error getting inner boolean");
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
//! Implementation of the python bytearray object.
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyResult, TypeProtocol};
|
||||
|
||||
use super::objint;
|
||||
@@ -140,7 +142,12 @@ fn bytearray_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
Ok(PyObject::new(PyObjectPayload::Bytes { value }, cls.clone()))
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Bytes {
|
||||
value: RefCell::new(value),
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
fn bytesarray_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -283,10 +290,9 @@ fn bytearray_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
fn bytearray_clear(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(zelf, Some(vm.ctx.bytearray_type()))]);
|
||||
let mut mut_obj = zelf.borrow_mut();
|
||||
match mut_obj.payload {
|
||||
PyObjectPayload::Bytes { ref mut value } => {
|
||||
value.clear();
|
||||
match zelf.payload {
|
||||
PyObjectPayload::Bytes { ref value } => {
|
||||
value.borrow_mut().clear();
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
_ => panic!("Bytearray has incorrect payload."),
|
||||
@@ -307,17 +313,11 @@ fn bytearray_pop(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
fn bytearray_lower(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(obj, Some(vm.ctx.bytearray_type()))]);
|
||||
let value = get_value(obj).to_vec().to_ascii_lowercase();
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Bytes { value },
|
||||
vm.ctx.bytearray_type(),
|
||||
))
|
||||
Ok(vm.ctx.new_bytearray(value))
|
||||
}
|
||||
|
||||
fn bytearray_upper(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(obj, Some(vm.ctx.bytearray_type()))]);
|
||||
let value = get_value(obj).to_vec().to_ascii_uppercase();
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Bytes { value },
|
||||
vm.ctx.bytearray_type(),
|
||||
))
|
||||
Ok(vm.ctx.new_bytearray(value))
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
use std::cell::RefCell;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Deref;
|
||||
use std::ops::DerefMut;
|
||||
|
||||
use super::objint;
|
||||
use super::objtype;
|
||||
use crate::pyobject::{
|
||||
@@ -5,11 +10,6 @@ use crate::pyobject::{
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_traits::ToPrimitive;
|
||||
use std::cell::Ref;
|
||||
use std::cell::RefMut;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Deref;
|
||||
use std::ops::DerefMut;
|
||||
|
||||
// Binary data support
|
||||
|
||||
@@ -70,7 +70,12 @@ fn bytes_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
vec![]
|
||||
};
|
||||
|
||||
Ok(PyObject::new(PyObjectPayload::Bytes { value }, cls.clone()))
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Bytes {
|
||||
value: RefCell::new(value),
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
fn bytes_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -98,11 +103,7 @@ fn bytes_ge(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let result = if objtype::isinstance(b, &vm.ctx.bytes_type()) {
|
||||
get_value(a).to_vec() >= get_value(b).to_vec()
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Cannot compare {} and {} using '>'",
|
||||
a.borrow(),
|
||||
b.borrow()
|
||||
)));
|
||||
return Err(vm.new_type_error(format!("Cannot compare {} and {} using '>'", a, b)));
|
||||
};
|
||||
Ok(vm.ctx.new_bool(result))
|
||||
}
|
||||
@@ -117,11 +118,7 @@ fn bytes_gt(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let result = if objtype::isinstance(b, &vm.ctx.bytes_type()) {
|
||||
get_value(a).to_vec() > get_value(b).to_vec()
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Cannot compare {} and {} using '>='",
|
||||
a.borrow(),
|
||||
b.borrow()
|
||||
)));
|
||||
return Err(vm.new_type_error(format!("Cannot compare {} and {} using '>='", a, b)));
|
||||
};
|
||||
Ok(vm.ctx.new_bool(result))
|
||||
}
|
||||
@@ -136,11 +133,7 @@ fn bytes_le(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let result = if objtype::isinstance(b, &vm.ctx.bytes_type()) {
|
||||
get_value(a).to_vec() <= get_value(b).to_vec()
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Cannot compare {} and {} using '<'",
|
||||
a.borrow(),
|
||||
b.borrow()
|
||||
)));
|
||||
return Err(vm.new_type_error(format!("Cannot compare {} and {} using '<'", a, b)));
|
||||
};
|
||||
Ok(vm.ctx.new_bool(result))
|
||||
}
|
||||
@@ -155,11 +148,7 @@ fn bytes_lt(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let result = if objtype::isinstance(b, &vm.ctx.bytes_type()) {
|
||||
get_value(a).to_vec() < get_value(b).to_vec()
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Cannot compare {} and {} using '<='",
|
||||
a.borrow(),
|
||||
b.borrow()
|
||||
)));
|
||||
return Err(vm.new_type_error(format!("Cannot compare {} and {} using '<='", a, b)));
|
||||
};
|
||||
Ok(vm.ctx.new_bool(result))
|
||||
}
|
||||
@@ -181,23 +170,19 @@ fn bytes_hash(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
pub fn get_value<'a>(obj: &'a PyObjectRef) -> impl Deref<Target = Vec<u8>> + 'a {
|
||||
Ref::map(obj.borrow(), |py_obj| {
|
||||
if let PyObjectPayload::Bytes { ref value } = py_obj.payload {
|
||||
value
|
||||
} else {
|
||||
panic!("Inner error getting bytearray {:?}", obj);
|
||||
}
|
||||
})
|
||||
if let PyObjectPayload::Bytes { ref value } = obj.payload {
|
||||
value.borrow()
|
||||
} else {
|
||||
panic!("Inner error getting bytearray {:?}", obj);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mut_value<'a>(obj: &'a PyObjectRef) -> impl DerefMut<Target = Vec<u8>> + 'a {
|
||||
RefMut::map(obj.borrow_mut(), |py_obj| {
|
||||
if let PyObjectPayload::Bytes { ref mut value } = py_obj.payload {
|
||||
value
|
||||
} else {
|
||||
panic!("Inner error getting bytearray {:?}", obj);
|
||||
}
|
||||
})
|
||||
if let PyObjectPayload::Bytes { ref value } = obj.payload {
|
||||
value.borrow_mut()
|
||||
} else {
|
||||
panic!("Inner error getting bytearray {:?}", obj);
|
||||
}
|
||||
}
|
||||
|
||||
fn bytes_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
@@ -29,7 +29,7 @@ pub fn init(context: &PyContext) {
|
||||
}
|
||||
|
||||
pub fn get_value(obj: &PyObjectRef) -> bytecode::CodeObject {
|
||||
if let PyObjectPayload::Code { code } = &obj.borrow().payload {
|
||||
if let PyObjectPayload::Code { code } = &obj.payload {
|
||||
code.clone()
|
||||
} else {
|
||||
panic!("Inner error getting code {:?}", obj)
|
||||
|
||||
@@ -45,7 +45,7 @@ pub fn init(context: &PyContext) {
|
||||
}
|
||||
|
||||
pub fn get_value(obj: &PyObjectRef) -> Complex64 {
|
||||
if let PyObjectPayload::Complex { value } = &obj.borrow().payload {
|
||||
if let PyObjectPayload::Complex { value } = &obj.payload {
|
||||
*value
|
||||
} else {
|
||||
panic!("Inner error getting complex");
|
||||
@@ -117,7 +117,7 @@ fn complex_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
v1.im,
|
||||
)))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot add {} and {}", i.borrow(), i2.borrow())))
|
||||
Err(vm.new_type_error(format!("Cannot add {} and {}", i, i2)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ fn complex_radd(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
v1.im,
|
||||
)))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot add {} and {}", i.borrow(), i2.borrow())))
|
||||
Err(vm.new_type_error(format!("Cannot add {} and {}", i, i2)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::pyobject::{
|
||||
TypeProtocol,
|
||||
};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
use std::cell::{Ref, RefCell, RefMut};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
@@ -19,30 +19,26 @@ pub type DictContentType = HashMap<String, (PyObjectRef, PyObjectRef)>;
|
||||
pub fn new(dict_type: PyObjectRef) -> PyObjectRef {
|
||||
PyObject::new(
|
||||
PyObjectPayload::Dict {
|
||||
elements: HashMap::new(),
|
||||
elements: RefCell::new(HashMap::new()),
|
||||
},
|
||||
dict_type.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_elements<'a>(obj: &'a PyObjectRef) -> impl Deref<Target = DictContentType> + 'a {
|
||||
Ref::map(obj.borrow(), |py_obj| {
|
||||
if let PyObjectPayload::Dict { ref elements } = py_obj.payload {
|
||||
elements
|
||||
} else {
|
||||
panic!("Cannot extract dict elements");
|
||||
}
|
||||
})
|
||||
if let PyObjectPayload::Dict { ref elements } = obj.payload {
|
||||
elements.borrow()
|
||||
} else {
|
||||
panic!("Cannot extract dict elements");
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mut_elements<'a>(obj: &'a PyObjectRef) -> impl DerefMut<Target = DictContentType> + 'a {
|
||||
RefMut::map(obj.borrow_mut(), |py_obj| {
|
||||
if let PyObjectPayload::Dict { ref mut elements } = py_obj.payload {
|
||||
elements
|
||||
} else {
|
||||
panic!("Cannot extract dict elements");
|
||||
}
|
||||
})
|
||||
if let PyObjectPayload::Dict { ref elements } = obj.payload {
|
||||
elements.borrow_mut()
|
||||
} else {
|
||||
panic!("Cannot extract dict elements");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_item(
|
||||
@@ -309,12 +305,16 @@ fn dict_getitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
pub fn create_type(type_type: PyObjectRef, object_type: PyObjectRef, dict_type: PyObjectRef) {
|
||||
(*dict_type.borrow_mut()).payload = PyObjectPayload::Class {
|
||||
name: String::from("dict"),
|
||||
dict: RefCell::new(HashMap::new()),
|
||||
mro: vec![object_type],
|
||||
};
|
||||
(*dict_type.borrow_mut()).typ = Some(type_type.clone());
|
||||
// this is not ideal
|
||||
let ptr = PyObjectRef::into_raw(dict_type.clone()) as *mut PyObject;
|
||||
unsafe {
|
||||
(*ptr).payload = PyObjectPayload::Class {
|
||||
name: String::from("dict"),
|
||||
dict: RefCell::new(HashMap::new()),
|
||||
mro: vec![object_type],
|
||||
};
|
||||
(*ptr).typ = Some(type_type.clone());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
use std::cell::RefCell;
|
||||
use std::ops::AddAssign;
|
||||
|
||||
use super::objint;
|
||||
use super::objiter;
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_bigint::BigInt;
|
||||
use num_traits::Zero;
|
||||
use std::ops::AddAssign;
|
||||
|
||||
fn enumerate_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
@@ -20,7 +22,10 @@ fn enumerate_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
};
|
||||
let iterator = objiter::get_iter(vm, iterable)?;
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::EnumerateIterator { counter, iterator },
|
||||
PyObjectPayload::EnumerateIterator {
|
||||
counter: RefCell::new(counter),
|
||||
iterator,
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
}
|
||||
@@ -33,16 +38,16 @@ fn enumerate_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
);
|
||||
|
||||
if let PyObjectPayload::EnumerateIterator {
|
||||
ref mut counter,
|
||||
ref mut iterator,
|
||||
} = enumerate.borrow_mut().payload
|
||||
ref counter,
|
||||
ref iterator,
|
||||
} = enumerate.payload
|
||||
{
|
||||
let next_obj = objiter::call_next(vm, iterator)?;
|
||||
let result = vm
|
||||
.ctx
|
||||
.new_tuple(vec![vm.ctx.new_int(counter.clone()), next_obj]);
|
||||
.new_tuple(vec![vm.ctx.new_int(counter.borrow().clone()), next_obj]);
|
||||
|
||||
AddAssign::add_assign(counter, 1);
|
||||
AddAssign::add_assign(&mut counter.borrow_mut() as &mut BigInt, 1);
|
||||
|
||||
Ok(result)
|
||||
} else {
|
||||
|
||||
@@ -25,9 +25,9 @@ fn filter_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(filter, Some(vm.ctx.filter_type()))]);
|
||||
|
||||
if let PyObjectPayload::FilterIterator {
|
||||
ref mut predicate,
|
||||
ref mut iterator,
|
||||
} = filter.borrow_mut().payload
|
||||
ref predicate,
|
||||
ref iterator,
|
||||
} = filter.payload
|
||||
{
|
||||
loop {
|
||||
let next_obj = objiter::call_next(vm, iterator)?;
|
||||
|
||||
@@ -61,7 +61,7 @@ fn float_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
// Retrieve inner float value:
|
||||
pub fn get_value(obj: &PyObjectRef) -> f64 {
|
||||
if let PyObjectPayload::Float { value } = &obj.borrow().payload {
|
||||
if let PyObjectPayload::Float { value } = &obj.payload {
|
||||
*value
|
||||
} else {
|
||||
panic!("Inner error getting float");
|
||||
@@ -81,12 +81,12 @@ pub fn make_float(vm: &mut VirtualMachine, obj: &PyObjectRef) -> Result<f64, PyO
|
||||
)?;
|
||||
Ok(get_value(&res))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot cast {} to float", obj.borrow())))
|
||||
Err(vm.new_type_error(format!("Cannot cast {} to float", obj)))
|
||||
}
|
||||
}
|
||||
|
||||
fn set_value(obj: &PyObjectRef, value: f64) {
|
||||
obj.borrow_mut().payload = PyObjectPayload::Float { value };
|
||||
//obj.payload = PyObjectPayload::Float { value }; // FIXME
|
||||
}
|
||||
|
||||
fn float_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
@@ -31,7 +31,6 @@ fn frame_flocals(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(frame, Some(vm.ctx.frame_type()))]);
|
||||
let frame = get_value(frame);
|
||||
let py_scope = frame.locals.clone();
|
||||
let py_scope = py_scope.borrow();
|
||||
|
||||
if let PyObjectPayload::Scope { scope } = &py_scope.payload {
|
||||
Ok(scope.locals.clone())
|
||||
@@ -46,7 +45,7 @@ fn frame_fcode(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
pub fn get_value(obj: &PyObjectRef) -> Frame {
|
||||
if let PyObjectPayload::Frame { frame } = &obj.borrow().payload {
|
||||
if let PyObjectPayload::Frame { frame } = &obj.payload {
|
||||
frame.clone()
|
||||
} else {
|
||||
panic!("Inner error getting int {:?}", obj);
|
||||
|
||||
@@ -67,7 +67,7 @@ fn bind_method(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
fn function_code(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
match args.args[0].borrow().payload {
|
||||
match args.args[0].payload {
|
||||
PyObjectPayload::Function { ref code, .. } => Ok(code.clone()),
|
||||
_ => Err(vm.new_type_error("no code".to_string())),
|
||||
}
|
||||
|
||||
@@ -56,16 +56,17 @@ fn generator_send(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
fn send(vm: &mut VirtualMachine, gen: &PyObjectRef, value: &PyObjectRef) -> PyResult {
|
||||
if let PyObjectPayload::Generator { ref mut frame } = gen.borrow_mut().payload {
|
||||
frame.push_value(value.clone());
|
||||
match frame.run_frame(vm)? {
|
||||
ExecutionResult::Yield(value) => Ok(value),
|
||||
ExecutionResult::Return(_value) => {
|
||||
// Stop iteration!
|
||||
let stop_iteration = vm.ctx.exceptions.stop_iteration.clone();
|
||||
Err(vm.new_exception(stop_iteration, "End of generator".to_string()))
|
||||
}
|
||||
}
|
||||
if let PyObjectPayload::Generator { ref frame } = gen.payload {
|
||||
//frame.push_value(value.clone());
|
||||
//match frame.run_frame(vm)? {
|
||||
// ExecutionResult::Yield(value) => Ok(value),
|
||||
// ExecutionResult::Return(_value) => {
|
||||
// // Stop iteration!
|
||||
// let stop_iteration = vm.ctx.exceptions.stop_iteration.clone();
|
||||
// Err(vm.new_exception(stop_iteration, "End of generator".to_string()))
|
||||
// }
|
||||
//}
|
||||
unimplemented!("FIXME")
|
||||
} else {
|
||||
panic!("Cannot extract frame from non-generator");
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ pub fn to_int(
|
||||
|
||||
// Retrieve inner int value:
|
||||
pub fn get_value(obj: &PyObjectRef) -> IntType {
|
||||
if let PyObjectPayload::Integer { value } = &obj.borrow().payload {
|
||||
if let PyObjectPayload::Integer { value } = &obj.payload {
|
||||
value.clone()
|
||||
} else {
|
||||
panic!("Inner error getting int {:?}", obj);
|
||||
|
||||
@@ -128,16 +128,15 @@ fn iter_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(iter, Some(vm.ctx.iter_type()))]);
|
||||
|
||||
if let PyObjectPayload::Iterator {
|
||||
ref mut position,
|
||||
iterated_obj: ref mut iterated_obj_ref,
|
||||
} = iter.borrow_mut().payload
|
||||
ref position,
|
||||
iterated_obj: ref iterated_obj_ref,
|
||||
} = iter.payload
|
||||
{
|
||||
let iterated_obj = iterated_obj_ref.borrow_mut();
|
||||
match iterated_obj.payload {
|
||||
match iterated_obj_ref.payload {
|
||||
PyObjectPayload::Sequence { ref elements } => {
|
||||
if *position < elements.len() {
|
||||
let obj_ref = elements[*position].clone();
|
||||
*position += 1;
|
||||
if *position < elements.borrow().len() {
|
||||
let obj_ref = elements.borrow()[*position].clone();
|
||||
//*position += 1; // FIXME
|
||||
Ok(obj_ref)
|
||||
} else {
|
||||
Err(new_stop_iteration(vm))
|
||||
@@ -146,7 +145,7 @@ fn iter_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
PyObjectPayload::Range { ref range } => {
|
||||
if let Some(int) = range.get(*position) {
|
||||
*position += 1;
|
||||
//*position += 1; // FIXME
|
||||
Ok(vm.ctx.new_int(int))
|
||||
} else {
|
||||
Err(new_stop_iteration(vm))
|
||||
@@ -154,9 +153,9 @@ fn iter_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
PyObjectPayload::Bytes { ref value } => {
|
||||
if *position < value.len() {
|
||||
let obj_ref = vm.ctx.new_int(value[*position]);
|
||||
*position += 1;
|
||||
if *position < value.borrow().len() {
|
||||
let obj_ref = vm.ctx.new_int(value.borrow()[*position]);
|
||||
// *position += 1; // FIXME
|
||||
Ok(obj_ref)
|
||||
} else {
|
||||
Err(new_stop_iteration(vm))
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::cell::RefCell;
|
||||
|
||||
use super::objbool;
|
||||
use super::objint;
|
||||
use super::objsequence::{
|
||||
@@ -55,7 +57,9 @@ fn list_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
};
|
||||
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Sequence { elements },
|
||||
PyObjectPayload::Sequence {
|
||||
elements: RefCell::new(elements),
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
}
|
||||
@@ -93,11 +97,7 @@ fn list_lt(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let other = get_elements(other);
|
||||
seq_lt(vm, &zelf, &other)?
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Cannot compare {} and {} using '<'",
|
||||
zelf.borrow(),
|
||||
other.borrow()
|
||||
)));
|
||||
return Err(vm.new_type_error(format!("Cannot compare {} and {} using '<'", zelf, other)));
|
||||
};
|
||||
|
||||
Ok(vm.ctx.new_bool(result))
|
||||
@@ -115,11 +115,7 @@ fn list_gt(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let other = get_elements(other);
|
||||
seq_gt(vm, &zelf, &other)?
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Cannot compare {} and {} using '>'",
|
||||
zelf.borrow(),
|
||||
other.borrow()
|
||||
)));
|
||||
return Err(vm.new_type_error(format!("Cannot compare {} and {} using '>'", zelf, other)));
|
||||
};
|
||||
|
||||
Ok(vm.ctx.new_bool(result))
|
||||
@@ -137,11 +133,7 @@ fn list_ge(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let other = get_elements(other);
|
||||
seq_ge(vm, &zelf, &other)?
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Cannot compare {} and {} using '>='",
|
||||
zelf.borrow(),
|
||||
other.borrow()
|
||||
)));
|
||||
return Err(vm.new_type_error(format!("Cannot compare {} and {} using '>='", zelf, other)));
|
||||
};
|
||||
|
||||
Ok(vm.ctx.new_bool(result))
|
||||
@@ -159,11 +151,7 @@ fn list_le(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let other = get_elements(other);
|
||||
seq_le(vm, &zelf, &other)?
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Cannot compare {} and {} using '<='",
|
||||
zelf.borrow(),
|
||||
other.borrow()
|
||||
)));
|
||||
return Err(vm.new_type_error(format!("Cannot compare {} and {} using '<='", zelf, other)));
|
||||
};
|
||||
|
||||
Ok(vm.ctx.new_bool(result))
|
||||
@@ -182,7 +170,7 @@ fn list_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let elements = e1.iter().chain(e2.iter()).cloned().collect();
|
||||
Ok(vm.ctx.new_list(elements))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot add {} and {}", o.borrow(), o2.borrow())))
|
||||
Err(vm.new_type_error(format!("Cannot add {} and {}", o, o2)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,9 +28,9 @@ fn map_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(map, Some(vm.ctx.map_type()))]);
|
||||
|
||||
if let PyObjectPayload::MapIterator {
|
||||
ref mut mapper,
|
||||
ref mut iterators,
|
||||
} = map.borrow_mut().payload
|
||||
ref mapper,
|
||||
ref iterators,
|
||||
} = map.payload
|
||||
{
|
||||
let next_objs = iterators
|
||||
.iter()
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use super::objstr;
|
||||
use super::objtype;
|
||||
use crate::pyobject::{
|
||||
AttributeProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectPayload, PyObjectRef, PyResult,
|
||||
TypeProtocol,
|
||||
AttributeProtocol, IdProtocol, PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef,
|
||||
PyResult, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use std::cell::RefCell;
|
||||
@@ -16,12 +16,16 @@ pub fn new_instance(vm: &mut VirtualMachine, mut args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
pub fn create_object(type_type: PyObjectRef, object_type: PyObjectRef, _dict_type: PyObjectRef) {
|
||||
(*object_type.borrow_mut()).payload = PyObjectPayload::Class {
|
||||
name: String::from("object"),
|
||||
dict: RefCell::new(HashMap::new()),
|
||||
mro: vec![],
|
||||
};
|
||||
(*object_type.borrow_mut()).typ = Some(type_type.clone());
|
||||
// this is not ideal
|
||||
let ptr = PyObjectRef::into_raw(object_type.clone()) as *mut PyObject;
|
||||
unsafe {
|
||||
(*ptr).payload = PyObjectPayload::Class {
|
||||
name: String::from("object"),
|
||||
dict: RefCell::new(HashMap::new()),
|
||||
mro: vec![],
|
||||
};
|
||||
(*ptr).typ = Some(type_type.clone());
|
||||
}
|
||||
}
|
||||
|
||||
fn object_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -101,7 +105,7 @@ fn object_delattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
]
|
||||
);
|
||||
|
||||
match zelf.borrow().payload {
|
||||
match zelf.payload {
|
||||
PyObjectPayload::Class { ref dict, .. } | PyObjectPayload::Instance { ref dict, .. } => {
|
||||
let attr_name = objstr::get_value(attr);
|
||||
dict.borrow_mut().remove(&attr_name);
|
||||
@@ -174,7 +178,7 @@ fn object_init(vm: &mut VirtualMachine, _args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
fn object_dict(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
match args.args[0].borrow().payload {
|
||||
match args.args[0].payload {
|
||||
PyObjectPayload::Class { ref dict, .. } | PyObjectPayload::Instance { ref dict, .. } => {
|
||||
let new_dict = vm.new_dict();
|
||||
for (attr, value) in dict.borrow().iter() {
|
||||
@@ -230,7 +234,7 @@ fn object_getattribute(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let attribute_error = vm.context().exceptions.attribute_error.clone();
|
||||
Err(vm.new_exception(
|
||||
attribute_error,
|
||||
format!("{} has no attribute '{}'", obj.borrow(), name),
|
||||
format!("{} has no attribute '{}'", obj, name),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ impl RangeType {
|
||||
}
|
||||
|
||||
pub fn get_value(obj: &PyObjectRef) -> RangeType {
|
||||
if let PyObjectPayload::Range { range } = &obj.borrow().payload {
|
||||
if let PyObjectPayload::Range { range } = &obj.payload {
|
||||
range.clone()
|
||||
} else {
|
||||
panic!("Inner error getting range {:?}", obj);
|
||||
@@ -287,7 +287,7 @@ fn range_getitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
let range = get_value(zelf);
|
||||
|
||||
match subscript.borrow().payload {
|
||||
match subscript.payload {
|
||||
PyObjectPayload::Integer { ref value } => {
|
||||
if let Some(int) = range.get(value) {
|
||||
Ok(vm.ctx.new_int(int))
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use std::cell::RefCell;
|
||||
use std::marker::Sized;
|
||||
use std::ops::{Deref, DerefMut, Range};
|
||||
|
||||
use super::objbool;
|
||||
use super::objint;
|
||||
use crate::pyobject::{IdProtocol, PyObject, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_bigint::BigInt;
|
||||
use num_traits::{One, Signed, ToPrimitive, Zero};
|
||||
use std::cell::{Ref, RefMut};
|
||||
use std::marker::Sized;
|
||||
use std::ops::{Deref, DerefMut, Range};
|
||||
|
||||
pub trait PySliceableSequence {
|
||||
fn do_slice(&self, range: Range<usize>) -> Self;
|
||||
@@ -64,7 +65,7 @@ pub trait PySliceableSequence {
|
||||
Self: Sized,
|
||||
{
|
||||
// TODO: we could potentially avoid this copy and use slice
|
||||
match &(slice.borrow()).payload {
|
||||
match &slice.payload {
|
||||
PyObjectPayload::Slice { start, stop, step } => {
|
||||
let step = step.clone().unwrap_or_else(BigInt::one);
|
||||
if step.is_zero() {
|
||||
@@ -140,7 +141,7 @@ pub fn get_item(
|
||||
elements: &[PyObjectRef],
|
||||
subscript: PyObjectRef,
|
||||
) -> PyResult {
|
||||
match &(subscript.borrow()).payload {
|
||||
match &subscript.payload {
|
||||
PyObjectPayload::Integer { value } => match value.to_i32() {
|
||||
Some(value) => {
|
||||
if let Some(pos_index) = elements.to_vec().get_pos(value) {
|
||||
@@ -156,9 +157,9 @@ pub fn get_item(
|
||||
},
|
||||
|
||||
PyObjectPayload::Slice { .. } => Ok(PyObject::new(
|
||||
match &(sequence.borrow()).payload {
|
||||
match &sequence.payload {
|
||||
PyObjectPayload::Sequence { .. } => PyObjectPayload::Sequence {
|
||||
elements: elements.to_vec().get_slice_items(vm, &subscript)?,
|
||||
elements: RefCell::new(elements.to_vec().get_slice_items(vm, &subscript)?),
|
||||
},
|
||||
ref payload => panic!("sequence get_item called for non-sequence: {:?}", payload),
|
||||
},
|
||||
@@ -302,23 +303,19 @@ pub fn seq_mul(elements: &[PyObjectRef], product: &PyObjectRef) -> Vec<PyObjectR
|
||||
}
|
||||
|
||||
pub fn get_elements<'a>(obj: &'a PyObjectRef) -> impl Deref<Target = Vec<PyObjectRef>> + 'a {
|
||||
Ref::map(obj.borrow(), |x| {
|
||||
if let PyObjectPayload::Sequence { ref elements } = x.payload {
|
||||
elements
|
||||
} else {
|
||||
panic!("Cannot extract elements from non-sequence");
|
||||
}
|
||||
})
|
||||
if let PyObjectPayload::Sequence { ref elements } = obj.payload {
|
||||
elements.borrow()
|
||||
} else {
|
||||
panic!("Cannot extract elements from non-sequence");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mut_elements<'a>(obj: &'a PyObjectRef) -> impl DerefMut<Target = Vec<PyObjectRef>> + 'a {
|
||||
RefMut::map(obj.borrow_mut(), |x| {
|
||||
if let PyObjectPayload::Sequence { ref mut elements } = x.payload {
|
||||
elements
|
||||
} else {
|
||||
panic!("Cannot extract list elements from non-sequence");
|
||||
// TODO: raise proper error?
|
||||
// Err(vm.new_type_error("list.append is called with no list".to_string()))
|
||||
}
|
||||
})
|
||||
if let PyObjectPayload::Sequence { ref elements } = obj.payload {
|
||||
elements.borrow_mut()
|
||||
} else {
|
||||
panic!("Cannot extract list elements from non-sequence");
|
||||
// TODO: raise proper error?
|
||||
// Err(vm.new_type_error("list.append is called with no list".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
* Builtin set type with a sequence of unique items.
|
||||
*/
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use super::objbool;
|
||||
use super::objint;
|
||||
use super::objiter;
|
||||
@@ -11,13 +16,10 @@ use crate::pyobject::{
|
||||
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
pub fn get_elements(obj: &PyObjectRef) -> HashMap<u64, PyObjectRef> {
|
||||
if let PyObjectPayload::Set { elements } = &obj.borrow().payload {
|
||||
elements.clone()
|
||||
if let PyObjectPayload::Set { elements } = &obj.payload {
|
||||
elements.borrow().clone()
|
||||
} else {
|
||||
panic!("Cannot extract set elements from non-set");
|
||||
}
|
||||
@@ -62,10 +64,10 @@ fn set_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
args,
|
||||
required = [(s, Some(vm.ctx.set_type())), (item, None)]
|
||||
);
|
||||
let mut mut_obj = s.borrow_mut();
|
||||
|
||||
match mut_obj.payload {
|
||||
PyObjectPayload::Set { ref mut elements } => insert_into_set(vm, elements, item),
|
||||
match s.payload {
|
||||
PyObjectPayload::Set { ref elements } => {
|
||||
insert_into_set(vm, &mut elements.borrow_mut(), item)
|
||||
}
|
||||
_ => Err(vm.new_type_error("set.add is called with no item".to_string())),
|
||||
}
|
||||
}
|
||||
@@ -77,10 +79,8 @@ fn set_remove(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
args,
|
||||
required = [(s, Some(vm.ctx.set_type())), (item, None)]
|
||||
);
|
||||
let mut mut_obj = s.borrow_mut();
|
||||
|
||||
match mut_obj.payload {
|
||||
PyObjectPayload::Set { ref mut elements } => {
|
||||
match s.payload {
|
||||
PyObjectPayload::Set { ref elements } => {
|
||||
fn remove(
|
||||
vm: &mut VirtualMachine,
|
||||
elements: &mut HashMap<u64, PyObjectRef>,
|
||||
@@ -89,13 +89,13 @@ fn set_remove(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
) -> PyResult {
|
||||
match elements.remove(&key) {
|
||||
None => {
|
||||
let item_str = format!("{:?}", value.borrow());
|
||||
let item_str = format!("{:?}", value);
|
||||
Err(vm.new_key_error(item_str))
|
||||
}
|
||||
Some(_) => Ok(vm.get_none()),
|
||||
}
|
||||
}
|
||||
perform_action_with_hash(vm, elements, item, &remove)
|
||||
perform_action_with_hash(vm, &mut elements.borrow_mut(), item, &remove)
|
||||
}
|
||||
_ => Err(vm.new_type_error("set.remove is called with no item".to_string())),
|
||||
}
|
||||
@@ -108,10 +108,8 @@ fn set_discard(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
args,
|
||||
required = [(s, Some(vm.ctx.set_type())), (item, None)]
|
||||
);
|
||||
let mut mut_obj = s.borrow_mut();
|
||||
|
||||
match mut_obj.payload {
|
||||
PyObjectPayload::Set { ref mut elements } => {
|
||||
match s.payload {
|
||||
PyObjectPayload::Set { ref elements } => {
|
||||
fn discard(
|
||||
vm: &mut VirtualMachine,
|
||||
elements: &mut HashMap<u64, PyObjectRef>,
|
||||
@@ -121,7 +119,7 @@ fn set_discard(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
elements.remove(&key);
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
perform_action_with_hash(vm, elements, item, &discard)
|
||||
perform_action_with_hash(vm, &mut elements.borrow_mut(), item, &discard)
|
||||
}
|
||||
_ => Err(vm.new_type_error("set.discard is called with no item".to_string())),
|
||||
}
|
||||
@@ -130,10 +128,9 @@ fn set_discard(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
fn set_clear(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
trace!("set.clear called");
|
||||
arg_check!(vm, args, required = [(s, Some(vm.ctx.set_type()))]);
|
||||
let mut mut_obj = s.borrow_mut();
|
||||
match mut_obj.payload {
|
||||
PyObjectPayload::Set { ref mut elements } => {
|
||||
elements.clear();
|
||||
match s.payload {
|
||||
PyObjectPayload::Set { ref elements } => {
|
||||
elements.borrow_mut().clear();
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
_ => Err(vm.new_type_error("".to_string())),
|
||||
@@ -150,7 +147,7 @@ fn set_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
);
|
||||
|
||||
if !objtype::issubclass(cls, &vm.ctx.set_type()) {
|
||||
return Err(vm.new_type_error(format!("{} is not a subtype of set", cls.borrow())));
|
||||
return Err(vm.new_type_error(format!("{} is not a subtype of set", cls)));
|
||||
}
|
||||
|
||||
let elements: HashMap<u64, PyObjectRef> = match iterable {
|
||||
@@ -166,7 +163,9 @@ fn set_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
};
|
||||
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Set { elements },
|
||||
PyObjectPayload::Set {
|
||||
elements: RefCell::new(elements),
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
}
|
||||
@@ -183,7 +182,9 @@ fn set_copy(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(s, Some(vm.ctx.set_type()))]);
|
||||
let elements = get_elements(s);
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Set { elements },
|
||||
PyObjectPayload::Set {
|
||||
elements: RefCell::new(elements),
|
||||
},
|
||||
vm.ctx.set_type(),
|
||||
))
|
||||
}
|
||||
@@ -335,7 +336,9 @@ fn set_union(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
elements.extend(get_elements(other).clone());
|
||||
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Set { elements },
|
||||
PyObjectPayload::Set {
|
||||
elements: RefCell::new(elements),
|
||||
},
|
||||
vm.ctx.set_type(),
|
||||
))
|
||||
}
|
||||
@@ -375,7 +378,9 @@ fn set_symmetric_difference(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResu
|
||||
}
|
||||
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Set { elements },
|
||||
PyObjectPayload::Set {
|
||||
elements: RefCell::new(elements),
|
||||
},
|
||||
vm.ctx.set_type(),
|
||||
))
|
||||
}
|
||||
@@ -413,7 +418,9 @@ fn set_combine_inner(
|
||||
}
|
||||
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Set { elements },
|
||||
PyObjectPayload::Set {
|
||||
elements: RefCell::new(elements),
|
||||
},
|
||||
vm.ctx.set_type(),
|
||||
))
|
||||
}
|
||||
@@ -421,11 +428,9 @@ fn set_combine_inner(
|
||||
fn set_pop(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(s, Some(vm.ctx.set_type()))]);
|
||||
|
||||
let mut mut_obj = s.borrow_mut();
|
||||
|
||||
match mut_obj.payload {
|
||||
PyObjectPayload::Set { ref mut elements } => match elements.clone().keys().next() {
|
||||
Some(key) => Ok(elements.remove(key).unwrap()),
|
||||
match s.payload {
|
||||
PyObjectPayload::Set { ref elements } => match elements.borrow().clone().keys().next() {
|
||||
Some(key) => Ok(elements.borrow_mut().remove(key).unwrap()),
|
||||
None => Err(vm.new_key_error("pop from an empty set".to_string())),
|
||||
},
|
||||
_ => Err(vm.new_type_error("".to_string())),
|
||||
@@ -444,13 +449,11 @@ fn set_ior(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
required = [(zelf, Some(vm.ctx.set_type())), (iterable, None)]
|
||||
);
|
||||
|
||||
let mut mut_obj = zelf.borrow_mut();
|
||||
|
||||
match mut_obj.payload {
|
||||
PyObjectPayload::Set { ref mut elements } => {
|
||||
match zelf.payload {
|
||||
PyObjectPayload::Set { ref elements } => {
|
||||
let iterator = objiter::get_iter(vm, iterable)?;
|
||||
while let Ok(v) = vm.call_method(&iterator, "__next__", vec![]) {
|
||||
insert_into_set(vm, elements, &v)?;
|
||||
insert_into_set(vm, &mut elements.borrow_mut(), &v)?;
|
||||
}
|
||||
}
|
||||
_ => return Err(vm.new_type_error("set.update is called with no other".to_string())),
|
||||
@@ -487,18 +490,16 @@ fn set_combine_update_inner(
|
||||
required = [(zelf, Some(vm.ctx.set_type())), (iterable, None)]
|
||||
);
|
||||
|
||||
let mut mut_obj = zelf.borrow_mut();
|
||||
|
||||
match mut_obj.payload {
|
||||
PyObjectPayload::Set { ref mut elements } => {
|
||||
for element in elements.clone().iter() {
|
||||
match zelf.payload {
|
||||
PyObjectPayload::Set { ref elements } => {
|
||||
for element in elements.borrow().clone().iter() {
|
||||
let value = vm.call_method(iterable, "__contains__", vec![element.1.clone()])?;
|
||||
let should_remove = match op {
|
||||
SetCombineOperation::Intersection => !objbool::get_value(&value),
|
||||
SetCombineOperation::Difference => objbool::get_value(&value),
|
||||
};
|
||||
if should_remove {
|
||||
elements.remove(&element.0.clone());
|
||||
elements.borrow_mut().remove(&element.0.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -519,19 +520,17 @@ fn set_ixor(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
required = [(zelf, Some(vm.ctx.set_type())), (iterable, None)]
|
||||
);
|
||||
|
||||
let mut mut_obj = zelf.borrow_mut();
|
||||
|
||||
match mut_obj.payload {
|
||||
PyObjectPayload::Set { ref mut elements } => {
|
||||
let elements_original = elements.clone();
|
||||
match zelf.payload {
|
||||
PyObjectPayload::Set { ref elements } => {
|
||||
let elements_original = elements.borrow().clone();
|
||||
let iterator = objiter::get_iter(vm, iterable)?;
|
||||
while let Ok(v) = vm.call_method(&iterator, "__next__", vec![]) {
|
||||
insert_into_set(vm, elements, &v)?;
|
||||
insert_into_set(vm, &mut elements.borrow_mut(), &v)?;
|
||||
}
|
||||
for element in elements_original.iter() {
|
||||
let value = vm.call_method(iterable, "__contains__", vec![element.1.clone()])?;
|
||||
if objbool::get_value(&value) {
|
||||
elements.remove(&element.0.clone());
|
||||
elements.borrow_mut().remove(&element.0.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ fn get_property_value(vm: &mut VirtualMachine, value: &Option<BigInt>) -> PyResu
|
||||
|
||||
fn slice_start(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(slice, Some(vm.ctx.slice_type()))]);
|
||||
if let PyObjectPayload::Slice { start, .. } = &slice.borrow().payload {
|
||||
if let PyObjectPayload::Slice { start, .. } = &slice.payload {
|
||||
get_property_value(vm, start)
|
||||
} else {
|
||||
panic!("Slice has incorrect payload.");
|
||||
@@ -68,7 +68,7 @@ fn slice_start(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
fn slice_stop(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(slice, Some(vm.ctx.slice_type()))]);
|
||||
if let PyObjectPayload::Slice { stop, .. } = &slice.borrow().payload {
|
||||
if let PyObjectPayload::Slice { stop, .. } = &slice.payload {
|
||||
get_property_value(vm, stop)
|
||||
} else {
|
||||
panic!("Slice has incorrect payload.");
|
||||
@@ -77,7 +77,7 @@ fn slice_stop(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
fn slice_step(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(slice, Some(vm.ctx.slice_type()))]);
|
||||
if let PyObjectPayload::Slice { step, .. } = &slice.borrow().payload {
|
||||
if let PyObjectPayload::Slice { step, .. } = &slice.payload {
|
||||
get_property_value(vm, step)
|
||||
} else {
|
||||
panic!("Slice has incorrect payload.");
|
||||
|
||||
@@ -3,12 +3,10 @@ use super::objsequence::PySliceableSequence;
|
||||
use super::objtype;
|
||||
use crate::format::{FormatParseError, FormatPart, FormatString};
|
||||
use crate::pyobject::{
|
||||
FromPyObject, PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef, PyResult,
|
||||
TypeProtocol,
|
||||
FromPyObject, PyContext, PyFuncArgs, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
|
||||
};
|
||||
use crate::vm::VirtualMachine;
|
||||
use num_traits::ToPrimitive;
|
||||
use std::cell::Ref;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Range;
|
||||
use std::str::FromStr;
|
||||
@@ -115,21 +113,19 @@ pub fn init(context: &PyContext) {
|
||||
}
|
||||
|
||||
pub fn get_value(obj: &PyObjectRef) -> String {
|
||||
if let PyObjectPayload::String { value } = &obj.borrow().payload {
|
||||
if let PyObjectPayload::String { value } = &obj.payload {
|
||||
value.to_string()
|
||||
} else {
|
||||
panic!("Inner error getting str");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn borrow_value(obj: &PyObjectRef) -> Ref<str> {
|
||||
Ref::map(obj.borrow(), |py_obj| {
|
||||
if let PyObjectPayload::String { value } = &py_obj.payload {
|
||||
value.as_ref()
|
||||
} else {
|
||||
panic!("Inner error getting str");
|
||||
}
|
||||
})
|
||||
pub fn borrow_value(obj: &PyObjectRef) -> &str {
|
||||
if let PyObjectPayload::String { value } = &obj.payload {
|
||||
value.as_str()
|
||||
} else {
|
||||
panic!("Inner error getting str");
|
||||
}
|
||||
}
|
||||
|
||||
fn str_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
@@ -158,7 +154,7 @@ fn str_gt(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
if objtype::isinstance(i2, &vm.ctx.str_type()) {
|
||||
Ok(vm.ctx.new_bool(v1 > get_value(i2)))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot compare {} and {}", i.borrow(), i2.borrow())))
|
||||
Err(vm.new_type_error(format!("Cannot compare {} and {}", i, i2)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +169,7 @@ fn str_ge(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
if objtype::isinstance(i2, &vm.ctx.str_type()) {
|
||||
Ok(vm.ctx.new_bool(v1 >= get_value(i2)))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot compare {} and {}", i.borrow(), i2.borrow())))
|
||||
Err(vm.new_type_error(format!("Cannot compare {} and {}", i, i2)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +184,7 @@ fn str_lt(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
if objtype::isinstance(i2, &vm.ctx.str_type()) {
|
||||
Ok(vm.ctx.new_bool(v1 < get_value(i2)))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot compare {} and {}", i.borrow(), i2.borrow())))
|
||||
Err(vm.new_type_error(format!("Cannot compare {} and {}", i, i2)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +199,7 @@ fn str_le(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
if objtype::isinstance(i2, &vm.ctx.str_type()) {
|
||||
Ok(vm.ctx.new_bool(v1 <= get_value(i2)))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot compare {} and {}", i.borrow(), i2.borrow())))
|
||||
Err(vm.new_type_error(format!("Cannot compare {} and {}", i, i2)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +254,7 @@ fn str_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
.ctx
|
||||
.new_str(format!("{}{}", get_value(&s), get_value(&s2))))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!("Cannot add {} and {}", s.borrow(), s2.borrow())))
|
||||
Err(vm.new_type_error(format!("Cannot add {} and {}", s, s2)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,11 +383,7 @@ fn str_mul(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
Ok(vm.ctx.new_str(result))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!(
|
||||
"Cannot multiply {} and {}",
|
||||
s.borrow(),
|
||||
s2.borrow()
|
||||
)))
|
||||
Err(vm.new_type_error(format!("Cannot multiply {} and {}", s, s2)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1115,7 +1107,7 @@ pub fn subscript(vm: &mut VirtualMachine, value: &str, b: PyObjectRef) -> PyResu
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match (*b.borrow()).payload {
|
||||
match b.payload {
|
||||
PyObjectPayload::Slice { .. } => {
|
||||
let string = value.to_string().get_slice_items(vm, &b)?;
|
||||
Ok(vm.new_str(string))
|
||||
@@ -1130,8 +1122,8 @@ pub fn subscript(vm: &mut VirtualMachine, value: &str, b: PyObjectRef) -> PyResu
|
||||
|
||||
// help get optional string indices
|
||||
fn get_slice(
|
||||
start: Option<&std::rc::Rc<std::cell::RefCell<PyObject>>>,
|
||||
end: Option<&std::rc::Rc<std::cell::RefCell<PyObject>>>,
|
||||
start: Option<&PyObjectRef>,
|
||||
end: Option<&PyObjectRef>,
|
||||
len: usize,
|
||||
) -> Result<(usize, usize), String> {
|
||||
let start_idx = match start {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use std::cell::RefCell;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
use super::objbool;
|
||||
use super::objint;
|
||||
use super::objsequence::{
|
||||
@@ -7,7 +10,6 @@ use super::objstr;
|
||||
use super::objtype;
|
||||
use crate::pyobject::{PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyResult, TypeProtocol};
|
||||
use crate::vm::{ReprGuard, VirtualMachine};
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
||||
fn tuple_lt(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(
|
||||
@@ -21,11 +23,7 @@ fn tuple_lt(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let other = get_elements(other);
|
||||
seq_lt(vm, &zelf, &other)?
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Cannot compare {} and {} using '<'",
|
||||
zelf.borrow(),
|
||||
other.borrow()
|
||||
)));
|
||||
return Err(vm.new_type_error(format!("Cannot compare {} and {} using '<'", zelf, other)));
|
||||
};
|
||||
|
||||
Ok(vm.ctx.new_bool(result))
|
||||
@@ -43,11 +41,7 @@ fn tuple_gt(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let other = get_elements(other);
|
||||
seq_gt(vm, &zelf, &other)?
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Cannot compare {} and {} using '>'",
|
||||
zelf.borrow(),
|
||||
other.borrow()
|
||||
)));
|
||||
return Err(vm.new_type_error(format!("Cannot compare {} and {} using '>'", zelf, other)));
|
||||
};
|
||||
|
||||
Ok(vm.ctx.new_bool(result))
|
||||
@@ -65,11 +59,7 @@ fn tuple_ge(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let other = get_elements(other);
|
||||
seq_ge(vm, &zelf, &other)?
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Cannot compare {} and {} using '>='",
|
||||
zelf.borrow(),
|
||||
other.borrow()
|
||||
)));
|
||||
return Err(vm.new_type_error(format!("Cannot compare {} and {} using '>='", zelf, other)));
|
||||
};
|
||||
|
||||
Ok(vm.ctx.new_bool(result))
|
||||
@@ -87,11 +77,7 @@ fn tuple_le(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let other = get_elements(other);
|
||||
seq_le(vm, &zelf, &other)?
|
||||
} else {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"Cannot compare {} and {} using '<='",
|
||||
zelf.borrow(),
|
||||
other.borrow()
|
||||
)));
|
||||
return Err(vm.new_type_error(format!("Cannot compare {} and {} using '<='", zelf, other)));
|
||||
};
|
||||
|
||||
Ok(vm.ctx.new_bool(result))
|
||||
@@ -110,11 +96,7 @@ fn tuple_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
let elements = e1.iter().chain(e2.iter()).cloned().collect();
|
||||
Ok(vm.ctx.new_tuple(elements))
|
||||
} else {
|
||||
Err(vm.new_type_error(format!(
|
||||
"Cannot add {} and {}",
|
||||
zelf.borrow(),
|
||||
other.borrow()
|
||||
)))
|
||||
Err(vm.new_type_error(format!("Cannot add {} and {}", zelf, other)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +175,7 @@ fn tuple_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
);
|
||||
|
||||
if !objtype::issubclass(cls, &vm.ctx.tuple_type()) {
|
||||
return Err(vm.new_type_error(format!("{} is not a subtype of tuple", cls.borrow())));
|
||||
return Err(vm.new_type_error(format!("{} is not a subtype of tuple", cls)));
|
||||
}
|
||||
|
||||
let elements = if let Some(iterable) = iterable {
|
||||
@@ -203,7 +185,9 @@ fn tuple_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
};
|
||||
|
||||
Ok(PyObject::new(
|
||||
PyObjectPayload::Sequence { elements },
|
||||
PyObjectPayload::Sequence {
|
||||
elements: RefCell::new(elements),
|
||||
},
|
||||
cls.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -14,12 +14,16 @@ use std::collections::HashMap;
|
||||
*/
|
||||
|
||||
pub fn create_type(type_type: PyObjectRef, object_type: PyObjectRef, _dict_type: PyObjectRef) {
|
||||
(*type_type.borrow_mut()).payload = PyObjectPayload::Class {
|
||||
name: String::from("type"),
|
||||
dict: RefCell::new(PyAttributes::new()),
|
||||
mro: vec![object_type],
|
||||
};
|
||||
(*type_type.borrow_mut()).typ = Some(type_type.clone());
|
||||
// this is not ideal
|
||||
let ptr = PyObjectRef::into_raw(type_type.clone()) as *mut PyObject;
|
||||
unsafe {
|
||||
(*ptr).payload = PyObjectPayload::Class {
|
||||
name: String::from("type"),
|
||||
dict: RefCell::new(PyAttributes::new()),
|
||||
mro: vec![object_type],
|
||||
};
|
||||
(*ptr).typ = Some(type_type);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
@@ -71,7 +75,7 @@ fn type_mro(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
fn _mro(cls: PyObjectRef) -> Option<Vec<PyObjectRef>> {
|
||||
match cls.borrow().payload {
|
||||
match cls.payload {
|
||||
PyObjectPayload::Class { ref mro, .. } => {
|
||||
let mut mro = mro.clone();
|
||||
mro.insert(0, cls.clone());
|
||||
@@ -96,7 +100,7 @@ pub fn issubclass(typ: &PyObjectRef, cls: &PyObjectRef) -> bool {
|
||||
}
|
||||
|
||||
pub fn get_type_name(typ: &PyObjectRef) -> String {
|
||||
if let PyObjectPayload::Class { name, .. } = &typ.borrow().payload {
|
||||
if let PyObjectPayload::Class { name, .. } = &typ.payload {
|
||||
name.clone()
|
||||
} else {
|
||||
panic!("Cannot get type_name of non-type type {:?}", typ);
|
||||
@@ -211,7 +215,7 @@ pub fn type_getattribute(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult
|
||||
let attribute_error = vm.context().exceptions.attribute_error.clone();
|
||||
Err(vm.new_exception(
|
||||
attribute_error,
|
||||
format!("{} has no attribute '{}'", cls.borrow(), name),
|
||||
format!("{} has no attribute '{}'", cls, name),
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -224,7 +228,7 @@ pub fn get_attributes(obj: &PyObjectRef) -> PyAttributes {
|
||||
let mut base_classes = objtype::base_classes(obj);
|
||||
base_classes.reverse();
|
||||
for bc in base_classes {
|
||||
if let PyObjectPayload::Class { dict, .. } = &bc.borrow().payload {
|
||||
if let PyObjectPayload::Class { dict, .. } = &bc.payload {
|
||||
for (name, value) in dict.borrow().iter() {
|
||||
attributes.insert(name.to_string(), value.clone());
|
||||
}
|
||||
@@ -232,7 +236,7 @@ pub fn get_attributes(obj: &PyObjectRef) -> PyAttributes {
|
||||
}
|
||||
|
||||
// Get instance attributes:
|
||||
if let PyObjectPayload::Instance { dict } = &obj.borrow().payload {
|
||||
if let PyObjectPayload::Instance { dict } = &obj.payload {
|
||||
for (name, value) in dict.borrow().iter() {
|
||||
attributes.insert(name.to_string(), value.clone());
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ fn zip_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
fn zip_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(zip, Some(vm.ctx.zip_type()))]);
|
||||
|
||||
if let PyObjectPayload::ZipIterator { ref mut iterators } = zip.borrow_mut().payload {
|
||||
if let PyObjectPayload::ZipIterator { ref iterators } = zip.payload {
|
||||
if iterators.is_empty() {
|
||||
Err(objiter::new_stop_iteration(vm))
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user