mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 20:10:17 +00:00
add breakpoint
This commit is contained in:
parent
b6d62c9d89
commit
d87c9ff850
@ -30,13 +30,14 @@ namespace pkpy{
|
|||||||
typedef PyObject* (*BinaryFuncC)(VM*, PyObject*, PyObject*);
|
typedef PyObject* (*BinaryFuncC)(VM*, PyObject*, PyObject*);
|
||||||
|
|
||||||
struct NextBreakpoint{
|
struct NextBreakpoint{
|
||||||
Frame* frame;
|
LinkedFrame* linked_frame;
|
||||||
int lineno;
|
int lineno;
|
||||||
bool should_step_into;
|
bool should_step_into;
|
||||||
NextBreakpoint(): frame(nullptr), lineno(-1), should_step_into(false) {}
|
NextBreakpoint(): linked_frame(nullptr) {}
|
||||||
NextBreakpoint(Frame* frame, int lineno, bool should_step_info): frame(frame), lineno(lineno), should_step_into(should_step_info) {}
|
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);
|
void _step(VM* vm, LinkedFrame* lf);
|
||||||
bool empty() const { return frame == nullptr; }
|
bool empty() const { return linked_frame == nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PyTypeInfo{
|
struct PyTypeInfo{
|
||||||
|
@ -73,11 +73,7 @@ void init_builtins(VM* _vm) {
|
|||||||
|
|
||||||
// builtin functions
|
// builtin functions
|
||||||
_vm->bind_func<0>(_vm->builtins, "breakpoint", [](VM* vm, ArgsView args) {
|
_vm->bind_func<0>(_vm->builtins, "breakpoint", [](VM* vm, ArgsView args) {
|
||||||
vm->_next_breakpoint = NextBreakpoint(
|
vm->_next_breakpoint = NextBreakpoint(vm->callstack._tail, false);
|
||||||
vm->top_frame(),
|
|
||||||
vm->top_frame()->curr_lineno(),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
return vm->None;
|
return vm->None;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
49
src/vm.cpp
49
src/vm.cpp
@ -1353,33 +1353,35 @@ PyObject* NativeFunc::call(VM *vm, ArgsView args) const {
|
|||||||
return f(vm, args);
|
return f(vm, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NextBreakpoint::_step(VM* vm, LinkedFrame* lf){
|
void NextBreakpoint::_step(VM* vm, LinkedFrame* linked_frame){
|
||||||
Frame* frame = &lf->frame;
|
int lineno = linked_frame->frame.curr_lineno();
|
||||||
int lineno = frame->co->lines[frame->_ip].lineno;
|
|
||||||
if(should_step_into){
|
if(should_step_into){
|
||||||
if(frame != this->frame || lineno != this->lineno){
|
if(linked_frame != this->linked_frame || lineno != this->lineno){
|
||||||
vm->_breakpoint();
|
vm->_breakpoint();
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(frame == this->frame){
|
if(linked_frame == this->linked_frame){
|
||||||
if(lineno != this->lineno) vm->_breakpoint();
|
if(lineno != this->lineno) vm->_breakpoint();
|
||||||
}else{
|
}else{
|
||||||
if(&lf->f_back->frame != this->frame) vm->_breakpoint();
|
if(this->linked_frame->f_back == linked_frame){
|
||||||
|
// returning
|
||||||
|
vm->_breakpoint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VM::_breakpoint(){
|
void VM::_breakpoint(){
|
||||||
_next_breakpoint = NextBreakpoint();
|
_next_breakpoint = NextBreakpoint();
|
||||||
|
|
||||||
bool show_where = false;
|
bool show_where = false;
|
||||||
bool show_headers = true;
|
bool show_headers = true;
|
||||||
|
|
||||||
while(true){
|
while(true){
|
||||||
std::vector<Frame*> frames;
|
std::vector<LinkedFrame*> frames;
|
||||||
LinkedFrame* lf = callstack._tail;
|
LinkedFrame* lf = callstack._tail;
|
||||||
while(lf != nullptr){
|
while(lf != nullptr){
|
||||||
frames.push_back(&lf->frame);
|
frames.push_back(lf);
|
||||||
lf = lf->f_back;
|
lf = lf->f_back;
|
||||||
if(frames.size() >= 4) break;
|
if(frames.size() >= 4) break;
|
||||||
}
|
}
|
||||||
@ -1389,7 +1391,7 @@ void VM::_breakpoint(){
|
|||||||
if(!show_where && i!=0) continue;
|
if(!show_where && i!=0) continue;
|
||||||
|
|
||||||
SStream ss;
|
SStream ss;
|
||||||
Frame* frame = frames[i];
|
Frame* frame = &frames[i]->frame;
|
||||||
int lineno = frame->curr_lineno();
|
int lineno = frame->curr_lineno();
|
||||||
auto [_0, _1] = frame->co->src->_get_line(lineno);
|
auto [_0, _1] = frame->co->src->_get_line(lineno);
|
||||||
ss << "File \"" << frame->co->src->filename << "\", line " << lineno;
|
ss << "File \"" << frame->co->src->filename << "\", line " << lineno;
|
||||||
@ -1409,6 +1411,7 @@ void VM::_breakpoint(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
vm->stdout_write("(Pdb) ");
|
vm->stdout_write("(Pdb) ");
|
||||||
|
Frame* frame_0 = &frames[0]->frame;
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
if(!std::getline(std::cin, line)){
|
if(!std::getline(std::cin, line)){
|
||||||
@ -1428,21 +1431,16 @@ void VM::_breakpoint(){
|
|||||||
stdout_write("!: execute statement\n");
|
stdout_write("!: execute statement\n");
|
||||||
continue;
|
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"){
|
if(line == "n" || line == "next"){
|
||||||
vm->_next_breakpoint = NextBreakpoint(
|
vm->_next_breakpoint = NextBreakpoint(frames[0], false);
|
||||||
frames[0],
|
|
||||||
frames[0]->curr_lineno(),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(line == "s" || line == "step"){
|
if(line == "s" || line == "step"){
|
||||||
vm->_next_breakpoint = NextBreakpoint(
|
vm->_next_breakpoint = NextBreakpoint(frames[0], true);
|
||||||
frames[0],
|
|
||||||
frames[0]->curr_lineno(),
|
|
||||||
true
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(line == "w" || line == "where"){
|
if(line == "w" || line == "where"){
|
||||||
@ -1453,9 +1451,9 @@ void VM::_breakpoint(){
|
|||||||
if(line == "c" || line == "continue") break;
|
if(line == "c" || line == "continue") break;
|
||||||
if(line == "a" || line == "args"){
|
if(line == "a" || line == "args"){
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for(PyObject* obj: frames[0]->_locals){
|
for(PyObject* obj: frame_0->_locals){
|
||||||
if(obj == PY_NULL) continue;
|
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'));
|
stdout_write(_S(name.sv(), " = ", CAST(Str&, vm->py_repr(obj)), '\n'));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@ -1468,17 +1466,16 @@ void VM::_breakpoint(){
|
|||||||
if(arg.empty()) continue; // ignore empty command
|
if(arg.empty()) continue; // ignore empty command
|
||||||
if(cmd == "p" || cmd == "print"){
|
if(cmd == "p" || cmd == "print"){
|
||||||
CodeObject_ code = compile(arg, "<stdin>", EVAL_MODE, true);
|
CodeObject_ code = compile(arg, "<stdin>", 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(CAST(Str&, vm->py_repr(retval)));
|
||||||
stdout_write("\n");
|
stdout_write("\n");
|
||||||
}else if(cmd == "!"){
|
}else if(cmd == "!"){
|
||||||
CodeObject_ code = compile(arg, "<stdin>", EXEC_MODE, true);
|
CodeObject_ code = compile(arg, "<stdin>", 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;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stdout_write("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
Loading…
x
Reference in New Issue
Block a user