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