blueloveTH 3 лет назад
Родитель
Сommit
63d8d6417c
4 измененных файлов с 41 добавлено и 72 удалено
  1. 30 26
      src/main.cpp
  2. 4 20
      src/pocketpy.h
  3. 1 24
      src/repl.h
  4. 6 2
      src/vm.h

+ 30 - 26
src/main.cpp

@@ -3,6 +3,7 @@
 #include "pocketpy.h"
 
 //#define PK_DEBUG_TIME
+//#define PK_DEBUG_THREADED_REPL
 
 struct Timer{
     const char* title;
@@ -22,39 +23,56 @@ struct Timer{
 
 // these code is for demo use, feel free to modify it
 REPL* _repl;
-VM* _vm;
 
 extern "C" {
     __EXPORT
     void repl_start(){
-        _vm = pkpy_new_vm(true);
-        _repl = pkpy_new_repl(_vm);
+        _repl = pkpy_new_repl(pkpy_new_vm(true));
     }
 
     __EXPORT
     bool repl_input(const char* line){
-        bool need_more_lines = pkpy_repl_input(_repl, line);
-        if(!need_more_lines) pkpy_exec_repl(_repl);
-        return need_more_lines;
+        return pkpy_repl_input(_repl, line);
     }
 }
 
 #else
 
+
+void _tvm_run_code(ThreadedVM* vm, _Code code){
+    vm->execAsync(code);
+    while(pkpy_tvm_get_state(vm) != THREAD_FINISHED){
+        if(pkpy_tvm_get_state(vm) == THREAD_SUSPENDED){
+            PyObjectDump* obj = pkpy_tvm_read_json(vm);
+            bool is_input_call = INPUT_JSONRPC_STR != obj->json;
+            pkpy_delete(obj);
+            if(is_input_call){
+                std::string line;
+                std::getline(std::cin, line);
+                pkpy_tvm_resume(vm, line.c_str());
+            }else{
+                pkpy_tvm_resume(vm, nullptr);
+            }
+        }
+    }
+}
+
+
 int main(int argc, char** argv){
     if(argc == 1){
+#ifndef PK_DEBUG_THREADED_REPL
         VM* vm = pkpy_new_vm(true);
         REPL repl(vm);
         while(true){
             (*vm->_stdout) << (repl.is_need_more_lines() ? "... " : ">>> ");
             std::string line;
             std::getline(std::cin, line);
-            if(repl.input(line) == false){      // do not need more lines
-                _Code code = repl.readBufferCode();
-                if(code == nullptr) continue;
-                vm->exec(code);
-            }
+            repl.input(line);
         }
+#else
+        ThreadedVM* vm = pkpy_new_tvm(true);
+        REPL repl(vm);
+#endif
         return 0;
     }
     
@@ -85,21 +103,7 @@ int main(int argc, char** argv){
         //     std::cout << kv.first << ", ";
 
         Timer("Running time").run([=]{
-            vm->startExec(code);
-            while(pkpy_tvm_get_state(vm) != THREAD_FINISHED){
-                if(pkpy_tvm_get_state(vm) == THREAD_SUSPENDED){
-                    PyObjectDump* obj = pkpy_tvm_read_json(vm);
-                    bool is_input_call = INPUT_JSONRPC_STR != obj->json;
-                    pkpy_delete(obj);
-                    if(is_input_call){
-                        std::string line;
-                        std::getline(std::cin, line);
-                        pkpy_tvm_resume(vm, line.c_str());
-                    }else{
-                        pkpy_tvm_resume(vm, nullptr);
-                    }
-                }
-            }
+            _tvm_run_code(vm, code);
         });
         return 0;
     }

+ 4 - 20
src/pocketpy.h

@@ -658,10 +658,11 @@ extern "C" {
     }
 
     __EXPORT
-    bool pkpy_exec_repl(REPL* r){
-        _Code code = r->readBufferCode();
+    bool pkpy_exec_async(VM* vm, const char* source){
+        _Code code = compile(vm, source, "main.py");
         if(code == nullptr) return false;
-        return r->getVM()->exec(code) != nullptr;
+        vm->execAsync(code);
+        return true;
     }
 
     __EXPORT
@@ -746,28 +747,11 @@ extern "C" {
         return vm->getState();
     }
 
-    __EXPORT
-    bool pkpy_tvm_start_exec(ThreadedVM* vm, const char* source){
-        _Code code = compile(vm, source, "main.py");
-        if(code == nullptr) return false;
-        vm->startExec(code);
-        return true;
-    }
-
     __EXPORT
     void pkpy_tvm_reset_state(ThreadedVM* vm){
         vm->resetState();
     }
 
-    __EXPORT
-    bool pkpy_tvm_start_exec_repl(REPL* r){
-        _Code code = r->readBufferCode();
-        if(code == nullptr) return false;
-        ThreadedVM* vm = dynamic_cast<ThreadedVM*>(r->getVM());
-        vm->startExec(code);
-        return true;
-    }
-
     __EXPORT
     PyObjectDump* pkpy_tvm_read_json(ThreadedVM* vm){
         std::optional<_Str> s = vm->readSharedStr();

+ 1 - 24
src/repl.h

@@ -22,16 +22,10 @@ public:
         (*vm->_stdout) << ("Type \"exit()\" to exit." "\n");
     }
 
-    VM* getVM() { return vm; }
-
     bool is_need_more_lines() const {
         return need_more_lines;
     }
 
-    bool input(const char* line){
-        return input(std::string(line));
-    }
-
     bool input(std::string line){
         if(exited) return false;
         mode = SINGLE_MODE;
@@ -58,7 +52,7 @@ __NOT_ENOUGH_LINES:
 
         try{
             _Code code = compile(vm, line.c_str(), "<stdin>", mode);
-            this->onCompiled(code);
+            if(code != nullptr) vm->execAsync(code);
         }catch(NeedMoreLines& ne){
             buffer += line;
             buffer += '\n';
@@ -67,21 +61,4 @@ __NOT_ENOUGH_LINES:
 __LOOP_CONTINUE:
         return is_need_more_lines();
     }
-
-    _Code readBufferCode(){
-        auto copy = std::move(bufferCode);
-        bufferCode = nullptr;
-        return copy;
-    }
-
-protected:
-    _Code bufferCode = nullptr;
-
-    void onCompiled(_Code code){
-        if(code == nullptr){
-            bufferCode = nullptr;
-        }else{
-            bufferCode = std::move(code);
-        }
-    }
 };

+ 6 - 2
src/vm.h

@@ -523,6 +523,10 @@ public:
         }
     }
 
+    virtual void execAsync(const _Code& code) {
+        exec(code);
+    }
+
     Frame* __pushNewFrame(const _Code& code, PyVar _module, const PyVarDict& locals){
         if(code == nullptr) UNREACHABLE();
         if(callstack.size() > maxRecursionDepth){
@@ -1111,12 +1115,12 @@ public:
         }
     }
 
-    void startExec(const _Code& code){
+    void execAsync(const _Code& code) override {
         if(_thread != nullptr) UNREACHABLE();
         if(_state != THREAD_READY) UNREACHABLE();
         _thread = new std::thread([this, code](){
             this->_state = THREAD_RUNNING;
-            this->exec(code);
+            VM::exec(code);
             this->_state = THREAD_FINISHED;
         });
     }