mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
...
This commit is contained in:
parent
8aa6893e29
commit
adc2f2cc3f
31
src/ceval.h
31
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();
|
||||
|
@ -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
|
||||
|
||||
|
121
src/frame.h
121
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();
|
||||
|
@ -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;
|
||||
|
9
src/vm.h
9
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){
|
||||
|
Loading…
x
Reference in New Issue
Block a user