Просмотр исходного кода

basic functionality is working much more smoothly thanks to LuaStyleFuncC
also added the code for handling python exceptions

Kolten Pearson 2 лет назад
Родитель
Сommit
8244a8a1a4
4 измененных файлов с 54 добавлено и 20 удалено
  1. 6 5
      c_bindings/main.c
  2. 34 0
      c_bindings/pocketpy_c.cpp
  3. 4 9
      c_bindings/pocketpy_c.h
  4. 10 6
      src/frame.h

+ 6 - 5
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);
 

+ 34 - 0
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) {

+ 4 - 9
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

+ 10 - 6
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;