From 649977aae7e5922f992cd69eb84da0a2db368580 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Wed, 24 Dec 2025 12:45:29 -0500 Subject: Split out new()/gc logic from stdlib/util.h --- src/compile/functions.c | 13 +++++++------ src/stdlib/bigint.c | 29 +++++++++++++++++++++++++++++ src/stdlib/bigint.h | 28 ++-------------------------- src/stdlib/files.c | 3 ++- src/stdlib/lists.c | 2 +- src/stdlib/lists.h | 2 +- src/stdlib/paths.c | 1 + src/stdlib/stdlib.c | 7 ++++++- src/stdlib/text.c | 7 ++++--- src/stdlib/util.h | 11 +++++++---- src/util.h | 4 ++++ 11 files changed, 64 insertions(+), 43 deletions(-) diff --git a/src/compile/functions.c b/src/compile/functions.c index a1b0a28c..9b8ba096 100644 --- a/src/compile/functions.c +++ b/src/compile/functions.c @@ -10,9 +10,9 @@ #include "../stdlib/optionals.h" #include "../stdlib/tables.h" #include "../stdlib/text.h" -#include "../util.h" #include "../typecheck.h" #include "../types.h" +#include "../util.h" #include "compilation.h" public @@ -683,8 +683,9 @@ Text_t compile_lambda(env_t *env, ast_t *ast) { code = Texts(code, "void *_)"); userdata = Text("NULL"); } else { - userdata = Texts("new(", name, "$userdata_t"); + userdata = Texts("heap(((", name, "$userdata_t){"); for (int64_t i = 0; i < (int64_t)closed_vars.entries.length; i++) { + if (i > 0) userdata = Text$concat(userdata, Text(", ")); struct { const char *name; binding_t *b; @@ -693,11 +694,11 @@ Text_t compile_lambda(env_t *env, ast_t *ast) { binding_t *b = get_binding(env, entry->name); assert(b); Text_t binding_code = b->code; - if (entry->b->type->tag == ListType) userdata = Texts(userdata, ", LIST_COPY(", binding_code, ")"); - else if (entry->b->type->tag == TableType) userdata = Texts(userdata, ", TABLE_COPY(", binding_code, ")"); - else userdata = Texts(userdata, ", ", binding_code); + if (entry->b->type->tag == ListType) userdata = Texts(userdata, "LIST_COPY(", binding_code, ")"); + else if (entry->b->type->tag == TableType) userdata = Texts(userdata, "TABLE_COPY(", binding_code, ")"); + else userdata = Texts(userdata, binding_code); } - userdata = Texts(userdata, ")"); + userdata = Texts(userdata, "}))"); code = Texts(code, name, "$userdata_t *userdata)"); } diff --git a/src/stdlib/bigint.c b/src/stdlib/bigint.c index 2d145bd5..84da1468 100644 --- a/src/stdlib/bigint.c +++ b/src/stdlib/bigint.c @@ -18,6 +18,35 @@ #include "text.h" #include "types.h" +#define Int$from_mpz(mpz) \ + (mpz_cmpabs_ui(mpz, BIGGEST_SMALL_INT) <= 0 \ + ? ((Int_t){.small = (mpz_get_si(mpz) << 2L) | 1L}) \ + : ((Int_t){.big = memcpy(GC_MALLOC(sizeof(__mpz_struct)), mpz, sizeof(__mpz_struct))})) + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif +public +PUREFUNC Int_t Int$from_num64(double n, bool truncate) { + mpz_t result; + mpz_init_set_d(result, n); + if (!truncate && unlikely(mpz_get_d(result) != n)) fail("Could not convert to an integer without truncation: ", n); + return Int$from_mpz(result); +} + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +public +PUREFUNC Int_t Int$from_int64(int64_t i) { + if likely (i >= SMALLEST_SMALL_INT && i <= BIGGEST_SMALL_INT) return (Int_t){.small = (i << 2L) | 1L}; + mpz_t result; + mpz_init_set_si(result, i); + return Int$from_mpz(result); +} + public int Int$print(FILE *f, Int_t i) { if (likely(i.small & 1L)) { diff --git a/src/stdlib/bigint.h b/src/stdlib/bigint.h index 9ce4c800..387d47f5 100644 --- a/src/stdlib/bigint.h +++ b/src/stdlib/bigint.h @@ -5,7 +5,6 @@ #include #include "datatypes.h" -#include "stdlib.h" #include "types.h" #include "util.h" @@ -33,11 +32,6 @@ bool Int$get_bit(Int_t x, Int_t bit_index); #define BIGGEST_SMALL_INT 0x3fffffff #define SMALLEST_SMALL_INT -0x40000000 -#define Int$from_mpz(mpz) \ - (mpz_cmpabs_ui(mpz, BIGGEST_SMALL_INT) <= 0 \ - ? ((Int_t){.small = (mpz_get_si(mpz) << 2L) | 1L}) \ - : ((Int_t){.big = memcpy(new (__mpz_struct), mpz, sizeof(__mpz_struct))})) - #define mpz_init_set_int(mpz, i) \ do { \ if likely ((i).small & 1L) mpz_init_set_si(mpz, (i).small >> 2L); \ @@ -185,29 +179,11 @@ MACROLIKE PUREFUNC bool Int$is_negative(Int_t x) { // Constructors/conversion functions: // Int constructors: -#ifdef __GNUC__ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif -MACROLIKE PUREFUNC Int_t Int$from_num64(double n, bool truncate) { - mpz_t result; - mpz_init_set_d(result, n); - if (!truncate && unlikely(mpz_get_d(result) != n)) fail("Could not convert to an integer without truncation: ", n); - return Int$from_mpz(result); -} +PUREFUNC Int_t Int$from_num64(double n, bool truncate); MACROLIKE PUREFUNC Int_t Int$from_num32(float n, bool truncate) { return Int$from_num64((double)n, truncate); } -MACROLIKE Int_t Int$from_int64(int64_t i) { - if likely (i >= SMALLEST_SMALL_INT && i <= BIGGEST_SMALL_INT) return (Int_t){.small = (i << 2L) | 1L}; - mpz_t result; - mpz_init_set_si(result, i); - return Int$from_mpz(result); -} +PUREFUNC Int_t Int$from_int64(int64_t i); MACROLIKE CONSTFUNC Int_t Int$from_int32(Int32_t i) { return Int$from_int64((Int32_t)i); } MACROLIKE CONSTFUNC Int_t Int$from_int16(Int16_t i) { return I_small(i); } MACROLIKE CONSTFUNC Int_t Int$from_int8(Int8_t i) { return I_small(i); } MACROLIKE CONSTFUNC Int_t Int$from_byte(Byte_t b) { return I_small(b); } MACROLIKE CONSTFUNC Int_t Int$from_bool(Bool_t b) { return I_small(b); } - -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif diff --git a/src/stdlib/files.c b/src/stdlib/files.c index b0545420..7d56fcfc 100644 --- a/src/stdlib/files.c +++ b/src/stdlib/files.c @@ -81,7 +81,8 @@ char *file_base_name(const char *path) { static file_t *_load_file(const char *filename, FILE *file) { if (!file) return NULL; - file_t *ret = new (file_t, .filename = filename); + file_t *ret = GC_MALLOC(sizeof(file_t)); + ret->filename = filename; size_t file_size = 0, line_cap = 0; char *file_buf = NULL, *line_buf = NULL; diff --git a/src/stdlib/lists.c b/src/stdlib/lists.c index db514671..80c407da 100644 --- a/src/stdlib/lists.c +++ b/src/stdlib/lists.c @@ -227,7 +227,7 @@ void List$remove_item(List_t *list, void *item, Int_t max_removals, const TypeIn } public -OptionalInt_t List$find(List_t list, void *item, const TypeInfo_t *type) { +PUREFUNC OptionalInt_t List$find(List_t list, void *item, const TypeInfo_t *type) { const TypeInfo_t *item_type = type->ListInfo.item; for (int64_t i = 0; i < (int64_t)list.length; i++) { if (generic_equal(item, list.data + i * list.stride, item_type)) return I(i + 1); diff --git a/src/stdlib/lists.h b/src/stdlib/lists.h index 9ac8bf1b..12a9e5b5 100644 --- a/src/stdlib/lists.h +++ b/src/stdlib/lists.h @@ -119,7 +119,7 @@ void List$remove_item(List_t *list, void *item, Int_t max_removals, const TypeIn : none_expr; \ }) -OptionalInt_t List$find(List_t list, void *item, const TypeInfo_t *type); +PUREFUNC OptionalInt_t List$find(List_t list, void *item, const TypeInfo_t *type); #define List$find_value(list, item_expr, type) \ ({ \ __typeof(item_expr) item = item_expr; \ diff --git a/src/stdlib/paths.c b/src/stdlib/paths.c index e3028cce..0198fda8 100644 --- a/src/stdlib/paths.c +++ b/src/stdlib/paths.c @@ -18,6 +18,7 @@ #include #include "../unistr-fixed.h" +#include "../util.h" #include "enums.h" #include "integers.h" #include "lists.h" diff --git a/src/stdlib/stdlib.c b/src/stdlib/stdlib.c index 7b038dac..7ed18af1 100644 --- a/src/stdlib/stdlib.c +++ b/src/stdlib/stdlib.c @@ -328,7 +328,12 @@ typedef struct cleanup_s { static cleanup_t *cleanups = NULL; public -void tomo_at_cleanup(Closure_t fn) { cleanups = new (cleanup_t, .cleanup_fn = fn, .next = cleanups); } +void tomo_at_cleanup(Closure_t fn) { + cleanup_t *new_cleanup = GC_MALLOC(sizeof(cleanup_t)); + new_cleanup->cleanup_fn = fn; + new_cleanup->next = cleanups; + cleanups = new_cleanup; +} public void tomo_cleanup(void) { diff --git a/src/stdlib/text.c b/src/stdlib/text.c index 411f3546..969c2e51 100644 --- a/src/stdlib/text.c +++ b/src/stdlib/text.c @@ -108,6 +108,7 @@ #include #include +#include "../util.h" #include "bytes.h" #include "datatypes.h" #include "integers.h" @@ -199,9 +200,9 @@ int32_t get_synthetic_grapheme(const ucs4_t *codepoints, int64_t utf32_len) { if (num_synthetic_graphemes >= synthetic_grapheme_capacity) { // If we don't have space, allocate more: synthetic_grapheme_capacity = MAX(128, synthetic_grapheme_capacity * 2); - synthetic_grapheme_t *new = GC_MALLOC_ATOMIC(sizeof(synthetic_grapheme_t[synthetic_grapheme_capacity])); - memcpy(new, synthetic_graphemes, sizeof(synthetic_grapheme_t[num_synthetic_graphemes])); - synthetic_graphemes = new; + synthetic_grapheme_t *synth = GC_MALLOC_ATOMIC(sizeof(synthetic_grapheme_t[synthetic_grapheme_capacity])); + memcpy(synth, synthetic_graphemes, sizeof(synthetic_grapheme_t[num_synthetic_graphemes])); + synthetic_graphemes = synth; } int32_t grapheme_id = -(num_synthetic_graphemes + 1); diff --git a/src/stdlib/util.h b/src/stdlib/util.h index db667ccf..3ab025f4 100644 --- a/src/stdlib/util.h +++ b/src/stdlib/util.h @@ -4,7 +4,6 @@ #include #include -#include #include #include @@ -12,9 +11,6 @@ #define starts_with(line, prefix) (strncmp(line, prefix, strlen(prefix)) == 0) #define ends_with(line, suffix) \ (strlen(line) >= strlen(suffix) && strcmp(line + strlen(line) - strlen(suffix), suffix) == 0) -#define new(t, ...) ((t *)memcpy(GC_MALLOC(sizeof(t)), &(t){__VA_ARGS__}, sizeof(t))) -#define heap(x) (__typeof(x) *)memcpy(GC_MALLOC(sizeof(x)), (__typeof(x)[1]){x}, sizeof(x)) -#define stack(x) (__typeof(x) *)((__typeof(x)[1]){x}) #define check_initialized(var, init_var, name) \ *({ \ if (!init_var) fail("The variable " name " is being accessed before it has been initialized!"); \ @@ -61,3 +57,10 @@ #define MACROLIKE extern inline __attribute__((gnu_inline, always_inline)) #endif #endif + +#ifndef GC_MALLOC +extern void *GC_malloc(size_t); +#define GC_MALLOC GC_malloc +#define heap(x) (__typeof(x) *)memcpy(GC_malloc(sizeof(x)), (__typeof(x)[1]){x}, sizeof(x)) +#define stack(x) (__typeof(x) *)((__typeof(x)[1]){x}) +#endif diff --git a/src/util.h b/src/util.h index 79cb31d8..53b10a83 100644 --- a/src/util.h +++ b/src/util.h @@ -1,3 +1,7 @@ #pragma once +#include // IWYU pragma: export + #include "./stdlib/util.h" // IWYU pragma: export + +#define new(t, ...) ((t *)memcpy(GC_MALLOC(sizeof(t)), &(t){__VA_ARGS__}, sizeof(t))) -- cgit v1.2.3