Explorar o código

added operations for working with void* as well as a way to check
if a global exists

Kolten Pearson %!s(int64=2) %!d(string=hai) anos
pai
achega
d1f9aab008
Modificáronse 6 ficheiros con 90 adicións e 10 borrados
  1. 42 0
      c_bindings/pocketpy_c.cpp
  2. 7 0
      c_bindings/pocketpy_c.h
  3. 34 7
      c_bindings/test.c
  4. 5 1
      c_bindings/test_answers.txt
  5. 1 1
      run_c_binding_test.sh
  6. 1 1
      src/cffi.h

+ 42 - 0
c_bindings/pocketpy_c.cpp

@@ -236,6 +236,14 @@ bool pkpy_push_stringn(struct pkpy_vm_wrapper* w, const char* value, int length)
     ERRHANDLER_CLOSE
 }
 
+bool pkpy_push_voidp(struct pkpy_vm_wrapper* w, void* value) {
+    ERRHANDLER_OPEN
+    w->c_data->push(py_var(w->vm, value));
+
+    return true;
+    ERRHANDLER_CLOSE
+}
+
 bool pkpy_push_none(struct pkpy_vm_wrapper* w) {
     ERRHANDLER_OPEN
     w->c_data->push(w->vm->None);
@@ -369,6 +377,19 @@ bool pkpy_to_bool(struct pkpy_vm_wrapper* w, int index, bool* ret) {
     ERRHANDLER_CLOSE
 }
 
+bool pkpy_to_voidp(pkpy_vm_wrapper* w, int index, void** ret) {
+    ERRHANDLER_OPEN
+
+    index = lua_to_cstack_index(index, w->c_data->size());
+
+    PyObject* o = w->c_data->begin()[index];
+    if (ret != nullptr) 
+        *ret = py_cast<void*>(w->vm, o);
+
+    return true;
+    ERRHANDLER_CLOSE
+}
+
 bool pkpy_to_string(struct pkpy_vm_wrapper* w, int index, char** ret) {
     ERRHANDLER_OPEN
 
@@ -408,6 +429,13 @@ bool pkpy_is_string(struct pkpy_vm_wrapper* w, int index) {
 
     return is_type(o, w->vm->tp_str);
 }
+bool pkpy_is_voidp(struct pkpy_vm_wrapper* w, int index) {
+    index = lua_to_cstack_index(index, w->c_data->size());
+    PyObject* o = w->c_data->begin()[index];
+
+    return is_type(o, VoidP::_type(w->vm));
+}
+
 bool pkpy_is_none(struct pkpy_vm_wrapper* w, int index) {
     index = lua_to_cstack_index(index, w->c_data->size());
     PyObject* o = w->c_data->begin()[index];
@@ -415,6 +443,20 @@ bool pkpy_is_none(struct pkpy_vm_wrapper* w, int index) {
     return o == w->vm->None;
 }
 
+bool pkpy_check_global(pkpy_vm_wrapper* w, const char* name) {
+    SAFEGUARD_OPEN
+    PyObject* o = w->vm->_main->attr().try_get(name);
+    if (o == nullptr) {
+        o = w->vm->builtins->attr().try_get(name);
+        if (o == nullptr)
+            return false;
+    }
+    return true;
+
+    SAFEGUARD_CLOSE
+}
+
+
 bool pkpy_check_stack(struct pkpy_vm_wrapper* w, int free) {
     return free + w->c_data->size() <= PKPY_STACK_SIZE;
 }

+ 7 - 0
c_bindings/pocketpy_c.h

@@ -36,6 +36,7 @@ bool pkpy_push_float(pkpy_vm*, double);
 bool pkpy_push_bool(pkpy_vm*, bool);
 bool pkpy_push_string(pkpy_vm*, const char*);
 bool pkpy_push_stringn(pkpy_vm*, const char*, int length);
+bool pkpy_push_voidp(pkpy_vm*, void*);
 bool pkpy_push_none(pkpy_vm*);
 
 bool pkpy_set_global(pkpy_vm*, const char* name);
@@ -60,6 +61,7 @@ bool pkpy_call_method(pkpy_vm*, const char* name, int argc);
 bool pkpy_to_int(pkpy_vm*, int index, int* ret);
 bool pkpy_to_float(pkpy_vm*, int index, double* ret);
 bool pkpy_to_bool(pkpy_vm*, int index, bool* ret);
+bool pkpy_to_voidp(pkpy_vm*, int index, void** ret);
 bool pkpy_to_string(pkpy_vm*, int index, char** ret);
 //the ret string pointer is only valid until the next api call, so copy it if you want it
 
@@ -70,8 +72,13 @@ bool pkpy_is_int(pkpy_vm*, int index);
 bool pkpy_is_float(pkpy_vm*, int index);
 bool pkpy_is_bool(pkpy_vm*, int index);
 bool pkpy_is_string(pkpy_vm*, int index);
+bool pkpy_is_voidp(pkpy_vm*, int index);
 bool pkpy_is_none(pkpy_vm*, int index);
 
+
+//will return true if global exists
+bool pkpy_check_global(pkpy_vm*, const char* name);
+
 //will return true if at least free empty slots remain on the stack
 bool pkpy_check_stack(pkpy_vm*, int free);
 

+ 34 - 7
c_bindings/test.c

@@ -101,6 +101,7 @@ int main(int argc, char** argv) {
     fail(pkpy_is_bool(vm, -1));
     fail(pkpy_is_string(vm, -1));
     fail(pkpy_is_none(vm, -1));
+    fail(pkpy_is_voidp(vm, -1));
 
     printf("\ntesting float methods\n");
     double r_float;
@@ -115,6 +116,7 @@ int main(int argc, char** argv) {
     fail(pkpy_is_bool(vm, -1));
     fail(pkpy_is_string(vm, -1));
     fail(pkpy_is_none(vm, -1));
+    fail(pkpy_is_voidp(vm, -1));
 
     printf("\ntesting bool methods\n");
     bool r_bool;
@@ -129,6 +131,7 @@ int main(int argc, char** argv) {
     fail(pkpy_is_float(vm, -1));
     fail(pkpy_is_string(vm, -1));
     fail(pkpy_is_none(vm, -1));
+    fail(pkpy_is_voidp(vm, -1));
 
     printf("\ntesting string methods\n");
     char* r_string;
@@ -143,6 +146,7 @@ int main(int argc, char** argv) {
     fail(pkpy_is_float(vm, -1));
     fail(pkpy_is_bool(vm, -1));
     fail(pkpy_is_none(vm, -1));
+    fail(pkpy_is_voidp(vm, -1));
 
     printf("\ntesting None methods\n");
     check(pkpy_push_none(vm));
@@ -154,23 +158,43 @@ int main(int argc, char** argv) {
     fail(pkpy_is_float(vm, -1));
     fail(pkpy_is_bool(vm, -1));
     fail(pkpy_is_string(vm, -1));
+    fail(pkpy_is_voidp(vm, -1));
+
+    printf("\ntesting voidp methods\n");
+    void* vp = (void*) 123;
+    check(pkpy_push_voidp(vm, vp));
+    check(pkpy_set_global(vm, "vp"));
+    check(pkpy_vm_run(vm, "print(vp)"));
+    check(pkpy_get_global(vm, "vp"));
+    check(pkpy_is_voidp(vm, -1));
+    vp = NULL;
+    check(pkpy_to_voidp(vm, -1, &vp));
+    printf("%i\n", (int) (intptr_t) vp);
+    fail(pkpy_is_int(vm, -1));
+    fail(pkpy_is_float(vm, -1));
+    fail(pkpy_is_bool(vm, -1));
+    fail(pkpy_is_string(vm, -1));
+    fail(pkpy_is_none(vm, -1));
+
 
     printf("\ntesting sizing and indexing\n");
     int stack_size = pkpy_stack_size(vm);
     printf("stack size %i\n", stack_size);
     check(pkpy_check_stack(vm, 10));
-    check(pkpy_check_stack(vm, 27));
-    fail(pkpy_check_stack(vm, 28));
+    check(pkpy_check_stack(vm, 26));
+    fail(pkpy_check_stack(vm, 27));
     check(pkpy_is_int(vm, 0));
     check(pkpy_is_float(vm, 1));
     check(pkpy_is_bool(vm, 2));
     check(pkpy_is_string(vm, 3));
     check(pkpy_is_none(vm, 4));
-    check(pkpy_is_int(vm, -5));
-    check(pkpy_is_float(vm, -4));
-    check(pkpy_is_bool(vm, -3));
-    check(pkpy_is_string(vm, -2));
-    check(pkpy_is_none(vm, -1));
+    check(pkpy_is_voidp(vm, 5));
+    check(pkpy_is_int(vm, -6));
+    check(pkpy_is_float(vm, -5));
+    check(pkpy_is_bool(vm, -4));
+    check(pkpy_is_string(vm, -3));
+    check(pkpy_is_none(vm, -2));
+    check(pkpy_is_voidp(vm, -1));
     
     printf("\ntesting error catching\n");
     error(pkpy_vm_run(vm, "let's make sure syntax errors get caught"));
@@ -259,5 +283,8 @@ int main(int argc, char** argv) {
     check(pkpy_pop(vm, 2));
     check(pkpy_stack_size(vm) == 0);
 
+    check(pkpy_check_global(vm, "test_error_propagate"));
+    fail(pkpy_check_global(vm, "nonexistant"));
+
     return 0;
 }

+ 5 - 1
c_bindings/test_answers.txt

@@ -22,8 +22,12 @@ hello
 testing None methods
 None
 
+testing voidp methods
+<void* at 0x7b>
+123
+
 testing sizing and indexing
-stack size 5
+stack size 6
 
 testing error catching
 successfully errored with this message: 

+ 1 - 1
run_c_binding_test.sh

@@ -18,7 +18,7 @@ echo "checking results (they should be identical)"
 diff -q -s  binding_test_scratch c_bindings/test_answers.txt
 
 echo "cleaning up"
-rm pocketpy_c.o
+#rm pocketpy_c.o
 rm test.o
 rm binding_test_scratch
 

+ 1 - 1
src/cffi.h

@@ -81,4 +81,4 @@ T py_pointer_cast(VM* vm, PyObject* var){
     VoidP& p = CAST(VoidP&, var);
     return reinterpret_cast<T>(p.ptr);
 }
-}   // namespace pkpy
+}   // namespace pkpy