This commit is contained in:
blueloveTH 2025-03-06 17:02:05 +08:00
parent a9955cd210
commit 6b61c85dac
6 changed files with 27 additions and 24 deletions

View File

@ -20,7 +20,7 @@
typedef struct TraceInfo { typedef struct TraceInfo {
SourceLocation prev_loc; SourceLocation prev_loc;
py_TraceFunc tracefunc; py_TraceFunc func;
} TraceInfo; } TraceInfo;
typedef struct VM { typedef struct VM {

View File

@ -55,9 +55,9 @@ typedef struct py_Frame py_Frame;
// An enum for tracing events. // An enum for tracing events.
enum py_TraceEvent { enum py_TraceEvent {
TRACE_EVENT_LINE, TRACE_EVENT_LINE,
TRACE_EVENT_CALL,
TRACE_EVENT_RETURN,
TRACE_EVENT_EXCEPTION, TRACE_EVENT_EXCEPTION,
TRACE_EVENT_PUSH,
TRACE_EVENT_POP,
}; };
typedef void (*py_TraceFunc)(py_Frame* frame, enum py_TraceEvent); 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. /// Setup the callbacks for the current VM.
PK_API py_Callbacks* py_callbacks(); 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. /// Run a source string.
/// @param source source string. /// @param source source string.
/// @param filename filename (for error messages). /// @param filename filename (for error messages).

View File

@ -66,13 +66,7 @@ static bool stack_format_object(VM* self, c11_sv spec);
FrameResult res = VM__vectorcall(self, (argc), (kwargc), true); \ FrameResult res = VM__vectorcall(self, (argc), (kwargc), true); \
switch(res) { \ switch(res) { \
case RES_RETURN: PUSH(&self->last_retval); break; \ case RES_RETURN: PUSH(&self->last_retval); break; \
case RES_CALL: { \ case RES_CALL: frame = self->top_frame; goto __NEXT_FRAME; \
frame = self->top_frame; \
if(self->trace_info.tracefunc) { \
self->trace_info.tracefunc(frame, TRACE_EVENT_CALL); \
} \
goto __NEXT_FRAME; \
} \
case RES_ERROR: goto __ERROR; \ case RES_ERROR: goto __ERROR; \
default: c11__unreachable(); \ default: c11__unreachable(); \
} \ } \
@ -105,14 +99,14 @@ FrameResult VM__run_top_frame(VM* self) {
__NEXT_STEP: __NEXT_STEP:
byte = codes[frame->ip]; byte = codes[frame->ip];
if(self->trace_info.tracefunc) { if(self->trace_info.func) {
SourceLocation loc = Frame__source_location(frame); SourceLocation loc = Frame__source_location(frame);
SourceLocation prev_loc = self->trace_info.prev_loc; SourceLocation prev_loc = self->trace_info.prev_loc;
if(loc.lineno != prev_loc.lineno || loc.src != prev_loc.src) { if(loc.lineno != prev_loc.lineno || loc.src != prev_loc.src) {
if(prev_loc.src) PK_DECREF(prev_loc.src); if(prev_loc.src) PK_DECREF(prev_loc.src);
PK_INCREF(loc.src); PK_INCREF(loc.src);
self->trace_info.prev_loc = loc; 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 { } else {
py_newnone(&self->last_retval); py_newnone(&self->last_retval);
} }
if(self->trace_info.tracefunc) {
self->trace_info.tracefunc(frame, TRACE_EVENT_RETURN);
}
VM__pop_frame(self); VM__pop_frame(self);
if(frame == base_frame) { // [ frameBase<- ] if(frame == base_frame) { // [ frameBase<- ]
return RES_RETURN; return RES_RETURN;
@ -1459,7 +1450,7 @@ static bool stack_format_object(VM* self, c11_sv spec) {
void py_sys_settrace(py_TraceFunc func) { void py_sys_settrace(py_TraceFunc func) {
TraceInfo* info = &pk_current_vm->trace_info; TraceInfo* info = &pk_current_vm->trace_info;
info->tracefunc = func; info->func = func;
if(info->prev_loc.src) { if(info->prev_loc.src) {
PK_DECREF(info->prev_loc.src); PK_DECREF(info->prev_loc.src);
info->prev_loc.src = NULL; info->prev_loc.src = NULL;

View File

@ -48,11 +48,11 @@ UnwindTarget* UnwindTarget__new(UnwindTarget* next, int iblock, int offset) {
void UnwindTarget__delete(UnwindTarget* self) { PK_FREE(self); } void UnwindTarget__delete(UnwindTarget* self) { PK_FREE(self); }
py_Frame* Frame__new(const CodeObject* co, py_Frame* Frame__new(const CodeObject* co,
py_StackRef p0, py_StackRef p0,
py_GlobalRef module, py_GlobalRef module,
py_Ref globals, py_Ref globals,
py_Ref locals, py_Ref locals,
bool is_locals_special) { bool is_locals_special) {
assert(module->type == tp_module); assert(module->type == tp_module);
assert(globals->type == tp_module || globals->type == tp_dict); assert(globals->type == tp_module || globals->type == tp_dict);
if(is_locals_special) { if(is_locals_special) {
@ -121,6 +121,7 @@ void Frame__gc_mark(py_Frame* self) {
int Frame__lineno(const py_Frame* self) { int Frame__lineno(const py_Frame* self) {
int ip = self->ip; int ip = self->ip;
if(ip < 0) return 0;
return c11__getitem(BytecodeEx, &self->co->codes_ex, ip).lineno; 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.lineno = Frame__lineno(self);
loc.src = self->co->src; loc.src = self->co->src;
return loc; 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;
} }

View File

@ -265,13 +265,14 @@ void VM__dtor(VM* self) {
void VM__push_frame(VM* self, py_Frame* frame) { void VM__push_frame(VM* self, py_Frame* frame) {
frame->f_back = self->top_frame; frame->f_back = self->top_frame;
self->top_frame = frame; self->top_frame = frame;
if(self->trace_info.func) self->trace_info.func(frame, TRACE_EVENT_PUSH);
} }
void VM__pop_frame(VM* self) { void VM__pop_frame(VM* self) {
assert(self->top_frame); assert(self->top_frame);
py_Frame* frame = 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 // reset stack pointer
self->stack.sp = frame->p0; self->stack.sp = frame->p0;
// pop frame and delete // pop frame and delete
self->top_frame = frame->f_back; self->top_frame = frame->f_back;

View File

@ -251,9 +251,10 @@ bool py_raise(py_Ref exc) {
} }
vm->curr_exception = *exc; vm->curr_exception = *exc;
vm->is_curr_exc_handled = false; 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; py_Frame* frame = vm->top_frame;
vm->trace_info.tracefunc(frame, TRACE_EVENT_EXCEPTION); vm->trace_info.func(frame, TRACE_EVENT_EXCEPTION);
} }
return false; return false;
} }