From 40a181a7678daa1cd83b7aa0c2436fd852905f00 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 28 Nov 2022 18:55:08 +0800 Subject: [PATCH] fix some issues --- src/main.cpp | 28 +++++++++++++++++----------- src/obj.h | 2 +- src/pocketpy.h | 2 +- src/repl.h | 21 ++++++++++++++------- src/vm.h | 19 +++++++++++-------- 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index b8251854..6ef9230c 100644 --- a/src/main.cpp +++ b/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; } diff --git a/src/obj.h b/src/obj.h index de00017c..a773a249 100644 --- a/src/obj.h +++ b/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; diff --git a/src/pocketpy.h b/src/pocketpy.h index 5ad0f8dc..e9c1913e 100644 --- a/src/pocketpy.h +++ b/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); } diff --git a/src/repl.h b/src/repl.h index e051981e..92fd2095 100644 --- a/src/repl.h +++ b/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(), "", 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(); } }; \ No newline at end of file diff --git a/src/vm.h b/src/vm.h index c685e25f..dade6f08 100644 --- a/src/vm.h +++ b/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(); } }; \ No newline at end of file