mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
up
This commit is contained in:
parent
5412186365
commit
29bdeca8eb
30
src/main.cpp
30
src/main.cpp
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
64
src/vm.h
64
src/vm.h
@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user