aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compile/functions.c13
-rw-r--r--src/stdlib/bigint.c29
-rw-r--r--src/stdlib/bigint.h28
-rw-r--r--src/stdlib/files.c3
-rw-r--r--src/stdlib/lists.c2
-rw-r--r--src/stdlib/lists.h2
-rw-r--r--src/stdlib/paths.c1
-rw-r--r--src/stdlib/stdlib.c7
-rw-r--r--src/stdlib/text.c7
-rw-r--r--src/stdlib/util.h11
-rw-r--r--src/util.h4
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 <stdint.h>
#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 <unistd.h>
#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 <unistring/version.h>
#include <uniwidth.h>
+#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 <assert.h>
#include <err.h>
-#include <gc.h>
#include <stdbool.h>
#include <string.h>
@@ -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 <gc.h> // IWYU pragma: export
+
#include "./stdlib/util.h" // IWYU pragma: export
+
+#define new(t, ...) ((t *)memcpy(GC_MALLOC(sizeof(t)), &(t){__VA_ARGS__}, sizeof(t)))