From d432b03d621be0bd8d322321e80318084a9e0041 Mon Sep 17 00:00:00 2001 From: underscorediscovery Date: Fri, 10 Jul 2020 20:00:17 -0700 Subject: [PATCH] fix many module imports causing GC to pull the rug on our module instance --- src/vm/wren_vm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/vm/wren_vm.c b/src/vm/wren_vm.c index 163b1ae7..dbd111f7 100644 --- a/src/vm/wren_vm.c +++ b/src/vm/wren_vm.c @@ -446,10 +446,21 @@ static ObjClosure* compileInModule(WrenVM* vm, Value name, const char* source, { module = wrenNewModule(vm, AS_STRING(name)); + // It's possible for the map set call below to resize the modules map, + // and trigger a GC while doing so. When this happens and there are enough + // objects and modules, it will collect the module we've just created. + // wrenPushRoot isn't an option when there are enough modules to exhaust + // WREN_MAX_TEMP_ROOTS, however handles are also not collected by GC. + // Note that this only affects the module until it's in the map, because + // then it has a reference to it, and won't be collected. + WrenHandle* moduleHandle = wrenMakeHandle(vm, OBJ_VAL(module)); + // Store it in the VM's module registry so we don't load the same module // multiple times. wrenMapSet(vm, vm->modules, name, OBJ_VAL(module)); + wrenReleaseHandle(vm, moduleHandle); + // Implicitly import the core module. ObjModule* coreModule = getModule(vm, NULL_VAL); for (int i = 0; i < coreModule->variables.count; i++)