Attempt to reduce the size of the pyobject.rs files by splitting out builtin types.

This commit is contained in:
Windel Bouwman
2019-08-14 17:48:54 +02:00
parent 11cbf556e5
commit d06dec77ea
42 changed files with 477 additions and 418 deletions

View File

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

View 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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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