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++)