diff --git a/include/pocketpy/error.h b/include/pocketpy/error.h index 4d6de5ca..950bb742 100644 --- a/include/pocketpy/error.h +++ b/include/pocketpy/error.h @@ -44,8 +44,9 @@ struct Exception { stack stacktrace; int _ip_on_error; + void* _code_on_error; - Exception(StrName type, Str msg): type(type), msg(msg), is_re(true), _ip_on_error(-1) {} + Exception(StrName type, Str msg): type(type), msg(msg), is_re(true), _ip_on_error(-1), _code_on_error(nullptr) {} bool match_type(StrName t) const { return this->type == t;} void st_push(Str&& snapshot); Str summary() const; diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index e37eedb4..7e375cd0 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -352,8 +352,14 @@ public: _error(Exception(name, msg)); } - void _raise(){ - bool ok = top_frame()->jump_to_exception_handler(); + void _raise(bool re_raise=false){ + Frame* top = top_frame().get(); + if(!re_raise){ + Exception& e = PK_OBJ_GET(Exception, s_data.top()); + e._ip_on_error = top->_ip; + e._code_on_error = (void*)top->co; + } + bool ok = top->jump_to_exception_handler(); if(ok) throw HandledException(); else throw UnhandledException(); } diff --git a/src/ceval.cpp b/src/ceval.cpp index 5e517e52..0c34c75e 100644 --- a/src/ceval.cpp +++ b/src/ceval.cpp @@ -695,7 +695,7 @@ __NEXT_STEP:; Str msg = _0 == None ? "" : CAST(Str, py_str(_0)); _error(StrName(byte.arg), msg); } DISPATCH(); - TARGET(RE_RAISE) _raise(); DISPATCH(); + TARGET(RE_RAISE) _raise(true); DISPATCH(); TARGET(POP_EXCEPTION) _last_exception = POPX(); DISPATCH(); /*****************************************/ TARGET(FORMAT_STRING) { @@ -751,8 +751,8 @@ __NEXT_STEP:; PyObject* obj = POPX(); Exception& _e = CAST(Exception&, obj); int actual_ip = frame->_ip; - if(_e._ip_on_error >= 0) actual_ip = _e._ip_on_error; - int current_line = frame->co->lines[actual_ip]; // current line + if(_e._ip_on_error >= 0 && _e._code_on_error == (void*)frame->co) actual_ip = _e._ip_on_error; + int current_line = frame->co->lines[actual_ip]; // current line auto current_f_name = frame->co->name.sv(); // current function name if(frame->_callable == nullptr) current_f_name = ""; // not in a function _e.st_push(frame->co->src->snapshot(current_line, nullptr, current_f_name)); diff --git a/src/vm.cpp b/src/vm.cpp index 13e79adb..14b3ac94 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -1069,7 +1069,6 @@ PyObject* VM::bind_property(PyObject* obj, Str name, NativeFuncC fget, NativeFun } void VM::_error(Exception e){ - e._ip_on_error = top_frame()->_ip; if(callstack.empty()){ e.is_re = false; throw e;