diff --git a/include/pocketpy/interpreter/frame.h b/include/pocketpy/interpreter/frame.h index 510ae0f6..ed9fd6cb 100644 --- a/include/pocketpy/interpreter/frame.h +++ b/include/pocketpy/interpreter/frame.h @@ -40,6 +40,11 @@ typedef struct Frame { UnwindTarget* uw_list; } Frame; +typedef struct SourceLocation { + SourceData_ src; + int lineno; +} SourceLocation; + Frame* Frame__new(const CodeObject* co, py_StackRef p0, py_GlobalRef module, @@ -63,4 +68,5 @@ int Frame__prepare_jump_exception_handler(Frame* self, ValueStack*); UnwindTarget* Frame__find_unwind_target(Frame* self, int iblock); void Frame__set_unwind_target(Frame* self, py_TValue* sp); -void Frame__gc_mark(Frame* self); \ No newline at end of file +void Frame__gc_mark(Frame* self); +SourceLocation Frame__source_location(Frame* self); \ No newline at end of file diff --git a/include/pocketpy/interpreter/vm.h b/include/pocketpy/interpreter/vm.h index 9db880ff..836c0b38 100644 --- a/include/pocketpy/interpreter/vm.h +++ b/include/pocketpy/interpreter/vm.h @@ -18,11 +18,6 @@ // 5. stack effect of each opcode // 6. py_TypeInfo -typedef struct SourceLocation { - SourceData_ src; - int lineno; -} SourceLocation; - typedef struct TraceInfo { SourceLocation prev_loc; py_TraceFunc tracefunc; diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index 38f81009..9d7c65ae 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -97,12 +97,19 @@ FrameResult VM__run_top_frame(VM* self) { frame->ip++; __NEXT_STEP: - if(self->trace_info.tracefunc) { - // TODO: implement tracing mechanism - } - byte = codes[frame->ip]; + if(self->trace_info.tracefunc) { + 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((py_Frame*)frame, TRACE_EVENT_LINE); + } + } + #ifndef NDEBUG pk_print_stack(self, frame, byte); #endif @@ -1439,4 +1446,14 @@ static bool stack_format_object(VM* self, c11_sv spec) { #undef POPX #undef SP #undef INSERT_THIRD -#undef vectorcall_opcall \ No newline at end of file +#undef vectorcall_opcall + +void py_sys_settrace(py_TraceFunc func) { + TraceInfo* info = &pk_current_vm->trace_info; + info->tracefunc = func; + if(info->prev_loc.src) { + PK_DECREF(info->prev_loc.src); + info->prev_loc.src = NULL; + } + info->prev_loc.lineno = -1; +} \ No newline at end of file diff --git a/src/interpreter/frame.c b/src/interpreter/frame.c index 7ce44fab..1ce45cb4 100644 --- a/src/interpreter/frame.c +++ b/src/interpreter/frame.c @@ -173,4 +173,11 @@ py_Ref Frame__getclosure(Frame* self, py_Name name) { Function* ud = py_touserdata(self->p0); if(ud->closure == NULL) return NULL; return NameDict__try_get(ud->closure, name); +} + +SourceLocation Frame__source_location(Frame* self) { + SourceLocation loc; + loc.lineno = Frame__lineno(self); + loc.src = self->co->src; + return loc; } \ No newline at end of file