add RELOAD_MODE

This commit is contained in:
blueloveTH 2025-06-22 13:01:50 +08:00
parent f64885f4ca
commit 0b09246a6d
7 changed files with 102 additions and 57 deletions

View File

@ -25,4 +25,19 @@ typedef struct py_TypeInfo {
py_TypeInfo* pk_typeinfo(py_Type type); py_TypeInfo* pk_typeinfo(py_Type type);
py_ItemRef pk_tpfindname(py_TypeInfo* ti, py_Name name); py_ItemRef pk_tpfindname(py_TypeInfo* ti, py_Name name);
#define pk_tpfindmagic pk_tpfindname #define pk_tpfindmagic pk_tpfindname
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 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);

View File

@ -100,13 +100,6 @@ typedef enum FrameResult {
FrameResult VM__run_top_frame(VM* self); FrameResult VM__run_top_frame(VM* self);
py_Type pk_newtype(const char* name,
py_Type base,
const py_GlobalRef module,
void (*dtor)(void*),
bool is_python,
bool is_sealed);
FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall); FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall);
const char* pk_opname(Opcode op); const char* pk_opname(Opcode op);

View File

@ -92,7 +92,8 @@ typedef bool (*py_CFunction)(int argc, py_StackRef argv) PY_RAISE PY_RETURN;
/// + `EXEC_MODE`: for statements. /// + `EXEC_MODE`: for statements.
/// + `EVAL_MODE`: for expressions. /// + `EVAL_MODE`: for expressions.
/// + `SINGLE_MODE`: for REPL or jupyter notebook execution. /// + `SINGLE_MODE`: for REPL or jupyter notebook execution.
enum py_CompileMode { EXEC_MODE, EVAL_MODE, SINGLE_MODE }; /// + `RELOAD_MODE`: for reloading a module without allocating new types if possible.
enum py_CompileMode { EXEC_MODE, EVAL_MODE, SINGLE_MODE, RELOAD_MODE };
/************* Global Setup *************/ /************* Global Setup *************/

View File

@ -1042,12 +1042,13 @@ FrameResult VM__run_top_frame(VM* self) {
goto __ERROR; goto __ERROR;
} }
py_Type type = pk_newtype(py_name2str(name), py_Type type = pk_newtypewithmode(name,
base, base,
frame->module, frame->module,
NULL, NULL,
base_ti->is_python, base_ti->is_python,
false); false,
frame->co->src->mode);
PUSH(py_tpobject(type)); PUSH(py_tpobject(type));
self->curr_class = TOP(); self->curr_class = TOP();
DISPATCH(); DISPATCH();

View File

@ -46,4 +46,80 @@ const char* py_tpname(py_Type type) {
py_TypeInfo* pk_typeinfo(py_Type type) { py_TypeInfo* pk_typeinfo(py_Type type) {
return c11__getitem(TypePointer, &pk_current_vm->types, type).ti; 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;
} }

View File

@ -364,47 +364,6 @@ bool pk__normalize_index(int* index, int length) {
return true; return true;
} }
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* 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 = py_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;
TypePointer* pointer = c11_vector__emplace(&pk_current_vm->types);
pointer->ti = self;
pointer->dtor = dtor;
return index;
}
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;
}
static bool static bool
prepare_py_call(py_TValue* buffer, py_Ref argv, py_Ref p1, int kwargc, const FuncDecl* decl) { prepare_py_call(py_TValue* buffer, py_Ref argv, py_Ref p1, int kwargc, const FuncDecl* decl) {
const CodeObject* co = &decl->code; const CodeObject* co = &decl->code;

View File

@ -176,7 +176,7 @@ bool py_importlib_reload(py_GlobalRef module) {
} }
c11_string__delete(slashed_path); c11_string__delete(slashed_path);
if(data == NULL) return ImportError("module '%v' not found", path); if(data == NULL) return ImportError("module '%v' not found", path);
bool ok = py_exec(data, filename->data, EXEC_MODE, module); bool ok = py_exec(data, filename->data, RELOAD_MODE, module);
c11_string__delete(filename); c11_string__delete(filename);
PK_FREE(data); PK_FREE(data);
py_assign(py_retval(), module); py_assign(py_retval(), module);