mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
basic functionality is working much more smoothly thanks to LuaStyleFuncC
also added the code for handling python exceptions
This commit is contained in:
parent
aea01c5aca
commit
8244a8a1a4
@ -4,8 +4,9 @@
|
|||||||
//tests the c bindings for pocketpy
|
//tests the c bindings for pocketpy
|
||||||
|
|
||||||
|
|
||||||
void test_binding(pkpy_vm vm) {
|
int test_binding(pkpy_vm vm) {
|
||||||
pkpy_push_int(vm, 12);
|
pkpy_push_int(vm, 12);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
@ -17,11 +18,11 @@ int main(int argc, char** argv) {
|
|||||||
pkpy_push_int(vm, 11);
|
pkpy_push_int(vm, 11);
|
||||||
pkpy_set_global(vm, "eleven");
|
pkpy_set_global(vm, "eleven");
|
||||||
|
|
||||||
//pkpy_push_cfunction(vm, test_binding);
|
pkpy_push_function(vm, test_binding);
|
||||||
//pkpy_set_global(vm, "binding");
|
pkpy_set_global(vm, "binding");
|
||||||
|
|
||||||
pkpy_vm_exec(vm, "print(eleven)");
|
pkpy_vm_exec(vm, "print(eleven)");
|
||||||
//pkpy_vm_exec(vm, "print(binding())");
|
pkpy_vm_exec(vm, "print(binding())");
|
||||||
|
|
||||||
pkpy_vm_exec(vm, "def x(x) : return x + 1");
|
pkpy_vm_exec(vm, "def x(x) : return x + 1");
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
int r;
|
int r;
|
||||||
pkpy_to_int(vm, -1, &r);
|
pkpy_to_int(vm, -1, &r);
|
||||||
printf("%li\n", r);
|
printf("%i\n", r);
|
||||||
|
|
||||||
pkpy_clear_error(vm, NULL);
|
pkpy_clear_error(vm, NULL);
|
||||||
|
|
||||||
|
@ -69,8 +69,42 @@ void pkpy_vm_destroy(pkpy_vm vm_handle) {
|
|||||||
delete vm;
|
delete vm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject* c_function_wrapper(VM* vm, ArgsView args) {
|
||||||
|
LuaStyleFuncC f = CAST(NativeFunc&, args[-2])._lua_f;
|
||||||
|
|
||||||
|
//setup c stack
|
||||||
|
int stored = vm->c_data.store();
|
||||||
|
|
||||||
|
for (int i = 0; i < args.size(); i++)
|
||||||
|
vm->c_data.push(args[i]);
|
||||||
|
|
||||||
|
int retc = f(vm);
|
||||||
|
|
||||||
|
PyObject* ret = vm->None;
|
||||||
|
|
||||||
|
//TODO handle tuple packing for multiple returns
|
||||||
|
if (retc > 0)
|
||||||
|
ret = vm->c_data.top();
|
||||||
|
|
||||||
|
vm->c_data.clear();
|
||||||
|
vm->c_data.restore(stored);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool pkpy_push_function(pkpy_vm vm_handle, pkpy_function f) {
|
bool pkpy_push_function(pkpy_vm vm_handle, pkpy_function f) {
|
||||||
|
VM* vm = (VM*) vm_handle;
|
||||||
|
ERRHANDLER_OPEN
|
||||||
|
|
||||||
|
//TODO right now we just treat all c bound functions a varargs functions
|
||||||
|
//do we want to change that?
|
||||||
|
NativeFunc nf = NativeFunc(c_function_wrapper, -1, 0);
|
||||||
|
nf._lua_f = (LuaStyleFuncC) f;
|
||||||
|
|
||||||
|
vm->c_data.push(VAR(nf));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
ERRHANDLER_CLOSE
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pkpy_push_int(pkpy_vm vm_handle, int value) {
|
bool pkpy_push_int(pkpy_vm vm_handle, int value) {
|
||||||
|
@ -11,18 +11,17 @@ extern "C" {
|
|||||||
typedef struct pkpy_vm_handle* pkpy_vm;
|
typedef struct pkpy_vm_handle* pkpy_vm;
|
||||||
|
|
||||||
//we mostly follow the lua api for these bindings
|
//we mostly follow the lua api for these bindings
|
||||||
//the key difference being each method returns a bool, true if it succeeded
|
//the key difference being most methods return a bool, true if it succeeded
|
||||||
//false if it did not
|
//false if it did not
|
||||||
|
|
||||||
//if a method returns false call this next method to check the error and clear it
|
//if a method returns false call this next method to check the error and clear it
|
||||||
//if this method returns false it means that no error was set, and no action is taken
|
//if this method returns false it means that no error was set, and no action is taken
|
||||||
//if it returns true it means there was an error and it was cleared, it will provide a string summary of the error in the message parameter (if it is not NULL)
|
//if it returns true it means there was an error and it was cleared, it will provide a string summary of the error in the message parameter (if it is not NULL)
|
||||||
//NOTE : you need to free the message that is passed back after you are done using it
|
//NOTE : you need to free the message that is passed back after you are done using it
|
||||||
//or else pass in null
|
//or else pass in null as message, and it will just print the message to stderr
|
||||||
bool pkpy_clear_error(pkpy_vm, const char** message);
|
bool pkpy_clear_error(pkpy_vm, const char** message);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pkpy_vm pkpy_vm_create(bool use_stdio, bool enable_os);
|
pkpy_vm pkpy_vm_create(bool use_stdio, bool enable_os);
|
||||||
bool pkpy_vm_exec(pkpy_vm vm_handle, const char* source);
|
bool pkpy_vm_exec(pkpy_vm vm_handle, const char* source);
|
||||||
void pkpy_vm_destroy(pkpy_vm vm);
|
void pkpy_vm_destroy(pkpy_vm vm);
|
||||||
@ -39,27 +38,23 @@ bool pkpy_get_global(pkpy_vm vm_handle, const char* name);
|
|||||||
|
|
||||||
//first push callable you want to call
|
//first push callable you want to call
|
||||||
//then push the arguments to send
|
//then push the arguments to send
|
||||||
//argc is the number of arguments
|
//argc is the number of arguments that was pushed (not counting the callable)
|
||||||
bool pkpy_call(pkpy_vm vm_handle, int argc);
|
bool pkpy_call(pkpy_vm vm_handle, int argc);
|
||||||
|
|
||||||
//first push the object the method belongs to (self)
|
//first push the object the method belongs to (self)
|
||||||
//then push the callable you want to call
|
//then push the callable you want to call
|
||||||
//then push the the argments
|
//then push the the argments
|
||||||
//argc is the number of arguments that was pushed
|
//argc is the number of arguments that was pushed (not counting the callable or self)
|
||||||
bool pkpy_call_method(pkpy_vm vm_handle, int argc);
|
bool pkpy_call_method(pkpy_vm vm_handle, int argc);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//we will break with the lua api here
|
//we will break with the lua api here
|
||||||
//lua uses 1 as the index to the first pushed element for all of these functions
|
//lua uses 1 as the index to the first pushed element for all of these functions
|
||||||
//but we will start counting at zero to match python
|
//but we will start counting at zero to match python
|
||||||
//we will allow negative numbers to count backwards from the top
|
//we will allow negative numbers to count backwards from the top
|
||||||
|
|
||||||
bool pkpy_to_int(pkpy_vm vm_handle, int index, int* ret);
|
bool pkpy_to_int(pkpy_vm vm_handle, int index, int* ret);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
16
src/frame.h
16
src/frame.h
@ -103,20 +103,24 @@ struct CVirtualStack {
|
|||||||
static const size_t MAX_SIZE = 256;
|
static const size_t MAX_SIZE = 256;
|
||||||
PyObject* _begin[MAX_SIZE];
|
PyObject* _begin[MAX_SIZE];
|
||||||
PyObject** _sp;
|
PyObject** _sp;
|
||||||
|
size_t offset;
|
||||||
|
|
||||||
CVirtualStack(): _sp(_begin) {}
|
CVirtualStack(): _sp(_begin), offset(0) {}
|
||||||
|
|
||||||
PyObject* top() const { return _sp[-1]; }
|
PyObject* top() const { return _sp[-1]; }
|
||||||
PyObject* get(int index) const { return _begin[index]; }
|
PyObject* get(int index) const { return _begin[offset + index]; }
|
||||||
void push(PyObject* v){ *_sp++ = v; }
|
void push(PyObject* v){ *_sp++ = v; }
|
||||||
void pop(){ --_sp; }
|
void pop(){ --_sp; }
|
||||||
void shrink(int n){ _sp -= n; }
|
void shrink(int n){ _sp -= n; }
|
||||||
int size() const { return _sp - _begin; }
|
int size() const { return (_sp - _begin) - offset; }
|
||||||
bool empty() const { return _sp == _begin; }
|
bool empty() const { return size() == 0; }
|
||||||
PyObject** begin() { return _begin; }
|
PyObject** begin() { return _begin + offset; }
|
||||||
PyObject** end() { return _sp; }
|
PyObject** end() { return _sp; }
|
||||||
void clear() { _sp = _begin; }
|
void clear() { _sp = _begin + offset;}
|
||||||
|
|
||||||
|
size_t store() { size_t ret = offset; offset = _sp - _begin; return ret; }
|
||||||
|
void restore(size_t stored) { offset = stored; }
|
||||||
|
|
||||||
CVirtualStack(const CVirtualStack&) = delete;
|
CVirtualStack(const CVirtualStack&) = delete;
|
||||||
CVirtualStack(CVirtualStack&&) = delete;
|
CVirtualStack(CVirtualStack&&) = delete;
|
||||||
CVirtualStack& operator=(const CVirtualStack&) = delete;
|
CVirtualStack& operator=(const CVirtualStack&) = delete;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user