From 6b61c85dac0d7a0e6135b7a2bc136ec9fb32d127 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Thu, 6 Mar 2025 17:02:05 +0800 Subject: [PATCH] ... --- include/pocketpy/interpreter/vm.h | 2 +- include/pocketpy/pocketpy.h | 7 +++++-- src/interpreter/ceval.c | 17 ++++------------- src/interpreter/frame.c | 17 ++++++++++++----- src/interpreter/vm.c | 3 ++- src/public/py_exception.c | 5 +++-- 6 files changed, 27 insertions(+), 24 deletions(-) diff --git a/include/pocketpy/interpreter/vm.h b/include/pocketpy/interpreter/vm.h index 6c3cfce5..1aca1336 100644 --- a/include/pocketpy/interpreter/vm.h +++ b/include/pocketpy/interpreter/vm.h @@ -20,7 +20,7 @@ typedef struct TraceInfo { SourceLocation prev_loc; - py_TraceFunc tracefunc; + py_TraceFunc func; } TraceInfo; typedef struct VM { diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index a0cea0e6..45fbb0d7 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -55,9 +55,9 @@ typedef struct py_Frame py_Frame; // An enum for tracing events. enum py_TraceEvent { TRACE_EVENT_LINE, - TRACE_EVENT_CALL, - TRACE_EVENT_RETURN, TRACE_EVENT_EXCEPTION, + TRACE_EVENT_PUSH, + TRACE_EVENT_POP, }; typedef void (*py_TraceFunc)(py_Frame* frame, enum py_TraceEvent); @@ -108,6 +108,9 @@ PK_API void py_sys_settrace(py_TraceFunc func); /// Setup the callbacks for the current VM. PK_API py_Callbacks* py_callbacks(); +/// Get the current source location of the frame. +PK_API const char* py_Frame_sourceloc(py_Frame* frame, int* lineno); + /// Run a source string. /// @param source source string. /// @param filename filename (for error messages). diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index 6ebc864d..cc08a3ee 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -66,13 +66,7 @@ static bool stack_format_object(VM* self, c11_sv spec); FrameResult res = VM__vectorcall(self, (argc), (kwargc), true); \ switch(res) { \ case RES_RETURN: PUSH(&self->last_retval); break; \ - case RES_CALL: { \ - frame = self->top_frame; \ - if(self->trace_info.tracefunc) { \ - self->trace_info.tracefunc(frame, TRACE_EVENT_CALL); \ - } \ - goto __NEXT_FRAME; \ - } \ + case RES_CALL: frame = self->top_frame; goto __NEXT_FRAME; \ case RES_ERROR: goto __ERROR; \ default: c11__unreachable(); \ } \ @@ -105,14 +99,14 @@ FrameResult VM__run_top_frame(VM* self) { __NEXT_STEP: byte = codes[frame->ip]; - if(self->trace_info.tracefunc) { + if(self->trace_info.func) { SourceLocation loc = Frame__source_location(frame); SourceLocation prev_loc = self->trace_info.prev_loc; if(loc.lineno != prev_loc.lineno || loc.src != prev_loc.src) { if(prev_loc.src) PK_DECREF(prev_loc.src); PK_INCREF(loc.src); self->trace_info.prev_loc = loc; - self->trace_info.tracefunc(frame, TRACE_EVENT_LINE); + self->trace_info.func(frame, TRACE_EVENT_LINE); } } @@ -757,9 +751,6 @@ FrameResult VM__run_top_frame(VM* self) { } else { py_newnone(&self->last_retval); } - if(self->trace_info.tracefunc) { - self->trace_info.tracefunc(frame, TRACE_EVENT_RETURN); - } VM__pop_frame(self); if(frame == base_frame) { // [ frameBase<- ] return RES_RETURN; @@ -1459,7 +1450,7 @@ static bool stack_format_object(VM* self, c11_sv spec) { void py_sys_settrace(py_TraceFunc func) { TraceInfo* info = &pk_current_vm->trace_info; - info->tracefunc = func; + info->func = func; if(info->prev_loc.src) { PK_DECREF(info->prev_loc.src); info->prev_loc.src = NULL; diff --git a/src/interpreter/frame.c b/src/interpreter/frame.c index dbb98aa0..ae9cc2f0 100644 --- a/src/interpreter/frame.c +++ b/src/interpreter/frame.c @@ -48,11 +48,11 @@ UnwindTarget* UnwindTarget__new(UnwindTarget* next, int iblock, int offset) { void UnwindTarget__delete(UnwindTarget* self) { PK_FREE(self); } py_Frame* Frame__new(const CodeObject* co, - py_StackRef p0, - py_GlobalRef module, - py_Ref globals, - py_Ref locals, - bool is_locals_special) { + py_StackRef p0, + py_GlobalRef module, + py_Ref globals, + py_Ref locals, + bool is_locals_special) { assert(module->type == tp_module); assert(globals->type == tp_module || globals->type == tp_dict); if(is_locals_special) { @@ -121,6 +121,7 @@ void Frame__gc_mark(py_Frame* self) { int Frame__lineno(const py_Frame* self) { int ip = self->ip; + if(ip < 0) return 0; return c11__getitem(BytecodeEx, &self->co->codes_ex, ip).lineno; } @@ -180,4 +181,10 @@ SourceLocation Frame__source_location(py_Frame* self) { loc.lineno = Frame__lineno(self); loc.src = self->co->src; return loc; +} + +const char* py_Frame_sourceloc(py_Frame* self, int* lineno) { + SourceLocation loc = Frame__source_location(self); + *lineno = loc.lineno; + return loc.src->filename->data; } \ No newline at end of file diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index 9f3f22d4..4905e4db 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -265,13 +265,14 @@ void VM__dtor(VM* self) { void VM__push_frame(VM* self, py_Frame* frame) { frame->f_back = self->top_frame; self->top_frame = frame; + if(self->trace_info.func) self->trace_info.func(frame, TRACE_EVENT_PUSH); } void VM__pop_frame(VM* self) { assert(self->top_frame); py_Frame* frame = self->top_frame; + if(self->trace_info.func) self->trace_info.func(frame, TRACE_EVENT_POP); // reset stack pointer - self->stack.sp = frame->p0; // pop frame and delete self->top_frame = frame->f_back; diff --git a/src/public/py_exception.c b/src/public/py_exception.c index 38d8afc4..e716b655 100644 --- a/src/public/py_exception.c +++ b/src/public/py_exception.c @@ -251,9 +251,10 @@ bool py_raise(py_Ref exc) { } vm->curr_exception = *exc; vm->is_curr_exc_handled = false; - if(vm->trace_info.tracefunc && !py_istype(exc, tp_StopIteration)) { + + if(vm->trace_info.func && !py_istype(exc, tp_StopIteration)) { py_Frame* frame = vm->top_frame; - vm->trace_info.tracefunc(frame, TRACE_EVENT_EXCEPTION); + vm->trace_info.func(frame, TRACE_EVENT_EXCEPTION); } return false; }