This commit is contained in:
BLUELOVETH 2023-04-18 07:10:24 +00:00
parent e49e204c28
commit ab3605a661
3 changed files with 22 additions and 8 deletions

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "ceval.h" #include "ceval.h"
#include "frame.h"
namespace pkpy{ namespace pkpy{
@ -68,6 +69,7 @@ inline PyObject* Generator::next(){
if(state == 2) return nullptr; if(state == 2) return nullptr;
// reset frame._sp_base // reset frame._sp_base
frame._sp_base = frame._s->_sp; frame._sp_base = frame._s->_sp;
frame._locals.a = frame._s->_sp;
// restore the context // restore the context
for(PyObject* obj: s_backup) frame._s->push(obj); for(PyObject* obj: s_backup) frame._s->push(obj);
s_backup.clear(); s_backup.clear();

View File

@ -99,13 +99,13 @@ inline void init_builtins(VM* _vm) {
_vm->bind_builtin_func<1>("eval", [](VM* vm, ArgsView args) { _vm->bind_builtin_func<1>("eval", [](VM* vm, ArgsView args) {
CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<eval>", EVAL_MODE, true); CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<eval>", EVAL_MODE, true);
FrameId frame = vm->top_frame(); FrameId frame = vm->top_frame();
return vm->_exec(code.get(), frame->_module, nullptr, frame->_locals); return vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
}); });
_vm->bind_builtin_func<1>("exec", [](VM* vm, ArgsView args) { _vm->bind_builtin_func<1>("exec", [](VM* vm, ArgsView args) {
CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<exec>", EXEC_MODE, true); CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<exec>", EXEC_MODE, true);
FrameId frame = vm->top_frame(); FrameId frame = vm->top_frame();
vm->_exec(code.get(), frame->_module, nullptr, frame->_locals); vm->_exec(code.get(), frame->_module, frame->_callable, frame->_locals);
return vm->None; return vm->None;
}); });

View File

@ -51,7 +51,9 @@ class Generator final: public BaseIter {
int state; // 0,1,2 int state; // 0,1,2
List s_backup; List s_backup;
public: public:
Generator(VM* vm, Frame&& frame): BaseIter(vm), frame(std::move(frame)), state(0) {} Generator(VM* vm, Frame&& frame, ArgsView buffer): BaseIter(vm), frame(std::move(frame)), state(0) {
for(PyObject* obj: buffer) s_backup.push_back(obj);
}
PyObject* next() override; PyObject* next() override;
void _gc_mark() const override; void _gc_mark() const override;
@ -97,6 +99,8 @@ public:
std::ostream* _stdout; std::ostream* _stdout;
std::ostream* _stderr; std::ostream* _stderr;
bool _initialized;
// for quick access // for quick access
Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str; Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str;
Type tp_list, tp_tuple; Type tp_list, tp_tuple;
@ -109,7 +113,9 @@ public:
this->_stdout = use_stdio ? &std::cout : &_stdout_buffer; this->_stdout = use_stdio ? &std::cout : &_stdout_buffer;
this->_stderr = use_stdio ? &std::cerr : &_stderr_buffer; this->_stderr = use_stdio ? &std::cerr : &_stderr_buffer;
callstack.reserve(8); callstack.reserve(8);
_initialized = false;
init_builtin_types(); init_builtin_types();
_initialized = true;
} }
bool is_stdio_used() const { return _stdout == &std::cout; } bool is_stdio_used() const { return _stdout == &std::cout; }
@ -660,6 +666,7 @@ inline Str VM::disassemble(CodeObject_ co){
} }
inline void VM::_log_s_data(const char* title) { inline void VM::_log_s_data(const char* title) {
if(!_initialized) return;
if(callstack.empty()) return; if(callstack.empty()) return;
std::stringstream ss; std::stringstream ss;
if(title) ss << title << " | "; if(title) ss << title << " | ";
@ -913,13 +920,17 @@ inline PyObject* VM::_py_call(PyObject** p0, PyObject* callable, ArgsView args,
PyObject* _module = fn._module != nullptr ? fn._module : top_frame()->_module; PyObject* _module = fn._module != nullptr ? fn._module : top_frame()->_module;
s_data.reset(p0); s_data.reset(p0);
// copy buffer to stack
for(int i=0; i<co->varnames.size(); i++) PUSH(buffer[i]);
if(co->is_generator){ if(co->is_generator){
PyObject* ret = PyIter(Generator(this, Frame(&s_data, p0, co, _module, callable))); PyObject* ret = PyIter(Generator(
this,
Frame(&s_data, nullptr, co, _module, callable),
ArgsView(buffer, buffer + co->varnames.size())
));
return ret; return ret;
} }
// copy buffer to stack
for(int i=0; i<co->varnames.size(); i++) PUSH(buffer[i]);
callstack.emplace(&s_data, p0, co, _module, callable); callstack.emplace(&s_data, p0, co, _module, callable);
return nullptr; return nullptr;
} }
@ -1041,7 +1052,8 @@ inline void VM::_error(Exception e){
inline void ManagedHeap::mark() { inline void ManagedHeap::mark() {
for(PyObject* obj: _no_gc) OBJ_MARK(obj); for(PyObject* obj: _no_gc) OBJ_MARK(obj);
for(auto& frame : vm->callstack.data()) frame._gc_mark(); for(auto& frame : vm->callstack.data()) frame._gc_mark();
for(PyObject* obj: vm->s_data) OBJ_MARK(obj); // TODO: avoid use nullptr?
for(PyObject* obj: vm->s_data) if(obj != nullptr) OBJ_MARK(obj);
} }
inline Str obj_type_name(VM *vm, Type type){ inline Str obj_type_name(VM *vm, Type type){