blueloveTH 1 год назад
Родитель
Сommit
6b61c85dac

+ 1 - 1
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 {

+ 5 - 2
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).

+ 4 - 13
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;

+ 12 - 5
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;
 }

+ 2 - 1
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;

+ 3 - 2
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;
 }