From e9ee4eb147bafa31a038392d7c67dc1472846936 Mon Sep 17 00:00:00 2001 From: Bob Nystrom Date: Wed, 5 Feb 2014 06:30:20 -0800 Subject: [PATCH] Add FFI support for returning strings and null. --- include/wren.h | 15 +++++++++++++++ src/wren_vm.c | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/wren.h b/include/wren.h index 9aa378d2..f930881d 100644 --- a/include/wren.h +++ b/include/wren.h @@ -130,4 +130,19 @@ const char* wrenGetArgumentString(WrenVM* vm, int index); // foreign call is done, and no more arguments can be read or return calls made. void wrenReturnDouble(WrenVM* vm, double value); +// Provides a null return value for a foreign call. This must only be called +// within a function provided to [wrenDefineMethod]. Once this is called, the +// foreign call is done, and no more arguments can be read or return calls made. +void wrenReturnNull(WrenVM* vm); + +// Provides a string return value for a foreign call. This must only be called +// within a function provided to [wrenDefineMethod]. Once this is called, the +// foreign call is done, and no more arguments can be read or return calls made. +// +// The [text] will be copied to a new string within Wren's heap, so you can +// free memory used by it after this is called. If [length] is non-zero, Wren +// will copy that many bytes from [text]. If it is -1, then the length of +// [text] will be calculated using `strlen()`. +void wrenReturnString(WrenVM* vm, const char* text, int length); + #endif diff --git a/src/wren_vm.c b/src/wren_vm.c index 3b7950cd..716a46b3 100644 --- a/src/wren_vm.c +++ b/src/wren_vm.c @@ -1166,3 +1166,22 @@ void wrenReturnDouble(WrenVM* vm, double value) *vm->foreignCallSlot = NUM_VAL(value); vm->foreignCallSlot = NULL; } + +void wrenReturnNull(WrenVM* vm) +{ + ASSERT(vm->foreignCallSlot != NULL, "Must be in foreign call."); + + *vm->foreignCallSlot = NULL_VAL; + vm->foreignCallSlot = NULL; +} + +void wrenReturnString(WrenVM* vm, const char* text, int length) +{ + ASSERT(vm->foreignCallSlot != NULL, "Must be in foreign call."); + + size_t size = length; + if (length == -1) size = strlen(text); + + *vm->foreignCallSlot = wrenNewString(vm, text, size); + vm->foreignCallSlot = NULL; +}