From ae0afe6198a6b9dc3787d8a6ecc9ab05ecb2b6d6 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Tue, 27 Jan 2026 13:28:52 -0600 Subject: [PATCH] Add janet_decref_abstract_maybe_free --- Makefile | 1 - src/core/abstract.c | 13 +++++++++++++ src/core/filewatch.c | 8 ++++---- src/core/gc.c | 16 ++-------------- src/include/janet.h | 3 +++ 5 files changed, 22 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index b60c2c90..8e2523b3 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,6 @@ LDFLAGS?=-rdynamic LIBJANET_LDFLAGS?=$(LDFLAGS) RUN:=$(RUN) - COMMON_CFLAGS:=-std=c99 -Wall -Wextra -Isrc/include -Isrc/conf -fvisibility=hidden -fPIC BOOT_CFLAGS:=-DJANET_BOOTSTRAP -DJANET_BUILD=$(JANET_BUILD) -O0 $(COMMON_CFLAGS) -g BUILD_CFLAGS:=$(CFLAGS) $(COMMON_CFLAGS) diff --git a/src/core/abstract.c b/src/core/abstract.c index 94d69b98..cbda2296 100644 --- a/src/core/abstract.c +++ b/src/core/abstract.c @@ -201,4 +201,17 @@ int32_t janet_abstract_decref(void *abst) { return janet_atomic_dec(&janet_abstract_head(abst)->gc.data.refcount); } +int32_t janet_abstract_decref_maybe_free(void *abst) { + int32_t result = janet_abstract_decref(abst); + if (0 == result) { + JanetAbstractHead *head = janet_abstract_head(abst); + if (head->type->gc) { + janet_assert(!head->type->gc(head->data, head->size), "finalizer failed"); + } + /* Free memory */ + janet_free(head); + } + return result; +} + #endif diff --git a/src/core/filewatch.c b/src/core/filewatch.c index 91d24801..8023271c 100644 --- a/src/core/filewatch.c +++ b/src/core/filewatch.c @@ -521,23 +521,23 @@ static void janet_watcher_add(JanetWatcher *watcher, const char *path, uint32_t (void) watcher; (void) flags; (void) path; - janet_panic("nyi"); + janet_panic("filewatch not supported on this platform"); } static void janet_watcher_remove(JanetWatcher *watcher, const char *path) { (void) watcher; (void) path; - janet_panic("nyi"); + janet_panic("filewatch not supported on this platform"); } static void janet_watcher_listen(JanetWatcher *watcher) { (void) watcher; - janet_panic("nyi"); + janet_panic("filewatch not supported on this platform"); } static void janet_watcher_unlisten(JanetWatcher *watcher) { (void) watcher; - janet_panic("nyi"); + janet_panic("filewatch not supported on this platform"); } #endif diff --git a/src/core/gc.c b/src/core/gc.c index 532a9cc6..82d68780 100644 --- a/src/core/gc.c +++ b/src/core/gc.c @@ -504,14 +504,7 @@ void janet_sweep() { if (head->type->gcperthread) { janet_assert(!head->type->gcperthread(head->data, head->size), "per-thread finalizer failed"); } - if (0 == janet_abstract_decref(abst)) { - /* Run finalizer */ - if (head->type->gc) { - janet_assert(!head->type->gc(head->data, head->size), "finalizer failed"); - } - /* Free memory */ - janet_free(janet_abstract_head(abst)); - } + janet_abstract_decref_maybe_free(abst); /* Mark as tombstone in place */ items[i].key = janet_wrap_nil(); @@ -682,12 +675,7 @@ void janet_clear_memory(void) { if (head->type->gcperthread) { janet_assert(!head->type->gcperthread(head->data, head->size), "per-thread finalizer failed"); } - if (0 == janet_abstract_decref(abst)) { - if (head->type->gc) { - janet_assert(!head->type->gc(head->data, head->size), "finalizer failed"); - } - janet_free(janet_abstract_head(abst)); - } + janet_abstract_decref_maybe_free(abst); } } #endif diff --git a/src/include/janet.h b/src/include/janet.h index 248998d9..10d38dd0 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1482,6 +1482,9 @@ JANET_API void *janet_abstract_threaded(const JanetAbstractType *atype, size_t s JANET_API int32_t janet_abstract_incref(void *abst); JANET_API int32_t janet_abstract_decref(void *abst); +/* If this returns 0, *abst will be deinitialized and freed */ +JANET_API int32_t janet_abstract_decref_maybe_free(void *abst); + /* Expose channel utilities */ JANET_API JanetChannel *janet_channel_make(uint32_t limit); JANET_API JanetChannel *janet_channel_make_threaded(uint32_t limit);