mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-22 04:20:17 +00:00
refactor frameobject
This commit is contained in:
parent
51170e4a47
commit
57b4595c11
@ -84,6 +84,8 @@ struct UnwindTarget{
|
||||
};
|
||||
|
||||
struct Frame {
|
||||
PK_ALWAYS_PASS_BY_POINTER(Frame)
|
||||
|
||||
const Bytecode* _ip;
|
||||
// This is for unwinding only, use `actual_sp_base()` for value stack access
|
||||
PyVar* _sp_base;
|
||||
@ -129,9 +131,9 @@ struct Frame {
|
||||
|
||||
void set_unwind_target(PyVar* _sp);
|
||||
UnwindTarget* find_unwind_target(int iblock);
|
||||
void free_unwind_target();
|
||||
|
||||
void _gc_mark(VM* vm) const;
|
||||
~Frame();
|
||||
};
|
||||
|
||||
struct LinkedFrame{
|
||||
@ -141,8 +143,9 @@ struct LinkedFrame{
|
||||
LinkedFrame(LinkedFrame* f_back, Args&&... args) : f_back(f_back), frame(std::forward<Args>(args)...) {}
|
||||
};
|
||||
|
||||
|
||||
struct CallStack{
|
||||
static_assert(sizeof(LinkedFrame) <= 128 && std::is_trivially_destructible_v<LinkedFrame>);
|
||||
static_assert(sizeof(LinkedFrame) <= 128);
|
||||
|
||||
LinkedFrame* _tail;
|
||||
int _size;
|
||||
@ -162,10 +165,26 @@ struct CallStack{
|
||||
PK_DEBUG_ASSERT(!empty())
|
||||
LinkedFrame* p = _tail;
|
||||
_tail = p->f_back;
|
||||
p->~LinkedFrame();
|
||||
pool128_dealloc(p);
|
||||
--_size;
|
||||
}
|
||||
|
||||
LinkedFrame* popx(){
|
||||
PK_DEBUG_ASSERT(!empty())
|
||||
LinkedFrame* p = _tail;
|
||||
_tail = p->f_back;
|
||||
--_size;
|
||||
p->f_back = nullptr; // unlink
|
||||
return p;
|
||||
}
|
||||
|
||||
void pushx(LinkedFrame* p){
|
||||
p->f_back = _tail;
|
||||
_tail = p;
|
||||
++_size;
|
||||
}
|
||||
|
||||
Frame& top() const {
|
||||
PK_DEBUG_ASSERT(!empty())
|
||||
return _tail->frame;
|
||||
@ -175,6 +194,8 @@ struct CallStack{
|
||||
void apply(Func&& f){
|
||||
for(LinkedFrame* p = _tail; p != nullptr; p = p->f_back) f(p->frame);
|
||||
}
|
||||
|
||||
~CallStack(){ clear(); }
|
||||
};
|
||||
|
||||
}; // namespace pkpy
|
@ -43,21 +43,29 @@ struct StringIter{
|
||||
};
|
||||
|
||||
struct Generator{
|
||||
Frame frame;
|
||||
LinkedFrame* lf;
|
||||
int state; // 0,1,2
|
||||
List s_backup;
|
||||
|
||||
Generator(Frame&& frame, ArgsView buffer): frame(std::move(frame)), state(0) {
|
||||
Generator(LinkedFrame* lf, ArgsView buffer): lf(lf), state(0) {
|
||||
for(PyVar obj: buffer) s_backup.push_back(obj);
|
||||
}
|
||||
|
||||
void _gc_mark(VM* vm) {
|
||||
frame._gc_mark(vm);
|
||||
if(lf == nullptr) return;
|
||||
lf->frame._gc_mark(vm);
|
||||
vm->__stack_gc_mark(s_backup.begin(), s_backup.end());
|
||||
}
|
||||
|
||||
PyVar next(VM* vm);
|
||||
static void _register(VM* vm, PyVar mod, PyVar type);
|
||||
|
||||
~Generator(){
|
||||
if(lf){
|
||||
lf->~LinkedFrame();
|
||||
pool128_dealloc(lf);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct DictItemsIter{
|
||||
|
@ -479,7 +479,7 @@ public:
|
||||
PyVar __format_object(PyVar, Str);
|
||||
PyVar __run_top_frame();
|
||||
void __pop_frame();
|
||||
PyVar __py_generator(Frame&& frame, ArgsView buffer);
|
||||
PyVar __py_generator(LinkedFrame* frame, ArgsView buffer);
|
||||
void __op_unpack_sequence(uint16_t arg);
|
||||
void __prepare_py_call(PyVar*, ArgsView, ArgsView, const FuncDecl_&);
|
||||
void __unpack_as_list(ArgsView args, List& list);
|
||||
|
@ -91,7 +91,7 @@ namespace pkpy{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Frame::free_unwind_target(){
|
||||
Frame::~Frame(){
|
||||
while(_uw_list != nullptr){
|
||||
UnwindTarget* p = _uw_list;
|
||||
_uw_list = p->next;
|
||||
|
23
src/iter.cpp
23
src/iter.cpp
@ -51,12 +51,12 @@ namespace pkpy{
|
||||
PyVar Generator::next(VM* vm){
|
||||
if(state == 2) return vm->StopIteration;
|
||||
// reset frame._sp_base
|
||||
frame._sp_base = vm->s_data._sp;
|
||||
frame._locals.a = vm->s_data._sp;
|
||||
lf->frame._sp_base = vm->s_data._sp;
|
||||
lf->frame._locals.a = vm->s_data._sp;
|
||||
// restore the context
|
||||
for(PyVar obj: s_backup) vm->s_data.push(obj);
|
||||
// relocate stack objects (their addresses become invalid)
|
||||
for(PyVar* p=frame.actual_sp_base(); p!=vm->s_data.end(); p++){
|
||||
for(PyVar* p=lf->frame.actual_sp_base(); p!=vm->s_data.end(); p++){
|
||||
if(p->type == VM::tp_stack_memory){
|
||||
// TODO: refactor this
|
||||
int count = p->as<StackMemory>().count;
|
||||
@ -67,7 +67,8 @@ namespace pkpy{
|
||||
}
|
||||
}
|
||||
s_backup.clear();
|
||||
vm->callstack.emplace(std::move(frame));
|
||||
vm->callstack.pushx(lf);
|
||||
lf = nullptr;
|
||||
|
||||
PyVar ret;
|
||||
try{
|
||||
@ -79,10 +80,16 @@ namespace pkpy{
|
||||
|
||||
if(ret == PY_OP_YIELD){
|
||||
// backup the context
|
||||
frame = std::move(vm->callstack.top());
|
||||
lf = vm->callstack.popx();
|
||||
ret = vm->s_data.popx();
|
||||
for(PyVar obj: frame.stack_view(&vm->s_data)) s_backup.push_back(obj);
|
||||
vm->__pop_frame();
|
||||
for(PyVar obj: lf->frame.stack_view(&vm->s_data)) s_backup.push_back(obj);
|
||||
vm->s_data.reset(lf->frame._sp_base);
|
||||
// TODO: should we add this snippet here?
|
||||
// #if PK_ENABLE_PROFILER
|
||||
// if(!_next_breakpoint.empty() && callstack.size()<_next_breakpoint.callstack_size){
|
||||
// _next_breakpoint = NextBreakpoint();
|
||||
// }
|
||||
// #endif
|
||||
state = 1;
|
||||
if(ret == vm->StopIteration) state = 2;
|
||||
return ret;
|
||||
@ -116,7 +123,7 @@ namespace pkpy{
|
||||
});
|
||||
}
|
||||
|
||||
PyVar VM::__py_generator(Frame&& frame, ArgsView buffer){
|
||||
PyVar VM::__py_generator(LinkedFrame* frame, ArgsView buffer){
|
||||
return vm->new_user_object<Generator>(std::move(frame), buffer);
|
||||
}
|
||||
|
||||
|
@ -1093,8 +1093,9 @@ PyVar VM::vectorcall(int ARGC, int KWARGC, bool op_call){
|
||||
case FuncType::GENERATOR:
|
||||
__prepare_py_call(__vectorcall_buffer, args, kwargs, fn.decl);
|
||||
s_data.reset(p0);
|
||||
callstack.emplace(nullptr, co, fn._module, callable, nullptr);
|
||||
return __py_generator(
|
||||
Frame(nullptr, co, fn._module, callable, nullptr),
|
||||
callstack.popx(),
|
||||
ArgsView(__vectorcall_buffer, __vectorcall_buffer + co->nlocals)
|
||||
);
|
||||
#if PK_DEBUG_EXTRA_CHECK
|
||||
@ -1644,9 +1645,7 @@ void NextBreakpoint::_step(VM* vm){
|
||||
#endif
|
||||
|
||||
void VM::__pop_frame(){
|
||||
Frame& frame = callstack.top();
|
||||
s_data.reset(frame._sp_base);
|
||||
frame.free_unwind_target();
|
||||
s_data.reset(callstack.top()._sp_base);
|
||||
callstack.pop();
|
||||
|
||||
#if PK_ENABLE_PROFILER
|
||||
|
Loading…
x
Reference in New Issue
Block a user