mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Attempt to reduce the size of the pyobject.rs files by splitting out builtin types.
This commit is contained in:
@@ -3,7 +3,8 @@ use crate::obj::objsequence;
|
||||
use crate::obj::objtuple::{PyTuple, PyTupleRef};
|
||||
use crate::obj::objtype;
|
||||
use crate::obj::objtype::PyClassRef;
|
||||
use crate::pyobject::{create_type, IdProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::pyobject::{IdProtocol, PyContext, PyObjectRef, PyResult, TypeProtocol};
|
||||
use crate::types::create_type;
|
||||
use crate::vm::VirtualMachine;
|
||||
use itertools::Itertools;
|
||||
use std::fs::File;
|
||||
|
||||
@@ -68,6 +68,7 @@ pub mod scope;
|
||||
pub mod stdlib;
|
||||
mod sysmodule;
|
||||
mod traceback;
|
||||
pub mod types;
|
||||
pub mod util;
|
||||
mod version;
|
||||
mod vm;
|
||||
|
||||
@@ -66,7 +66,7 @@ Returns True when the argument x is true, False otherwise.
|
||||
The builtins True and False are the only two instances of the class bool.
|
||||
The class bool is a subclass of the class int, and cannot be subclassed.";
|
||||
|
||||
let bool_type = &context.bool_type;
|
||||
let bool_type = &context.types.bool_type;
|
||||
extend_class!(context, bool_type, {
|
||||
"__new__" => context.new_rustfunc(bool_new),
|
||||
"__repr__" => context.new_rustfunc(bool_repr),
|
||||
|
||||
@@ -78,14 +78,14 @@ impl PyValue for PyByteArray {
|
||||
|
||||
/// Fill bytearray class methods dictionary.
|
||||
pub fn init(context: &PyContext) {
|
||||
PyByteArrayRef::extend_class(context, &context.bytearray_type);
|
||||
let bytearray_type = &context.bytearray_type;
|
||||
PyByteArrayRef::extend_class(context, &context.types.bytearray_type);
|
||||
let bytearray_type = &context.types.bytearray_type;
|
||||
extend_class!(context, bytearray_type, {
|
||||
"fromhex" => context.new_rustfunc(PyByteArrayRef::fromhex),
|
||||
"maketrans" => context.new_rustfunc(PyByteInner::maketrans),
|
||||
});
|
||||
|
||||
PyByteArrayIterator::extend_class(context, &context.bytearrayiterator_type);
|
||||
PyByteArrayIterator::extend_class(context, &context.types.bytearrayiterator_type);
|
||||
}
|
||||
|
||||
#[pyimpl]
|
||||
|
||||
@@ -85,14 +85,14 @@ pub fn get_value<'a>(obj: &'a PyObjectRef) -> impl Deref<Target = Vec<u8>> + 'a
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyBytesRef::extend_class(context, &context.bytes_type);
|
||||
let bytes_type = &context.bytes_type;
|
||||
PyBytesRef::extend_class(context, &context.types.bytes_type);
|
||||
let bytes_type = &context.types.bytes_type;
|
||||
extend_class!(context, bytes_type, {
|
||||
"fromhex" => context.new_rustfunc(PyBytesRef::fromhex),
|
||||
"maketrans" => context.new_rustfunc(PyByteInner::maketrans),
|
||||
|
||||
});
|
||||
PyBytesIterator::extend_class(context, &context.bytesiterator_type);
|
||||
PyBytesIterator::extend_class(context, &context.types.bytesiterator_type);
|
||||
}
|
||||
|
||||
#[pyimpl]
|
||||
|
||||
@@ -65,5 +65,5 @@ impl PyClassMethod {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyClassMethod::extend_class(context, &context.classmethod_type);
|
||||
PyClassMethod::extend_class(context, &context.types.classmethod_type);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ impl PyCodeRef {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
extend_class!(context, &context.code_type, {
|
||||
extend_class!(context, &context.types.code_type, {
|
||||
"__new__" => context.new_rustfunc(PyCodeRef::new),
|
||||
"__repr__" => context.new_rustfunc(PyCodeRef::repr),
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ impl From<Complex64> for PyComplex {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyComplex::extend_class(context, &context.complex_type);
|
||||
PyComplex::extend_class(context, &context.types.complex_type);
|
||||
}
|
||||
|
||||
pub fn get_value(obj: &PyObjectRef) -> Complex64 {
|
||||
|
||||
@@ -423,7 +423,7 @@ macro_rules! dict_iterator {
|
||||
|
||||
impl PyValue for $name {
|
||||
fn class(vm: &VirtualMachine) -> PyClassRef {
|
||||
vm.ctx.$class.clone()
|
||||
vm.ctx.types.$class.clone()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ macro_rules! dict_iterator {
|
||||
|
||||
impl PyValue for $iter_name {
|
||||
fn class(vm: &VirtualMachine) -> PyClassRef {
|
||||
vm.ctx.$iter_class.clone()
|
||||
vm.ctx.types.$iter_class.clone()
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -511,7 +511,7 @@ dict_iterator! {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
extend_class!(context, &context.dict_type, {
|
||||
extend_class!(context, &context.types.dict_type, {
|
||||
"__bool__" => context.new_rustfunc(PyDictRef::bool),
|
||||
"__len__" => context.new_rustfunc(PyDictRef::len),
|
||||
"__contains__" => context.new_rustfunc(PyDictRef::contains),
|
||||
@@ -536,10 +536,10 @@ pub fn init(context: &PyContext) {
|
||||
"popitem" => context.new_rustfunc(PyDictRef::popitem),
|
||||
});
|
||||
|
||||
PyDictKeys::extend_class(context, &context.dictkeys_type);
|
||||
PyDictKeyIterator::extend_class(context, &context.dictkeyiterator_type);
|
||||
PyDictValues::extend_class(context, &context.dictvalues_type);
|
||||
PyDictValueIterator::extend_class(context, &context.dictvalueiterator_type);
|
||||
PyDictItems::extend_class(context, &context.dictitems_type);
|
||||
PyDictItemIterator::extend_class(context, &context.dictitemiterator_type);
|
||||
PyDictKeys::extend_class(context, &context.types.dictkeys_type);
|
||||
PyDictKeyIterator::extend_class(context, &context.types.dictkeyiterator_type);
|
||||
PyDictValues::extend_class(context, &context.types.dictvalues_type);
|
||||
PyDictValueIterator::extend_class(context, &context.types.dictvalueiterator_type);
|
||||
PyDictItems::extend_class(context, &context.types.dictitems_type);
|
||||
PyDictItemIterator::extend_class(context, &context.types.dictitemiterator_type);
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@ impl PyEnumerate {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyEnumerate::extend_class(context, &context.enumerate_type);
|
||||
extend_class!(context, &context.enumerate_type, {
|
||||
PyEnumerate::extend_class(context, &context.types.enumerate_type);
|
||||
extend_class!(context, &context.types.enumerate_type, {
|
||||
"__new__" => context.new_rustfunc(enumerate_new),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ impl PyFilter {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyFilter::extend_class(context, &context.filter_type);
|
||||
extend_class!(context, &context.filter_type, {
|
||||
PyFilter::extend_class(context, &context.types.filter_type);
|
||||
extend_class!(context, &context.types.filter_type, {
|
||||
"__new__" => context.new_rustfunc(filter_new),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -619,5 +619,5 @@ pub fn make_float(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<f64> {
|
||||
|
||||
#[rustfmt::skip] // to avoid line splitting
|
||||
pub fn init(context: &PyContext) {
|
||||
PyFloat::extend_class(context, &context.float_type);
|
||||
PyFloat::extend_class(context, &context.types.float_type);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::pyobject::{PyContext, PyObjectRef, PyResult};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
extend_class!(context, &context.frame_type, {
|
||||
extend_class!(context, &context.types.frame_type, {
|
||||
"__new__" => context.new_rustfunc(FrameRef::new),
|
||||
"__repr__" => context.new_rustfunc(FrameRef::repr),
|
||||
"f_locals" => context.new_property(FrameRef::flocals),
|
||||
|
||||
@@ -78,7 +78,7 @@ impl PyValue for PyMethod {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let function_type = &context.function_type;
|
||||
let function_type = &context.types.function_type;
|
||||
extend_class!(context, function_type, {
|
||||
"__get__" => context.new_rustfunc(bind_method),
|
||||
"__call__" => context.new_rustfunc(PyFunctionRef::call),
|
||||
@@ -87,7 +87,7 @@ pub fn init(context: &PyContext) {
|
||||
"__kwdefaults__" => context.new_property(PyFunctionRef::kwdefaults),
|
||||
});
|
||||
|
||||
let builtin_function_or_method_type = &context.builtin_function_or_method_type;
|
||||
let builtin_function_or_method_type = &context.types.builtin_function_or_method_type;
|
||||
extend_class!(context, builtin_function_or_method_type, {
|
||||
"__get__" => context.new_rustfunc(bind_method)
|
||||
});
|
||||
|
||||
@@ -75,5 +75,5 @@ fn handle_execution_result(result: ExecutionResult, vm: &VirtualMachine) -> PyRe
|
||||
}
|
||||
|
||||
pub fn init(ctx: &PyContext) {
|
||||
PyGenerator::extend_class(ctx, &ctx.generator_type);
|
||||
PyGenerator::extend_class(ctx, &ctx.types.generator_type);
|
||||
}
|
||||
|
||||
@@ -671,7 +671,7 @@ impl IntOptions {
|
||||
fn get_int_value(self, vm: &VirtualMachine) -> PyResult<BigInt> {
|
||||
if let OptionalArg::Present(val) = self.val_options {
|
||||
let base = if let OptionalArg::Present(base) = self.base {
|
||||
if !objtype::isinstance(&val, &vm.ctx.str_type) {
|
||||
if !objtype::isinstance(&val, &vm.ctx.str_type()) {
|
||||
return Err(vm.new_type_error(
|
||||
"int() can't convert non-string with explicit base".to_string(),
|
||||
));
|
||||
@@ -766,8 +766,8 @@ fn div_ints(vm: &VirtualMachine, i1: &BigInt, i2: &BigInt) -> PyResult {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyInt::extend_class(context, &context.int_type);
|
||||
extend_class!(context, &context.int_type, {
|
||||
PyInt::extend_class(context, &context.types.int_type);
|
||||
extend_class!(context, &context.types.int_type, {
|
||||
"__new__" => context.new_rustfunc(int_new),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -122,5 +122,5 @@ impl PySequenceIterator {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PySequenceIterator::extend_class(context, &context.iter_type);
|
||||
PySequenceIterator::extend_class(context, &context.types.iter_type);
|
||||
}
|
||||
|
||||
@@ -859,7 +859,7 @@ impl PyListReverseIterator {
|
||||
|
||||
#[rustfmt::skip] // to avoid line splitting
|
||||
pub fn init(context: &PyContext) {
|
||||
let list_type = &context.list_type;
|
||||
let list_type = &context.types.list_type;
|
||||
|
||||
let list_doc = "Built-in mutable sequence.\n\n\
|
||||
If no argument is given, the constructor creates a new empty list.\n\
|
||||
@@ -901,6 +901,6 @@ pub fn init(context: &PyContext) {
|
||||
"remove" => context.new_rustfunc(PyListRef::remove)
|
||||
});
|
||||
|
||||
PyListIterator::extend_class(context, &context.listiterator_type);
|
||||
PyListReverseIterator::extend_class(context, &context.listreverseiterator_type);
|
||||
PyListIterator::extend_class(context, &context.types.listiterator_type);
|
||||
PyListReverseIterator::extend_class(context, &context.types.listreverseiterator_type);
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ impl PyMap {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyMap::extend_class(context, &context.map_type);
|
||||
extend_class!(context, &context.map_type, {
|
||||
PyMap::extend_class(context, &context.types.map_type);
|
||||
extend_class!(context, &context.types.map_type, {
|
||||
"__new__" => context.new_rustfunc(map_new),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ pub type PyMappingProxyRef = PyRef<PyMappingProxy>;
|
||||
|
||||
impl PyValue for PyMappingProxy {
|
||||
fn class(vm: &VirtualMachine) -> PyClassRef {
|
||||
vm.ctx.mappingproxy_type.clone()
|
||||
vm.ctx.types.mappingproxy_type.clone()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,5 +38,5 @@ impl PyMappingProxy {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyMappingProxy::extend_class(context, &context.mappingproxy_type)
|
||||
PyMappingProxy::extend_class(context, &context.types.mappingproxy_type)
|
||||
}
|
||||
|
||||
@@ -47,5 +47,5 @@ impl PyValue for PyMemoryView {
|
||||
}
|
||||
|
||||
pub fn init(ctx: &PyContext) {
|
||||
PyMemoryView::extend_class(ctx, &ctx.memoryview_type)
|
||||
PyMemoryView::extend_class(ctx, &ctx.types.memoryview_type)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ impl PyModuleRef {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
extend_class!(&context, &context.module_type, {
|
||||
extend_class!(&context, &context.types.module_type, {
|
||||
"__init__" => context.new_rustfunc(PyModuleRef::init),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,5 +28,5 @@ impl PyNamespace {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyNamespace::extend_class(context, &context.namespace_type);
|
||||
PyNamespace::extend_class(context, &context.types.namespace_type);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ impl PyValue for PyInstance {
|
||||
pub fn new_instance(vm: &VirtualMachine, mut args: PyFuncArgs) -> PyResult {
|
||||
// more or less __new__ operator
|
||||
let cls = PyClassRef::try_from_object(vm, args.shift())?;
|
||||
let dict = if cls.is(&vm.ctx.object) {
|
||||
let dict = if cls.is(&vm.ctx.object()) {
|
||||
None
|
||||
} else {
|
||||
Some(vm.ctx.new_dict())
|
||||
@@ -149,7 +149,7 @@ fn object_format(
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let object = &context.object;
|
||||
let object = &context.types.object_type;
|
||||
let object_doc = "The most base type";
|
||||
|
||||
extend_class!(context, object, {
|
||||
|
||||
@@ -293,6 +293,6 @@ impl<'a> PropertyBuilder<'a> {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyReadOnlyProperty::extend_class(context, &context.readonly_property_type);
|
||||
PyProperty::extend_class(context, &context.property_type);
|
||||
PyReadOnlyProperty::extend_class(context, &context.types.readonly_property_type);
|
||||
PyProperty::extend_class(context, &context.types.property_type);
|
||||
}
|
||||
|
||||
@@ -105,8 +105,8 @@ pub fn get_value(obj: &PyObjectRef) -> PyRange {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyRange::extend_class(context, &context.range_type);
|
||||
PyRangeIterator::extend_class(context, &context.rangeiterator_type);
|
||||
PyRange::extend_class(context, &context.types.range_type);
|
||||
PyRangeIterator::extend_class(context, &context.types.rangeiterator_type);
|
||||
}
|
||||
|
||||
type PyRangeRef = PyRef<PyRange>;
|
||||
|
||||
@@ -748,6 +748,6 @@ impl TryFromObject for SetIterable {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PySet::extend_class(context, &context.set_type);
|
||||
PyFrozenSet::extend_class(context, &context.frozenset_type);
|
||||
PySet::extend_class(context, &context.types.set_type);
|
||||
PyFrozenSet::extend_class(context, &context.types.frozenset_type);
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ fn to_index_value(vm: &VirtualMachine, obj: &PyObjectRef) -> PyResult<Option<Big
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let slice_type = &context.slice_type;
|
||||
let slice_type = &context.types.slice_type;
|
||||
|
||||
extend_class!(context, slice_type, {
|
||||
"__new__" => context.new_rustfunc(slice_new),
|
||||
|
||||
@@ -32,7 +32,7 @@ impl PyStaticMethodRef {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let staticmethod_type = &context.staticmethod_type;
|
||||
let staticmethod_type = &context.types.staticmethod_type;
|
||||
extend_class!(context, staticmethod_type, {
|
||||
"__get__" => context.new_rustfunc(PyStaticMethodRef::get),
|
||||
"__new__" => context.new_rustfunc(PyStaticMethodRef::new),
|
||||
|
||||
@@ -1145,10 +1145,10 @@ impl IntoPyObject for &String {
|
||||
}
|
||||
|
||||
pub fn init(ctx: &PyContext) {
|
||||
PyString::extend_class(ctx, &ctx.str_type);
|
||||
PyString::extend_class(ctx, &ctx.types.str_type);
|
||||
|
||||
PyStringIterator::extend_class(ctx, &ctx.striterator_type);
|
||||
PyStringReverseIterator::extend_class(ctx, &ctx.strreverseiterator_type);
|
||||
PyStringIterator::extend_class(ctx, &ctx.types.striterator_type);
|
||||
PyStringReverseIterator::extend_class(ctx, &ctx.types.strreverseiterator_type);
|
||||
}
|
||||
|
||||
pub fn get_value(obj: &PyObjectRef) -> String {
|
||||
@@ -1312,9 +1312,9 @@ fn do_cformat(
|
||||
} else {
|
||||
// check for only literal parts, in which case only dict or empty tuple is allowed
|
||||
if num_specifiers == 0
|
||||
&& !(objtype::isinstance(&values_obj, &vm.ctx.tuple_type)
|
||||
&& !(objtype::isinstance(&values_obj, &vm.ctx.types.tuple_type)
|
||||
&& objtuple::get_value(&values_obj).is_empty())
|
||||
&& !objtype::isinstance(&values_obj, &vm.ctx.dict_type)
|
||||
&& !objtype::isinstance(&values_obj, &vm.ctx.types.dict_type)
|
||||
{
|
||||
return Err(vm.new_type_error(
|
||||
"not all arguments converted during string formatting".to_string(),
|
||||
@@ -1380,7 +1380,7 @@ fn do_cformat(
|
||||
.into_iter()
|
||||
.nth(tuple_index)
|
||||
.is_some())
|
||||
&& !objtype::isinstance(&values_obj, &vm.ctx.dict_type)
|
||||
&& !objtype::isinstance(&values_obj, &vm.ctx.types.dict_type)
|
||||
{
|
||||
return Err(
|
||||
vm.new_type_error("not all arguments converted during string formatting".to_string())
|
||||
|
||||
@@ -33,7 +33,7 @@ impl PyValue for PySuper {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
let super_type = &context.super_type;
|
||||
let super_type = &context.types.super_type;
|
||||
|
||||
let super_doc = "super() -> same as super(__class__, <first argument>)\n\
|
||||
super(type) -> unbound super object\n\
|
||||
|
||||
@@ -276,7 +276,7 @@ impl PyTupleIterator {
|
||||
|
||||
#[rustfmt::skip] // to avoid line splitting
|
||||
pub fn init(context: &PyContext) {
|
||||
let tuple_type = &context.tuple_type;
|
||||
let tuple_type = &context.types.tuple_type;
|
||||
let tuple_doc = "tuple() -> empty tuple
|
||||
tuple(iterable) -> tuple initialized from iterable's items
|
||||
|
||||
@@ -303,5 +303,5 @@ If the argument is a tuple, the return value is the same object.";
|
||||
"index" => context.new_rustfunc(PyTupleRef::index)
|
||||
});
|
||||
|
||||
PyTupleIterator::extend_class(context, &context.tupleiterator_type);
|
||||
PyTupleIterator::extend_class(context, &context.types.tupleiterator_type);
|
||||
}
|
||||
|
||||
@@ -212,7 +212,7 @@ pub fn init(ctx: &PyContext) {
|
||||
type(object) -> the object's type\n\
|
||||
type(name, bases, dict) -> a new type";
|
||||
|
||||
extend_class!(&ctx, &ctx.type_type, {
|
||||
extend_class!(&ctx, &ctx.types.type_type, {
|
||||
"__call__" => ctx.new_rustfunc(type_call),
|
||||
"__dict__" =>
|
||||
PropertyBuilder::new(ctx)
|
||||
@@ -433,8 +433,8 @@ mod tests {
|
||||
#[test]
|
||||
fn test_linearise() {
|
||||
let context = PyContext::new();
|
||||
let object: PyClassRef = context.object.clone();
|
||||
let type_type = &context.type_type;
|
||||
let object: PyClassRef = context.object();
|
||||
let type_type = &context.types.type_type;
|
||||
|
||||
let a = new(type_type.clone(), "A", vec![object.clone()], HashMap::new()).unwrap();
|
||||
let b = new(type_type.clone(), "B", vec![object.clone()], HashMap::new()).unwrap();
|
||||
|
||||
@@ -61,5 +61,5 @@ impl PyWeakProxy {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyWeakProxy::extend_class(&context, &context.weakproxy_type);
|
||||
PyWeakProxy::extend_class(&context, &context.types.weakproxy_type);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ impl PyWeakRef {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
extend_class!(context, &context.weakref_type, {
|
||||
extend_class!(context, &context.types.weakref_type, {
|
||||
"__new__" => context.new_rustfunc(PyWeakRef::create),
|
||||
"__call__" => context.new_rustfunc(PyWeakRef::call)
|
||||
});
|
||||
|
||||
@@ -51,8 +51,8 @@ impl PyZip {
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyZip::extend_class(context, &context.zip_type);
|
||||
extend_class!(context, &context.zip_type, {
|
||||
PyZip::extend_class(context, &context.types.zip_type);
|
||||
extend_class!(context, &context.types.zip_type, {
|
||||
"__new__" => context.new_rustfunc(zip_new),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
use std::any::Any;
|
||||
use std::cell::Cell;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
|
||||
use num_bigint::BigInt;
|
||||
@@ -16,46 +13,30 @@ use num_traits::{One, Zero};
|
||||
use crate::bytecode;
|
||||
use crate::exceptions;
|
||||
use crate::function::{IntoPyNativeFunc, PyFuncArgs};
|
||||
use crate::obj::objbool;
|
||||
use crate::obj::objbuiltinfunc::PyBuiltinFunction;
|
||||
use crate::obj::objbytearray;
|
||||
use crate::obj::objbytes;
|
||||
use crate::obj::objclassmethod::{self, PyClassMethod};
|
||||
use crate::obj::objclassmethod::PyClassMethod;
|
||||
use crate::obj::objcode;
|
||||
use crate::obj::objcode::PyCodeRef;
|
||||
use crate::obj::objcomplex::{self, PyComplex};
|
||||
use crate::obj::objdict::{self, PyDict, PyDictRef};
|
||||
use crate::obj::objellipsis;
|
||||
use crate::obj::objenumerate;
|
||||
use crate::obj::objfilter;
|
||||
use crate::obj::objfloat::{self, PyFloat};
|
||||
use crate::obj::objframe;
|
||||
use crate::obj::objfunction::{self, PyFunction, PyMethod};
|
||||
use crate::obj::objgenerator;
|
||||
use crate::obj::objint::{self, PyInt, PyIntRef};
|
||||
use crate::obj::objcomplex::PyComplex;
|
||||
use crate::obj::objdict::{PyDict, PyDictRef};
|
||||
use crate::obj::objfloat::PyFloat;
|
||||
use crate::obj::objfunction::{PyFunction, PyMethod};
|
||||
use crate::obj::objint::{PyInt, PyIntRef};
|
||||
use crate::obj::objiter;
|
||||
use crate::obj::objlist::{self, PyList};
|
||||
use crate::obj::objmap;
|
||||
use crate::obj::objmappingproxy;
|
||||
use crate::obj::objmemory;
|
||||
use crate::obj::objmodule::{self, PyModule};
|
||||
use crate::obj::objnamespace::{self, PyNamespace};
|
||||
use crate::obj::objnone::{self, PyNone, PyNoneRef};
|
||||
use crate::obj::objlist::PyList;
|
||||
use crate::obj::objmodule::PyModule;
|
||||
use crate::obj::objnamespace::PyNamespace;
|
||||
use crate::obj::objnone::{PyNone, PyNoneRef};
|
||||
use crate::obj::objobject;
|
||||
use crate::obj::objproperty;
|
||||
use crate::obj::objproperty::PropertyBuilder;
|
||||
use crate::obj::objrange;
|
||||
use crate::obj::objset::{self, PySet};
|
||||
use crate::obj::objslice;
|
||||
use crate::obj::objstaticmethod;
|
||||
use crate::obj::objset::PySet;
|
||||
use crate::obj::objstr;
|
||||
use crate::obj::objsuper;
|
||||
use crate::obj::objtuple::{self, PyTuple, PyTupleRef};
|
||||
use crate::obj::objtuple::{PyTuple, PyTupleRef};
|
||||
use crate::obj::objtype::{self, PyClass, PyClassRef};
|
||||
use crate::obj::objweakproxy;
|
||||
use crate::obj::objweakref;
|
||||
use crate::obj::objzip;
|
||||
use crate::scope::Scope;
|
||||
use crate::types::{create_type, initialize_types, TypeZoo};
|
||||
use crate::vm::VirtualMachine;
|
||||
use indexmap::IndexMap;
|
||||
|
||||
@@ -112,71 +93,16 @@ impl fmt::Display for PyObject<dyn PyObjectPayload> {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PyContext {
|
||||
pub bytes_type: PyClassRef,
|
||||
pub bytesiterator_type: PyClassRef,
|
||||
pub bytearray_type: PyClassRef,
|
||||
pub bytearrayiterator_type: PyClassRef,
|
||||
pub bool_type: PyClassRef,
|
||||
pub classmethod_type: PyClassRef,
|
||||
pub code_type: PyClassRef,
|
||||
pub dict_type: PyClassRef,
|
||||
pub ellipsis_type: PyClassRef,
|
||||
pub enumerate_type: PyClassRef,
|
||||
pub filter_type: PyClassRef,
|
||||
pub float_type: PyClassRef,
|
||||
pub frame_type: PyClassRef,
|
||||
pub frozenset_type: PyClassRef,
|
||||
pub generator_type: PyClassRef,
|
||||
pub int_type: PyClassRef,
|
||||
pub iter_type: PyClassRef,
|
||||
pub complex_type: PyClassRef,
|
||||
pub true_value: PyIntRef,
|
||||
pub false_value: PyIntRef,
|
||||
pub list_type: PyClassRef,
|
||||
pub listiterator_type: PyClassRef,
|
||||
pub listreverseiterator_type: PyClassRef,
|
||||
pub striterator_type: PyClassRef,
|
||||
pub strreverseiterator_type: PyClassRef,
|
||||
pub dictkeyiterator_type: PyClassRef,
|
||||
pub dictvalueiterator_type: PyClassRef,
|
||||
pub dictitemiterator_type: PyClassRef,
|
||||
pub dictkeys_type: PyClassRef,
|
||||
pub dictvalues_type: PyClassRef,
|
||||
pub dictitems_type: PyClassRef,
|
||||
pub map_type: PyClassRef,
|
||||
pub memoryview_type: PyClassRef,
|
||||
pub none: PyNoneRef,
|
||||
pub empty_tuple: PyTupleRef,
|
||||
pub ellipsis_type: PyClassRef,
|
||||
pub ellipsis: PyEllipsisRef,
|
||||
pub not_implemented: PyNotImplementedRef,
|
||||
pub empty_tuple: PyTupleRef,
|
||||
pub tuple_type: PyClassRef,
|
||||
pub tupleiterator_type: PyClassRef,
|
||||
pub set_type: PyClassRef,
|
||||
pub staticmethod_type: PyClassRef,
|
||||
pub super_type: PyClassRef,
|
||||
pub str_type: PyClassRef,
|
||||
pub range_type: PyClassRef,
|
||||
pub rangeiterator_type: PyClassRef,
|
||||
pub slice_type: PyClassRef,
|
||||
pub type_type: PyClassRef,
|
||||
pub zip_type: PyClassRef,
|
||||
pub function_type: PyClassRef,
|
||||
pub builtin_function_or_method_type: PyClassRef,
|
||||
pub property_type: PyClassRef,
|
||||
pub readonly_property_type: PyClassRef,
|
||||
pub module_type: PyClassRef,
|
||||
pub namespace_type: PyClassRef,
|
||||
pub bound_method_type: PyClassRef,
|
||||
pub weakref_type: PyClassRef,
|
||||
pub weakproxy_type: PyClassRef,
|
||||
pub mappingproxy_type: PyClassRef,
|
||||
pub object: PyClassRef,
|
||||
pub exceptions: exceptions::ExceptionZoo,
|
||||
}
|
||||
|
||||
pub fn create_type(name: &str, type_type: &PyClassRef, base: &PyClassRef) -> PyClassRef {
|
||||
let dict = PyAttributes::new();
|
||||
objtype::new(type_type.clone(), name, vec![base.clone()], dict).unwrap()
|
||||
pub types: TypeZoo,
|
||||
pub exceptions: exceptions::ExceptionZoo,
|
||||
}
|
||||
|
||||
pub type PyNotImplementedRef = PyRef<PyNotImplemented>;
|
||||
@@ -201,115 +127,12 @@ impl PyValue for PyEllipsis {
|
||||
}
|
||||
}
|
||||
|
||||
fn init_type_hierarchy() -> (PyClassRef, PyClassRef) {
|
||||
// `type` inherits from `object`
|
||||
// and both `type` and `object are instances of `type`.
|
||||
// to produce this circular dependency, we need an unsafe block.
|
||||
// (and yes, this will never get dropped. TODO?)
|
||||
let (type_type, object_type) = unsafe {
|
||||
let object_type = PyObject {
|
||||
typ: mem::uninitialized(), // !
|
||||
dict: None,
|
||||
payload: PyClass {
|
||||
name: String::from("object"),
|
||||
mro: vec![],
|
||||
subclasses: RefCell::new(vec![]),
|
||||
attributes: RefCell::new(PyAttributes::new()),
|
||||
},
|
||||
}
|
||||
.into_ref();
|
||||
|
||||
let type_type = PyObject {
|
||||
typ: mem::uninitialized(), // !
|
||||
dict: None,
|
||||
payload: PyClass {
|
||||
name: String::from("type"),
|
||||
mro: vec![object_type.clone().downcast().unwrap()],
|
||||
subclasses: RefCell::new(vec![]),
|
||||
attributes: RefCell::new(PyAttributes::new()),
|
||||
},
|
||||
}
|
||||
.into_ref();
|
||||
|
||||
let object_type_ptr = PyObjectRef::into_raw(object_type.clone()) as *mut PyObject<PyClass>;
|
||||
let type_type_ptr = PyObjectRef::into_raw(type_type.clone()) as *mut PyObject<PyClass>;
|
||||
|
||||
let type_type: PyClassRef = type_type.downcast().unwrap();
|
||||
let object_type: PyClassRef = object_type.downcast().unwrap();
|
||||
|
||||
ptr::write(&mut (*object_type_ptr).typ, type_type.clone());
|
||||
ptr::write(&mut (*type_type_ptr).typ, type_type.clone());
|
||||
|
||||
(type_type, object_type)
|
||||
};
|
||||
|
||||
object_type
|
||||
.subclasses
|
||||
.borrow_mut()
|
||||
.push(objweakref::PyWeak::downgrade(&type_type.as_object()));
|
||||
|
||||
(type_type, object_type)
|
||||
}
|
||||
|
||||
// Basic objects:
|
||||
impl PyContext {
|
||||
pub fn new() -> Self {
|
||||
flame_guard!("init PyContext");
|
||||
let (type_type, object_type) = init_type_hierarchy();
|
||||
|
||||
let dict_type = create_type("dict", &type_type, &object_type);
|
||||
let module_type = create_type("module", &type_type, &object_type);
|
||||
let namespace_type = create_type("SimpleNamespace", &type_type, &object_type);
|
||||
let classmethod_type = create_type("classmethod", &type_type, &object_type);
|
||||
let staticmethod_type = create_type("staticmethod", &type_type, &object_type);
|
||||
let function_type = create_type("function", &type_type, &object_type);
|
||||
let builtin_function_or_method_type =
|
||||
create_type("builtin_function_or_method", &type_type, &object_type);
|
||||
let property_type = create_type("property", &type_type, &object_type);
|
||||
let readonly_property_type = create_type("readonly_property", &type_type, &object_type);
|
||||
let super_type = create_type("super", &type_type, &object_type);
|
||||
let weakref_type = create_type("ref", &type_type, &object_type);
|
||||
let weakproxy_type = create_type("weakproxy", &type_type, &object_type);
|
||||
let generator_type = create_type("generator", &type_type, &object_type);
|
||||
let bound_method_type = create_type("method", &type_type, &object_type);
|
||||
let str_type = create_type("str", &type_type, &object_type);
|
||||
let list_type = create_type("list", &type_type, &object_type);
|
||||
let listiterator_type = create_type("list_iterator", &type_type, &object_type);
|
||||
let listreverseiterator_type =
|
||||
create_type("list_reverseiterator", &type_type, &object_type);
|
||||
let striterator_type = create_type("str_iterator", &type_type, &object_type);
|
||||
let strreverseiterator_type = create_type("str_reverseiterator", &type_type, &object_type);
|
||||
let dictkeys_type = create_type("dict_keys", &type_type, &object_type);
|
||||
let dictvalues_type = create_type("dict_values", &type_type, &object_type);
|
||||
let dictitems_type = create_type("dict_items", &type_type, &object_type);
|
||||
let dictkeyiterator_type = create_type("dict_keyiterator", &type_type, &object_type);
|
||||
let dictvalueiterator_type = create_type("dict_valueiterator", &type_type, &object_type);
|
||||
let dictitemiterator_type = create_type("dict_itemiterator", &type_type, &object_type);
|
||||
let set_type = create_type("set", &type_type, &object_type);
|
||||
let frozenset_type = create_type("frozenset", &type_type, &object_type);
|
||||
let int_type = create_type("int", &type_type, &object_type);
|
||||
let float_type = create_type("float", &type_type, &object_type);
|
||||
let frame_type = create_type("frame", &type_type, &object_type);
|
||||
let complex_type = create_type("complex", &type_type, &object_type);
|
||||
let bytes_type = create_type("bytes", &type_type, &object_type);
|
||||
let bytesiterator_type = create_type("bytes_iterator", &type_type, &object_type);
|
||||
let bytearray_type = create_type("bytearray", &type_type, &object_type);
|
||||
let bytearrayiterator_type = create_type("bytearray_iterator", &type_type, &object_type);
|
||||
let tuple_type = create_type("tuple", &type_type, &object_type);
|
||||
let tupleiterator_type = create_type("tuple_iterator", &type_type, &object_type);
|
||||
let iter_type = create_type("iter", &type_type, &object_type);
|
||||
let enumerate_type = create_type("enumerate", &type_type, &object_type);
|
||||
let filter_type = create_type("filter", &type_type, &object_type);
|
||||
let map_type = create_type("map", &type_type, &object_type);
|
||||
let zip_type = create_type("zip", &type_type, &object_type);
|
||||
let bool_type = create_type("bool", &type_type, &int_type);
|
||||
let memoryview_type = create_type("memoryview", &type_type, &object_type);
|
||||
let code_type = create_type("code", &type_type, &object_type);
|
||||
let range_type = create_type("range", &type_type, &object_type);
|
||||
let rangeiterator_type = create_type("range_iterator", &type_type, &object_type);
|
||||
let slice_type = create_type("slice", &type_type, &object_type);
|
||||
let mappingproxy_type = create_type("mappingproxy", &type_type, &object_type);
|
||||
let exceptions = exceptions::ExceptionZoo::new(&type_type, &object_type);
|
||||
let types = TypeZoo::new();
|
||||
let exceptions = exceptions::ExceptionZoo::new(&types.type_type, &types.object_type);
|
||||
|
||||
fn create_object<T: PyObjectPayload>(payload: T, cls: &PyClassRef) -> PyRef<T> {
|
||||
PyRef {
|
||||
@@ -318,297 +141,213 @@ impl PyContext {
|
||||
}
|
||||
}
|
||||
|
||||
let none_type = create_type("NoneType", &type_type, &object_type);
|
||||
let none_type = create_type("NoneType", &types.type_type, &types.object_type);
|
||||
let none = create_object(PyNone, &none_type);
|
||||
|
||||
let ellipsis_type = create_type("EllipsisType", &type_type, &object_type);
|
||||
let ellipsis_type = create_type("EllipsisType", &types.type_type, &types.object_type);
|
||||
let ellipsis = create_object(PyEllipsis, &ellipsis_type);
|
||||
|
||||
let not_implemented_type = create_type("NotImplementedType", &type_type, &object_type);
|
||||
let not_implemented_type =
|
||||
create_type("NotImplementedType", &types.type_type, &types.object_type);
|
||||
let not_implemented = create_object(PyNotImplemented, ¬_implemented_type);
|
||||
|
||||
let true_value = create_object(PyInt::new(BigInt::one()), &bool_type);
|
||||
let false_value = create_object(PyInt::new(BigInt::zero()), &bool_type);
|
||||
let true_value = create_object(PyInt::new(BigInt::one()), &types.bool_type);
|
||||
let false_value = create_object(PyInt::new(BigInt::zero()), &types.bool_type);
|
||||
|
||||
let empty_tuple = create_object(PyTuple::from(vec![]), &tuple_type);
|
||||
let empty_tuple = create_object(PyTuple::from(vec![]), &types.tuple_type);
|
||||
|
||||
let context = PyContext {
|
||||
bool_type,
|
||||
memoryview_type,
|
||||
bytearray_type,
|
||||
bytearrayiterator_type,
|
||||
bytes_type,
|
||||
bytesiterator_type,
|
||||
code_type,
|
||||
complex_type,
|
||||
classmethod_type,
|
||||
int_type,
|
||||
float_type,
|
||||
frame_type,
|
||||
staticmethod_type,
|
||||
list_type,
|
||||
listiterator_type,
|
||||
listreverseiterator_type,
|
||||
striterator_type,
|
||||
strreverseiterator_type,
|
||||
dictkeys_type,
|
||||
dictvalues_type,
|
||||
dictitems_type,
|
||||
dictkeyiterator_type,
|
||||
dictvalueiterator_type,
|
||||
dictitemiterator_type,
|
||||
set_type,
|
||||
frozenset_type,
|
||||
true_value,
|
||||
false_value,
|
||||
tuple_type,
|
||||
tupleiterator_type,
|
||||
iter_type,
|
||||
ellipsis_type,
|
||||
enumerate_type,
|
||||
filter_type,
|
||||
map_type,
|
||||
zip_type,
|
||||
dict_type,
|
||||
not_implemented,
|
||||
none,
|
||||
ellipsis,
|
||||
not_implemented,
|
||||
str_type,
|
||||
range_type,
|
||||
rangeiterator_type,
|
||||
slice_type,
|
||||
object: object_type,
|
||||
function_type,
|
||||
builtin_function_or_method_type,
|
||||
super_type,
|
||||
mappingproxy_type,
|
||||
property_type,
|
||||
readonly_property_type,
|
||||
generator_type,
|
||||
module_type,
|
||||
namespace_type,
|
||||
bound_method_type,
|
||||
weakref_type,
|
||||
weakproxy_type,
|
||||
type_type,
|
||||
ellipsis_type,
|
||||
|
||||
types,
|
||||
exceptions,
|
||||
empty_tuple,
|
||||
};
|
||||
objtype::init(&context);
|
||||
objlist::init(&context);
|
||||
objset::init(&context);
|
||||
objtuple::init(&context);
|
||||
objobject::init(&context);
|
||||
objdict::init(&context);
|
||||
objfunction::init(&context);
|
||||
objstaticmethod::init(&context);
|
||||
objclassmethod::init(&context);
|
||||
objgenerator::init(&context);
|
||||
objint::init(&context);
|
||||
objfloat::init(&context);
|
||||
objcomplex::init(&context);
|
||||
objbytes::init(&context);
|
||||
objbytearray::init(&context);
|
||||
objproperty::init(&context);
|
||||
objmemory::init(&context);
|
||||
objstr::init(&context);
|
||||
objrange::init(&context);
|
||||
objslice::init(&context);
|
||||
objsuper::init(&context);
|
||||
objtuple::init(&context);
|
||||
objiter::init(&context);
|
||||
objellipsis::init(&context);
|
||||
objenumerate::init(&context);
|
||||
objfilter::init(&context);
|
||||
objmap::init(&context);
|
||||
objzip::init(&context);
|
||||
objbool::init(&context);
|
||||
objcode::init(&context);
|
||||
objframe::init(&context);
|
||||
objweakref::init(&context);
|
||||
objweakproxy::init(&context);
|
||||
objnone::init(&context);
|
||||
objmodule::init(&context);
|
||||
objnamespace::init(&context);
|
||||
objmappingproxy::init(&context);
|
||||
initialize_types(&context);
|
||||
|
||||
exceptions::init(&context);
|
||||
context
|
||||
}
|
||||
|
||||
pub fn bytearray_type(&self) -> PyClassRef {
|
||||
self.bytearray_type.clone()
|
||||
self.types.bytearray_type.clone()
|
||||
}
|
||||
|
||||
pub fn bytearrayiterator_type(&self) -> PyClassRef {
|
||||
self.bytearrayiterator_type.clone()
|
||||
self.types.bytearrayiterator_type.clone()
|
||||
}
|
||||
|
||||
pub fn bytes_type(&self) -> PyClassRef {
|
||||
self.bytes_type.clone()
|
||||
self.types.bytes_type.clone()
|
||||
}
|
||||
|
||||
pub fn bytesiterator_type(&self) -> PyClassRef {
|
||||
self.bytesiterator_type.clone()
|
||||
self.types.bytesiterator_type.clone()
|
||||
}
|
||||
|
||||
pub fn code_type(&self) -> PyClassRef {
|
||||
self.code_type.clone()
|
||||
self.types.code_type.clone()
|
||||
}
|
||||
|
||||
pub fn complex_type(&self) -> PyClassRef {
|
||||
self.complex_type.clone()
|
||||
self.types.complex_type.clone()
|
||||
}
|
||||
|
||||
pub fn dict_type(&self) -> PyClassRef {
|
||||
self.dict_type.clone()
|
||||
self.types.dict_type.clone()
|
||||
}
|
||||
|
||||
pub fn float_type(&self) -> PyClassRef {
|
||||
self.float_type.clone()
|
||||
self.types.float_type.clone()
|
||||
}
|
||||
|
||||
pub fn frame_type(&self) -> PyClassRef {
|
||||
self.frame_type.clone()
|
||||
self.types.frame_type.clone()
|
||||
}
|
||||
|
||||
pub fn int_type(&self) -> PyClassRef {
|
||||
self.int_type.clone()
|
||||
self.types.int_type.clone()
|
||||
}
|
||||
|
||||
pub fn list_type(&self) -> PyClassRef {
|
||||
self.list_type.clone()
|
||||
self.types.list_type.clone()
|
||||
}
|
||||
|
||||
pub fn listiterator_type(&self) -> PyClassRef {
|
||||
self.listiterator_type.clone()
|
||||
self.types.listiterator_type.clone()
|
||||
}
|
||||
|
||||
pub fn listreverseiterator_type(&self) -> PyClassRef {
|
||||
self.listreverseiterator_type.clone()
|
||||
self.types.listreverseiterator_type.clone()
|
||||
}
|
||||
|
||||
pub fn striterator_type(&self) -> PyClassRef {
|
||||
self.striterator_type.clone()
|
||||
self.types.striterator_type.clone()
|
||||
}
|
||||
|
||||
pub fn strreverseiterator_type(&self) -> PyClassRef {
|
||||
self.strreverseiterator_type.clone()
|
||||
self.types.strreverseiterator_type.clone()
|
||||
}
|
||||
|
||||
pub fn module_type(&self) -> PyClassRef {
|
||||
self.module_type.clone()
|
||||
self.types.module_type.clone()
|
||||
}
|
||||
|
||||
pub fn namespace_type(&self) -> PyClassRef {
|
||||
self.namespace_type.clone()
|
||||
self.types.namespace_type.clone()
|
||||
}
|
||||
|
||||
pub fn set_type(&self) -> PyClassRef {
|
||||
self.set_type.clone()
|
||||
self.types.set_type.clone()
|
||||
}
|
||||
|
||||
pub fn range_type(&self) -> PyClassRef {
|
||||
self.range_type.clone()
|
||||
self.types.range_type.clone()
|
||||
}
|
||||
|
||||
pub fn rangeiterator_type(&self) -> PyClassRef {
|
||||
self.rangeiterator_type.clone()
|
||||
self.types.rangeiterator_type.clone()
|
||||
}
|
||||
|
||||
pub fn slice_type(&self) -> PyClassRef {
|
||||
self.slice_type.clone()
|
||||
self.types.slice_type.clone()
|
||||
}
|
||||
|
||||
pub fn frozenset_type(&self) -> PyClassRef {
|
||||
self.frozenset_type.clone()
|
||||
self.types.frozenset_type.clone()
|
||||
}
|
||||
|
||||
pub fn bool_type(&self) -> PyClassRef {
|
||||
self.bool_type.clone()
|
||||
self.types.bool_type.clone()
|
||||
}
|
||||
|
||||
pub fn memoryview_type(&self) -> PyClassRef {
|
||||
self.memoryview_type.clone()
|
||||
self.types.memoryview_type.clone()
|
||||
}
|
||||
|
||||
pub fn tuple_type(&self) -> PyClassRef {
|
||||
self.tuple_type.clone()
|
||||
self.types.tuple_type.clone()
|
||||
}
|
||||
|
||||
pub fn tupleiterator_type(&self) -> PyClassRef {
|
||||
self.tupleiterator_type.clone()
|
||||
self.types.tupleiterator_type.clone()
|
||||
}
|
||||
|
||||
pub fn iter_type(&self) -> PyClassRef {
|
||||
self.iter_type.clone()
|
||||
self.types.iter_type.clone()
|
||||
}
|
||||
|
||||
pub fn enumerate_type(&self) -> PyClassRef {
|
||||
self.enumerate_type.clone()
|
||||
self.types.enumerate_type.clone()
|
||||
}
|
||||
|
||||
pub fn filter_type(&self) -> PyClassRef {
|
||||
self.filter_type.clone()
|
||||
self.types.filter_type.clone()
|
||||
}
|
||||
|
||||
pub fn map_type(&self) -> PyClassRef {
|
||||
self.map_type.clone()
|
||||
self.types.map_type.clone()
|
||||
}
|
||||
|
||||
pub fn zip_type(&self) -> PyClassRef {
|
||||
self.zip_type.clone()
|
||||
self.types.zip_type.clone()
|
||||
}
|
||||
|
||||
pub fn str_type(&self) -> PyClassRef {
|
||||
self.str_type.clone()
|
||||
self.types.str_type.clone()
|
||||
}
|
||||
|
||||
pub fn super_type(&self) -> PyClassRef {
|
||||
self.super_type.clone()
|
||||
self.types.super_type.clone()
|
||||
}
|
||||
|
||||
pub fn function_type(&self) -> PyClassRef {
|
||||
self.function_type.clone()
|
||||
self.types.function_type.clone()
|
||||
}
|
||||
|
||||
pub fn builtin_function_or_method_type(&self) -> PyClassRef {
|
||||
self.builtin_function_or_method_type.clone()
|
||||
self.types.builtin_function_or_method_type.clone()
|
||||
}
|
||||
|
||||
pub fn property_type(&self) -> PyClassRef {
|
||||
self.property_type.clone()
|
||||
self.types.property_type.clone()
|
||||
}
|
||||
|
||||
pub fn readonly_property_type(&self) -> PyClassRef {
|
||||
self.readonly_property_type.clone()
|
||||
self.types.readonly_property_type.clone()
|
||||
}
|
||||
|
||||
pub fn classmethod_type(&self) -> PyClassRef {
|
||||
self.classmethod_type.clone()
|
||||
self.types.classmethod_type.clone()
|
||||
}
|
||||
|
||||
pub fn staticmethod_type(&self) -> PyClassRef {
|
||||
self.staticmethod_type.clone()
|
||||
self.types.staticmethod_type.clone()
|
||||
}
|
||||
|
||||
pub fn generator_type(&self) -> PyClassRef {
|
||||
self.generator_type.clone()
|
||||
self.types.generator_type.clone()
|
||||
}
|
||||
|
||||
pub fn bound_method_type(&self) -> PyClassRef {
|
||||
self.bound_method_type.clone()
|
||||
self.types.bound_method_type.clone()
|
||||
}
|
||||
|
||||
pub fn weakref_type(&self) -> PyClassRef {
|
||||
self.weakref_type.clone()
|
||||
self.types.weakref_type.clone()
|
||||
}
|
||||
|
||||
pub fn weakproxy_type(&self) -> PyClassRef {
|
||||
self.weakproxy_type.clone()
|
||||
self.types.weakproxy_type.clone()
|
||||
}
|
||||
|
||||
pub fn type_type(&self) -> PyClassRef {
|
||||
self.type_type.clone()
|
||||
self.types.type_type.clone()
|
||||
}
|
||||
|
||||
pub fn none(&self) -> PyObjectRef {
|
||||
@@ -624,7 +363,7 @@ impl PyContext {
|
||||
}
|
||||
|
||||
pub fn object(&self) -> PyClassRef {
|
||||
self.object.clone()
|
||||
self.types.object_type.clone()
|
||||
}
|
||||
|
||||
pub fn new_int<T: Into<BigInt>>(&self, i: T) -> PyObjectRef {
|
||||
@@ -696,7 +435,7 @@ impl PyContext {
|
||||
PyModule {
|
||||
name: name.to_string(),
|
||||
},
|
||||
self.module_type.clone(),
|
||||
self.types.module_type.clone(),
|
||||
Some(dict),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::obj::objstr::PyStringRef;
|
||||
use crate::py_serde;
|
||||
use crate::pyobject::{create_type, ItemProtocol, PyObjectRef, PyResult};
|
||||
use crate::pyobject::{ItemProtocol, PyObjectRef, PyResult};
|
||||
use crate::types::create_type;
|
||||
use crate::VirtualMachine;
|
||||
use serde_json;
|
||||
|
||||
@@ -39,7 +40,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
// TODO: Make this a proper type with a constructor
|
||||
let json_decode_error = create_type(
|
||||
"JSONDecodeError",
|
||||
&ctx.type_type,
|
||||
&ctx.types.type_type,
|
||||
&ctx.exceptions.exception_type,
|
||||
);
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ fn math_trunc(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
fn math_ceil(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(value, None)]);
|
||||
if objtype::isinstance(value, &vm.ctx.float_type) {
|
||||
if objtype::isinstance(value, &vm.ctx.float_type()) {
|
||||
let v = objfloat::get_value(value);
|
||||
Ok(vm.ctx.new_float(v.ceil()))
|
||||
} else {
|
||||
@@ -201,7 +201,7 @@ fn math_ceil(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
|
||||
fn math_floor(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
arg_check!(vm, args, required = [(value, None)]);
|
||||
if objtype::isinstance(value, &vm.ctx.float_type) {
|
||||
if objtype::isinstance(value, &vm.ctx.float_type()) {
|
||||
let v = objfloat::get_value(value);
|
||||
Ok(vm.ctx.new_float(v.floor()))
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::function::OptionalArg;
|
||||
use crate::obj::{objbytes::PyBytesRef, objint::PyIntRef};
|
||||
use crate::pyobject::{create_type, ItemProtocol, PyObjectRef, PyResult};
|
||||
use crate::pyobject::{ItemProtocol, PyObjectRef, PyResult};
|
||||
use crate::types::create_type;
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use adler32::RollingAdler32 as Adler32;
|
||||
@@ -18,7 +19,11 @@ const DEF_BUF_SIZE: usize = 16 * 1024;
|
||||
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
let zlib_error = create_type("error", &ctx.type_type, &ctx.exceptions.exception_type);
|
||||
let zlib_error = create_type(
|
||||
"error",
|
||||
&ctx.types.type_type,
|
||||
&ctx.exceptions.exception_type,
|
||||
);
|
||||
|
||||
py_module!(vm, "zlib", {
|
||||
"crc32" => ctx.new_rustfunc(zlib_crc32),
|
||||
|
||||
313
vm/src/types.rs
Normal file
313
vm/src/types.rs
Normal file
@@ -0,0 +1,313 @@
|
||||
use crate::obj::objbool;
|
||||
use crate::obj::objbytearray;
|
||||
use crate::obj::objbytes;
|
||||
use crate::obj::objclassmethod;
|
||||
use crate::obj::objcode;
|
||||
use crate::obj::objcomplex;
|
||||
use crate::obj::objdict;
|
||||
use crate::obj::objellipsis;
|
||||
use crate::obj::objenumerate;
|
||||
use crate::obj::objfilter;
|
||||
use crate::obj::objfloat;
|
||||
use crate::obj::objframe;
|
||||
use crate::obj::objfunction;
|
||||
use crate::obj::objgenerator;
|
||||
use crate::obj::objint;
|
||||
use crate::obj::objiter;
|
||||
use crate::obj::objlist;
|
||||
use crate::obj::objmap;
|
||||
use crate::obj::objmappingproxy;
|
||||
use crate::obj::objmemory;
|
||||
use crate::obj::objmodule;
|
||||
use crate::obj::objnamespace;
|
||||
use crate::obj::objnone;
|
||||
use crate::obj::objobject;
|
||||
use crate::obj::objproperty;
|
||||
use crate::obj::objrange;
|
||||
use crate::obj::objset;
|
||||
use crate::obj::objslice;
|
||||
use crate::obj::objstaticmethod;
|
||||
use crate::obj::objstr;
|
||||
use crate::obj::objsuper;
|
||||
use crate::obj::objtuple;
|
||||
use crate::obj::objtype::{self, PyClass, PyClassRef};
|
||||
use crate::obj::objweakproxy;
|
||||
use crate::obj::objweakref;
|
||||
use crate::obj::objzip;
|
||||
use crate::pyobject::{PyAttributes, PyContext, PyObject, PyObjectRef};
|
||||
use std::cell::RefCell;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
/// Holder of references to builtin types.
|
||||
#[derive(Debug)]
|
||||
pub struct TypeZoo {
|
||||
pub bytes_type: PyClassRef,
|
||||
pub bytesiterator_type: PyClassRef,
|
||||
pub bytearray_type: PyClassRef,
|
||||
pub bytearrayiterator_type: PyClassRef,
|
||||
pub bool_type: PyClassRef,
|
||||
pub classmethod_type: PyClassRef,
|
||||
pub code_type: PyClassRef,
|
||||
pub dict_type: PyClassRef,
|
||||
pub enumerate_type: PyClassRef,
|
||||
pub filter_type: PyClassRef,
|
||||
pub float_type: PyClassRef,
|
||||
pub frame_type: PyClassRef,
|
||||
pub frozenset_type: PyClassRef,
|
||||
pub generator_type: PyClassRef,
|
||||
pub int_type: PyClassRef,
|
||||
pub iter_type: PyClassRef,
|
||||
pub complex_type: PyClassRef,
|
||||
pub list_type: PyClassRef,
|
||||
pub listiterator_type: PyClassRef,
|
||||
pub listreverseiterator_type: PyClassRef,
|
||||
pub striterator_type: PyClassRef,
|
||||
pub strreverseiterator_type: PyClassRef,
|
||||
pub dictkeyiterator_type: PyClassRef,
|
||||
pub dictvalueiterator_type: PyClassRef,
|
||||
pub dictitemiterator_type: PyClassRef,
|
||||
pub dictkeys_type: PyClassRef,
|
||||
pub dictvalues_type: PyClassRef,
|
||||
pub dictitems_type: PyClassRef,
|
||||
pub map_type: PyClassRef,
|
||||
pub memoryview_type: PyClassRef,
|
||||
pub tuple_type: PyClassRef,
|
||||
pub tupleiterator_type: PyClassRef,
|
||||
pub set_type: PyClassRef,
|
||||
pub staticmethod_type: PyClassRef,
|
||||
pub super_type: PyClassRef,
|
||||
pub str_type: PyClassRef,
|
||||
pub range_type: PyClassRef,
|
||||
pub rangeiterator_type: PyClassRef,
|
||||
pub slice_type: PyClassRef,
|
||||
pub type_type: PyClassRef,
|
||||
pub zip_type: PyClassRef,
|
||||
pub function_type: PyClassRef,
|
||||
pub builtin_function_or_method_type: PyClassRef,
|
||||
pub property_type: PyClassRef,
|
||||
pub readonly_property_type: PyClassRef,
|
||||
pub module_type: PyClassRef,
|
||||
pub namespace_type: PyClassRef,
|
||||
pub bound_method_type: PyClassRef,
|
||||
pub weakref_type: PyClassRef,
|
||||
pub weakproxy_type: PyClassRef,
|
||||
pub mappingproxy_type: PyClassRef,
|
||||
pub object_type: PyClassRef,
|
||||
}
|
||||
|
||||
impl Default for TypeZoo {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl TypeZoo {
|
||||
pub fn new() -> Self {
|
||||
let (type_type, object_type) = init_type_hierarchy();
|
||||
|
||||
let dict_type = create_type("dict", &type_type, &object_type);
|
||||
let module_type = create_type("module", &type_type, &object_type);
|
||||
let namespace_type = create_type("SimpleNamespace", &type_type, &object_type);
|
||||
let classmethod_type = create_type("classmethod", &type_type, &object_type);
|
||||
let staticmethod_type = create_type("staticmethod", &type_type, &object_type);
|
||||
let function_type = create_type("function", &type_type, &object_type);
|
||||
let builtin_function_or_method_type =
|
||||
create_type("builtin_function_or_method", &type_type, &object_type);
|
||||
let property_type = create_type("property", &type_type, &object_type);
|
||||
let readonly_property_type = create_type("readonly_property", &type_type, &object_type);
|
||||
let super_type = create_type("super", &type_type, &object_type);
|
||||
let weakref_type = create_type("ref", &type_type, &object_type);
|
||||
let weakproxy_type = create_type("weakproxy", &type_type, &object_type);
|
||||
let generator_type = create_type("generator", &type_type, &object_type);
|
||||
let bound_method_type = create_type("method", &type_type, &object_type);
|
||||
let str_type = create_type("str", &type_type, &object_type);
|
||||
let list_type = create_type("list", &type_type, &object_type);
|
||||
let listiterator_type = create_type("list_iterator", &type_type, &object_type);
|
||||
let listreverseiterator_type =
|
||||
create_type("list_reverseiterator", &type_type, &object_type);
|
||||
let striterator_type = create_type("str_iterator", &type_type, &object_type);
|
||||
let strreverseiterator_type = create_type("str_reverseiterator", &type_type, &object_type);
|
||||
let dictkeys_type = create_type("dict_keys", &type_type, &object_type);
|
||||
let dictvalues_type = create_type("dict_values", &type_type, &object_type);
|
||||
let dictitems_type = create_type("dict_items", &type_type, &object_type);
|
||||
let dictkeyiterator_type = create_type("dict_keyiterator", &type_type, &object_type);
|
||||
let dictvalueiterator_type = create_type("dict_valueiterator", &type_type, &object_type);
|
||||
let dictitemiterator_type = create_type("dict_itemiterator", &type_type, &object_type);
|
||||
let set_type = create_type("set", &type_type, &object_type);
|
||||
let frozenset_type = create_type("frozenset", &type_type, &object_type);
|
||||
let int_type = create_type("int", &type_type, &object_type);
|
||||
let float_type = create_type("float", &type_type, &object_type);
|
||||
let frame_type = create_type("frame", &type_type, &object_type);
|
||||
let complex_type = create_type("complex", &type_type, &object_type);
|
||||
let bytes_type = create_type("bytes", &type_type, &object_type);
|
||||
let bytesiterator_type = create_type("bytes_iterator", &type_type, &object_type);
|
||||
let bytearray_type = create_type("bytearray", &type_type, &object_type);
|
||||
let bytearrayiterator_type = create_type("bytearray_iterator", &type_type, &object_type);
|
||||
let tuple_type = create_type("tuple", &type_type, &object_type);
|
||||
let tupleiterator_type = create_type("tuple_iterator", &type_type, &object_type);
|
||||
let iter_type = create_type("iter", &type_type, &object_type);
|
||||
let enumerate_type = create_type("enumerate", &type_type, &object_type);
|
||||
let filter_type = create_type("filter", &type_type, &object_type);
|
||||
let map_type = create_type("map", &type_type, &object_type);
|
||||
let zip_type = create_type("zip", &type_type, &object_type);
|
||||
let bool_type = create_type("bool", &type_type, &int_type);
|
||||
let memoryview_type = create_type("memoryview", &type_type, &object_type);
|
||||
let code_type = create_type("code", &type_type, &object_type);
|
||||
let range_type = create_type("range", &type_type, &object_type);
|
||||
let rangeiterator_type = create_type("range_iterator", &type_type, &object_type);
|
||||
let slice_type = create_type("slice", &type_type, &object_type);
|
||||
let mappingproxy_type = create_type("mappingproxy", &type_type, &object_type);
|
||||
|
||||
Self {
|
||||
bool_type,
|
||||
memoryview_type,
|
||||
bytearray_type,
|
||||
bytearrayiterator_type,
|
||||
bytes_type,
|
||||
bytesiterator_type,
|
||||
code_type,
|
||||
complex_type,
|
||||
classmethod_type,
|
||||
int_type,
|
||||
float_type,
|
||||
frame_type,
|
||||
staticmethod_type,
|
||||
list_type,
|
||||
listiterator_type,
|
||||
listreverseiterator_type,
|
||||
striterator_type,
|
||||
strreverseiterator_type,
|
||||
dictkeys_type,
|
||||
dictvalues_type,
|
||||
dictitems_type,
|
||||
dictkeyiterator_type,
|
||||
dictvalueiterator_type,
|
||||
dictitemiterator_type,
|
||||
set_type,
|
||||
frozenset_type,
|
||||
tuple_type,
|
||||
tupleiterator_type,
|
||||
iter_type,
|
||||
enumerate_type,
|
||||
filter_type,
|
||||
map_type,
|
||||
zip_type,
|
||||
dict_type,
|
||||
str_type,
|
||||
range_type,
|
||||
rangeiterator_type,
|
||||
slice_type,
|
||||
object_type,
|
||||
function_type,
|
||||
builtin_function_or_method_type,
|
||||
super_type,
|
||||
mappingproxy_type,
|
||||
property_type,
|
||||
readonly_property_type,
|
||||
generator_type,
|
||||
module_type,
|
||||
namespace_type,
|
||||
bound_method_type,
|
||||
weakref_type,
|
||||
weakproxy_type,
|
||||
type_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_type(name: &str, type_type: &PyClassRef, base: &PyClassRef) -> PyClassRef {
|
||||
let dict = PyAttributes::new();
|
||||
objtype::new(type_type.clone(), name, vec![base.clone()], dict).unwrap()
|
||||
}
|
||||
|
||||
fn init_type_hierarchy() -> (PyClassRef, PyClassRef) {
|
||||
// `type` inherits from `object`
|
||||
// and both `type` and `object are instances of `type`.
|
||||
// to produce this circular dependency, we need an unsafe block.
|
||||
// (and yes, this will never get dropped. TODO?)
|
||||
let (type_type, object_type) = unsafe {
|
||||
let object_type = PyObject {
|
||||
typ: mem::uninitialized(), // !
|
||||
dict: None,
|
||||
payload: PyClass {
|
||||
name: String::from("object"),
|
||||
mro: vec![],
|
||||
subclasses: RefCell::new(vec![]),
|
||||
attributes: RefCell::new(PyAttributes::new()),
|
||||
},
|
||||
}
|
||||
.into_ref();
|
||||
|
||||
let type_type = PyObject {
|
||||
typ: mem::uninitialized(), // !
|
||||
dict: None,
|
||||
payload: PyClass {
|
||||
name: String::from("type"),
|
||||
mro: vec![object_type.clone().downcast().unwrap()],
|
||||
subclasses: RefCell::new(vec![]),
|
||||
attributes: RefCell::new(PyAttributes::new()),
|
||||
},
|
||||
}
|
||||
.into_ref();
|
||||
|
||||
let object_type_ptr = PyObjectRef::into_raw(object_type.clone()) as *mut PyObject<PyClass>;
|
||||
let type_type_ptr = PyObjectRef::into_raw(type_type.clone()) as *mut PyObject<PyClass>;
|
||||
|
||||
let type_type: PyClassRef = type_type.downcast().unwrap();
|
||||
let object_type: PyClassRef = object_type.downcast().unwrap();
|
||||
|
||||
ptr::write(&mut (*object_type_ptr).typ, type_type.clone());
|
||||
ptr::write(&mut (*type_type_ptr).typ, type_type.clone());
|
||||
|
||||
(type_type, object_type)
|
||||
};
|
||||
|
||||
object_type
|
||||
.subclasses
|
||||
.borrow_mut()
|
||||
.push(objweakref::PyWeak::downgrade(&type_type.as_object()));
|
||||
|
||||
(type_type, object_type)
|
||||
}
|
||||
|
||||
/// Fill attributes of builtin types.
|
||||
pub fn initialize_types(context: &PyContext) {
|
||||
objtype::init(&context);
|
||||
objlist::init(&context);
|
||||
objset::init(&context);
|
||||
objtuple::init(&context);
|
||||
objobject::init(&context);
|
||||
objdict::init(&context);
|
||||
objfunction::init(&context);
|
||||
objstaticmethod::init(&context);
|
||||
objclassmethod::init(&context);
|
||||
objgenerator::init(&context);
|
||||
objint::init(&context);
|
||||
objfloat::init(&context);
|
||||
objcomplex::init(&context);
|
||||
objbytes::init(&context);
|
||||
objbytearray::init(&context);
|
||||
objproperty::init(&context);
|
||||
objmemory::init(&context);
|
||||
objstr::init(&context);
|
||||
objrange::init(&context);
|
||||
objslice::init(&context);
|
||||
objsuper::init(&context);
|
||||
objtuple::init(&context);
|
||||
objiter::init(&context);
|
||||
objellipsis::init(&context);
|
||||
objenumerate::init(&context);
|
||||
objfilter::init(&context);
|
||||
objmap::init(&context);
|
||||
objzip::init(&context);
|
||||
objbool::init(&context);
|
||||
objcode::init(&context);
|
||||
objframe::init(&context);
|
||||
objweakref::init(&context);
|
||||
objweakproxy::init(&context);
|
||||
objnone::init(&context);
|
||||
objmodule::init(&context);
|
||||
objnamespace::init(&context);
|
||||
objmappingproxy::init(&context);
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
use js_sys::{Array, Object, Reflect};
|
||||
use rustpython_vm::function::Args;
|
||||
use rustpython_vm::obj::{objfloat::PyFloatRef, objstr::PyStringRef, objtype::PyClassRef};
|
||||
use rustpython_vm::pyobject::{
|
||||
create_type, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
|
||||
};
|
||||
use rustpython_vm::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject};
|
||||
use rustpython_vm::types::create_type;
|
||||
use rustpython_vm::VirtualMachine;
|
||||
use wasm_bindgen::{prelude::*, JsCast};
|
||||
|
||||
@@ -244,7 +243,7 @@ fn new_js_error(vm: &VirtualMachine, err: JsValue) -> PyObjectRef {
|
||||
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
py_module!(vm, "_js", {
|
||||
"JsError" => create_type("JsError", &ctx.type_type, &ctx.exceptions.exception_type),
|
||||
"JsError" => create_type("JsError", &ctx.type_type(), &ctx.exceptions.exception_type),
|
||||
"JsValue" => PyJsValue::make_class(ctx),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user