BLUELOVETH 2 лет назад
Родитель
Сommit
adc2f2cc3f
5 измененных файлов с 80 добавлено и 91 удалено
  1. 19 12
      src/ceval.h
  2. 4 4
      src/common.h
  3. 51 70
      src/frame.h
  4. 1 1
      src/iter.h
  5. 5 4
      src/vm.h

+ 19 - 12
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();

+ 4 - 4
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
 

+ 51 - 70
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>(Function& t){
     t._closure._gc_mark();
 }
 
-struct ValueStack: pod_vector<PyObject*> {
-    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();

+ 1 - 1
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;

+ 5 - 4
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<PyTypeInfo> _all_types;
 
@@ -192,7 +193,7 @@ public:
         if(callstack.size() > recursionlimit){
             _error("RecursionError", "maximum recursion depth exceeded");
         }
-        callstack.emplace(std::forward<Args>(args)...);
+        callstack.emplace(&s_data, std::forward<Args>(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){