This commit is contained in:
BLUELOVETH 2023-04-16 17:23:49 +00:00
parent 8aa6893e29
commit adc2f2cc3f
5 changed files with 80 additions and 91 deletions

View File

@ -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();

View File

@ -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

View File

@ -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;
// struct ValueStack {
// PyObject** _begin;
// PyObject** _sp;
ValueStack(): _sp(_begin) {}
// 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; }
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; }
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(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); }
// };
ValueStack(const ValueStack&) = delete;
ValueStack(ValueStack&&) = delete;
ValueStack& operator=(const ValueStack&) = delete;
ValueStack& operator=(ValueStack&&) = delete;
};
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();

View File

@ -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;

View File

@ -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){