fix some issues

This commit is contained in:
blueloveTH 2022-11-28 18:55:08 +08:00
parent 63d8d6417c
commit 40a181a767
5 changed files with 44 additions and 28 deletions

View File

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

View File

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

View File

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

View File

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

View File

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