diff --git a/include/pocketpy/frame.h b/include/pocketpy/frame.h index 98a77821..55a2bfed 100644 --- a/include/pocketpy/frame.h +++ b/include/pocketpy/frame.h @@ -69,7 +69,7 @@ struct ValueStack { }; struct Frame { - int _ip; + const Bytecode* _ip_addr; // This is for unwinding only, use `actual_sp_base()` for value stack access PyVar* _sp_base; @@ -80,18 +80,19 @@ struct Frame { NameDict& f_globals() { return _module->attr(); } PyVar f_closure_try_get(StrName name); + int ip() const { return _ip_addr - co->codes.data(); } // function scope Frame(PyVar* p0, const CodeObject* co, PyVar _module, PyVar _callable, PyVar* _locals_base) - : _ip(-1), _sp_base(p0), co(co), _module(_module), _callable(_callable), _locals(co, _locals_base) { } + : _ip_addr(co->codes.data()-1), _sp_base(p0), co(co), _module(_module), _callable(_callable), _locals(co, _locals_base) { } // exec/eval Frame(PyVar* p0, const CodeObject* co, PyVar _module, PyVar _callable, FastLocals _locals) - : _ip(-1), _sp_base(p0), co(co), _module(_module), _callable(_callable), _locals(_locals) { } + : _ip_addr(co->codes.data()-1), _sp_base(p0), co(co), _module(_module), _callable(_callable), _locals(_locals) { } // global scope Frame(PyVar* p0, const CodeObject_& co, PyVar _module) - : _ip(-1), _sp_base(p0), co(co.get()), _module(_module), _callable(nullptr), _locals(co.get(), p0) {} + : _ip_addr(co->codes.data()-1), _sp_base(p0), co(co.get()), _module(_module), _callable(nullptr), _locals(co.get(), p0) {} PyVar* actual_sp_base() const { return _locals.a; } @@ -103,12 +104,12 @@ struct Frame { int _exit_block(ValueStack*, int); [[nodiscard]] int prepare_loop_break(ValueStack* s_data){ - int target = co->_get_block_codei(_ip).end; + int target = co->_get_block_codei(ip()).end; prepare_jump_break(s_data, target); return target; } - int curr_lineno() const { return co->lines[_ip].lineno; } + int curr_lineno() const { return co->lines[ip()].lineno; } void _gc_mark() const { PK_OBJ_MARK(_module); diff --git a/src/ceval.cpp b/src/ceval.cpp index 113a726c..ccd9d3f4 100644 --- a/src/ceval.cpp +++ b/src/ceval.cpp @@ -94,8 +94,8 @@ bool VM::py_ge(PyVar _0, PyVar _1){ } #endif -#define DISPATCH() { frame->_ip++; goto __NEXT_STEP; } -#define DISPATCH_JUMP(__target) { frame->_ip = __target; goto __NEXT_STEP; } +#define DISPATCH() { frame->_ip_addr++; goto __NEXT_STEP; } +#define DISPATCH_JUMP(__target) { frame->_ip_addr = co_codes+__target; goto __NEXT_STEP; } PyVar VM::__run_top_frame(){ Frame* frame = &callstack.top(); @@ -107,12 +107,16 @@ PyVar VM::__run_top_frame(){ /**********************************************************************/ { __NEXT_FRAME: + // TODO: when jit is enabled, co_codes may not be const + const Bytecode* co_codes = frame->co->codes.data(); + Bytecode byte; + if(__internal_exception.type == InternalExceptionType::Null){ // None - frame->_ip++; + frame->_ip_addr++; }else if(__internal_exception.type == InternalExceptionType::Handled){ // HandledException + continue - frame->_ip = __internal_exception.arg; + frame->_ip_addr = co_codes + __internal_exception.arg; __internal_exception = {}; }else{ // UnhandledException + continue (need_raise = true) @@ -121,12 +125,8 @@ __NEXT_FRAME: __raise_exc(); // no return } - // TODO: when jit is enabled, co_codes may not be const - const Bytecode* co_codes = frame->co->codes.data(); - Bytecode byte; - __NEXT_STEP: - byte = co_codes[frame->_ip]; + byte = *frame->_ip_addr; CEVAL_STEP_CALLBACK() #if PK_DEBUG_CEVAL_STEP @@ -542,13 +542,11 @@ __NEXT_STEP: case OP_COMPARE_EQ:{ PyVar _1 = POPX(); PyVar _0 = TOP(); - PREDICT_INT_OP(==) TOP() = VAR(py_eq(_0, _1)); } DISPATCH() case OP_COMPARE_NE:{ PyVar _1 = POPX(); PyVar _0 = TOP(); - PREDICT_INT_OP(!=) TOP() = VAR(py_ne(_0, _1)); } DISPATCH() case OP_COMPARE_GT:{ diff --git a/src/frame.cpp b/src/frame.cpp index ca843cd7..48bcbcbd 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -25,7 +25,7 @@ namespace pkpy{ int Frame::prepare_jump_exception_handler(ValueStack* _s){ // try to find a parent try block - int block = co->iblocks[_ip]; + int block = co->iblocks[ip()]; while(block >= 0){ if(co->blocks[block].type == CodeBlockType::TRY_EXCEPT) break; block = co->blocks[block].parent; @@ -47,7 +47,7 @@ namespace pkpy{ } void Frame::prepare_jump_break(ValueStack* _s, int target){ - int i = co->iblocks[_ip]; + int i = co->iblocks[ip()]; if(target >= co->codes.size()){ while(i>=0) i = _exit_block(_s, i); }else{ diff --git a/src/profiler.cpp b/src/profiler.cpp index 728d6f0f..75dd1021 100644 --- a/src/profiler.cpp +++ b/src/profiler.cpp @@ -19,7 +19,7 @@ void LineProfiler::begin(){ } void LineProfiler::_step(int callstack_size, Frame* frame){ - auto line_info = frame->co->lines[frame->_ip]; + auto line_info = frame->co->lines[frame->ip()]; if(line_info.is_virtual) return; std::string_view filename = frame->co->src->filename.sv(); int line = line_info.lineno; diff --git a/src/vm.cpp b/src/vm.cpp index d67eab91..d8f51a26 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -224,6 +224,7 @@ namespace pkpy{ } bool VM::py_eq(PyVar lhs, PyVar rhs){ + if(is_int(lhs) && is_int(rhs)) return lhs.as() == rhs.as(); const PyTypeInfo* ti = _tp_info(lhs); PyVar res; if(ti->m__eq__){ @@ -1394,12 +1395,12 @@ void VM::__raise_exc(bool re_raise){ Frame* frame = &callstack.top(); Exception& e = PK_OBJ_GET(Exception, s_data.top()); if(!re_raise){ - e._ip_on_error = frame->_ip; + e._ip_on_error = frame->ip(); e._code_on_error = (void*)frame->co; } int next_ip = frame->prepare_jump_exception_handler(&s_data); - int actual_ip = frame->_ip; + int actual_ip = frame->ip(); 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].lineno; // current line auto current_f_name = frame->co->name.sv(); // current function name