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