From d87c9ff850fa73ce26a937864f0208d76db44995 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sun, 14 Apr 2024 20:33:04 +0800 Subject: [PATCH] add `breakpoint` --- include/pocketpy/vm.h | 9 ++++---- src/pocketpy.cpp | 6 +----- src/vm.cpp | 49 ++++++++++++++++++++----------------------- 3 files changed, 29 insertions(+), 35 deletions(-) diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index c3355d80..04d51df1 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -30,13 +30,14 @@ namespace pkpy{ typedef PyObject* (*BinaryFuncC)(VM*, PyObject*, PyObject*); struct NextBreakpoint{ - Frame* frame; + LinkedFrame* linked_frame; int lineno; bool should_step_into; - NextBreakpoint(): frame(nullptr), lineno(-1), should_step_into(false) {} - NextBreakpoint(Frame* frame, int lineno, bool should_step_info): frame(frame), lineno(lineno), should_step_into(should_step_info) {} + NextBreakpoint(): linked_frame(nullptr) {} + NextBreakpoint(LinkedFrame* lf, bool should_step_into): + linked_frame(lf), lineno(lf->frame.curr_lineno()), should_step_into(should_step_into) {} void _step(VM* vm, LinkedFrame* lf); - bool empty() const { return frame == nullptr; } + bool empty() const { return linked_frame == nullptr; } }; struct PyTypeInfo{ diff --git a/src/pocketpy.cpp b/src/pocketpy.cpp index f0bb589a..94550cbb 100644 --- a/src/pocketpy.cpp +++ b/src/pocketpy.cpp @@ -73,11 +73,7 @@ void init_builtins(VM* _vm) { // builtin functions _vm->bind_func<0>(_vm->builtins, "breakpoint", [](VM* vm, ArgsView args) { - vm->_next_breakpoint = NextBreakpoint( - vm->top_frame(), - vm->top_frame()->curr_lineno(), - false - ); + vm->_next_breakpoint = NextBreakpoint(vm->callstack._tail, false); return vm->None; }); diff --git a/src/vm.cpp b/src/vm.cpp index 0212d3d9..587592bd 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -1353,33 +1353,35 @@ PyObject* NativeFunc::call(VM *vm, ArgsView args) const { return f(vm, args); } -void NextBreakpoint::_step(VM* vm, LinkedFrame* lf){ - Frame* frame = &lf->frame; - int lineno = frame->co->lines[frame->_ip].lineno; +void NextBreakpoint::_step(VM* vm, LinkedFrame* linked_frame){ + int lineno = linked_frame->frame.curr_lineno(); if(should_step_into){ - if(frame != this->frame || lineno != this->lineno){ + if(linked_frame != this->linked_frame || lineno != this->lineno){ vm->_breakpoint(); } }else{ - if(frame == this->frame){ + if(linked_frame == this->linked_frame){ if(lineno != this->lineno) vm->_breakpoint(); }else{ - if(&lf->f_back->frame != this->frame) vm->_breakpoint(); + if(this->linked_frame->f_back == linked_frame){ + // returning + vm->_breakpoint(); + } } } } void VM::_breakpoint(){ _next_breakpoint = NextBreakpoint(); - + bool show_where = false; bool show_headers = true; while(true){ - std::vector frames; + std::vector frames; LinkedFrame* lf = callstack._tail; while(lf != nullptr){ - frames.push_back(&lf->frame); + frames.push_back(lf); lf = lf->f_back; if(frames.size() >= 4) break; } @@ -1389,7 +1391,7 @@ void VM::_breakpoint(){ if(!show_where && i!=0) continue; SStream ss; - Frame* frame = frames[i]; + Frame* frame = &frames[i]->frame; int lineno = frame->curr_lineno(); auto [_0, _1] = frame->co->src->_get_line(lineno); ss << "File \"" << frame->co->src->filename << "\", line " << lineno; @@ -1409,6 +1411,7 @@ void VM::_breakpoint(){ } vm->stdout_write("(Pdb) "); + Frame* frame_0 = &frames[0]->frame; std::string line; if(!std::getline(std::cin, line)){ @@ -1428,21 +1431,16 @@ void VM::_breakpoint(){ stdout_write("!: execute statement\n"); continue; } - if(line == "q" || line == "quit") std::exit(0); + if(line == "q" || line == "quit") { + vm->RuntimeError("pdb quit"); + PK_UNREACHABLE() + } if(line == "n" || line == "next"){ - vm->_next_breakpoint = NextBreakpoint( - frames[0], - frames[0]->curr_lineno(), - false - ); + vm->_next_breakpoint = NextBreakpoint(frames[0], false); break; } if(line == "s" || line == "step"){ - vm->_next_breakpoint = NextBreakpoint( - frames[0], - frames[0]->curr_lineno(), - true - ); + vm->_next_breakpoint = NextBreakpoint(frames[0], true); break; } if(line == "w" || line == "where"){ @@ -1453,9 +1451,9 @@ void VM::_breakpoint(){ if(line == "c" || line == "continue") break; if(line == "a" || line == "args"){ int i = 0; - for(PyObject* obj: frames[0]->_locals){ + for(PyObject* obj: frame_0->_locals){ if(obj == PY_NULL) continue; - StrName name = frames[0]->co->varnames[i++]; + StrName name = frame_0->co->varnames[i++]; stdout_write(_S(name.sv(), " = ", CAST(Str&, vm->py_repr(obj)), '\n')); } continue; @@ -1468,17 +1466,16 @@ void VM::_breakpoint(){ if(arg.empty()) continue; // ignore empty command if(cmd == "p" || cmd == "print"){ CodeObject_ code = compile(arg, "", EVAL_MODE, true); - PyObject* retval = vm->_exec(code.get(), frames[0]->_module, frames[0]->_callable, frames[0]->_locals); + PyObject* retval = vm->_exec(code.get(), frame_0->_module, frame_0->_callable, frame_0->_locals); stdout_write(CAST(Str&, vm->py_repr(retval))); stdout_write("\n"); }else if(cmd == "!"){ CodeObject_ code = compile(arg, "", EXEC_MODE, true); - vm->_exec(code.get(), frames[0]->_module, frames[0]->_callable, frames[0]->_locals); + vm->_exec(code.get(), frame_0->_module, frame_0->_callable, frame_0->_locals); } continue; } } - stdout_write("\n"); } } // namespace pkpy \ No newline at end of file