This commit is contained in:
blueloveTH 2022-11-28 02:52:32 +08:00
parent 5412186365
commit 29bdeca8eb
5 changed files with 69 additions and 45 deletions

View File

@ -70,24 +70,26 @@ int main(int argc, char** argv){
if(code == nullptr) return 1;
//std::cout << code->toString() << std::endl;
Timer("Running time").run([=]{
vm->exec(code);
});
// Timer("Running time").run([=]{
// vm->exec(code);
// });
// for(auto& kv : _strIntern)
// 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){
// std::string line;
// std::getline(std::cin, line);
// pkpy_tvm_write_stdin(vm, line.c_str());
// pkpy_tvm_resume(vm);
// }
// }
// });
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);
if(INPUT_JSONRPC_STR != obj->json) UNREACHABLE();
pkpy_delete(obj);
std::string line;
std::getline(std::cin, line);
pkpy_tvm_resume(vm, line.c_str());
}
}
});
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.1"
#define PK_VERSION "0.3.2"
class CodeObject;
class BasePointer;

View File

@ -48,14 +48,6 @@ void __initializeBuiltinFunctions(VM* _vm) {
return vm->None;
});
_vm->bindBuiltinFunc("input", [](VM* vm, const pkpy::ArgList& args) {
vm->__checkArgSize(args, 0);
ThreadedVM* tvm = dynamic_cast<ThreadedVM*>(vm);
if(tvm == nullptr) vm->typeError("input() can only be called in threaded mode");
tvm->suspend();
return vm->PyStr(tvm->readStdin());
});
_vm->bindBuiltinFunc("super", [](VM* vm, const pkpy::ArgList& args) {
vm->__checkArgSize(args, 0);
auto it = vm->topFrame()->f_locals.find("self"_c);
@ -776,12 +768,14 @@ extern "C" {
}
__EXPORT
void pkpy_tvm_write_stdin(ThreadedVM* vm, const char* line){
vm->_stdin = _Str(line);
PyObjectDump* pkpy_tvm_read_json(ThreadedVM* vm){
std::optional<_Str> s = vm->readSharedStr();
if(!s.has_value()) return nullptr;
return new PyObjectDump("str", s.value());
}
__EXPORT
void pkpy_tvm_resume(ThreadedVM* vm){
vm->resume();
void pkpy_tvm_resume(ThreadedVM* vm, const char* value){
vm->resume(value);
}
}

View File

@ -44,7 +44,7 @@
typedef void(*PrintFn)(const VM*, const char*);
class VM: public PkExportedResource{
private:
protected:
std::deque< std::unique_ptr<Frame> > callstack;
PyVarDict _modules; // 3rd modules
PyVar __py2py_call_signal;
@ -1042,48 +1042,76 @@ enum ThreadState {
THREAD_FINISHED
};
const _Str INPUT_JSONRPC_STR = "{\"method\":\"input\", \"params\":[]}";
class ThreadedVM : public VM {
std::thread* _thread = nullptr;
std::atomic<ThreadState> state = THREAD_READY;
public:
ThreadedVM(bool use_stdio) : VM(use_stdio) {}
std::atomic<ThreadState> _state = THREAD_READY;
std::optional<_Str> _sharedStr = {};
_Str _stdin;
PyVar jsonRpc(const _Str& _json){
_sharedStr = _json;
suspend();
std::optional<_Str> ret = readSharedStr();
if(ret.has_value()) return PyStr(ret.value());
return None;
}
public:
ThreadedVM(bool use_stdio) : VM(use_stdio) {
bindBuiltinFunc("jsonrpc", [](VM* vm, const pkpy::ArgList& args){
ThreadedVM *tvm = dynamic_cast<ThreadedVM*>(vm);
if(tvm == nullptr) UNREACHABLE();
tvm->__checkArgSize(args, 1);
return tvm->jsonRpc(tvm->PyStr_AS_C(args[0]));
});
bindBuiltinFunc("input", [](VM* vm, const pkpy::ArgList& args) {
ThreadedVM *tvm = dynamic_cast<ThreadedVM*>(vm);
if(tvm == nullptr) UNREACHABLE();
tvm->__checkArgSize(args, 0);
return tvm->jsonRpc(INPUT_JSONRPC_STR);
});
}
void suspend(){
if(_thread == nullptr) UNREACHABLE();
if(state != THREAD_RUNNING) UNREACHABLE();
state = THREAD_SUSPENDED;
if(_state != THREAD_RUNNING) UNREACHABLE();
_state = THREAD_SUSPENDED;
// 50 fps is enough
while(state == THREAD_SUSPENDED) std::this_thread::sleep_for(std::chrono::milliseconds(20));
while(_state == THREAD_SUSPENDED) std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
_Str readStdin(){
std::optional<_Str> readSharedStr(){
if(_thread == nullptr) UNREACHABLE();
_Str copy = _stdin;
_stdin = "";
std::optional<_Str> copy = _sharedStr.value();
_sharedStr = {};
return copy;
}
/***** For outer use *****/
ThreadState getState(){
return state.load();
return _state;
}
void resume(){
void resume(const char* value=nullptr){
if(_thread == nullptr) UNREACHABLE();
if(state != THREAD_SUSPENDED) UNREACHABLE();
state = THREAD_RUNNING;
if(_state != THREAD_SUSPENDED) UNREACHABLE();
_state = THREAD_RUNNING;
if(value == nullptr){
_sharedStr = {};
}else{
_sharedStr = value;
}
}
void startExec(const _Code& code){
if(_thread != nullptr) UNREACHABLE();
if(state != THREAD_READY) UNREACHABLE();
if(_state != THREAD_READY) UNREACHABLE();
_thread = new std::thread([this, code](){
this->state = THREAD_RUNNING;
this->_state = THREAD_RUNNING;
this->exec(code);
this->state = THREAD_FINISHED;
this->_state = THREAD_FINISHED;
});
}