BLUELOVETH 2 anni fa
parent
commit
ab3605a661
3 ha cambiato i file con 22 aggiunte e 8 eliminazioni
  1. 2 0
      src/iter.h
  2. 2 2
      src/pocketpy.h
  3. 18 6
      src/vm.h

+ 2 - 0
src/iter.h

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

+ 2 - 2
src/pocketpy.h

@@ -99,13 +99,13 @@ inline void init_builtins(VM* _vm) {
     _vm->bind_builtin_func<1>("eval", [](VM* vm, ArgsView args) {
         CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<eval>", EVAL_MODE, true);
         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) {
         CodeObject_ code = vm->compile(CAST(Str&, args[0]), "<exec>", EXEC_MODE, true);
         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;
     });
 

+ 18 - 6
src/vm.h

@@ -51,7 +51,9 @@ class Generator final: public BaseIter {
     int state;      // 0,1,2
     List s_backup;
 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;
     void _gc_mark() const override;
@@ -97,6 +99,8 @@ public:
     std::ostream* _stdout;
     std::ostream* _stderr;
 
+    bool _initialized;
+
     // for quick access
     Type tp_object, tp_type, tp_int, tp_float, tp_bool, tp_str;
     Type tp_list, tp_tuple;
@@ -109,7 +113,9 @@ public:
         this->_stdout = use_stdio ? &std::cout : &_stdout_buffer;
         this->_stderr = use_stdio ? &std::cerr : &_stderr_buffer;
         callstack.reserve(8);
+        _initialized = false;
         init_builtin_types();
+        _initialized = true;
     }
 
     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) {
+    if(!_initialized) return;
     if(callstack.empty()) return;
     std::stringstream ss;
     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;
     
     s_data.reset(p0);
-    // copy buffer to stack
-    for(int i=0; i<co->varnames.size(); i++) PUSH(buffer[i]);
-
     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;
     }
+
+    // copy buffer to stack
+    for(int i=0; i<co->varnames.size(); i++) PUSH(buffer[i]);
     callstack.emplace(&s_data, p0, co, _module, callable);
     return nullptr;
 }
@@ -1041,7 +1052,8 @@ inline void VM::_error(Exception e){
 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);
+    // 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){