This commit is contained in:
blueloveTH 2025-03-06 19:48:04 +08:00
parent 6b61c85dac
commit 8be90c3ba5
7 changed files with 40 additions and 15 deletions

View File

@ -44,7 +44,7 @@ typedef struct VM {
void* ctx; // user-defined context void* ctx; // user-defined context
py_StackRef curr_class; py_StackRef curr_class;
py_StackRef curr_function; py_StackRef curr_decl_based_function;
TraceInfo trace_info; TraceInfo trace_info;
py_TValue vectorcall_buffer[PK_MAX_CO_VARNAMES]; py_TValue vectorcall_buffer[PK_MAX_CO_VARNAMES];

View File

@ -110,6 +110,9 @@ PK_API py_Callbacks* py_callbacks();
/// Get the current source location of the frame. /// Get the current source location of the frame.
PK_API const char* py_Frame_sourceloc(py_Frame* frame, int* lineno); PK_API const char* py_Frame_sourceloc(py_Frame* frame, int* lineno);
/// Get the function object of the frame.
/// Returns `NULL` if not available.
PK_API py_StackRef py_Frame_function(py_Frame* frame);
/// Run a source string. /// Run a source string.
/// @param source source string. /// @param source source string.
@ -388,7 +391,9 @@ PK_API py_StackRef py_inspect_currentfunction();
/// Get the current `module` object where the code is executed. /// Get the current `module` object where the code is executed.
/// Return `NULL` if not available. /// Return `NULL` if not available.
PK_API py_GlobalRef py_inspect_currentmodule(); PK_API py_GlobalRef py_inspect_currentmodule();
/// Get the current frame object.
/// Return `NULL` if not available.
PK_API py_Frame* py_inspect_currentframe();
/************* Bindings *************/ /************* Bindings *************/
/// Bind a function to the object via "decl-based" style. /// Bind a function to the object via "decl-based" style.

View File

@ -188,3 +188,9 @@ const char* py_Frame_sourceloc(py_Frame* self, int* lineno) {
*lineno = loc.lineno; *lineno = loc.lineno;
return loc.src->filename->data; return loc.src->filename->data;
} }
py_StackRef py_Frame_function(py_Frame* self) {
if(self->is_locals_special) return NULL;
assert(self->p0->type == tp_function);
return self->p0;
}

View File

@ -75,7 +75,7 @@ void VM__ctor(VM* self) {
self->ctx = NULL; self->ctx = NULL;
self->curr_class = NULL; self->curr_class = NULL;
self->curr_function = NULL; self->curr_decl_based_function = NULL;
memset(&self->trace_info, 0, sizeof(TraceInfo)); memset(&self->trace_info, 0, sizeof(TraceInfo));
FixedMemoryPool__ctor(&self->pool_frame, sizeof(py_Frame), 32); FixedMemoryPool__ctor(&self->pool_frame, sizeof(py_Frame), 32);
@ -492,10 +492,10 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
return opcall ? RES_CALL : VM__run_top_frame(self); return opcall ? RES_CALL : VM__run_top_frame(self);
} else { } else {
// decl-based binding // decl-based binding
self->curr_function = p0; self->curr_decl_based_function = p0;
bool ok = py_callcfunc(fn->cfunc, co->nlocals, argv); bool ok = py_callcfunc(fn->cfunc, co->nlocals, argv);
self->stack.sp = p0; self->stack.sp = p0;
self->curr_function = NULL; self->curr_decl_based_function = NULL;
return ok ? RES_RETURN : RES_ERROR; return ok ? RES_RETURN : RES_ERROR;
} }
} }
@ -521,10 +521,10 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
return opcall ? RES_CALL : VM__run_top_frame(self); return opcall ? RES_CALL : VM__run_top_frame(self);
} else { } else {
// decl-based binding // decl-based binding
self->curr_function = p0; self->curr_decl_based_function = p0;
bool ok = py_callcfunc(fn->cfunc, co->nlocals, argv); bool ok = py_callcfunc(fn->cfunc, co->nlocals, argv);
self->stack.sp = p0; self->stack.sp = p0;
self->curr_function = NULL; self->curr_decl_based_function = NULL;
return ok ? RES_RETURN : RES_ERROR; return ok ? RES_RETURN : RES_ERROR;
} }
case FuncType_GENERATOR: { case FuncType_GENERATOR: {

View File

@ -797,10 +797,18 @@ static bool function__doc__(int argc, py_Ref argv) {
return true; return true;
} }
static bool function__name__(int argc, py_Ref argv) {
PY_CHECK_ARGC(1);
Function* func = py_touserdata(py_arg(0));
py_newstr(py_retval(), func->decl->code.name->data);
return true;
}
py_Type pk_function__register() { py_Type pk_function__register() {
py_Type type = py_Type type =
pk_newtype("function", tp_object, NULL, (void (*)(void*))Function__dtor, false, true); pk_newtype("function", tp_object, NULL, (void (*)(void*))Function__dtor, false, true);
py_bindproperty(type, "__doc__", function__doc__, NULL); py_bindproperty(type, "__doc__", function__doc__, NULL);
py_bindproperty(type, "__name__", function__name__, NULL);
return type; return type;
} }

View File

@ -154,7 +154,7 @@ void py_clearexc(py_StackRef p0) {
vm->is_curr_exc_handled = false; vm->is_curr_exc_handled = false;
/* Don't clear this, because StopIteration() may corrupt the class definition */ /* Don't clear this, because StopIteration() may corrupt the class definition */
// vm->curr_class = NULL; // vm->curr_class = NULL;
vm->curr_function = NULL; vm->curr_decl_based_function = NULL;
if(p0) vm->stack.sp = p0; if(p0) vm->stack.sp = p0;
} }

View File

@ -29,15 +29,15 @@ void py_setdict(py_Ref self, py_Name name, py_Ref val) {
} }
} }
py_ItemRef py_emplacedict(py_Ref self, py_Name name){ py_ItemRef py_emplacedict(py_Ref self, py_Name name) {
py_setdict(self, name, py_NIL()); py_setdict(self, name, py_NIL());
return py_getdict(self, name); return py_getdict(self, name);
} }
bool py_applydict(py_Ref self, bool (*f)(py_Name, py_Ref, void *), void *ctx){ bool py_applydict(py_Ref self, bool (*f)(py_Name, py_Ref, void*), void* ctx) {
assert(self && self->is_ptr); assert(self && self->is_ptr);
NameDict* dict = PyObject__dict(self->_obj); NameDict* dict = PyObject__dict(self->_obj);
for(int i = 0; i < dict->length; i++){ for(int i = 0; i < dict->length; i++) {
NameDict_KV* kv = c11__at(NameDict_KV, dict, i); NameDict_KV* kv = c11__at(NameDict_KV, dict, i);
bool ok = f(kv->key, &kv->value, ctx); bool ok = f(kv->key, &kv->value, ctx);
if(!ok) return false; if(!ok) return false;
@ -68,16 +68,22 @@ void py_setslot(py_Ref self, int i, py_Ref val) {
PyObject__slots(self->_obj)[i] = *val; PyObject__slots(self->_obj)[i] = *val;
} }
py_StackRef py_inspect_currentfunction(){ py_StackRef py_inspect_currentfunction() {
return pk_current_vm->curr_function; VM* vm = pk_current_vm;
if(vm->curr_decl_based_function) { return vm->curr_decl_based_function; }
py_Frame* frame = vm->top_frame;
if(!frame || frame->is_locals_special) return NULL;
return frame->p0;
} }
py_GlobalRef py_inspect_currentmodule(){ py_GlobalRef py_inspect_currentmodule() {
py_Frame* frame = pk_current_vm->top_frame; py_Frame* frame = pk_current_vm->top_frame;
if(!frame) return NULL; if(!frame) return NULL;
return frame->module; return frame->module;
} }
py_Frame* py_inspect_currentframe() { return pk_current_vm->top_frame; }
void py_assign(py_Ref dst, py_Ref src) { *dst = *src; } void py_assign(py_Ref dst, py_Ref src) { *dst = *src; }
/* Stack References */ /* Stack References */
@ -111,7 +117,7 @@ void py_pushnone() {
py_newnone(vm->stack.sp++); py_newnone(vm->stack.sp++);
} }
void py_pushname(py_Name name){ void py_pushname(py_Name name) {
VM* vm = pk_current_vm; VM* vm = pk_current_vm;
py_newint(vm->stack.sp++, name); py_newint(vm->stack.sp++, name);
} }