Remove outer RefCell from PyObjectRef

This commit is contained in:
Joey Hain
2019-02-25 19:01:01 -08:00
parent 027a6847e5
commit f10fa6db44
33 changed files with 380 additions and 425 deletions

View File

@@ -281,7 +281,7 @@ impl Frame {
let mut out: Vec<Option<BigInt>> = elements
.into_iter()
.map(|x| match x.borrow().payload {
.map(|x| match x.payload {
PyObjectPayload::Integer { ref value } => Some(value.clone()),
PyObjectPayload::None => None,
_ => panic!("Expect Int or None as BUILD_SLICE arguments, got {:?}", x),
@@ -531,7 +531,7 @@ impl Frame {
} else {
let msg = format!(
"Can only raise BaseException derived types, not {}",
exception.borrow()
exception
);
let type_error_type = vm.ctx.exceptions.type_error.clone();
let type_error = vm.new_exception(type_error_type, msg);
@@ -564,7 +564,7 @@ impl Frame {
}
bytecode::Instruction::PrintExpr => {
let expr = self.pop_value();
match expr.borrow().payload {
match expr.payload {
PyObjectPayload::None => (),
_ => {
let repr = vm.to_repr(&expr)?;
@@ -591,9 +591,9 @@ impl Frame {
}
bytecode::Instruction::StoreLocals => {
let locals = self.pop_value();
match self.locals.borrow_mut().payload {
PyObjectPayload::Scope { ref mut scope } => {
scope.locals = locals;
match self.locals.payload {
PyObjectPayload::Scope { ref scope } => {
//scope.locals = locals; // FIXME
}
_ => panic!("We really expect our scope to be a scope!"),
}
@@ -854,7 +854,7 @@ impl Frame {
}
fn delete_name(&mut self, vm: &mut VirtualMachine, name: &str) -> FrameResult {
let locals = match self.locals.borrow().payload {
let locals = match self.locals.payload {
PyObjectPayload::Scope { ref scope } => scope.locals.clone(),
_ => panic!("We really expect our scope to be a scope!"),
};
@@ -1127,7 +1127,7 @@ impl fmt::Debug for Frame {
let stack_str = self
.stack
.iter()
.map(|elem| format!("\n > {:?}", elem.borrow()))
.map(|elem| format!("\n > {:?}", elem))
.collect::<Vec<_>>()
.join("");
let block_str = self
@@ -1136,12 +1136,12 @@ impl fmt::Debug for Frame {
.map(|elem| format!("\n > {:?}", elem))
.collect::<Vec<_>>()
.join("");
let local_str = match self.locals.borrow().payload {
PyObjectPayload::Scope { ref scope } => match scope.locals.borrow().payload {
let local_str = match self.locals.payload {
PyObjectPayload::Scope { ref scope } => match scope.locals.payload {
PyObjectPayload::Dict { ref elements } => {
objdict::get_key_value_pairs_from_content(elements)
objdict::get_key_value_pairs_from_content(&elements.borrow())
.iter()
.map(|elem| format!("\n {:?} = {:?}", elem.0.borrow(), elem.1.borrow()))
.map(|elem| format!("\n {:?} = {:?}", elem.0, elem.1))
.collect::<Vec<_>>()
.join("")
}

View File

@@ -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");

View File

@@ -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))
}

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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)))
}
}

View File

@@ -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) {

View File

@@ -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 {

View File

@@ -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)?;

View File

@@ -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 {

View File

@@ -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);

View File

@@ -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())),
}

View File

@@ -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");
}

View File

@@ -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);

View File

@@ -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))

View File

@@ -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)))
}
}

View File

@@ -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()

View File

@@ -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),
))
}
}

View File

@@ -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))

View File

@@ -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()))
}
}

View File

@@ -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());
}
}
}

View File

@@ -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.");

View File

@@ -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 {

View File

@@ -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(),
))
}

View File

@@ -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());
}

View File

@@ -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 {

View File

@@ -54,21 +54,15 @@ Basically reference counting, but then done by rust.
* Good reference: https://github.com/ProgVal/pythonvm-rust/blob/master/src/objects/mod.rs
*/
/*
The PyRef type implements
https://doc.rust-lang.org/std/cell/index.html#introducing-mutability-inside-of-something-immutable
*/
pub type PyRef<T> = Rc<RefCell<T>>;
/// The `PyObjectRef` is one of the most used types. It is a reference to a
/// python object. A single python object can have multiple references, and
/// this reference counting is accounted for by this type. Use the `.clone()`
/// method to create a new reference and increment the amount of references
/// to the python object by 1.
pub type PyObjectRef = PyRef<PyObject>;
pub type PyObjectRef = Rc<PyObject>;
/// Same as PyObjectRef, except for being a weak reference.
pub type PyObjectWeakRef = Weak<RefCell<PyObject>>;
pub type PyObjectWeakRef = Weak<PyObject>;
/// Use this type for function which return a python object or and exception.
/// Both the python object and the python exception are `PyObjectRef` types
@@ -488,12 +482,19 @@ impl PyContext {
}
pub fn new_bytes(&self, data: Vec<u8>) -> PyObjectRef {
PyObject::new(PyObjectPayload::Bytes { value: data }, self.bytes_type())
PyObject::new(
PyObjectPayload::Bytes {
value: RefCell::new(data),
},
self.bytes_type(),
)
}
pub fn new_bytearray(&self, data: Vec<u8>) -> PyObjectRef {
PyObject::new(
PyObjectPayload::Bytes { value: data },
PyObjectPayload::Bytes {
value: RefCell::new(data),
},
self.bytearray_type(),
)
}
@@ -507,24 +508,38 @@ impl PyContext {
}
pub fn new_tuple(&self, elements: Vec<PyObjectRef>) -> PyObjectRef {
PyObject::new(PyObjectPayload::Sequence { elements }, self.tuple_type())
PyObject::new(
PyObjectPayload::Sequence {
elements: RefCell::new(elements),
},
self.tuple_type(),
)
}
pub fn new_list(&self, elements: Vec<PyObjectRef>) -> PyObjectRef {
PyObject::new(PyObjectPayload::Sequence { elements }, self.list_type())
PyObject::new(
PyObjectPayload::Sequence {
elements: RefCell::new(elements),
},
self.list_type(),
)
}
pub fn new_set(&self) -> PyObjectRef {
// Initialized empty, as calling __hash__ is required for adding each object to the set
// which requires a VM context - this is done in the objset code itself.
let elements: HashMap<u64, PyObjectRef> = HashMap::new();
PyObject::new(PyObjectPayload::Set { elements }, self.set_type())
PyObject::new(
PyObjectPayload::Set {
elements: RefCell::new(HashMap::new()),
},
self.set_type(),
)
}
pub fn new_dict(&self) -> PyObjectRef {
PyObject::new(
PyObjectPayload::Dict {
elements: HashMap::new(),
elements: RefCell::new(HashMap::new()),
},
self.dict_type(),
)
@@ -642,10 +657,10 @@ impl PyContext {
// Item set/get:
pub fn set_item(&self, obj: &PyObjectRef, key: &str, v: PyObjectRef) {
match obj.borrow_mut().payload {
PyObjectPayload::Dict { ref mut elements } => {
match obj.payload {
PyObjectPayload::Dict { ref elements } => {
let key = self.new_str(key.to_string());
objdict::set_item_in_content(elements, &key, &v);
objdict::set_item_in_content(&mut elements.borrow_mut(), &key, &v);
}
ref k => panic!("TODO {:?}", k),
};
@@ -659,7 +674,7 @@ impl PyContext {
}
pub fn set_attr(&self, obj: &PyObjectRef, attr_name: &str, value: PyObjectRef) {
match obj.borrow().payload {
match obj.payload {
PyObjectPayload::Module { ref dict, .. } => self.set_attr(dict, attr_name, value),
PyObjectPayload::Instance { ref dict } | PyObjectPayload::Class { ref dict, .. } => {
dict.borrow_mut().insert(attr_name.to_string(), value);
@@ -708,7 +723,7 @@ pub trait IdProtocol {
impl IdProtocol for PyObjectRef {
fn get_id(&self) -> usize {
self.as_ptr() as usize
&*self as &PyObject as *const PyObject as usize
}
fn is(&self, other: &PyObjectRef) -> bool {
@@ -726,7 +741,7 @@ pub trait TypeProtocol {
impl TypeProtocol for PyObjectRef {
fn typ(&self) -> PyObjectRef {
self.borrow().typ()
(**self).typ()
}
}
@@ -746,14 +761,14 @@ pub trait ParentProtocol {
impl ParentProtocol for PyObjectRef {
fn has_parent(&self) -> bool {
match self.borrow().payload {
match self.payload {
PyObjectPayload::Scope { ref scope } => scope.parent.is_some(),
_ => panic!("Only scopes have parent (not {:?}", self),
}
}
fn get_parent(&self) -> PyObjectRef {
match self.borrow().payload {
match self.payload {
PyObjectPayload::Scope { ref scope } => match scope.parent {
Some(ref value) => value.clone(),
None => panic!("OMG"),
@@ -769,7 +784,6 @@ pub trait AttributeProtocol {
}
fn class_get_item(class: &PyObjectRef, attr_name: &str) -> Option<PyObjectRef> {
let class = class.borrow();
match class.payload {
PyObjectPayload::Class { ref dict, .. } => dict.borrow().get(attr_name).cloned(),
_ => panic!("Only classes should be in MRO!"),
@@ -777,7 +791,6 @@ fn class_get_item(class: &PyObjectRef, attr_name: &str) -> Option<PyObjectRef> {
}
fn class_has_item(class: &PyObjectRef, attr_name: &str) -> bool {
let class = class.borrow();
match class.payload {
PyObjectPayload::Class { ref dict, .. } => dict.borrow().contains_key(attr_name),
_ => panic!("Only classes should be in MRO!"),
@@ -786,8 +799,7 @@ fn class_has_item(class: &PyObjectRef, attr_name: &str) -> bool {
impl AttributeProtocol for PyObjectRef {
fn get_attr(&self, attr_name: &str) -> Option<PyObjectRef> {
let obj = self.borrow();
match obj.payload {
match self.payload {
PyObjectPayload::Module { ref dict, .. } => dict.get_item(attr_name),
PyObjectPayload::Class { ref mro, .. } => {
if let Some(item) = class_get_item(self, attr_name) {
@@ -806,8 +818,7 @@ impl AttributeProtocol for PyObjectRef {
}
fn has_attr(&self, attr_name: &str) -> bool {
let obj = self.borrow();
match obj.payload {
match self.payload {
PyObjectPayload::Module { ref dict, .. } => dict.contains_key(attr_name),
PyObjectPayload::Class { ref mro, .. } => {
class_has_item(self, attr_name) || mro.iter().any(|d| class_has_item(d, attr_name))
@@ -826,9 +837,9 @@ pub trait DictProtocol {
impl DictProtocol for PyObjectRef {
fn contains_key(&self, k: &str) -> bool {
match self.borrow().payload {
match self.payload {
PyObjectPayload::Dict { ref elements } => {
objdict::content_contains_key_str(elements, k)
objdict::content_contains_key_str(&elements.borrow(), k)
}
PyObjectPayload::Scope { ref scope } => scope.locals.contains_key(k),
ref payload => unimplemented!("TODO {:?}", payload),
@@ -836,15 +847,17 @@ impl DictProtocol for PyObjectRef {
}
fn get_item(&self, k: &str) -> Option<PyObjectRef> {
match self.borrow().payload {
PyObjectPayload::Dict { ref elements } => objdict::content_get_key_str(elements, k),
match self.payload {
PyObjectPayload::Dict { ref elements } => {
objdict::content_get_key_str(&elements.borrow(), k)
}
PyObjectPayload::Scope { ref scope } => scope.locals.get_item(k),
_ => panic!("TODO"),
}
}
fn get_key_value_pairs(&self) -> Vec<(PyObjectRef, PyObjectRef)> {
match self.borrow().payload {
match self.payload {
PyObjectPayload::Dict { .. } => objdict::get_key_value_pairs(self),
PyObjectPayload::Module { ref dict, .. } => dict.get_key_value_pairs(),
PyObjectPayload::Scope { ref scope } => scope.locals.get_key_value_pairs(),
@@ -1161,23 +1174,23 @@ pub enum PyObjectPayload {
value: Complex64,
},
Bytes {
value: Vec<u8>,
value: RefCell<Vec<u8>>,
},
Sequence {
elements: Vec<PyObjectRef>,
elements: RefCell<Vec<PyObjectRef>>,
},
Dict {
elements: objdict::DictContentType,
elements: RefCell<objdict::DictContentType>,
},
Set {
elements: HashMap<u64, PyObjectRef>,
elements: RefCell<HashMap<u64, PyObjectRef>>,
},
Iterator {
position: usize,
iterated_obj: PyObjectRef,
},
EnumerateIterator {
counter: BigInt,
counter: RefCell<BigInt>,
iterator: PyObjectRef,
},
FilterIterator {
@@ -1244,7 +1257,7 @@ pub enum PyObjectPayload {
function: Box<Fn(&mut VirtualMachine, PyFuncArgs) -> PyResult>,
},
Socket {
socket: Socket,
socket: RefCell<Socket>,
},
}
@@ -1303,7 +1316,7 @@ impl PyObject {
// Move this object into a reference object, transferring ownership.
pub fn into_ref(self) -> PyObjectRef {
Rc::new(RefCell::new(self))
Rc::new(self)
}
}

View File

@@ -84,8 +84,8 @@ fn buffered_reader_read(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
.map_err(|_| vm.new_value_error("IO Error".to_string()))?;
//Copy bytes from the buffer vector into the results vector
if let PyObjectPayload::Bytes { ref mut value } = buffer.borrow_mut().payload {
result.extend(value.iter().cloned());
if let PyObjectPayload::Bytes { ref value } = buffer.payload {
result.extend(value.borrow().iter().cloned());
};
let len = vm.get_method(buffer.clone(), &"__len__".to_string());
@@ -167,11 +167,12 @@ fn file_io_readinto(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let handle = os::rust_file(raw_fd);
let mut f = handle.take(length);
if let PyObjectPayload::Bytes { ref mut value } = obj.borrow_mut().payload {
if let PyObjectPayload::Bytes { ref value } = obj.payload {
//TODO: Implement for MemoryView
value.clear();
match f.read_to_end(&mut *value) {
let mut value_mut = value.borrow_mut();
value_mut.clear();
match f.read_to_end(&mut value_mut) {
Ok(_) => {}
Err(_) => return Err(vm.new_value_error("Error reading from Take".to_string())),
}
@@ -197,9 +198,10 @@ fn file_io_write(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
//to support windows - i.e. raw file_handles
let mut handle = os::rust_file(raw_fd);
match obj.borrow_mut().payload {
PyObjectPayload::Bytes { ref mut value } => {
match handle.write(&value[..]) {
match obj.payload {
PyObjectPayload::Bytes { ref value } => {
let value_mut = value.borrow();
match handle.write(&value_mut[..]) {
Ok(len) => {
//reset raw fd on the FileIO object
let updated = os::raw_file_number(handle);

View File

@@ -65,7 +65,7 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
map.serialize_entry(&key, &self.clone_with_object(&e.1))?;
}
map.end()
} else if let PyObjectPayload::None = self.pyobject.borrow().payload {
} else if let PyObjectPayload::None = self.pyobject.payload {
serializer.serialize_none()
} else {
Err(serde::ser::Error::custom(format!(
@@ -167,7 +167,7 @@ impl<'de> Visitor<'de> for PyObjectDeserializer<'de> {
// than wrapping the given object up and then unwrapping it to determine whether or
// not it is a string
while let Some((key_obj, value)) = access.next_entry_seed(self.clone(), self.clone())? {
let key = match key_obj.borrow().payload {
let key = match key_obj.payload {
PyObjectPayload::String { ref value } => value.clone(),
_ => unimplemented!("map keys must be strings"),
};

View File

@@ -1,3 +1,9 @@
use std::cell::RefCell;
use std::io;
use std::io::Read;
use std::io::Write;
use std::net::{SocketAddr, TcpListener, TcpStream, UdpSocket};
use crate::obj::objbytes;
use crate::obj::objint;
use crate::obj::objsequence::get_elements;
@@ -8,10 +14,6 @@ use crate::pyobject::{
use crate::vm::VirtualMachine;
use num_traits::ToPrimitive;
use std::io;
use std::io::Read;
use std::io::Write;
use std::net::{SocketAddr, TcpListener, TcpStream, UdpSocket};
#[derive(Copy, Clone)]
enum AddressFamily {
@@ -113,7 +115,7 @@ fn socket_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let address_family = AddressFamily::from_i32(objint::get_value(family_int).to_i32().unwrap());
let kind = SocketKind::from_i32(objint::get_value(kind_int).to_i32().unwrap());
let socket = Socket::new(address_family, kind);
let socket = RefCell::new(Socket::new(address_family, kind));
Ok(PyObject::new(
PyObjectPayload::Socket { socket },
@@ -134,12 +136,10 @@ fn socket_connect(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let address_string = format!("{}:{}", host, port.to_string());
let mut mut_obj = zelf.borrow_mut();
match mut_obj.payload {
PyObjectPayload::Socket { ref mut socket } => {
match zelf.payload {
PyObjectPayload::Socket { ref socket } => {
if let Ok(stream) = TcpStream::connect(address_string) {
socket.con = Some(Connection::TcpStream(stream));
socket.borrow_mut().con = Some(Connection::TcpStream(stream));
Ok(vm.get_none())
} else {
// TODO: Socket error
@@ -163,12 +163,10 @@ fn socket_bind(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let address_string = format!("{}:{}", host, port.to_string());
let mut mut_obj = zelf.borrow_mut();
match mut_obj.payload {
PyObjectPayload::Socket { ref mut socket } => {
match zelf.payload {
PyObjectPayload::Socket { ref socket } => {
if let Ok(stream) = TcpListener::bind(address_string) {
socket.con = Some(Connection::TcpListener(stream));
socket.borrow_mut().con = Some(Connection::TcpListener(stream));
Ok(vm.get_none())
} else {
// TODO: Socket error
@@ -186,11 +184,9 @@ fn socket_listen(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
fn socket_accept(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(zelf, None)]);
let mut mut_obj = zelf.borrow_mut();
match mut_obj.payload {
PyObjectPayload::Socket { ref mut socket } => {
let ret = match socket.con {
match zelf.payload {
PyObjectPayload::Socket { ref socket } => {
let ret = match socket.borrow_mut().con {
Some(ref mut v) => v.accept(),
None => return Err(vm.new_type_error("".to_string())),
};
@@ -200,15 +196,15 @@ fn socket_accept(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
_ => return Err(vm.new_type_error("".to_string())),
};
let socket = Socket {
address_family: socket.address_family.clone(),
sk: socket.sk.clone(),
let socket = RefCell::new(Socket {
address_family: socket.borrow().address_family.clone(),
sk: socket.borrow().sk.clone(),
con: Some(Connection::TcpStream(tcp_stream)),
};
});
let sock_obj = PyObject::new(PyObjectPayload::Socket { socket }, mut_obj.typ());
let sock_obj = PyObject::new(PyObjectPayload::Socket { socket }, zelf.typ());
let elements = vec![sock_obj, vm.get_none()];
let elements = RefCell::new(vec![sock_obj, vm.get_none()]);
Ok(PyObject::new(
PyObjectPayload::Sequence { elements },
@@ -225,19 +221,14 @@ fn socket_recv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
args,
required = [(zelf, None), (bufsize, Some(vm.ctx.int_type()))]
);
let mut mut_obj = zelf.borrow_mut();
match mut_obj.payload {
PyObjectPayload::Socket { ref mut socket } => {
match zelf.payload {
PyObjectPayload::Socket { ref socket } => {
let mut buffer = Vec::new();
let _temp = match socket.con {
let _temp = match socket.borrow_mut().con {
Some(ref mut v) => v.read_to_end(&mut buffer).unwrap(),
None => 0,
};
Ok(PyObject::new(
PyObjectPayload::Bytes { value: buffer },
vm.ctx.bytes_type(),
))
Ok(vm.ctx.new_bytes(buffer))
}
_ => Err(vm.new_type_error("".to_string())),
}
@@ -249,11 +240,9 @@ fn socket_send(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
args,
required = [(zelf, None), (bytes, Some(vm.ctx.bytes_type()))]
);
let mut mut_obj = zelf.borrow_mut();
match mut_obj.payload {
PyObjectPayload::Socket { ref mut socket } => {
match socket.con {
match zelf.payload {
PyObjectPayload::Socket { ref socket } => {
match socket.borrow_mut().con {
Some(ref mut v) => v.write(&objbytes::get_value(&bytes)).unwrap(),
None => return Err(vm.new_type_error("".to_string())),
};
@@ -265,13 +254,11 @@ fn socket_send(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
fn socket_close(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(zelf, None)]);
let mut mut_obj = zelf.borrow_mut();
match mut_obj.payload {
PyObjectPayload::Socket { ref mut socket } => match socket.address_family {
AddressFamily::AfInet => match socket.sk {
match zelf.payload {
PyObjectPayload::Socket { ref socket } => match socket.borrow().address_family {
AddressFamily::AfInet => match socket.borrow().sk {
SocketKind::SockStream => {
socket.con = None;
socket.borrow_mut().con = None;
Ok(vm.get_none())
}
_ => Err(vm.new_type_error("".to_string())),

View File

@@ -46,7 +46,7 @@ fn ref_call(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
fn get_value(obj: &PyObjectRef) -> PyObjectWeakRef {
if let PyObjectPayload::WeakRef { referent } = &obj.borrow().payload {
if let PyObjectPayload::WeakRef { referent } = &obj.payload {
referent.clone()
} else {
panic!("Inner error getting weak ref {:?}", obj);

View File

@@ -30,7 +30,7 @@ fn sys_getrefcount(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
fn sys_getsizeof(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(object, None)]);
// TODO: implement default optional argument.
let size = mem::size_of_val(&object.borrow());
let size = mem::size_of_val(&object);
Ok(vm.ctx.new_int(size))
}

View File

@@ -190,7 +190,7 @@ impl VirtualMachine {
}
pub fn get_builtin_scope(&mut self) -> PyObjectRef {
let a2 = &*self.builtins.borrow();
let a2 = &*self.builtins;
match a2.payload {
PyObjectPayload::Module { ref dict, .. } => dict.clone(),
_ => {
@@ -271,7 +271,7 @@ impl VirtualMachine {
pub fn invoke(&mut self, func_ref: PyObjectRef, args: PyFuncArgs) -> PyResult {
trace!("Invoke: {:?} {:?}", func_ref, args);
match func_ref.borrow().payload {
match func_ref.payload {
PyObjectPayload::RustFunction { ref function } => function(self, args),
PyObjectPayload::Function {
ref code,
@@ -406,8 +406,8 @@ impl VirtualMachine {
// Add missing positional arguments, if we have fewer positional arguments than the
// function definition calls for
if nargs < nexpected_args {
let available_defaults = match defaults.borrow().payload {
PyObjectPayload::Sequence { ref elements } => elements.clone(),
let available_defaults = match defaults.payload {
PyObjectPayload::Sequence { ref elements } => elements.borrow().clone(),
PyObjectPayload::None => vec![],
_ => panic!("function defaults not tuple or None"),
};
@@ -493,11 +493,7 @@ impl VirtualMachine {
let cls = obj.typ();
match cls.get_attr(method_name) {
Some(method) => self.call_get_descriptor(method, obj.clone()),
None => Err(self.new_type_error(format!(
"{} has no method {:?}",
obj.borrow(),
method_name
))),
None => Err(self.new_type_error(format!("{} has no method {:?}", obj, method_name))),
}
}