1
0
forked from Mirror/wren

Add userData pointer to reallocateFn (#788)

* Add userData ptr to all reallocateFn calls
* Check that userData is correctly passed
* Update AUTHORS
This commit is contained in:
Kolja Kube
2020-12-03 20:46:22 +01:00
committed by GitHub
parent a11d66cbd3
commit 84b29e6995
6 changed files with 29 additions and 9 deletions

View File

@ -26,4 +26,6 @@ Charlotte Koch <cfkoch@edgebsd.org>
Michel Hermier <michel.hermier@gmail.com>
Taylor Hoff <primdevs@gmail.com>
ruby0x1 <ruby0x1@pm.me>
Kolja Kube <code@koljaku.be>
Alexander Klingenbeck <alexander.klingenbeck@gmx.de>

View File

@ -182,7 +182,7 @@ These fields control how the VM allocates and manages memory.
This lets you provide a custom memory allocation function. Its signature is:
<pre class="snippet" data-lang="c">
void* reallocate(void* memory, size_t newSize)
void* reallocate(void* memory, size_t newSize, void* userData)
</pre>
Wren uses this one function to allocate, grow, shrink, and deallocate memory.

View File

@ -47,7 +47,7 @@ typedef struct WrenHandle WrenHandle;
//
// - To free memory, [memory] will be the memory to free and [newSize] will be
// zero. It should return NULL.
typedef void* (*WrenReallocateFn)(void* memory, size_t newSize);
typedef void* (*WrenReallocateFn)(void* memory, size_t newSize, void* userData);
// A function callable from Wren code, but implemented in C.
typedef void (*WrenForeignMethodFn)(WrenVM* vm);

View File

@ -975,7 +975,8 @@ void wrenGrayObj(WrenVM* vm, Obj* obj)
{
vm->grayCapacity = vm->grayCount * 2;
vm->gray = (Obj**)vm->config.reallocateFn(vm->gray,
vm->grayCapacity * sizeof(Obj*));
vm->grayCapacity * sizeof(Obj*),
vm->config.userData);
}
vm->gray[vm->grayCount++] = obj;

View File

@ -25,7 +25,7 @@
// may return a non-NULL pointer which must not be dereferenced but nevertheless
// should be freed. To prevent that, we avoid calling realloc() with a zero
// size.
static void* defaultReallocate(void* ptr, size_t newSize)
static void* defaultReallocate(void* ptr, size_t newSize, void* _)
{
if (newSize == 0)
{
@ -54,9 +54,13 @@ void wrenInitConfiguration(WrenConfiguration* config)
WrenVM* wrenNewVM(WrenConfiguration* config)
{
WrenReallocateFn reallocate = defaultReallocate;
if (config != NULL) reallocate = config->reallocateFn;
void* userData = NULL;
if (config != NULL) {
reallocate = config->reallocateFn;
userData = config->userData;
}
WrenVM* vm = (WrenVM*)reallocate(NULL, sizeof(*vm));
WrenVM* vm = (WrenVM*)reallocate(NULL, sizeof(*vm), userData);
memset(vm, 0, sizeof(WrenVM));
// Copy the configuration if given one.
@ -73,7 +77,7 @@ WrenVM* wrenNewVM(WrenConfiguration* config)
vm->grayCount = 0;
// TODO: Tune this.
vm->grayCapacity = 4;
vm->gray = (Obj**)reallocate(NULL, vm->grayCapacity * sizeof(Obj*));
vm->gray = (Obj**)reallocate(NULL, vm->grayCapacity * sizeof(Obj*), userData);
vm->nextGC = vm->config.initialHeapSize;
wrenSymbolTableInit(&vm->methodNames);
@ -97,7 +101,7 @@ void wrenFreeVM(WrenVM* vm)
}
// Free up the GC gray set.
vm->gray = (Obj**)vm->config.reallocateFn(vm->gray, 0);
vm->gray = (Obj**)vm->config.reallocateFn(vm->gray, 0, vm->config.userData);
// Tell the user if they didn't free any handles. We don't want to just free
// them here because the host app may still have pointers to them that they
@ -220,7 +224,7 @@ void* wrenReallocate(WrenVM* vm, void* memory, size_t oldSize, size_t newSize)
if (newSize > 0 && vm->bytesAllocated > vm->nextGC) wrenCollectGarbage(vm);
#endif
return vm->config.reallocateFn(memory, newSize);
return vm->config.reallocateFn(memory, newSize, vm->config.userData);
}
// Captures the local variable [local] into an [Upvalue]. If that local is

View File

@ -5,6 +5,18 @@
static const char* data = "my user data";
static const char* otherData = "other user data";
void* testReallocateFn(void* ptr, size_t newSize, void* userData) {
if (strcmp(userData, data) != 0) return NULL;
if (newSize == 0)
{
free(ptr);
return NULL;
}
return realloc(ptr, newSize);
}
static void test(WrenVM* vm)
{
WrenConfiguration configuration;
@ -17,6 +29,7 @@ static void test(WrenVM* vm)
return;
}
configuration.reallocateFn = testReallocateFn;
configuration.userData = (void*)data;
WrenVM* otherVM = wrenNewVM(&configuration);