implement tracefunc

This commit is contained in:
blueloveTH 2025-03-06 00:48:16 +08:00
parent 64a4ae4676
commit 483e6fcb57
4 changed files with 36 additions and 11 deletions

View File

@ -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);
void Frame__gc_mark(Frame* self);
SourceLocation Frame__source_location(Frame* self);

View File

@ -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;

View File

@ -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
#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;
}

View File

@ -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;
}