use crate::obj::objbool;
use crate::obj::objbuiltinfunc;
use crate::obj::objbytearray;
use crate::obj::objbytes;
use crate::obj::objclassmethod;
use crate::obj::objcode;
use crate::obj::objcomplex;
use crate::obj::objcoroutine;
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::objgetset;
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::objtraceback;
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, PyObjectPayload};
use std::cell::RefCell;
use std::mem::{self, MaybeUninit};
use std::ptr;
use std::rc::Rc;
#[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 coroutine_type: PyClassRef,
pub coroutine_wrapper_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 method_descriptor_type: PyClassRef,
pub property_type: PyClassRef,
pub readonly_property_type: PyClassRef,
pub getset_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 traceback_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 method_descriptor_type = create_type("method_descriptor", &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 getset_type = create_type("getset_descriptor", &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 coroutine_type = create_type("coroutine", &type_type, &object_type);
let coroutine_wrapper_type = create_type("coroutine_wrapper", &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 traceback_type = create_type("traceback", &type_type, &object_type);
Self {
bool_type,
memoryview_type,
bytearray_type,
bytearrayiterator_type,
bytes_type,
bytesiterator_type,
code_type,
coroutine_type,
coroutine_wrapper_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,
method_descriptor_type,
super_type,
mappingproxy_type,
property_type,
readonly_property_type,
getset_type,
generator_type,
module_type,
namespace_type,
bound_method_type,
weakref_type,
weakproxy_type,
type_type,
traceback_type,
}
}
}
pub fn create_type(name: &str, type_type: &PyClassRef, base: &PyClassRef) -> PyClassRef {
let dict = PyAttributes::new();
objtype::new(
type_type.clone(),
name,
base.clone(),
vec![base.clone()],
dict,
)
.unwrap()
}
macro_rules! partially_init {
(
$ty:path {$($init_field:ident: $init_value:expr),*$(,)?},
Uninit { $($uninit_field:ident),*$(,)? }$(,)?
) => {{
if false {
#[allow(invalid_value)]
let _ = {$ty {
$($init_field: $init_value,)*
$($uninit_field: ::std::mem::MaybeUninit::uninit().assume_init(),)*
}};
}
let mut m = ::std::mem::MaybeUninit::<$ty>::uninit();
$(::std::ptr::write(&mut (*m.as_mut_ptr()).$init_field, $init_value);)*
m
}};
}
fn init_type_hierarchy() -> (PyClassRef, PyClassRef) {
let (type_type, object_type) = unsafe {
type PyClassObj = PyObject<PyClass>;
type UninitRef<T> = Rc<MaybeUninit<T>>;
let type_type: UninitRef<PyClassObj> = Rc::new(partially_init!(
PyObject::<PyClass> {
dict: None,
payload: PyClass {
name: String::from("type"),
bases: vec![],
mro: vec![],
subclasses: RefCell::default(),
attributes: RefCell::new(PyAttributes::new()),
slots: RefCell::default(),
},
},
Uninit { typ }
));
let object_type: UninitRef<PyClassObj> = Rc::new(partially_init!(
PyObject::<PyClass> {
dict: None,
payload: PyClass {
name: String::from("object"),
bases: vec![],
mro: vec![],
subclasses: RefCell::default(),
attributes: RefCell::new(PyAttributes::new()),
slots: RefCell::default(),
},
},
Uninit { typ },
));
let object_type_ptr =
Rc::into_raw(object_type) as *mut MaybeUninit<PyClassObj> as *mut PyClassObj;
let type_type_ptr =
Rc::into_raw(type_type.clone()) as *mut MaybeUninit<PyClassObj> as *mut PyClassObj;
#[repr(C)]
struct TraitObject {
data: *mut (),
vtable: *mut (),
}
let pyclass_vptr = {
let cls = PyClass {
name: Default::default(),
bases: Default::default(),
mro: Default::default(),
subclasses: Default::default(),
attributes: Default::default(),
slots: Default::default(),
};
mem::transmute::<_, TraitObject>(&cls as &dyn PyObjectPayload).vtable
};
let write_typ_ptr = |ptr: *mut PyClassObj, type_type: UninitRef<PyClassObj>| {
let type_type = mem::transmute(TraitObject {
data: mem::transmute(type_type),
vtable: pyclass_vptr,
});
ptr::write(
&mut (*ptr).typ as *mut PyClassRef as *mut MaybeUninit<PyClassRef>,
type_type,
);
};
write_typ_ptr(object_type_ptr, type_type.clone());
write_typ_ptr(type_type_ptr, type_type);
let type_type = PyClassRef::new_ref_unchecked(Rc::from_raw(type_type_ptr));
let object_type = PyClassRef::new_ref_unchecked(Rc::from_raw(object_type_ptr));
(*type_type_ptr).payload.mro = vec![object_type.clone()];
(*type_type_ptr).payload.bases = vec![object_type.clone()];
(type_type, object_type)
};
object_type
.subclasses
.borrow_mut()
.push(objweakref::PyWeak::downgrade(&type_type.as_object()));
(type_type, object_type)
}
pub fn initialize_types(context: &PyContext) {
objtype::init(&context);
objlist::init(&context);
objset::init(&context);
objtuple::init(&context);
objobject::init(&context);
objdict::init(&context);
objbuiltinfunc::init(&context);
objfunction::init(&context);
objstaticmethod::init(&context);
objclassmethod::init(&context);
objgenerator::init(&context);
objcoroutine::init(&context);
objint::init(&context);
objfloat::init(&context);
objcomplex::init(&context);
objbytes::init(&context);
objbytearray::init(&context);
objproperty::init(&context);
objgetset::init(&context);
objmemory::init(&context);
objstr::init(&context);
objrange::init(&context);
objslice::init(&context);
objsuper::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);
objtraceback::init(&context);
}