diff --git a/c_bindings/main.c b/c_bindings/main.c index 65670880..d66759f8 100644 --- a/c_bindings/main.c +++ b/c_bindings/main.c @@ -4,8 +4,9 @@ //tests the c bindings for pocketpy -void test_binding(pkpy_vm vm) { +int test_binding(pkpy_vm vm) { pkpy_push_int(vm, 12); + return 1; } int main(int argc, char** argv) { @@ -17,11 +18,11 @@ int main(int argc, char** argv) { pkpy_push_int(vm, 11); pkpy_set_global(vm, "eleven"); - //pkpy_push_cfunction(vm, test_binding); - //pkpy_set_global(vm, "binding"); + pkpy_push_function(vm, test_binding); + pkpy_set_global(vm, "binding"); 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"); @@ -31,7 +32,7 @@ int main(int argc, char** argv) { int r; pkpy_to_int(vm, -1, &r); - printf("%li\n", r); + printf("%i\n", r); pkpy_clear_error(vm, NULL); diff --git a/c_bindings/pocketpy_c.cpp b/c_bindings/pocketpy_c.cpp index d890eaa5..8a01971a 100644 --- a/c_bindings/pocketpy_c.cpp +++ b/c_bindings/pocketpy_c.cpp @@ -69,8 +69,42 @@ void pkpy_vm_destroy(pkpy_vm vm_handle) { 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) { + 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; + ERRHANDLER_CLOSE } bool pkpy_push_int(pkpy_vm vm_handle, int value) { diff --git a/c_bindings/pocketpy_c.h b/c_bindings/pocketpy_c.h index e88d707e..786756a4 100644 --- a/c_bindings/pocketpy_c.h +++ b/c_bindings/pocketpy_c.h @@ -11,18 +11,17 @@ extern "C" { typedef struct pkpy_vm_handle* pkpy_vm; //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 //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 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 -//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); - pkpy_vm pkpy_vm_create(bool use_stdio, bool enable_os); bool pkpy_vm_exec(pkpy_vm vm_handle, const char* source); 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 //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); //first push the object the method belongs to (self) //then push the callable you want to call //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); - //we will break with the lua api here //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 //we will allow negative numbers to count backwards from the top - bool pkpy_to_int(pkpy_vm vm_handle, int index, int* ret); - - #ifdef __cplusplus } #endif diff --git a/src/frame.h b/src/frame.h index 0240a6ac..ee8c1789 100644 --- a/src/frame.h +++ b/src/frame.h @@ -103,20 +103,24 @@ struct CVirtualStack { static const size_t MAX_SIZE = 256; PyObject* _begin[MAX_SIZE]; PyObject** _sp; + size_t offset; - CVirtualStack(): _sp(_begin) {} + CVirtualStack(): _sp(_begin), offset(0) {} 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 pop(){ --_sp; } void shrink(int n){ _sp -= n; } - int size() const { return _sp - _begin; } - bool empty() const { return _sp == _begin; } - PyObject** begin() { return _begin; } + int size() const { return (_sp - _begin) - offset; } + bool empty() const { return size() == 0; } + PyObject** begin() { return _begin + offset; } 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(CVirtualStack&&) = delete; CVirtualStack& operator=(const CVirtualStack&) = delete;