Sfoglia il codice sorgente

implement tracefunc

blueloveTH 1 anno fa
parent
commit
483e6fcb57

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

+ 0 - 5
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;

+ 21 - 4
src/interpreter/ceval.c

@@ -97,12 +97,19 @@ FrameResult VM__run_top_frame(VM* self) {
         frame->ip++;
 
     __NEXT_STEP:
+        byte = codes[frame->ip];
+
         if(self->trace_info.tracefunc) {
-            // TODO: implement tracing mechanism
+            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);
+            }
         }
 
-        byte = codes[frame->ip];
-
 #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;
+}

+ 7 - 0
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;
 }