From adc2f2cc3ff2cd3556be31458c87b00f2e52b804 Mon Sep 17 00:00:00 2001 From: BLUELOVETH Date: Sun, 16 Apr 2023 17:23:49 +0000 Subject: [PATCH] ... --- src/ceval.h | 31 ++++++++----- src/common.h | 8 ++-- src/frame.h | 121 ++++++++++++++++++++++----------------------------- src/iter.h | 2 +- src/vm.h | 9 ++-- 5 files changed, 80 insertions(+), 91 deletions(-) diff --git a/src/ceval.h b/src/ceval.h index 57b792e8..2f09176a 100644 --- a/src/ceval.h +++ b/src/ceval.h @@ -28,14 +28,14 @@ inline PyObject* VM::_run_top_frame(){ /* Stack manipulation macros */ // https://github.com/python/cpython/blob/3.9/Python/ceval.c#L1123 -#define TOP() (frame->_s.top()) -#define SECOND() (frame->_s.second()) -#define PEEK(n) (frame->_s.peek(n)) -#define STACK_SHRINK(n) (frame->_s.shrink(n)) -#define PUSH(v) (frame->_s.push(v)) -#define POP() (frame->_s.pop()) -#define POPX() (frame->_s.popx()) -#define STACK_VIEW(n) (frame->_s.view(n)) +#define TOP() (s_data.top()) +#define SECOND() (s_data.second()) +#define PEEK(n) (s_data.peek(n)) +#define STACK_SHRINK(n) (s_data.shrink(n)) +#define PUSH(v) (s_data.push(v)) +#define POP() (s_data.pop()) +#define POPX() (s_data.popx()) +#define STACK_VIEW(n) (s_data.view(n)) #define DISPATCH_OP_CALL() { frame = top_frame(); goto __NEXT_FRAME; } __NEXT_FRAME: @@ -392,6 +392,8 @@ __NEXT_STEP:; if(byte.op==OP_CALL && is_type(callable, tp_function)){ PyObject* ret = _py_call(callable, STACK_VIEW(ARGC + int(method_call)), {}); STACK_SHRINK(ARGC + 2); + // TODO: _sp_base is incorrect + top_frame()->_sp_base = s_data._sp; if(ret == nullptr) { DISPATCH_OP_CALL(); } else PUSH(ret); // a generator DISPATCH(); @@ -424,18 +426,23 @@ __NEXT_STEP:; PUSH(ret); } DISPATCH(); TARGET(RETURN_VALUE) { - PyObject* __ret = POPX(); +#if DEBUG_EXTRA_CHECK + if(frame->stack_size() != 1) FATAL_ERROR(); +#endif if(frame.index == base_id){ // [ frameBase<- ] callstack.pop(); - return __ret; + return POPX(); }else{ callstack.pop(); frame = top_frame(); - PUSH(__ret); goto __NEXT_FRAME; } } - TARGET(YIELD_VALUE) return _py_op_yield; + TARGET(YIELD_VALUE) +#if DEBUG_EXTRA_CHECK + if(frame->stack_size() != 1) FATAL_ERROR(); +#endif + return _py_op_yield; /*****************************************/ TARGET(LIST_APPEND) { PyObject* obj = POPX(); diff --git a/src/common.h b/src/common.h index 2b575ff7..488e00b7 100644 --- a/src/common.h +++ b/src/common.h @@ -33,9 +33,9 @@ // debug macros #define DEBUG_NO_BUILTIN_MODULES 0 -#define DEBUG_EXTRA_CHECK 0 -#define DEBUG_DIS_EXEC 0 -#define DEBUG_CEVAL_STEP 0 +#define DEBUG_EXTRA_CHECK 1 +#define DEBUG_DIS_EXEC 1 +#define DEBUG_CEVAL_STEP 1 #define DEBUG_CEVAL_STEP_MIN 0 #define DEBUG_FULL_EXCEPTION 0 #define DEBUG_MEMORY_POOL 0 @@ -53,7 +53,7 @@ #define PK_ENABLE_COMPUTED_GOTO 0 #define UNREACHABLE() __assume(0) #else -#define PK_ENABLE_COMPUTED_GOTO 1 +#define PK_ENABLE_COMPUTED_GOTO 0 #define UNREACHABLE() __builtin_unreachable() #endif diff --git a/src/frame.h b/src/frame.h index 2236c441..79e36b7c 100644 --- a/src/frame.h +++ b/src/frame.h @@ -3,6 +3,7 @@ #include "codeobject.h" #include "common.h" #include "memory.h" +#include "obj.h" #include "vector.h" namespace pkpy{ @@ -124,80 +125,59 @@ template<> inline void gc_mark(Function& t){ t._closure._gc_mark(); } -struct ValueStack: pod_vector { - PyObject*& top(){ return back(); } - PyObject* top() const { return back(); } - PyObject*& second(){ return (*this)[size()-2]; } - PyObject* second() const { return (*this)[size()-2]; } - PyObject*& peek(int n){ return (*this)[size()-n]; } - PyObject* peek(int n) const { return (*this)[size()-n]; } - void push(PyObject* v){ push_back(v); } - void pop(){ pop_back(); } - PyObject* popx(){ return popx_back(); } - ArgsView view(int n){ return ArgsView(end()-n, end()); } - void shrink(int n){ resize(size() - n); } +struct ValueStack { + static const int MAX_SIZE = 32768; + PyObject* _begin[MAX_SIZE]; + PyObject** _sp; + + ValueStack(): _sp(_begin) {} + + PyObject*& top(){ return _sp[-1]; } + PyObject* top() const { return _sp[-1]; } + PyObject*& second(){ return _sp[-2]; } + PyObject* second() const { return _sp[-2]; } + PyObject*& peek(int n){ return _sp[-n]; } + PyObject* peek(int n) const { return _sp[-n]; } + void push(PyObject* v){ *_sp++ = v; } + void pop(){ --_sp; } + PyObject* popx(){ return *--_sp; } + ArgsView view(int n){ return ArgsView(_sp-n, _sp); } + void shrink(int n){ _sp -= n; } + // int size() const { return _sp - _begin; } + // bool empty() const { return _sp == _begin; } + PyObject** begin() { return _begin; } + PyObject** end() { return _sp; } + void reset(PyObject** sp) { _sp = sp; } + // void resize(int n) { _sp = _begin + n; } + bool is_overflow() const { return _sp >= _begin + MAX_SIZE; } + + ValueStack(const ValueStack&) = delete; + ValueStack(ValueStack&&) = delete; + ValueStack& operator=(const ValueStack&) = delete; + ValueStack& operator=(ValueStack&&) = delete; }; -// struct ValueStack { -// PyObject** _begin; -// PyObject** _sp; - -// ValueStack(int n=16): _begin((PyObject**)pool128.alloc(n * sizeof(void*))), _sp(_begin) { } - -// PyObject*& top(){ return _sp[-1]; } -// PyObject* top() const { return _sp[-1]; } -// PyObject*& second(){ return _sp[-2]; } -// PyObject* second() const { return _sp[-2]; } -// PyObject*& peek(int n){ return _sp[-n]; } -// PyObject* peek(int n) const { return _sp[-n]; } -// void push(PyObject* v){ *_sp++ = v; } -// void pop(){ --_sp; } -// PyObject* popx(){ return *--_sp; } -// ArgsView view(int n){ return ArgsView(_sp-n, _sp); } -// void shrink(int n){ _sp -= n; } -// int size() const { return _sp - _begin; } -// bool empty() const { return _sp == _begin; } -// PyObject** begin() const { return _begin; } -// PyObject** end() const { return _sp; } -// void resize(int n) { _sp = _begin + n; } - -// ValueStack(ValueStack&& other) noexcept{ -// _begin = other._begin; -// _sp = other._sp; -// other._begin = nullptr; -// } - -// ValueStack& operator=(ValueStack&& other) noexcept{ -// if(_begin != nullptr) pool128.dealloc(_begin); -// _begin = other._begin; -// _sp = other._sp; -// other._begin = nullptr; -// return *this; -// } - -// ~ValueStack(){ if(_begin!=nullptr) pool128.dealloc(_begin); } -// }; - struct Frame { int _ip = -1; int _next_ip = 0; + ValueStack* _s; + PyObject** _sp_base; const CodeObject* co; - PyObject* _module; + PyObject* _module; FastLocals _locals; FastLocals _closure; - ValueStack _s; NameDict& f_globals() noexcept { return _module->attr(); } - Frame(const CodeObject* co, PyObject* _module, FastLocals&& _locals, const FastLocals& _closure) - : co(co), _module(_module), _locals(std::move(_locals)), _closure(_closure) { } + Frame(ValueStack* _s, const CodeObject* co, PyObject* _module, FastLocals&& _locals, const FastLocals& _closure) + : _s(_s), _sp_base(_s->_sp), co(co), _module(_module), _locals(std::move(_locals)), _closure(_closure) { } - Frame(const CodeObject* co, PyObject* _module, const FastLocals& _locals, const FastLocals& _closure) - : co(co), _module(_module), _locals(_locals), _closure(_closure) { } + Frame(ValueStack* _s, const CodeObject* co, PyObject* _module, const FastLocals& _locals, const FastLocals& _closure) + : _s(_s), _sp_base(_s->_sp), co(co), _module(_module), _locals(_locals), _closure(_closure) { } - Frame(const CodeObject_& co, PyObject* _module) - : co(co.get()), _module(_module), _locals(), _closure() { } + Frame(ValueStack* _s, const CodeObject_& co, PyObject* _module) + : _s(_s), _sp_base(_s->_sp), co(co.get()), _module(_module), _locals(), _closure() { } Frame(const Frame& other) = delete; Frame& operator=(const Frame& other) = delete; @@ -214,12 +194,14 @@ struct Frame { return co->src->snapshot(line); } + int stack_size() const { return _s->_sp - _sp_base; } + std::string stack_info(){ std::stringstream ss; ss << this << ": ["; - for(PyObject** t=_s.begin(); t<_s.end(); t++){ + for(PyObject** t=_sp_base; t<_s->end(); t++){ ss << *t; - if(t != _s.end()-1) ss << ", "; + if(t != _s->end()-1) ss << ", "; } ss << "]"; return ss.str(); @@ -236,18 +218,18 @@ struct Frame { block = co->blocks[block].parent; } if(block < 0) return false; - PyObject* obj = _s.popx(); // pop exception object + PyObject* obj = _s->popx(); // pop exception object // get the stack size of the try block (depth of for loops) - int stack_size = co->blocks[block].for_loop_depth; - if(_s.size() < stack_size) throw std::runtime_error("invalid stack size"); - _s.resize(stack_size); // rollback the stack - _s.push(obj); // push exception object + int _stack_size = co->blocks[block].for_loop_depth; + if(stack_size() < _stack_size) throw std::runtime_error("invalid stack size"); + _s->reset(_sp_base + _stack_size); // rollback the stack + _s->push(obj); // push exception object _next_ip = co->blocks[block].end; return true; } int _exit_block(int i){ - if(co->blocks[i].type == FOR_LOOP) _s.pop(); + if(co->blocks[i].type == FOR_LOOP) _s->pop(); return co->blocks[i].parent; } @@ -266,8 +248,7 @@ struct Frame { void _gc_mark() const { // do return if this frame has been moved - if(_s.data() == nullptr) return; - for(PyObject* obj: _s) OBJ_MARK(obj); + // TODO: fix here OBJ_MARK(_module); _locals._gc_mark(); _closure._gc_mark(); diff --git a/src/iter.h b/src/iter.h index 2e208db5..4ba31cad 100644 --- a/src/iter.h +++ b/src/iter.h @@ -69,7 +69,7 @@ inline PyObject* Generator::next(){ frame = std::move(vm->callstack.top()); vm->callstack.pop(); state = 1; - return frame._s.popx(); + return frame._s->popx(); }else{ state = 2; return nullptr; diff --git a/src/vm.h b/src/vm.h index d51040a0..097830cb 100644 --- a/src/vm.h +++ b/src/vm.h @@ -61,6 +61,7 @@ class VM { VM* vm; // self reference for simplify code public: ManagedHeap heap; + ValueStack s_data; stack< Frame > callstack; std::vector _all_types; @@ -192,7 +193,7 @@ public: if(callstack.size() > recursionlimit){ _error("RecursionError", "maximum recursion depth exceeded"); } - callstack.emplace(std::forward(args)...); + callstack.emplace(&s_data, std::forward(args)...); } void _push_new_frame(Frame&& frame){ @@ -731,7 +732,7 @@ inline PyObject* VM::_py_call(PyObject* callable, ArgsView args, ArgsView kwargs } PyObject* _module = fn._module != nullptr ? fn._module : top_frame()->_module; if(co->is_generator){ - return PyIter(Generator(this, Frame(co, _module, std::move(locals), fn._closure))); + return PyIter(Generator(this, Frame(&s_data, co, _module, std::move(locals), fn._closure))); } _push_new_frame(co, _module, std::move(locals), fn._closure); return nullptr; @@ -913,14 +914,14 @@ inline void VM::_error(Exception e){ e.is_re = false; throw e; } - Frame* frame = &callstack.top(); - frame->_s.push(VAR(e)); + s_data.push(VAR(e)); _raise(); } inline void ManagedHeap::mark() { for(PyObject* obj: _no_gc) OBJ_MARK(obj); for(auto& frame : vm->callstack.data()) frame._gc_mark(); + for(PyObject* obj: vm->s_data) OBJ_MARK(obj); } inline Str obj_type_name(VM *vm, Type type){