Kaynağa Gözat

fix some issues

blueloveTH 3 yıl önce
ebeveyn
işleme
40a181a767
5 değiştirilmiş dosya ile 44 ekleme ve 28 silme
  1. 17 11
      src/main.cpp
  2. 1 1
      src/obj.h
  3. 1 1
      src/pocketpy.h
  4. 14 7
      src/repl.h
  5. 11 8
      src/vm.h

+ 17 - 11
src/main.cpp

@@ -3,7 +3,7 @@
 #include "pocketpy.h"
 
 //#define PK_DEBUG_TIME
-//#define PK_DEBUG_THREADED_REPL
+#define PK_DEBUG_THREADED_REPL
 
 struct Timer{
     const char* title;
@@ -32,25 +32,25 @@ extern "C" {
 
     __EXPORT
     bool repl_input(const char* line){
-        return pkpy_repl_input(_repl, line);
+        return pkpy_repl_input(_repl, line) == NEED_MORE_LINES;
     }
 }
 
 #else
 
 
-void _tvm_run_code(ThreadedVM* vm, _Code code){
-    vm->execAsync(code);
+void _tvm_dispatch(ThreadedVM* vm){
     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;
+            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{
+                exit(999);
                 pkpy_tvm_resume(vm, nullptr);
             }
         }
@@ -62,17 +62,22 @@ int main(int argc, char** argv){
     if(argc == 1){
 #ifndef PK_DEBUG_THREADED_REPL
         VM* vm = pkpy_new_vm(true);
+#else
+        ThreadedVM* vm = pkpy_new_tvm(true);
+#endif
         REPL repl(vm);
         while(true){
             (*vm->_stdout) << (repl.is_need_more_lines() ? "... " : ">>> ");
             std::string line;
             std::getline(std::cin, line);
-            repl.input(line);
-        }
-#else
-        ThreadedVM* vm = pkpy_new_tvm(true);
-        REPL repl(vm);
+            int result = pkpy_repl_input(&repl, line.c_str());
+#ifdef PK_DEBUG_THREADED_REPL
+            if(result == (int)EXEC_DONE){
+                _tvm_dispatch(vm);
+                pkpy_tvm_reset_state(vm);
+            }
 #endif
+        }
         return 0;
     }
     
@@ -103,7 +108,8 @@ int main(int argc, char** argv){
         //     std::cout << kv.first << ", ";
 
         Timer("Running time").run([=]{
-            _tvm_run_code(vm, code);
+            vm->execAsync(code);
+            _tvm_dispatch(vm);
         });
         return 0;
     }

+ 1 - 1
src/obj.h

@@ -10,7 +10,7 @@ const _Int _Int_MAX_NEG = -9223372036854775807LL;
 const _Float _FLOAT_INF_POS = INFINITY;
 const _Float _FLOAT_INF_NEG = -INFINITY;
 
-#define PK_VERSION "0.3.2"
+#define PK_VERSION "0.3.3"
 
 class CodeObject;
 class BasePointer;

+ 1 - 1
src/pocketpy.h

@@ -693,7 +693,7 @@ extern "C" {
     }
 
     __EXPORT
-    bool pkpy_repl_input(REPL* r, const char* line){
+    int pkpy_repl_input(REPL* r, const char* line){
         return r->input(line);
     }
 

+ 14 - 7
src/repl.h

@@ -3,6 +3,12 @@
 #include "compiler.h"
 #include "vm.h"
 
+enum InputResult {
+    NEED_MORE_LINES = 0,
+    EXEC_DONE = 1,
+    EXEC_SKIPPED = 2,
+};
+
 class REPL: public PkExportedResource {
 protected:
     int need_more_lines = 0;
@@ -26,8 +32,8 @@ public:
         return need_more_lines;
     }
 
-    bool input(std::string line){
-        if(exited) return false;
+    InputResult input(std::string line){
+        if(exited) return EXEC_SKIPPED;
         mode = SINGLE_MODE;
         if(need_more_lines){
             buffer += line;
@@ -43,22 +49,23 @@ public:
                 buffer.clear();
             }else{
 __NOT_ENOUGH_LINES:
-                goto __LOOP_CONTINUE;
+                return NEED_MORE_LINES;
             }
         }else{
             if(line == "exit()") _exit();
-            if(line.empty()) goto __LOOP_CONTINUE;
+            if(line.empty()) return EXEC_SKIPPED;
         }
 
         try{
             _Code code = compile(vm, line.c_str(), "<stdin>", mode);
-            if(code != nullptr) vm->execAsync(code);
+            if(code == nullptr) return EXEC_SKIPPED;
+            vm->execAsync(code);
+            return EXEC_DONE;
         }catch(NeedMoreLines& ne){
             buffer += line;
             buffer += '\n';
             need_more_lines = ne.isClassDef ? 3 : 2;
+            return NEED_MORE_LINES;
         }
-__LOOP_CONTINUE:
-        return is_need_more_lines();
     }
 };

+ 11 - 8
src/vm.h

@@ -1065,6 +1065,15 @@ class ThreadedVM : public VM {
     PyVar jsonRpc(const PyVar& obj){
         return jsonRpc(asJson(obj));
     }
+
+    void __deleteThread(){
+        if(_thread != nullptr){
+            if(!_thread->joinable()) UNREACHABLE();
+            _thread->join();
+            delete _thread;
+            _thread = nullptr;
+        }
+    }
 public:
     ThreadedVM(bool use_stdio) : VM(use_stdio) {
         bindBuiltinFunc("jsonrpc", [](VM* vm, const pkpy::ArgList& args){
@@ -1084,7 +1093,6 @@ public:
     }
 
     void suspend(){
-        if(_thread == nullptr) UNREACHABLE();
         if(_state != THREAD_RUNNING) UNREACHABLE();
         _state = THREAD_SUSPENDED;
         // 50 fps is enough
@@ -1092,7 +1100,6 @@ public:
     }
 
     std::optional<_Str> readSharedStr(){
-        if(_thread == nullptr) UNREACHABLE();
         std::optional<_Str> copy = _sharedStr.value();
         _sharedStr = {};
         return copy;
@@ -1105,7 +1112,6 @@ public:
     }
 
     void resume(const char* value=nullptr){
-        if(_thread == nullptr) UNREACHABLE();
         if(_state != THREAD_SUSPENDED) UNREACHABLE();
         _state = THREAD_RUNNING;
         if(value == nullptr){
@@ -1116,8 +1122,8 @@ public:
     }
 
     void execAsync(const _Code& code) override {
-        if(_thread != nullptr) UNREACHABLE();
         if(_state != THREAD_READY) UNREACHABLE();
+        __deleteThread();
         _thread = new std::thread([this, code](){
             this->_state = THREAD_RUNNING;
             VM::exec(code);
@@ -1140,9 +1146,6 @@ public:
     }
 
     ~ThreadedVM(){
-        if(_thread != nullptr){
-            _thread->join();
-            delete _thread;
-        }
+        __deleteThread();
     }
 };