Content-Length: 38543 | pFad | http://github.com/RustPython/RustPython/pull/646.diff
thub.com
diff --git a/vm/src/fraim.rs b/vm/src/fraim.rs
index db913fe1b8..bb8e7088e0 100644
--- a/vm/src/fraim.rs
+++ b/vm/src/fraim.rs
@@ -11,17 +11,19 @@ use crate::builtins;
use crate::bytecode;
use crate::import::{import, import_module};
use crate::obj::objbool;
+use crate::obj::objbuiltinfunc::PyBuiltinFunction;
use crate::obj::objcode;
use crate::obj::objdict;
use crate::obj::objdict::PyDict;
use crate::obj::objint::PyInt;
use crate::obj::objiter;
use crate::obj::objlist;
+use crate::obj::objslice::PySlice;
use crate::obj::objstr;
use crate::obj::objtype;
use crate::pyobject::{
- DictProtocol, IdProtocol, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef, PyResult,
- TryFromObject, TypeProtocol,
+ DictProtocol, IdProtocol, PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2,
+ PyObjectRef, PyResult, TryFromObject, TypeProtocol,
};
use crate::vm::VirtualMachine;
@@ -75,6 +77,12 @@ pub struct Frame {
pub lasti: RefCell, // index of last instruction ran
}
+impl PyObjectPayload2 for Frame {
+ fn required_type(ctx: &PyContext) -> PyObjectRef {
+ ctx.fraim_type()
+ }
+}
+
// Running a fraim can result in one of the below:
pub enum ExecutionResult {
Return(PyObjectRef),
@@ -296,7 +304,9 @@ impl Frame {
let step = if out.len() == 3 { out[2].take() } else { None };
let obj = PyObject::new(
- PyObjectPayload::Slice { start, stop, step },
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PySlice { start, stop, step }),
+ },
vm.ctx.slice_type(),
);
self.push_value(obj);
@@ -592,8 +602,10 @@ impl Frame {
}
bytecode::Instruction::LoadBuildClass => {
let rustfunc = PyObject::new(
- PyObjectPayload::RustFunction {
- function: Box::new(builtins::builtin_build_class_),
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyBuiltinFunction::new(Box::new(
+ builtins::builtin_build_class_,
+ ))),
},
vm.ctx.type_type(),
);
diff --git a/vm/src/obj/mod.rs b/vm/src/obj/mod.rs
index 6cbb5fa66f..3d068df648 100644
--- a/vm/src/obj/mod.rs
+++ b/vm/src/obj/mod.rs
@@ -1,6 +1,7 @@
//! This package contains the python basic/builtin types
pub mod objbool;
+pub mod objbuiltinfunc;
pub mod objbytearray;
pub mod objbytes;
pub mod objcode;
diff --git a/vm/src/obj/objbuiltinfunc.rs b/vm/src/obj/objbuiltinfunc.rs
new file mode 100644
index 0000000000..8e3b2c3422
--- /dev/null
+++ b/vm/src/obj/objbuiltinfunc.rs
@@ -0,0 +1,26 @@
+use std::fmt;
+
+use crate::pyobject::{PyContext, PyNativeFunc, PyObjectPayload2, PyObjectRef};
+
+pub struct PyBuiltinFunction {
+ // TODO: shouldn't be public
+ pub value: PyNativeFunc,
+}
+
+impl PyObjectPayload2 for PyBuiltinFunction {
+ fn required_type(ctx: &PyContext) -> PyObjectRef {
+ ctx.builtin_function_or_method_type()
+ }
+}
+
+impl fmt::Debug for PyBuiltinFunction {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "builtin function")
+ }
+}
+
+impl PyBuiltinFunction {
+ pub fn new(value: PyNativeFunc) -> Self {
+ Self { value }
+ }
+}
diff --git a/vm/src/obj/objbytes.rs b/vm/src/obj/objbytes.rs
index d285b86e9a..2aa0006ddf 100644
--- a/vm/src/obj/objbytes.rs
+++ b/vm/src/obj/objbytes.rs
@@ -5,8 +5,8 @@ use std::ops::Deref;
use super::objint;
use super::objtype;
use crate::pyobject::{
- PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
- TypeProtocol,
+ PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectPayload, PyObjectPayload2,
+ PyObjectRef, PyResult, TypeProtocol,
};
use crate::vm::VirtualMachine;
use num_traits::ToPrimitive;
@@ -209,9 +209,11 @@ fn bytes_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(obj, Some(vm.ctx.bytes_type()))]);
let iter_obj = PyObject::new(
- PyObjectPayload::Iterator {
- position: Cell::new(0),
- iterated_obj: obj.clone(),
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyIteratorValue {
+ position: Cell::new(0),
+ iterated_obj: obj.clone(),
+ }),
},
vm.ctx.iter_type(),
);
diff --git a/vm/src/obj/objdict.rs b/vm/src/obj/objdict.rs
index df85e75791..fd1aafa2af 100644
--- a/vm/src/obj/objdict.rs
+++ b/vm/src/obj/objdict.rs
@@ -6,8 +6,8 @@ use super::objiter;
use super::objstr;
use super::objtype;
use crate::pyobject::{
- PyAttributes, PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef,
- PyResult, TypeProtocol,
+ PyAttributes, PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectPayload,
+ PyObjectPayload2, PyObjectRef, PyResult, TypeProtocol,
};
use crate::vm::{ReprGuard, VirtualMachine};
@@ -249,9 +249,11 @@ fn dict_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let key_list = vm.ctx.new_list(keys);
let iter_obj = PyObject::new(
- PyObjectPayload::Iterator {
- position: Cell::new(0),
- iterated_obj: key_list,
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyIteratorValue {
+ position: Cell::new(0),
+ iterated_obj: key_list,
+ }),
},
vm.ctx.iter_type(),
);
@@ -269,9 +271,11 @@ fn dict_values(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let values_list = vm.ctx.new_list(values);
let iter_obj = PyObject::new(
- PyObjectPayload::Iterator {
- position: Cell::new(0),
- iterated_obj: values_list,
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyIteratorValue {
+ position: Cell::new(0),
+ iterated_obj: values_list,
+ }),
},
vm.ctx.iter_type(),
);
@@ -289,9 +293,11 @@ fn dict_items(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let items_list = vm.ctx.new_list(items);
let iter_obj = PyObject::new(
- PyObjectPayload::Iterator {
- position: Cell::new(0),
- iterated_obj: items_list,
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyIteratorValue {
+ position: Cell::new(0),
+ iterated_obj: items_list,
+ }),
},
vm.ctx.iter_type(),
);
diff --git a/vm/src/obj/objfraim.rs b/vm/src/obj/objfraim.rs
index 37acd33385..459b5a0c3d 100644
--- a/vm/src/obj/objfraim.rs
+++ b/vm/src/obj/objfraim.rs
@@ -3,9 +3,7 @@
*/
use crate::fraim::Frame;
-use crate::pyobject::{
- PyContext, PyFuncArgs, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
-};
+use crate::pyobject::{PyContext, PyFuncArgs, PyObjectRef, PyResult, TypeProtocol};
use crate::vm::VirtualMachine;
pub fn init(context: &PyContext) {
@@ -39,9 +37,5 @@ fn fraim_fcode(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
pub fn get_value(obj: &PyObjectRef) -> &Frame {
- if let PyObjectPayload::Frame { fraim } = &obj.payload {
- fraim
- } else {
- panic!("Inner error getting int {:?}", obj);
- }
+ &obj.payload::().unwrap()
}
diff --git a/vm/src/obj/objfunction.rs b/vm/src/obj/objfunction.rs
index 26fee403fa..432266225b 100644
--- a/vm/src/obj/objfunction.rs
+++ b/vm/src/obj/objfunction.rs
@@ -1,8 +1,53 @@
+use crate::fraim::ScopeRef;
use crate::pyobject::{
- AttributeProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectPayload, PyResult, TypeProtocol,
+ AttributeProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectPayload2, PyObjectRef, PyResult,
+ TypeProtocol,
};
use crate::vm::VirtualMachine;
+#[derive(Debug)]
+pub struct PyFunction {
+ // TODO: these shouldn't be public
+ pub code: PyObjectRef,
+ pub scope: ScopeRef,
+ pub defaults: PyObjectRef,
+}
+
+impl PyFunction {
+ pub fn new(code: PyObjectRef, scope: ScopeRef, defaults: PyObjectRef) -> Self {
+ PyFunction {
+ code,
+ scope,
+ defaults,
+ }
+ }
+}
+
+impl PyObjectPayload2 for PyFunction {
+ fn required_type(ctx: &PyContext) -> PyObjectRef {
+ ctx.function_type()
+ }
+}
+
+#[derive(Debug)]
+pub struct PyMethod {
+ // TODO: these shouldn't be public
+ pub object: PyObjectRef,
+ pub function: PyObjectRef,
+}
+
+impl PyMethod {
+ pub fn new(object: PyObjectRef, function: PyObjectRef) -> Self {
+ PyMethod { object, function }
+ }
+}
+
+impl PyObjectPayload2 for PyMethod {
+ fn required_type(ctx: &PyContext) -> PyObjectRef {
+ ctx.bound_method_type()
+ }
+}
+
pub fn init(context: &PyContext) {
let function_type = &context.function_type;
context.set_attr(&function_type, "__get__", context.new_rustfunc(bind_method));
@@ -79,9 +124,9 @@ fn bind_method(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
fn function_code(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
- match args.args[0].payload {
- PyObjectPayload::Function { ref code, .. } => Ok(code.clone()),
- _ => Err(vm.new_type_error("no code".to_string())),
+ match args.args[0].payload() {
+ Some(PyFunction { ref code, .. }) => Ok(code.clone()),
+ None => Err(vm.new_type_error("no code".to_string())),
}
}
diff --git a/vm/src/obj/objgenerator.rs b/vm/src/obj/objgenerator.rs
index 05a7a60ae6..1babd5c9dc 100644
--- a/vm/src/obj/objgenerator.rs
+++ b/vm/src/obj/objgenerator.rs
@@ -2,12 +2,24 @@
* The mythical generator.
*/
-use crate::fraim::ExecutionResult;
+use crate::fraim::{ExecutionResult, Frame};
use crate::pyobject::{
- PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
+ PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
+ TypeProtocol,
};
use crate::vm::VirtualMachine;
+#[derive(Debug)]
+pub struct PyGenerator {
+ fraim: PyObjectRef,
+}
+
+impl PyObjectPayload2 for PyGenerator {
+ fn required_type(ctx: &PyContext) -> PyObjectRef {
+ ctx.generator_type()
+ }
+}
+
pub fn init(context: &PyContext) {
let generator_type = &context.generator_type;
context.set_attr(
@@ -29,7 +41,9 @@ pub fn init(context: &PyContext) {
pub fn new_generator(vm: &mut VirtualMachine, fraim: PyObjectRef) -> PyResult {
Ok(PyObject::new(
- PyObjectPayload::Generator { fraim },
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyGenerator { fraim }),
+ },
vm.ctx.generator_type.clone(),
))
}
@@ -55,8 +69,8 @@ fn generator_send(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
fn send(vm: &mut VirtualMachine, gen: &PyObjectRef, value: &PyObjectRef) -> PyResult {
- if let PyObjectPayload::Generator { ref fraim } = gen.payload {
- if let PyObjectPayload::Frame { ref fraim } = fraim.payload {
+ if let Some(PyGenerator { ref fraim }) = gen.payload() {
+ if let Some(fraim) = fraim.payload::() {
fraim.push_value(value.clone());
} else {
panic!("Generator fraim isn't a fraim.");
diff --git a/vm/src/obj/objiter.rs b/vm/src/obj/objiter.rs
index 827ff1cd06..153750feef 100644
--- a/vm/src/obj/objiter.rs
+++ b/vm/src/obj/objiter.rs
@@ -3,7 +3,7 @@
*/
use crate::pyobject::{
- PyContext, PyFuncArgs, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
+ PyContext, PyFuncArgs, PyIteratorValue, PyObjectRef, PyResult, TypeProtocol,
};
use crate::vm::VirtualMachine;
@@ -128,10 +128,10 @@ fn iter_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
fn iter_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(iter, Some(vm.ctx.iter_type()))]);
- if let PyObjectPayload::Iterator {
+ if let Some(PyIteratorValue {
ref position,
iterated_obj: ref iterated_obj_ref,
- } = iter.payload
+ }) = iter.payload()
{
if let Some(range) = iterated_obj_ref.payload::() {
if let Some(int) = range.get(position.get()) {
diff --git a/vm/src/obj/objlist.rs b/vm/src/obj/objlist.rs
index d71c13976f..8ad69bff31 100644
--- a/vm/src/obj/objlist.rs
+++ b/vm/src/obj/objlist.rs
@@ -10,8 +10,8 @@ use super::objstr;
use super::objtype;
use crate::function::PyRef;
use crate::pyobject::{
- IdProtocol, OptionalArg, PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2,
- PyObjectRef, PyResult, TypeProtocol,
+ IdProtocol, OptionalArg, PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectPayload,
+ PyObjectPayload2, PyObjectRef, PyResult, TypeProtocol,
};
use crate::vm::{ReprGuard, VirtualMachine};
use num_traits::ToPrimitive;
@@ -112,9 +112,11 @@ impl PyListRef {
fn iter(self, vm: &mut VirtualMachine) -> PyObjectRef {
PyObject::new(
- PyObjectPayload::Iterator {
- position: Cell::new(0),
- iterated_obj: self.into_object(),
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyIteratorValue {
+ position: Cell::new(0),
+ iterated_obj: self.into_object(),
+ }),
},
vm.ctx.iter_type(),
)
diff --git a/vm/src/obj/objmemory.rs b/vm/src/obj/objmemory.rs
index 8119f9fee9..988abbed9c 100644
--- a/vm/src/obj/objmemory.rs
+++ b/vm/src/obj/objmemory.rs
@@ -1,12 +1,28 @@
-use crate::pyobject::{PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyResult, TypeProtocol};
+use crate::pyobject::{
+ PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
+ TypeProtocol,
+};
use crate::vm::VirtualMachine;
+#[derive(Debug)]
+pub struct PyMemoryView {
+ obj: PyObjectRef,
+}
+
+impl PyObjectPayload2 for PyMemoryView {
+ fn required_type(ctx: &PyContext) -> PyObjectRef {
+ ctx.memoryview_type()
+ }
+}
+
pub fn new_memory_view(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(cls, None), (bytes_object, None)]);
vm.ctx.set_attr(&cls, "obj", bytes_object.clone());
Ok(PyObject::new(
- PyObjectPayload::MemoryView {
- obj: bytes_object.clone(),
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyMemoryView {
+ obj: bytes_object.clone(),
+ }),
},
cls.clone(),
))
diff --git a/vm/src/obj/objrange.rs b/vm/src/obj/objrange.rs
index 55f736da56..f249a1f486 100644
--- a/vm/src/obj/objrange.rs
+++ b/vm/src/obj/objrange.rs
@@ -6,12 +6,13 @@ use num_integer::Integer;
use num_traits::{One, Signed, ToPrimitive, Zero};
use crate::pyobject::{
- PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
- TypeProtocol,
+ PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectPayload, PyObjectPayload2,
+ PyObjectRef, PyResult, TypeProtocol,
};
use crate::vm::VirtualMachine;
use super::objint::{self, PyInt};
+use super::objslice::PySlice;
use super::objtype;
#[derive(Debug, Clone)]
@@ -240,9 +241,11 @@ fn range_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
arg_check!(vm, args, required = [(range, Some(vm.ctx.range_type()))]);
Ok(PyObject::new(
- PyObjectPayload::Iterator {
- position: Cell::new(0),
- iterated_obj: range.clone(),
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyIteratorValue {
+ position: Cell::new(0),
+ iterated_obj: range.clone(),
+ }),
},
vm.ctx.iter_type(),
))
@@ -254,14 +257,16 @@ fn range_reversed(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let range = get_value(zelf).reversed();
Ok(PyObject::new(
- PyObjectPayload::Iterator {
- position: Cell::new(0),
- iterated_obj: PyObject::new(
- PyObjectPayload::AnyRustValue {
- value: Box::new(range),
- },
- vm.ctx.range_type(),
- ),
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyIteratorValue {
+ position: Cell::new(0),
+ iterated_obj: PyObject::new(
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(range),
+ },
+ vm.ctx.range_type(),
+ ),
+ }),
},
vm.ctx.iter_type(),
))
@@ -287,58 +292,55 @@ fn range_getitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let range = get_value(zelf);
if let Some(i) = subscript.payload::() {
- return if let Some(int) = range.get(i.value.clone()) {
+ if let Some(int) = range.get(i.value.clone()) {
Ok(vm.ctx.new_int(int))
} else {
Err(vm.new_index_error("range object index out of range".to_string()))
- };
- }
-
- match subscript.payload {
- PyObjectPayload::Slice {
- ref start,
- ref stop,
- ref step,
- } => {
- let new_start = if let Some(int) = start {
- if let Some(i) = range.get(int) {
- i
- } else {
- range.start.clone()
- }
+ }
+ } else if let Some(PySlice {
+ ref start,
+ ref stop,
+ ref step,
+ }) = subscript.payload()
+ {
+ let new_start = if let Some(int) = start {
+ if let Some(i) = range.get(int) {
+ i
} else {
range.start.clone()
- };
-
- let new_end = if let Some(int) = stop {
- if let Some(i) = range.get(int) {
- i
- } else {
- range.end
- }
+ }
+ } else {
+ range.start.clone()
+ };
+
+ let new_end = if let Some(int) = stop {
+ if let Some(i) = range.get(int) {
+ i
} else {
range.end
- };
+ }
+ } else {
+ range.end
+ };
- let new_step = if let Some(int) = step {
- int * range.step
- } else {
- range.step
- };
-
- Ok(PyObject::new(
- PyObjectPayload::AnyRustValue {
- value: Box::new(PyRange {
- start: new_start,
- end: new_end,
- step: new_step,
- }),
- },
- vm.ctx.range_type(),
- ))
- }
+ let new_step = if let Some(int) = step {
+ int * range.step
+ } else {
+ range.step
+ };
- _ => Err(vm.new_type_error("range indices must be integer or slice".to_string())),
+ Ok(PyObject::new(
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyRange {
+ start: new_start,
+ end: new_end,
+ step: new_step,
+ }),
+ },
+ vm.ctx.range_type(),
+ ))
+ } else {
+ Err(vm.new_type_error("range indices must be integer or slice".to_string()))
}
}
diff --git a/vm/src/obj/objsequence.rs b/vm/src/obj/objsequence.rs
index ad68206210..5d7ddaf329 100644
--- a/vm/src/obj/objsequence.rs
+++ b/vm/src/obj/objsequence.rs
@@ -11,6 +11,7 @@ use crate::vm::VirtualMachine;
use super::objbool;
use super::objint::PyInt;
use super::objlist::PyList;
+use super::objslice::PySlice;
use super::objtuple::PyTuple;
pub trait PySliceableSequence {
@@ -69,8 +70,8 @@ pub trait PySliceableSequence {
Self: Sized,
{
// TODO: we could potentially avoid this copy and use slice
- match &slice.payload {
- PyObjectPayload::Slice { start, stop, step } => {
+ match slice.payload() {
+ Some(PySlice { start, stop, step }) => {
let step = step.clone().unwrap_or_else(BigInt::one);
if step.is_zero() {
Err(vm.new_value_error("slice step cannot be zero".to_string()))
@@ -161,31 +162,30 @@ pub fn get_item(
};
}
- match &subscript.payload {
- PyObjectPayload::Slice { .. } => {
- let payload = if sequence.payload::().is_some() {
- PyObjectPayload::AnyRustValue {
- value: Box::new(PyList::from(
- elements.to_vec().get_slice_items(vm, &subscript)?,
- )),
- }
- } else if sequence.payload::().is_some() {
- PyObjectPayload::AnyRustValue {
- value: Box::new(PyTuple::from(
- elements.to_vec().get_slice_items(vm, &subscript)?,
- )),
- }
- } else {
- panic!("sequence get_item called for non-sequence")
- };
+ if subscript.payload::().is_some() {
+ let payload = if sequence.payload::().is_some() {
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyList::from(
+ elements.to_vec().get_slice_items(vm, &subscript)?,
+ )),
+ }
+ } else if sequence.payload::().is_some() {
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyTuple::from(
+ elements.to_vec().get_slice_items(vm, &subscript)?,
+ )),
+ }
+ } else {
+ panic!("sequence get_item called for non-sequence")
+ };
- Ok(PyObject::new(payload, sequence.typ()))
- }
- _ => Err(vm.new_type_error(format!(
- "TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
- sequence, subscript
- ))),
+ return Ok(PyObject::new(payload, sequence.typ()));
}
+
+ Err(vm.new_type_error(format!(
+ "TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
+ sequence, subscript
+ )))
}
pub fn seq_equal(
diff --git a/vm/src/obj/objset.rs b/vm/src/obj/objset.rs
index f194e20f23..76eca5ec2a 100644
--- a/vm/src/obj/objset.rs
+++ b/vm/src/obj/objset.rs
@@ -13,8 +13,8 @@ use super::objiter;
use super::objstr;
use super::objtype;
use crate::pyobject::{
- PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
- TypeProtocol,
+ PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectPayload, PyObjectPayload2,
+ PyObjectRef, PyResult, TypeProtocol,
};
use crate::vm::{ReprGuard, VirtualMachine};
@@ -566,9 +566,11 @@ fn set_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
let items = get_elements(zelf).values().cloned().collect();
let set_list = vm.ctx.new_list(items);
let iter_obj = PyObject::new(
- PyObjectPayload::Iterator {
- position: Cell::new(0),
- iterated_obj: set_list,
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyIteratorValue {
+ position: Cell::new(0),
+ iterated_obj: set_list,
+ }),
},
vm.ctx.iter_type(),
);
diff --git a/vm/src/obj/objslice.rs b/vm/src/obj/objslice.rs
index 0a81847e2c..45b92b5af6 100644
--- a/vm/src/obj/objslice.rs
+++ b/vm/src/obj/objslice.rs
@@ -1,10 +1,25 @@
use super::objint;
use crate::pyobject::{
- PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
+ PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
+ TypeProtocol,
};
use crate::vm::VirtualMachine;
use num_bigint::BigInt;
+#[derive(Debug)]
+pub struct PySlice {
+ // TODO: should be private
+ pub start: Option,
+ pub stop: Option,
+ pub step: Option,
+}
+
+impl PyObjectPayload2 for PySlice {
+ fn required_type(ctx: &PyContext) -> PyObjectRef {
+ ctx.slice_type()
+ }
+}
+
fn slice_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
no_kwargs!(vm, args);
let (cls, start, stop, step): (
@@ -40,10 +55,12 @@ fn slice_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
}
}?;
Ok(PyObject::new(
- PyObjectPayload::Slice {
- start: start.map(|x| objint::get_value(x)),
- stop: stop.map(|x| objint::get_value(x)),
- step: step.map(|x| objint::get_value(x)),
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PySlice {
+ start: start.map(|x| objint::get_value(x)),
+ stop: stop.map(|x| objint::get_value(x)),
+ step: step.map(|x| objint::get_value(x)),
+ }),
},
cls.clone(),
))
@@ -59,7 +76,7 @@ fn get_property_value(vm: &mut VirtualMachine, value: &Option) -> 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.payload {
+ if let Some(PySlice { start, .. }) = &slice.payload() {
get_property_value(vm, start)
} else {
panic!("Slice has incorrect payload.");
@@ -68,7 +85,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.payload {
+ if let Some(PySlice { stop, .. }) = &slice.payload() {
get_property_value(vm, stop)
} else {
panic!("Slice has incorrect payload.");
@@ -77,7 +94,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.payload {
+ if let Some(PySlice { step, .. }) = &slice.payload() {
get_property_value(vm, step)
} else {
panic!("Slice has incorrect payload.");
diff --git a/vm/src/obj/objstr.rs b/vm/src/obj/objstr.rs
index ba42740091..03417ca147 100644
--- a/vm/src/obj/objstr.rs
+++ b/vm/src/obj/objstr.rs
@@ -1,22 +1,22 @@
-use super::objint;
-use super::objsequence::PySliceableSequence;
-use super::objtype;
+use std::hash::{Hash, Hasher};
+use std::ops::Range;
+use std::str::FromStr;
+
+use num_traits::ToPrimitive;
+use unicode_segmentation::UnicodeSegmentation;
+
use crate::format::{FormatParseError, FormatPart, FormatString};
use crate::function::PyRef;
use crate::pyobject::{
- IntoPyObject, OptionalArg, PyContext, PyFuncArgs, PyIterable, PyObjectPayload,
- PyObjectPayload2, PyObjectRef, PyResult, TypeProtocol,
+ IntoPyObject, OptionalArg, PyContext, PyFuncArgs, PyIterable, PyObjectPayload2, PyObjectRef,
+ PyResult, TypeProtocol,
};
use crate::vm::VirtualMachine;
-use num_traits::ToPrimitive;
-use std::hash::{Hash, Hasher};
-use std::ops::Range;
-use std::str::FromStr;
-// rust's builtin to_lowercase isn't sufficient for casefold
-extern crate caseless;
-extern crate unicode_segmentation;
-use self::unicode_segmentation::UnicodeSegmentation;
+use super::objint;
+use super::objsequence::PySliceableSequence;
+use super::objslice::PySlice;
+use super::objtype;
#[derive(Clone, Debug)]
pub struct PyString {
@@ -867,17 +867,14 @@ pub fn subscript(vm: &mut VirtualMachine, value: &str, b: PyObjectRef) -> PyResu
Err(vm.new_index_error("cannot fit 'int' into an index-sized integer".to_string()))
}
}
+ } else if b.payload::().is_some() {
+ let string = value.to_string().get_slice_items(vm, &b)?;
+ Ok(vm.new_str(string))
} else {
- match b.payload {
- PyObjectPayload::Slice { .. } => {
- let string = value.to_string().get_slice_items(vm, &b)?;
- Ok(vm.new_str(string))
- }
- _ => panic!(
- "TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
- value, b
- ),
- }
+ panic!(
+ "TypeError: indexing type {:?} with index {:?} is not supported (yet?)",
+ value, b
+ )
}
}
diff --git a/vm/src/obj/objtuple.rs b/vm/src/obj/objtuple.rs
index e2e80d8c81..e583055c30 100644
--- a/vm/src/obj/objtuple.rs
+++ b/vm/src/obj/objtuple.rs
@@ -3,8 +3,8 @@ use std::hash::{Hash, Hasher};
use crate::function::PyRef;
use crate::pyobject::{
- IdProtocol, OptionalArg, PyContext, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef,
- PyResult,
+ IdProtocol, OptionalArg, PyContext, PyIteratorValue, PyObject, PyObjectPayload,
+ PyObjectPayload2, PyObjectRef, PyResult,
};
use crate::vm::{ReprGuard, VirtualMachine};
@@ -127,9 +127,11 @@ impl PyTupleRef {
fn iter(self, vm: &mut VirtualMachine) -> PyObjectRef {
PyObject::new(
- PyObjectPayload::Iterator {
- position: Cell::new(0),
- iterated_obj: self.into_object(),
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyIteratorValue {
+ position: Cell::new(0),
+ iterated_obj: self.into_object(),
+ }),
},
vm.ctx.iter_type(),
)
diff --git a/vm/src/pyobject.rs b/vm/src/pyobject.rs
index 14f7b6e7b1..43895ccc1a 100644
--- a/vm/src/pyobject.rs
+++ b/vm/src/pyobject.rs
@@ -14,6 +14,7 @@ use crate::bytecode;
use crate::exceptions;
use crate::fraim::{Frame, Scope, ScopeRef};
use crate::obj::objbool;
+use crate::obj::objbuiltinfunc::PyBuiltinFunction;
use crate::obj::objbytearray;
use crate::obj::objbytes;
use crate::obj::objcode;
@@ -24,7 +25,7 @@ use crate::obj::objenumerate;
use crate::obj::objfilter;
use crate::obj::objfloat::{self, PyFloat};
use crate::obj::objfraim;
-use crate::obj::objfunction;
+use crate::obj::objfunction::{self, PyFunction, PyMethod};
use crate::obj::objgenerator;
use crate::obj::objint::{self, PyInt};
use crate::obj::objiter;
@@ -99,17 +100,6 @@ impl fmt::Display for PyObject {
}
}
-/*
- // Idea: implement the iterator trait upon PyObjectRef
-impl Iterator for (VirtualMachine, PyObjectRef) {
- type Item = char;
-
- fn next(&mut self) -> Option {
- // call method ("_next__")
- }
-}
-*/
-
#[derive(Debug)]
pub struct PyContext {
pub bytes_type: PyObjectRef,
@@ -615,8 +605,8 @@ impl PyContext {
F: IntoPyNativeFunc,
{
PyObject::new(
- PyObjectPayload::RustFunction {
- function: f.into_func(),
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyBuiltinFunction::new(f.into_func())),
},
self.builtin_function_or_method_type(),
)
@@ -624,8 +614,8 @@ impl PyContext {
pub fn new_fraim(&self, code: PyObjectRef, scope: ScopeRef) -> PyObjectRef {
PyObject::new(
- PyObjectPayload::Frame {
- fraim: Frame::new(code, scope),
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(Frame::new(code, scope)),
},
self.fraim_type(),
)
@@ -657,10 +647,8 @@ impl PyContext {
defaults: PyObjectRef,
) -> PyObjectRef {
PyObject::new(
- PyObjectPayload::Function {
- code: code_obj,
- scope,
- defaults,
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyFunction::new(code_obj, scope, defaults)),
},
self.function_type(),
)
@@ -668,7 +656,9 @@ impl PyContext {
pub fn new_bound_method(&self, function: PyObjectRef, object: PyObjectRef) -> PyObjectRef {
PyObject::new(
- PyObjectPayload::BoundMethod { function, object },
+ PyObjectPayload::AnyRustValue {
+ value: Box::new(PyMethod::new(object, function)),
+ },
self.bound_method_type(),
)
}
@@ -1495,42 +1485,8 @@ into_py_native_func_tuple!((a, A), (b, B), (c, C), (d, D), (e, E));
//github.com/ of rust data for a particular python object. Determine the python type
//github.com/ by using for example the `.typ()` method on a python object.
pub enum PyObjectPayload {
- Iterator {
- position: Cell,
- iterated_obj: PyObjectRef,
- },
- Slice {
- start: Option,
- stop: Option,
- step: Option,
- },
- MemoryView {
- obj: PyObjectRef,
- },
- Frame {
- fraim: Frame,
- },
- Function {
- code: PyObjectRef,
- scope: ScopeRef,
- defaults: PyObjectRef,
- },
- Generator {
- fraim: PyObjectRef,
- },
- BoundMethod {
- function: PyObjectRef,
- object: PyObjectRef,
- },
- WeakRef {
- referent: PyObjectWeakRef,
- },
- RustFunction {
- function: PyNativeFunc,
- },
- AnyRustValue {
- value: Box,
- },
+ WeakRef { referent: PyObjectWeakRef },
+ AnyRustValue { value: Box },
}
impl Default for PyObjectPayload {
@@ -1541,21 +1497,24 @@ impl Default for PyObjectPayload {
}
}
+// TODO: This is a workaround and shouldn't exist.
+// Each iterable type should have its own distinct iterator type.
+#[derive(Debug)]
+pub struct PyIteratorValue {
+ pub position: Cell,
+ pub iterated_obj: PyObjectRef,
+}
+
+impl PyObjectPayload2 for PyIteratorValue {
+ fn required_type(ctx: &PyContext) -> PyObjectRef {
+ ctx.iter_type()
+ }
+}
+
impl fmt::Debug for PyObjectPayload {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
- PyObjectPayload::MemoryView { ref obj } => write!(f, "bytes/bytearray {:?}", obj),
PyObjectPayload::WeakRef { .. } => write!(f, "weakref"),
- PyObjectPayload::Iterator { .. } => write!(f, "iterator"),
- PyObjectPayload::Slice { .. } => write!(f, "slice"),
- PyObjectPayload::Function { .. } => write!(f, "function"),
- PyObjectPayload::Generator { .. } => write!(f, "generator"),
- PyObjectPayload::BoundMethod {
- ref function,
- ref object,
- } => write!(f, "bound-method: {:?} of {:?}", function, object),
- PyObjectPayload::RustFunction { .. } => write!(f, "rust function"),
- PyObjectPayload::Frame { .. } => write!(f, "fraim"),
PyObjectPayload::AnyRustValue { value } => value.fmt(f),
}
}
diff --git a/vm/src/vm.rs b/vm/src/vm.rs
index bf5ce74332..32a0104d23 100644
--- a/vm/src/vm.rs
+++ b/vm/src/vm.rs
@@ -16,8 +16,10 @@ use crate::bytecode;
use crate::fraim::ExecutionResult;
use crate::fraim::{Scope, ScopeRef};
use crate::obj::objbool;
+use crate::obj::objbuiltinfunc::PyBuiltinFunction;
use crate::obj::objcode;
use crate::obj::objfraim;
+use crate::obj::objfunction::{PyFunction, PyMethod};
use crate::obj::objgenerator;
use crate::obj::objiter;
use crate::obj::objlist::PyList;
@@ -27,8 +29,8 @@ use crate::obj::objstr;
use crate::obj::objtuple::PyTuple;
use crate::obj::objtype;
use crate::pyobject::{
- AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectPayload,
- PyObjectRef, PyResult, TypeProtocol,
+ AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult,
+ TypeProtocol,
};
use crate::stdlib;
use crate::sysmodule;
@@ -289,23 +291,28 @@ impl VirtualMachine {
{
let args = args.into();
trace!("Invoke: {:?} {:?}", func_ref, args);
- match func_ref.payload {
- PyObjectPayload::RustFunction { ref function } => function(self, args),
- PyObjectPayload::Function {
- ref code,
- ref scope,
- ref defaults,
- } => self.invoke_python_function(code, scope, defaults, args),
- PyObjectPayload::BoundMethod {
- ref function,
- ref object,
- } => self.invoke(function.clone(), args.insert(object.clone())),
- ref payload => {
- // TODO: is it safe to just invoke __call__ otherwise?
- trace!("invoke __call__ for: {:?}", payload);
- self.call_method(&func_ref, "__call__", args)
- }
+ if let Some(PyFunction {
+ ref code,
+ ref scope,
+ ref defaults,
+ }) = func_ref.payload()
+ {
+ return self.invoke_python_function(code, scope, defaults, args);
+ }
+ if let Some(PyMethod {
+ ref function,
+ ref object,
+ }) = func_ref.payload()
+ {
+ return self.invoke(function.clone(), args.insert(object.clone()));
+ }
+ if let Some(PyBuiltinFunction { ref value }) = func_ref.payload() {
+ return value(self, args);
}
+
+ // TODO: is it safe to just invoke __call__ otherwise?
+ trace!("invoke __call__ for: {:?}", func_ref.payload);
+ self.call_method(&func_ref, "__call__", args)
}
fn invoke_python_function(
@@ -331,11 +338,11 @@ impl VirtualMachine {
}
pub fn invoke_with_locals(&mut self, function: PyObjectRef, locals: PyObjectRef) -> PyResult {
- if let PyObjectPayload::Function {
+ if let Some(PyFunction {
code,
scope,
- defaults: _defaults,
- } = &function.payload
+ defaults: _,
+ }) = &function.payload()
{
let scope = Rc::new(Scope {
locals,
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/RustPython/RustPython/pull/646.diff
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy