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

View File

@ -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<ThreadedVM*>(r->getVM());
vm->startExec(code);
return true;
}
__EXPORT
PyObjectDump* pkpy_tvm_read_json(ThreadedVM* vm){
std::optional<_Str> s = vm->readSharedStr();

View File

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

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