diff --git a/c_bindings/pocketpy_c.cpp b/c_bindings/pocketpy_c.cpp index dc14c2c6..77baf496 100644 --- a/c_bindings/pocketpy_c.cpp +++ b/c_bindings/pocketpy_c.cpp @@ -36,6 +36,7 @@ using namespace pkpy; struct pkpy_vm_wrapper { VM* vm; ValueStackImpl* c_data; + char* string_ret; }; @@ -62,6 +63,13 @@ static void unpack_return(struct pkpy_vm_wrapper* w, PyObject* ret) { } +static char* manage_string(struct pkpy_vm_wrapper* w, char* s) { + if (w->string_ret != NULL) + free(w->string_ret); + w->string_ret = s; + return w->string_ret; +} + bool pkpy_clear_error(struct pkpy_vm_wrapper* w, char** message) { SAFEGUARD_OPEN @@ -72,7 +80,7 @@ bool pkpy_clear_error(struct pkpy_vm_wrapper* w, char** message) { w->c_data->pop(); Exception& e = py_cast(w->vm, w->c_data->top()); if (message != nullptr) - *message = e.summary().c_str_dup(); + *message = manage_string(w, e.summary().c_str_dup()); else std::cerr << "ERROR: " << e.summary() << "\n"; @@ -88,6 +96,7 @@ struct pkpy_vm_wrapper* pkpy_vm_create(bool use_stdio, bool enable_os) { struct pkpy_vm_wrapper* w = (struct pkpy_vm_wrapper*) malloc(sizeof(*w)); w->vm = new VM(use_stdio, enable_os); w->c_data = new ValueStackImpl(); + w->string_ret = NULL; return w; } @@ -110,6 +119,8 @@ bool pkpy_vm_run(struct pkpy_vm_wrapper* w, const char* source) { void pkpy_vm_destroy(struct pkpy_vm_wrapper* w) { delete w->vm; delete w->c_data; + if (w->string_ret != NULL) + free(w->string_ret); free(w); } @@ -366,7 +377,7 @@ bool pkpy_to_string(struct pkpy_vm_wrapper* w, int index, char** ret) { PyObject* o = w->c_data->begin()[index]; if (ret != nullptr) { Str& s = py_cast(w->vm, o); - *ret = s.c_str_dup(); + *ret = manage_string(w, s.c_str_dup()); } return true; diff --git a/c_bindings/pocketpy_c.h b/c_bindings/pocketpy_c.h index b1fda0fb..09c9660a 100644 --- a/c_bindings/pocketpy_c.h +++ b/c_bindings/pocketpy_c.h @@ -18,9 +18,9 @@ typedef struct pkpy_vm_wrapper pkpy_vm; //if pkpy_clear_error returns false it means that no error was set, and it takes no action //if pkpy_clear_error 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 as message, and it will just print the message to stderr +//if null is passed in as message, and it will just print the message to stderr bool pkpy_clear_error(pkpy_vm*, char** message); +//the message pointer is only valid until the next api call, so copy it if you want it pkpy_vm* pkpy_vm_create(bool use_stdio, bool enable_os); bool pkpy_vm_run(pkpy_vm*, const char* source); @@ -60,9 +60,8 @@ 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); -//you have to free ret after you are done using it 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 //these do not follow the same error semantics as above, their return values //just say whether the check succeeded or not, or else return the value asked for diff --git a/c_bindings/test.c b/c_bindings/test.c index a295e2ea..75bcf694 100644 --- a/c_bindings/test.c +++ b/c_bindings/test.c @@ -14,7 +14,6 @@ void check_impl(pkpy_vm* vm, bool result, int lineno) { } printf("%s\n", message); - free(message); exit(1); } } @@ -27,7 +26,6 @@ void fail_impl(pkpy_vm* vm, bool result, int lineno) { char* message; if (pkpy_clear_error(vm, &message)) { printf("actually errored!\n"); - free(message); exit(1); } } @@ -44,7 +42,6 @@ void error_impl(pkpy_vm* vm, bool result, int lineno) { else { printf("successfully errored with this message: \n"); printf("%s\n", message); - free(message); } } } @@ -146,7 +143,6 @@ int main(int argc, char** argv) { fail(pkpy_is_float(vm, -1)); fail(pkpy_is_bool(vm, -1)); fail(pkpy_is_none(vm, -1)); - free(r_string); printf("\ntesting None methods\n"); check(pkpy_push_none(vm)); diff --git a/src/gc.h b/src/gc.h index 07567b16..64e86064 100644 --- a/src/gc.h +++ b/src/gc.h @@ -116,4 +116,4 @@ inline void FuncDecl::_gc_mark() const{ for(int i=0; i