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"
//#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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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();
}
};

View File

@ -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();
}
};