From d1f9aab008870061be408dcef7ac0ef90be470b0 Mon Sep 17 00:00:00 2001 From: Kolten Pearson Date: Tue, 2 May 2023 00:35:22 -0600 Subject: [PATCH] added operations for working with void* as well as a way to check if a global exists --- c_bindings/pocketpy_c.cpp | 42 +++++++++++++++++++++++++++++++++++++ c_bindings/pocketpy_c.h | 7 +++++++ c_bindings/test.c | 41 +++++++++++++++++++++++++++++------- c_bindings/test_answers.txt | 6 +++++- run_c_binding_test.sh | 2 +- src/cffi.h | 2 +- 6 files changed, 90 insertions(+), 10 deletions(-) diff --git a/c_bindings/pocketpy_c.cpp b/c_bindings/pocketpy_c.cpp index 77baf496..6bdbe9c6 100644 --- a/c_bindings/pocketpy_c.cpp +++ b/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(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; } diff --git a/c_bindings/pocketpy_c.h b/c_bindings/pocketpy_c.h index 09c9660a..42a75c15 100644 --- a/c_bindings/pocketpy_c.h +++ b/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); diff --git a/c_bindings/test.c b/c_bindings/test.c index 75bcf694..4d237011 100644 --- a/c_bindings/test.c +++ b/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; } diff --git a/c_bindings/test_answers.txt b/c_bindings/test_answers.txt index ecce1763..7a6c586e 100644 --- a/c_bindings/test_answers.txt +++ b/c_bindings/test_answers.txt @@ -22,8 +22,12 @@ hello testing None methods None +testing voidp methods + +123 + testing sizing and indexing -stack size 5 +stack size 6 testing error catching successfully errored with this message: diff --git a/run_c_binding_test.sh b/run_c_binding_test.sh index c98603d8..33018288 100644 --- a/run_c_binding_test.sh +++ b/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 diff --git a/src/cffi.h b/src/cffi.h index 6f97688b..fbcc48aa 100644 --- a/src/cffi.h +++ b/src/cffi.h @@ -81,4 +81,4 @@ T py_pointer_cast(VM* vm, PyObject* var){ VoidP& p = CAST(VoidP&, var); return reinterpret_cast(p.ptr); } -} // namespace pkpy \ No newline at end of file +} // namespace pkpy