diff --git a/src/main.cpp b/src/main.cpp index 5b12fcd7..b8251854 100644 --- a/src/main.cpp +++ b/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; } diff --git a/src/pocketpy.h b/src/pocketpy.h index a7549a7d..5ad0f8dc 100644 --- a/src/pocketpy.h +++ b/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(r->getVM()); - vm->startExec(code); - return true; - } - __EXPORT PyObjectDump* pkpy_tvm_read_json(ThreadedVM* vm){ std::optional<_Str> s = vm->readSharedStr(); diff --git a/src/repl.h b/src/repl.h index 06f1111b..e051981e 100644 --- a/src/repl.h +++ b/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(), "", 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); - } - } }; \ No newline at end of file diff --git a/src/vm.h b/src/vm.h index a91861cc..c685e25f 100644 --- a/src/vm.h +++ b/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; }); }