mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-21 12:00:18 +00:00
...
This commit is contained in:
parent
90fa4b087f
commit
b950e75a0c
@ -11,6 +11,11 @@ extern "C" {
|
|||||||
#include "export.h"
|
#include "export.h"
|
||||||
|
|
||||||
typedef struct pkpy_vm_handle pkpy_vm;
|
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
|
//we we take a lot of inspiration from the lua api for these bindings
|
||||||
//the key difference being most methods return a bool,
|
//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
|
//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 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);
|
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_setattr(pkpy_vm*, const char* name);
|
||||||
PK_EXPORT bool pkpy_eval(pkpy_vm*, const char* source);
|
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 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_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 void* pkpy_new_repl(void* vm);
|
||||||
PK_EXPORT bool pkpy_repl_input(void* r, const char* line);
|
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);
|
PK_EXPORT void pkpy_delete_repl(void* repl);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -50,41 +50,31 @@ struct LuaStack: public ValueStackImpl<32>{
|
|||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CVM;
|
||||||
|
void gc_marker_ex(CVM* vm);
|
||||||
|
|
||||||
class CVM: public VM {
|
class CVM: public VM {
|
||||||
public:
|
public:
|
||||||
|
LuaStack c_data;
|
||||||
LuaStack* c_data;
|
|
||||||
PyObject* error;
|
PyObject* error;
|
||||||
|
|
||||||
CVM(bool enable_os=true) : VM(enable_os) {
|
CVM(bool use_stdio, bool enable_os) : VM(enable_os) {
|
||||||
c_data = new LuaStack();
|
c_data = new LuaStack();
|
||||||
error = nullptr;
|
error = nullptr;
|
||||||
|
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);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
~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;
|
|
||||||
}
|
|
||||||
|
|
||||||
~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
|
//for now I will unpack a tuple automatically, we may not want to handle
|
||||||
//it this way, not sure
|
//it this way, not sure
|
||||||
@ -126,38 +116,34 @@ bool pkpy_clear_error(pkpy_vm* vm_handle, char** message) {
|
|||||||
return true;
|
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) {
|
pkpy_vm* pkpy_vm_create(bool use_stdio, bool enable_os) {
|
||||||
CVM* vm = new CVM(enable_os);
|
CVM* vm = new CVM(use_stdio, 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);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return (pkpy_vm*) vm;
|
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;
|
CVM* vm = (CVM*) vm_handle;
|
||||||
PyObject* res;
|
PyObject* res;
|
||||||
ERRHANDLER_OPEN
|
ERRHANDLER_OPEN
|
||||||
CodeObject_ code = vm->compile(source, "<c-bound>", EXEC_MODE);
|
CodeObject_ code = vm->compile(source, "main.py", EXEC_MODE);
|
||||||
res = vm->_exec(code, vm->_main);
|
res = vm->_exec(code, vm->_main);
|
||||||
ERRHANDLER_CLOSE
|
ERRHANDLER_CLOSE
|
||||||
|
return res != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
//unpack_return(w, result);
|
bool pkpy_vm_exec_2(pkpy_vm* vm_handle, const char* source, const char* filename, int mode, const char* module){
|
||||||
//NOTE: it seems like vm->_exec should return whatever the last command it
|
CVM* vm = (CVM*) vm_handle;
|
||||||
//ran returned but instead it seems to pretty much always return None
|
PyObject* res;
|
||||||
//so I guess uncomment this line if that every changes
|
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;
|
return res != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,7 +483,6 @@ bool pkpy_push(pkpy_vm* vm_handle, int index) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool pkpy_error(pkpy_vm* vm_handle, const char* name, const char* message) {
|
bool pkpy_error(pkpy_vm* vm_handle, const char* name, const char* message) {
|
||||||
CVM* vm = (CVM*) vm_handle;
|
CVM* vm = (CVM*) vm_handle;
|
||||||
// already in error state
|
// already in error state
|
||||||
@ -541,29 +526,20 @@ bool pkpy_eval(pkpy_vm* vm_handle, const char* code) {
|
|||||||
return true;
|
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){
|
void pkpy_free(void* p){
|
||||||
free(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){
|
void pkpy_vm_compile(void* vm_, const char* source, const char* filename, int mode, bool* ok, char** res){
|
||||||
VM* vm = (VM*)vm_;
|
VM* vm = (VM*)vm_;
|
||||||
try{
|
try{
|
||||||
@ -590,19 +566,6 @@ bool pkpy_eval(pkpy_vm* vm_handle, const char* code) {
|
|||||||
return ((REPL*)r)->input(line);
|
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){
|
void pkpy_delete_repl(void* repl){
|
||||||
delete (REPL*)repl;
|
delete (REPL*)repl;
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user