|
|
@@ -46,4 +46,80 @@ const char* py_tpname(py_Type type) {
|
|
|
|
|
|
py_TypeInfo* pk_typeinfo(py_Type type) {
|
|
|
return c11__getitem(TypePointer, &pk_current_vm->types, type).ti;
|
|
|
+}
|
|
|
+
|
|
|
+static void py_TypeInfo__common_init(py_Name name,
|
|
|
+ py_Type base,
|
|
|
+ py_Type index,
|
|
|
+ const py_GlobalRef module,
|
|
|
+ void (*dtor)(void*),
|
|
|
+ bool is_python,
|
|
|
+ bool is_sealed,
|
|
|
+ py_TypeInfo* self) {
|
|
|
+ py_TypeInfo* base_ti = base ? pk_typeinfo(base) : NULL;
|
|
|
+ if(base_ti && base_ti->is_sealed) {
|
|
|
+ c11__abort("type '%s' is not an acceptable base type", py_name2str(base_ti->name));
|
|
|
+ }
|
|
|
+
|
|
|
+ memset(self, 0, sizeof(py_TypeInfo));
|
|
|
+ self->name = name;
|
|
|
+ self->index = index;
|
|
|
+ self->base = base;
|
|
|
+ self->base_ti = base_ti;
|
|
|
+
|
|
|
+ self->self = *py_retval();
|
|
|
+ self->module = module ? module : py_NIL();
|
|
|
+ self->annotations = *py_NIL();
|
|
|
+
|
|
|
+ if(!dtor && base) dtor = base_ti->dtor;
|
|
|
+ self->is_python = is_python;
|
|
|
+ self->is_sealed = is_sealed;
|
|
|
+ self->dtor = dtor;
|
|
|
+}
|
|
|
+
|
|
|
+py_Type pk_newtype(const char* name,
|
|
|
+ py_Type base,
|
|
|
+ const py_GlobalRef module,
|
|
|
+ void (*dtor)(void*),
|
|
|
+ bool is_python,
|
|
|
+ bool is_sealed) {
|
|
|
+ py_Type index = pk_current_vm->types.length;
|
|
|
+ py_TypeInfo* self = py_newobject(py_retval(), tp_type, -1, sizeof(py_TypeInfo));
|
|
|
+ py_TypeInfo__common_init(py_name(name), base, index, module, dtor, is_python, is_sealed, self);
|
|
|
+ TypePointer* pointer = c11_vector__emplace(&pk_current_vm->types);
|
|
|
+ pointer->ti = self;
|
|
|
+ pointer->dtor = self->dtor;
|
|
|
+ return index;
|
|
|
+}
|
|
|
+
|
|
|
+py_Type pk_newtypewithmode(py_Name name,
|
|
|
+ py_Type base,
|
|
|
+ const py_GlobalRef module,
|
|
|
+ void (*dtor)(void*),
|
|
|
+ bool is_python,
|
|
|
+ bool is_sealed,
|
|
|
+ enum py_CompileMode mode) {
|
|
|
+ if(mode == RELOAD_MODE && module != NULL) {
|
|
|
+ py_ItemRef old_class = py_getdict(module, name);
|
|
|
+ if(old_class != NULL && py_istype(old_class, tp_type)) {
|
|
|
+ NameDict* old_dict = PyObject__dict(old_class->_obj);
|
|
|
+ NameDict__clear(old_dict);
|
|
|
+ py_TypeInfo* self = py_touserdata(old_class);
|
|
|
+ py_Type index = self->index;
|
|
|
+ py_TypeInfo__common_init(name, base, index, module, dtor, is_python, is_sealed, self);
|
|
|
+ TypePointer* pointer = c11__at(TypePointer, &pk_current_vm->types, index);
|
|
|
+ pointer->ti = self;
|
|
|
+ pointer->dtor = self->dtor;
|
|
|
+ return index;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return pk_newtype(py_name2str(name), base, module, dtor, is_python, is_sealed);
|
|
|
+}
|
|
|
+
|
|
|
+py_Type py_newtype(const char* name, py_Type base, const py_GlobalRef module, void (*dtor)(void*)) {
|
|
|
+ if(strlen(name) == 0) c11__abort("type name cannot be empty");
|
|
|
+ py_Type type = pk_newtype(name, base, module, dtor, false, false);
|
|
|
+ if(module) py_setdict(module, py_name(name), py_tpobject(type));
|
|
|
+ return type;
|
|
|
}
|