This commit is contained in:
blueloveTH 2022-11-28 18:04:51 +08:00
parent ceb8e2e5de
commit 63d8d6417c
4 changed files with 41 additions and 72 deletions

View File

@ -3,6 +3,7 @@
#include "pocketpy.h" #include "pocketpy.h"
//#define PK_DEBUG_TIME //#define PK_DEBUG_TIME
//#define PK_DEBUG_THREADED_REPL
struct Timer{ struct Timer{
const char* title; const char* title;
@ -22,39 +23,56 @@ struct Timer{
// these code is for demo use, feel free to modify it // these code is for demo use, feel free to modify it
REPL* _repl; REPL* _repl;
VM* _vm;
extern "C" { extern "C" {
__EXPORT __EXPORT
void repl_start(){ void repl_start(){
_vm = pkpy_new_vm(true); _repl = pkpy_new_repl(pkpy_new_vm(true));
_repl = pkpy_new_repl(_vm);
} }
__EXPORT __EXPORT
bool repl_input(const char* line){ bool repl_input(const char* line){
bool need_more_lines = pkpy_repl_input(_repl, line); return pkpy_repl_input(_repl, line);
if(!need_more_lines) pkpy_exec_repl(_repl);
return need_more_lines;
} }
} }
#else #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){ int main(int argc, char** argv){
if(argc == 1){ if(argc == 1){
#ifndef PK_DEBUG_THREADED_REPL
VM* vm = pkpy_new_vm(true); VM* vm = pkpy_new_vm(true);
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);
if(repl.input(line) == false){ // do not need more lines repl.input(line);
_Code code = repl.readBufferCode();
if(code == nullptr) continue;
vm->exec(code);
}
} }
#else
ThreadedVM* vm = pkpy_new_tvm(true);
REPL repl(vm);
#endif
return 0; return 0;
} }
@ -85,21 +103,7 @@ int main(int argc, char** argv){
// std::cout << kv.first << ", "; // std::cout << kv.first << ", ";
Timer("Running time").run([=]{ Timer("Running time").run([=]{
vm->startExec(code); _tvm_run_code(vm, 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);
}
}
}
}); });
return 0; return 0;
} }

View File

@ -658,10 +658,11 @@ extern "C" {
} }
__EXPORT __EXPORT
bool pkpy_exec_repl(REPL* r){ bool pkpy_exec_async(VM* vm, const char* source){
_Code code = r->readBufferCode(); _Code code = compile(vm, source, "main.py");
if(code == nullptr) return false; if(code == nullptr) return false;
return r->getVM()->exec(code) != nullptr; vm->execAsync(code);
return true;
} }
__EXPORT __EXPORT
@ -746,28 +747,11 @@ extern "C" {
return vm->getState(); 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 __EXPORT
void pkpy_tvm_reset_state(ThreadedVM* vm){ void pkpy_tvm_reset_state(ThreadedVM* vm){
vm->resetState(); vm->resetState();
} }
__EXPORT
bool pkpy_tvm_start_exec_repl(REPL* r){
_Code code = r->readBufferCode();
if(code == nullptr) return false;
ThreadedVM* vm = dynamic_cast<ThreadedVM*>(r->getVM());
vm->startExec(code);
return true;
}
__EXPORT __EXPORT
PyObjectDump* pkpy_tvm_read_json(ThreadedVM* vm){ PyObjectDump* pkpy_tvm_read_json(ThreadedVM* vm){
std::optional<_Str> s = vm->readSharedStr(); std::optional<_Str> s = vm->readSharedStr();

View File

@ -22,16 +22,10 @@ public:
(*vm->_stdout) << ("Type \"exit()\" to exit." "\n"); (*vm->_stdout) << ("Type \"exit()\" to exit." "\n");
} }
VM* getVM() { return vm; }
bool is_need_more_lines() const { bool is_need_more_lines() const {
return need_more_lines; return need_more_lines;
} }
bool input(const char* line){
return input(std::string(line));
}
bool input(std::string line){ bool input(std::string line){
if(exited) return false; if(exited) return false;
mode = SINGLE_MODE; mode = SINGLE_MODE;
@ -58,7 +52,7 @@ __NOT_ENOUGH_LINES:
try{ try{
_Code code = compile(vm, line.c_str(), "<stdin>", mode); _Code code = compile(vm, line.c_str(), "<stdin>", mode);
this->onCompiled(code); if(code != nullptr) vm->execAsync(code);
}catch(NeedMoreLines& ne){ }catch(NeedMoreLines& ne){
buffer += line; buffer += line;
buffer += '\n'; buffer += '\n';
@ -67,21 +61,4 @@ __NOT_ENOUGH_LINES:
__LOOP_CONTINUE: __LOOP_CONTINUE:
return is_need_more_lines(); 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);
}
}
}; };

View File

@ -523,6 +523,10 @@ public:
} }
} }
virtual void execAsync(const _Code& code) {
exec(code);
}
Frame* __pushNewFrame(const _Code& code, PyVar _module, const PyVarDict& locals){ Frame* __pushNewFrame(const _Code& code, PyVar _module, const PyVarDict& locals){
if(code == nullptr) UNREACHABLE(); if(code == nullptr) UNREACHABLE();
if(callstack.size() > maxRecursionDepth){ 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(_thread != nullptr) UNREACHABLE();
if(_state != THREAD_READY) UNREACHABLE(); if(_state != THREAD_READY) UNREACHABLE();
_thread = new std::thread([this, code](){ _thread = new std::thread([this, code](){
this->_state = THREAD_RUNNING; this->_state = THREAD_RUNNING;
this->exec(code); VM::exec(code);
this->_state = THREAD_FINISHED; this->_state = THREAD_FINISHED;
}); });
} }