diff --git a/include/pocketpy/frame.h b/include/pocketpy/frame.h index d56c82d5..90549026 100644 --- a/include/pocketpy/frame.h +++ b/include/pocketpy/frame.h @@ -79,7 +79,6 @@ using ValueStack = ValueStackImpl; struct Frame { int _ip; int _next_ip; - ValueStack* _s; // This is for unwinding only, use `actual_sp_base()` for value stack access PyObject** _sp_base; @@ -91,14 +90,14 @@ struct Frame { NameDict& f_globals() noexcept { return _module->attr(); } PyObject* f_closure_try_get(StrName name); - Frame(ValueStack* _s, PyObject** p0, const CodeObject* co, PyObject* _module, PyObject* _callable) - : _ip(-1), _next_ip(0), _s(_s), _sp_base(p0), co(co), _module(_module), _callable(_callable), _locals(co, p0) { } + Frame(PyObject** p0, const CodeObject* co, PyObject* _module, PyObject* _callable) + : _ip(-1), _next_ip(0), _sp_base(p0), co(co), _module(_module), _callable(_callable), _locals(co, p0) { } - Frame(ValueStack* _s, PyObject** p0, const CodeObject* co, PyObject* _module, PyObject* _callable, FastLocals _locals) - : _ip(-1), _next_ip(0), _s(_s), _sp_base(p0), co(co), _module(_module), _callable(_callable), _locals(_locals) { } + Frame(PyObject** p0, const CodeObject* co, PyObject* _module, PyObject* _callable, FastLocals _locals) + : _ip(-1), _next_ip(0), _sp_base(p0), co(co), _module(_module), _callable(_callable), _locals(_locals) { } - Frame(ValueStack* _s, PyObject** p0, const CodeObject_& co, PyObject* _module) - : _ip(-1), _next_ip(0), _s(_s), _sp_base(p0), co(co.get()), _module(_module), _callable(nullptr), _locals(co.get(), p0) {} + Frame(PyObject** p0, const CodeObject_& co, PyObject* _module) + : _ip(-1), _next_ip(0), _sp_base(p0), co(co.get()), _module(_module), _callable(nullptr), _locals(co.get(), p0) {} int next_bytecode() { _ip = _next_ip++; @@ -109,13 +108,14 @@ struct Frame { } PyObject** actual_sp_base() const { return _locals.a; } - int stack_size() const { return _s->_sp - actual_sp_base(); } - ArgsView stack_view() const { return ArgsView(actual_sp_base(), _s->_sp); } + + int stack_size(ValueStack* _s) const { return _s->_sp - actual_sp_base(); } + ArgsView stack_view(ValueStack* _s) const { return ArgsView(actual_sp_base(), _s->_sp); } void jump_abs(int i){ _next_ip = i; } - bool jump_to_exception_handler(); - int _exit_block(int i); - void jump_abs_break(int target); + bool jump_to_exception_handler(ValueStack*); + int _exit_block(ValueStack*, int); + void jump_abs_break(ValueStack*, int); void _gc_mark() const { PK_OBJ_MARK(_module); diff --git a/include/pocketpy/vm.h b/include/pocketpy/vm.h index 2741718c..2c1e413a 100644 --- a/include/pocketpy/vm.h +++ b/include/pocketpy/vm.h @@ -172,7 +172,7 @@ public: template PyObject* _exec(Args&&... args){ - callstack.emplace(&s_data, s_data._sp, std::forward(args)...); + callstack.emplace(s_data._sp, std::forward(args)...); return _run_top_frame(); } diff --git a/src/ceval.cpp b/src/ceval.cpp index ac5cda1a..d331ee91 100644 --- a/src/ceval.cpp +++ b/src/ceval.cpp @@ -529,13 +529,13 @@ __NEXT_STEP:; frame->jump_abs(byte.arg); DISPATCH(); TARGET(LOOP_BREAK) - frame->jump_abs_break(byte.arg); + frame->jump_abs_break(&s_data, byte.arg); DISPATCH(); TARGET(GOTO) { StrName _name(byte.arg); int index = co->labels.try_get_likely_found(_name); if(index < 0) RuntimeError(_S("label ", _name.escape(), " not found")); - frame->jump_abs_break(index); + frame->jump_abs_break(&s_data, index); } DISPATCH(); /*****************************************/ TARGET(FSTRING_EVAL){ @@ -651,7 +651,7 @@ __NEXT_STEP:; if(_0 != StopIteration){ PUSH(_0); }else{ - frame->jump_abs_break(byte.arg); + frame->jump_abs_break(&s_data, byte.arg); } } DISPATCH(); /*****************************************/ diff --git a/src/frame.cpp b/src/frame.cpp index b5030ccb..38b8c02f 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -23,7 +23,7 @@ namespace pkpy{ return fn._closure->try_get(name); } - bool Frame::jump_to_exception_handler(){ + bool Frame::jump_to_exception_handler(ValueStack* _s){ // try to find a parent try block int block = co->iblocks[_ip]; while(block >= 0){ @@ -34,24 +34,24 @@ namespace pkpy{ PyObject* obj = _s->popx(); // pop exception object // get the stack size of the try block int _stack_size = co->blocks[block].base_stack_size; - if(stack_size() < _stack_size) throw std::runtime_error(_S("invalid state: ", stack_size(), '<', _stack_size).str()); + if(stack_size(_s) < _stack_size) throw std::runtime_error(_S("invalid state: ", stack_size(_s), '<', _stack_size).str()); _s->reset(actual_sp_base() + _locals.size() + _stack_size); // rollback the stack _s->push(obj); // push exception object _next_ip = co->blocks[block].end; return true; } - int Frame::_exit_block(int i){ + int Frame::_exit_block(ValueStack* _s, int i){ auto type = co->blocks[i].type; if(type==CodeBlockType::FOR_LOOP || type==CodeBlockType::CONTEXT_MANAGER) _s->pop(); return co->blocks[i].parent; } - void Frame::jump_abs_break(int target){ + void Frame::jump_abs_break(ValueStack* _s, int target){ int i = co->iblocks[_ip]; _next_ip = target; if(_next_ip >= co->codes.size()){ - while(i>=0) i = _exit_block(i); + while(i>=0) i = _exit_block(_s, i); }else{ // BUG (solved) // for i in range(4): @@ -59,7 +59,7 @@ namespace pkpy{ // # if there is no op here, the block check will fail // while i: --i int next_block = co->iblocks[target]; - while(i>=0 && i!=next_block) i = _exit_block(i); + while(i>=0 && i!=next_block) i = _exit_block(_s, i); if(i!=next_block) throw std::runtime_error("invalid jump"); } } diff --git a/src/iter.cpp b/src/iter.cpp index eabc4790..0cd6908e 100644 --- a/src/iter.cpp +++ b/src/iter.cpp @@ -43,10 +43,10 @@ namespace pkpy{ PyObject* Generator::next(VM* vm){ if(state == 2) return vm->StopIteration; // reset frame._sp_base - frame._sp_base = frame._s->_sp; - frame._locals.a = frame._s->_sp; + frame._sp_base = vm->s_data._sp; + frame._locals.a = vm->s_data._sp; // restore the context - for(PyObject* obj: s_backup) frame._s->push(obj); + for(PyObject* obj: s_backup) vm->s_data.push(obj); s_backup.clear(); vm->callstack.push(std::move(frame)); @@ -61,8 +61,8 @@ namespace pkpy{ if(ret == PY_OP_YIELD){ // backup the context frame = std::move(vm->callstack.top()); - ret = frame._s->popx(); - for(PyObject* obj: frame.stack_view()) s_backup.push_back(obj); + ret = vm->s_data.popx(); + for(PyObject* obj: frame.stack_view(&vm->s_data)) s_backup.push_back(obj); vm->_pop_frame(); state = 1; if(ret == vm->StopIteration) state = 2; diff --git a/src/vm.cpp b/src/vm.cpp index 6ab0b71b..e4f38144 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -931,7 +931,7 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){ if(co->is_generator){ s_data.reset(p0); return _py_generator( - Frame(&s_data, nullptr, co, fn._module, callable), + Frame(nullptr, co, fn._module, callable), ArgsView(buffer, buffer + co_nlocals) ); } @@ -941,7 +941,7 @@ PyObject* VM::vectorcall(int ARGC, int KWARGC, bool op_call){ for(int j=0; j_ip; e._code_on_error = (void*)frame->co; } - bool ok = frame->jump_to_exception_handler(); + bool ok = frame->jump_to_exception_handler(&s_data); int actual_ip = frame->_ip; if(e._ip_on_error >= 0 && e._code_on_error == (void*)frame->co) actual_ip = e._ip_on_error;