From b950e75a0cdedfab46c83b2f8fcd58b3a88006cd Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Mon, 10 Jul 2023 00:24:41 +0800 Subject: [PATCH] ... --- include/pocketpy/pocketpy_c.h | 32 ++++++--- src/pocketpy_c.cpp | 125 ++++++++++++---------------------- 2 files changed, 66 insertions(+), 91 deletions(-) diff --git a/include/pocketpy/pocketpy_c.h b/include/pocketpy/pocketpy_c.h index ad91d5ef..df7fc132 100644 --- a/include/pocketpy/pocketpy_c.h +++ b/include/pocketpy/pocketpy_c.h @@ -11,6 +11,11 @@ extern "C" { #include "export.h" typedef struct pkpy_vm_handle pkpy_vm; +typedef int (*pkpy_function)(pkpy_vm*); + +/* Basic Functions */ +PK_EXPORT pkpy_vm* pkpy_vm_create(bool use_stdio, bool enable_os); +PK_EXPORT void pkpy_vm_destroy(pkpy_vm*); //we we take a lot of inspiration from the lua api for these bindings //the key difference being most methods return a bool, @@ -30,11 +35,9 @@ PK_EXPORT bool pkpy_clear_error(pkpy_vm*, char** message); //the user will not be able to catch it with python code PK_EXPORT bool pkpy_error(pkpy_vm*, const char* name, const char* message); -PK_EXPORT pkpy_vm* pkpy_vm_create(bool use_stdio, bool enable_os); -PK_EXPORT bool pkpy_vm_run(pkpy_vm*, const char* source); -PK_EXPORT void pkpy_vm_destroy(pkpy_vm*); -typedef int (*pkpy_function)(pkpy_vm*); + + PK_EXPORT bool pkpy_pop(pkpy_vm*, int n); @@ -110,16 +113,25 @@ PK_EXPORT bool pkpy_getattr(pkpy_vm*, const char* name); PK_EXPORT bool pkpy_setattr(pkpy_vm*, const char* name); PK_EXPORT bool pkpy_eval(pkpy_vm*, const char* source); -/* legacy api */ +// create a new native module with the given name and push it onto the stack +PK_EXPORT bool pkpy_new_module(void* vm, const char* name); + + +/* vm api */ + +// for backwards compatibility +#define pkpy_vm_run(vm, source) pkpy_vm_exec(vm, source) + +PK_EXPORT bool pkpy_vm_exec(pkpy_vm* vm, const char* source); +PK_EXPORT bool pkpy_vm_exec_2(pkpy_vm* vm, const char* source, const char* filename, int mode, const char* module); + +/* special api */ + +// free a pointer allocated from pkpy's heap PK_EXPORT void pkpy_free(void* p); -PK_EXPORT bool pkpy_vm_exec(void* vm, const char* source); -PK_EXPORT bool pkpy_vm_exec_2(void* vm, const char* source, const char* filename, int mode, const char* module); PK_EXPORT void pkpy_vm_compile(void* vm, const char* source, const char* filename, int mode, bool* ok, char** res); PK_EXPORT void* pkpy_new_repl(void* vm); PK_EXPORT bool pkpy_repl_input(void* r, const char* line); -PK_EXPORT void pkpy_vm_add_module(void* vm, const char* name, const char* source); -PK_EXPORT void* pkpy_new_vm(bool enable_os=true); -PK_EXPORT void pkpy_delete_vm(void* vm); PK_EXPORT void pkpy_delete_repl(void* repl); #ifdef __cplusplus diff --git a/src/pocketpy_c.cpp b/src/pocketpy_c.cpp index 6d86e680..bc90d03d 100644 --- a/src/pocketpy_c.cpp +++ b/src/pocketpy_c.cpp @@ -50,41 +50,31 @@ struct LuaStack: public ValueStackImpl<32>{ return false; \ } +class CVM; +void gc_marker_ex(CVM* vm); -class CVM : public VM { - public : - - LuaStack* c_data; +class CVM: public VM { +public: + LuaStack c_data; PyObject* error; - CVM(bool enable_os=true) : VM(enable_os) { + CVM(bool use_stdio, bool enable_os) : VM(enable_os) { c_data = new LuaStack(); error = nullptr; - } - - ~CVM() { - c_data->clear(); - delete c_data; - } - - struct TempStack{ - CVM* cvm; - LuaStack* prev; - TempStack(CVM* cvm, LuaStack* new_data) : cvm(cvm) { - prev = cvm->c_data; - cvm->c_data = new_data; + heap._gc_marker_ex = (void (*)(VM*)) gc_marker_ex; + if (!use_stdio) { + _stdout = _stderr = [](VM* vm, const Str& s){ + PK_UNUSED(vm); + PK_UNUSED(s); + }; } - - ~TempStack() { restore(); } - - void restore(){ - if(prev == nullptr) return; - cvm->c_data = prev; - prev = nullptr; - } - }; + } }; +void gc_marker_ex(CVM* vm) { + for(PyObject* obj: *vm->c_data) if(obj!=nullptr) PK_OBJ_MARK(obj); + if(vm->error != nullptr) PK_OBJ_MARK(vm->error); +} //for now I will unpack a tuple automatically, we may not want to handle //it this way, not sure @@ -126,38 +116,34 @@ bool pkpy_clear_error(pkpy_vm* vm_handle, char** message) { return true; } -void gc_marker_ex(CVM* vm) { - for(PyObject* obj: *vm->c_data) if(obj!=nullptr) PK_OBJ_MARK(obj); - if(vm->error != nullptr) PK_OBJ_MARK(vm->error); -} - pkpy_vm* pkpy_vm_create(bool use_stdio, bool enable_os) { - CVM* vm = new CVM(enable_os); - vm->c_data = new LuaStack(); - vm->heap._gc_marker_ex = (void (*)(VM*)) gc_marker_ex; - - if (!use_stdio) { - vm->_stdout = vm->_stderr = [](VM* vm, const Str& s){ - PK_UNUSED(vm); - PK_UNUSED(s); - }; - } - + CVM* vm = new CVM(use_stdio, enable_os); return (pkpy_vm*) vm; } -bool pkpy_vm_run(pkpy_vm* vm_handle, const char* source) { +bool pkpy_vm_exec(pkpy_vm* vm_handle, const char* source) { CVM* vm = (CVM*) vm_handle; PyObject* res; ERRHANDLER_OPEN - CodeObject_ code = vm->compile(source, "", EXEC_MODE); + CodeObject_ code = vm->compile(source, "main.py", EXEC_MODE); res = vm->_exec(code, vm->_main); ERRHANDLER_CLOSE + return res != nullptr; +} - //unpack_return(w, result); - //NOTE: it seems like vm->_exec should return whatever the last command it - //ran returned but instead it seems to pretty much always return None - //so I guess uncomment this line if that every changes +bool pkpy_vm_exec_2(pkpy_vm* vm_handle, const char* source, const char* filename, int mode, const char* module){ + CVM* vm = (CVM*) vm_handle; + PyObject* res; + PyObject* mod; + ERRHANDLER_OPEN + if(module == nullptr){ + mod = vm->_main; + }else{ + mod = vm->_modules[module]; // may raise + } + CodeObject_ code = vm->compile(source, filename, (CompileMode)mode); + res = vm->_exec(code, mod); + ERRHANDLER_CLOSE return res != nullptr; } @@ -497,7 +483,6 @@ bool pkpy_push(pkpy_vm* vm_handle, int index) { return true; } - bool pkpy_error(pkpy_vm* vm_handle, const char* name, const char* message) { CVM* vm = (CVM*) vm_handle; // already in error state @@ -541,29 +526,20 @@ bool pkpy_eval(pkpy_vm* vm_handle, const char* code) { return true; } -/*****************************************************************/ +bool pkpy_new_module(pkpy_vm* vm_handle, const char* name){ + CVM* vm = (CVM*) vm_handle; + ERRHANDLER_OPEN + PyObject* mod = vm->new_module(name); + vm->c_data->safe_push(mod); + ERRHANDLER_CLOSE + return true; +} +/*****************************************************************/ void pkpy_free(void* p){ free(p); } - bool pkpy_vm_exec(void* vm, const char* source){ - void* res = ((VM*)vm)->exec(source, "main.py", EXEC_MODE); - return res != nullptr; - } - - bool pkpy_vm_exec_2(void* vm_, const char* source, const char* filename, int mode, const char* module){ - VM* vm = (VM*)vm_; - PyObject* mod; - if(module == nullptr) mod = vm->_main; - else{ - mod = vm->_modules.try_get(module); - if(mod == nullptr) return false; - } - void* res = vm->exec(source, filename, (CompileMode)mode, mod); - return res != nullptr; - } - void pkpy_vm_compile(void* vm_, const char* source, const char* filename, int mode, bool* ok, char** res){ VM* vm = (VM*)vm_; try{ @@ -590,19 +566,6 @@ bool pkpy_eval(pkpy_vm* vm_handle, const char* code) { return ((REPL*)r)->input(line); } - void pkpy_vm_add_module(void* vm, const char* name, const char* source){ - ((VM*)vm)->_lazy_modules[name] = source; - } - - void* pkpy_new_vm(bool enable_os){ - void* p = new VM(enable_os); - return p; - } - - void pkpy_delete_vm(void* vm){ - delete (VM*)vm; - } - void pkpy_delete_repl(void* repl){ delete (REPL*)repl; } \ No newline at end of file