mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 19:40: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;
|
if(code == nullptr) return 1;
|
||||||
//std::cout << code->toString() << std::endl;
|
//std::cout << code->toString() << std::endl;
|
||||||
|
|
||||||
Timer("Running time").run([=]{
|
// Timer("Running time").run([=]{
|
||||||
vm->exec(code);
|
// vm->exec(code);
|
||||||
});
|
// });
|
||||||
|
|
||||||
// for(auto& kv : _strIntern)
|
// for(auto& kv : _strIntern)
|
||||||
// std::cout << kv.first << ", ";
|
// std::cout << kv.first << ", ";
|
||||||
|
|
||||||
// Timer("Running time").run([=]{
|
Timer("Running time").run([=]{
|
||||||
// vm->startExec(code);
|
vm->startExec(code);
|
||||||
// while(pkpy_tvm_get_state(vm) != THREAD_FINISHED){
|
while(pkpy_tvm_get_state(vm) != THREAD_FINISHED){
|
||||||
// if(pkpy_tvm_get_state(vm) == THREAD_SUSPENDED){
|
if(pkpy_tvm_get_state(vm) == THREAD_SUSPENDED){
|
||||||
// std::string line;
|
PyObjectDump* obj = pkpy_tvm_read_json(vm);
|
||||||
// std::getline(std::cin, line);
|
if(INPUT_JSONRPC_STR != obj->json) UNREACHABLE();
|
||||||
// pkpy_tvm_write_stdin(vm, line.c_str());
|
pkpy_delete(obj);
|
||||||
// pkpy_tvm_resume(vm);
|
std::string line;
|
||||||
// }
|
std::getline(std::cin, line);
|
||||||
// }
|
pkpy_tvm_resume(vm, line.c_str());
|
||||||
// });
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ const _Int _Int_MAX_NEG = -9223372036854775807LL;
|
|||||||
const _Float _FLOAT_INF_POS = INFINITY;
|
const _Float _FLOAT_INF_POS = INFINITY;
|
||||||
const _Float _FLOAT_INF_NEG = -INFINITY;
|
const _Float _FLOAT_INF_NEG = -INFINITY;
|
||||||
|
|
||||||
#define PK_VERSION "0.3.1"
|
#define PK_VERSION "0.3.2"
|
||||||
|
|
||||||
class CodeObject;
|
class CodeObject;
|
||||||
class BasePointer;
|
class BasePointer;
|
||||||
|
@ -48,14 +48,6 @@ void __initializeBuiltinFunctions(VM* _vm) {
|
|||||||
return vm->None;
|
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->bindBuiltinFunc("super", [](VM* vm, const pkpy::ArgList& args) {
|
||||||
vm->__checkArgSize(args, 0);
|
vm->__checkArgSize(args, 0);
|
||||||
auto it = vm->topFrame()->f_locals.find("self"_c);
|
auto it = vm->topFrame()->f_locals.find("self"_c);
|
||||||
@ -776,12 +768,14 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
void pkpy_tvm_write_stdin(ThreadedVM* vm, const char* line){
|
PyObjectDump* pkpy_tvm_read_json(ThreadedVM* vm){
|
||||||
vm->_stdin = _Str(line);
|
std::optional<_Str> s = vm->readSharedStr();
|
||||||
|
if(!s.has_value()) return nullptr;
|
||||||
|
return new PyObjectDump("str", s.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
__EXPORT
|
__EXPORT
|
||||||
void pkpy_tvm_resume(ThreadedVM* vm){
|
void pkpy_tvm_resume(ThreadedVM* vm, const char* value){
|
||||||
vm->resume();
|
vm->resume(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
64
src/vm.h
64
src/vm.h
@ -44,7 +44,7 @@
|
|||||||
typedef void(*PrintFn)(const VM*, const char*);
|
typedef void(*PrintFn)(const VM*, const char*);
|
||||||
|
|
||||||
class VM: public PkExportedResource{
|
class VM: public PkExportedResource{
|
||||||
private:
|
protected:
|
||||||
std::deque< std::unique_ptr<Frame> > callstack;
|
std::deque< std::unique_ptr<Frame> > callstack;
|
||||||
PyVarDict _modules; // 3rd modules
|
PyVarDict _modules; // 3rd modules
|
||||||
PyVar __py2py_call_signal;
|
PyVar __py2py_call_signal;
|
||||||
@ -1042,48 +1042,76 @@ enum ThreadState {
|
|||||||
THREAD_FINISHED
|
THREAD_FINISHED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const _Str INPUT_JSONRPC_STR = "{\"method\":\"input\", \"params\":[]}";
|
||||||
|
|
||||||
class ThreadedVM : public VM {
|
class ThreadedVM : public VM {
|
||||||
std::thread* _thread = nullptr;
|
std::thread* _thread = nullptr;
|
||||||
std::atomic<ThreadState> state = THREAD_READY;
|
std::atomic<ThreadState> _state = THREAD_READY;
|
||||||
public:
|
std::optional<_Str> _sharedStr = {};
|
||||||
ThreadedVM(bool use_stdio) : VM(use_stdio) {}
|
|
||||||
|
|
||||||
_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(){
|
void suspend(){
|
||||||
if(_thread == nullptr) UNREACHABLE();
|
if(_thread == nullptr) UNREACHABLE();
|
||||||
if(state != THREAD_RUNNING) UNREACHABLE();
|
if(_state != THREAD_RUNNING) UNREACHABLE();
|
||||||
state = THREAD_SUSPENDED;
|
_state = THREAD_SUSPENDED;
|
||||||
// 50 fps is enough
|
// 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();
|
if(_thread == nullptr) UNREACHABLE();
|
||||||
_Str copy = _stdin;
|
std::optional<_Str> copy = _sharedStr.value();
|
||||||
_stdin = "";
|
_sharedStr = {};
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***** For outer use *****/
|
/***** For outer use *****/
|
||||||
|
|
||||||
ThreadState getState(){
|
ThreadState getState(){
|
||||||
return state.load();
|
return _state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resume(){
|
void resume(const char* value=nullptr){
|
||||||
if(_thread == nullptr) UNREACHABLE();
|
if(_thread == nullptr) UNREACHABLE();
|
||||||
if(state != THREAD_SUSPENDED) UNREACHABLE();
|
if(_state != THREAD_SUSPENDED) UNREACHABLE();
|
||||||
state = THREAD_RUNNING;
|
_state = THREAD_RUNNING;
|
||||||
|
if(value == nullptr){
|
||||||
|
_sharedStr = {};
|
||||||
|
}else{
|
||||||
|
_sharedStr = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void startExec(const _Code& code){
|
void startExec(const _Code& code){
|
||||||
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);
|
this->exec(code);
|
||||||
this->state = THREAD_FINISHED;
|
this->_state = THREAD_FINISHED;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user