diff options
author | WormHeamer | 2025-03-06 01:06:03 -0500 |
---|---|---|
committer | WormHeamer | 2025-03-06 01:06:03 -0500 |
commit | 6e16ed9dc2ca7c6f828e89b0e62058ccd749c493 (patch) | |
tree | e8ae4a2d165ee513d755862f5e105d2915dda457 | |
parent | ac0c3567053901b65c8413929aa53aa78efb51e9 (diff) |
add (compiled but untested) support for wasm bulk memory
-rw-r--r-- | zone.h | 88 |
1 files changed, 69 insertions, 19 deletions
diff --git a/zone.h b/zone.h index 00d788d..c42b6b1 100644 --- a/zone.h +++ b/zone.h @@ -4,6 +4,10 @@ #include <stdint.h> #include <stddef.h> +#define ZONE_USE_MALLOC 0 +#define ZONE_USE_MMAP 1 +#define ZONE_USE_WASM_BULKMEM 2 + #ifndef ZONE_BACKEND #ifdef __unix__ #define ZONE_BACKEND ZONE_USE_MMAP @@ -11,8 +15,10 @@ #define ZONE_BACKEND ZONE_USE_MALLOC #endif #endif -#define ZONE_USE_MALLOC 0 -#define ZONE_USE_MMAP 1 + +#if !defined(ZONE_NOSTDLIB) && (ZONE_BACKEND != ZONE_USE_MMAP && ZONE_BACKEND != ZONE_USE_MALLOC) + #define ZONE_NOSTDLIB +#endif typedef struct ZoneFrame ZoneFrame; struct ZoneFrame { @@ -55,14 +61,38 @@ void *zn_zeroed(void *, size_t); #ifdef ZONE_IMPL -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - #ifndef ZONE_PAGE_MULT #define ZONE_PAGE_MULT 2 #endif +#define UPTR_ALIGN(x, align) ((x)+((-x)&((align)-1))) +#define PTR_ALIGN(ptr, align) (typeof(ptr)) (((uintptr_t)ptr + (align - 1)) & -align) + +#if ZONE_BACKEND == ZONE_USE_MMAP || ZONE_BACKEND == ZONE_USE_MALLOC + #include <stdio.h> + #include <stdlib.h> + [[noreturn]] void zn_abort(const char *msg) { + fprintf(stderr, "%s\n", msg); + abort(); + } +#elif ZONE_BACKEND == ZONE_USE_WASM_BULKMEM + __attribute((import_name("alert"))) void js_alert(const char *msg); + __attribute((import_name("abort"))) [[noreturn]] void js_abort(void); + [[noreturn]] void zn_abort(const char *msg) { + js_alert(msg); + js_abort(); + } +#else + #error "zn_abort not implemented for the current platform -- using __builtin_trap() instead" + [[noreturn]] void zn_abort(cont char *msg) { + (void)msg; + __builtin_trap(); + } +#endif + +#define ZONE_MEMSET __builtin_memset +#define ZONE_MEMCPY __builtin_memcpy + #if ZONE_BACKEND == ZONE_USE_MMAP #include <sys/mman.h> @@ -90,6 +120,32 @@ void *zn_zeroed(void *, size_t); free(p); } +#elif ZONE_BACKEND == ZONE_USE_WASM_BULKMEM + + #define ZONE_PAGE_SIZE 65536 + #define ZONE_PAGE_FAIL (void*)(uintptr_t)-1 + extern uint8_t __heap_base; + static void *zn_pg_free_adr = 0; + static void *zn_pg_alloc(size_t n) { + if (zn_pg_free_adr) { + void *p = zn_pg_free_adr; + zn_pg_free_adr = *(void **)zn_pg_free_adr; + return p; + } + void *p = &__heap_base + __builtin_wasm_memory_size(0); + __builtin_wasm_memory_grow(0, 1); + return p; + } + static void zn_pg_free(void *p, size_t n) { + uintptr_t adr = ((uintptr_t)p & ~0xFFFF); + n = (n + 0xFFFF) >> 16; + while (n--) { + void *pg = (void *)(adr + (n << 16)); + *(void **)pg = zn_pg_free_adr; + zn_pg_free_adr = pg; + } + } + #else #error "unknown or unsupported zone backend" @@ -102,10 +158,7 @@ static inline size_t zn_pg_fit(size_t cap) { static ZoneFrame *zn_zf_new(size_t capacity) { ZoneFrame *zf = zn_pg_alloc(capacity / ZONE_PAGE_SIZE); - if (zf == ZONE_PAGE_FAIL) { - fprintf(stderr, "failed to allocate zone frame\n"); - abort(); - } + if (zf == ZONE_PAGE_FAIL) zn_abort("failed to allocate zone frame\n"); zf->prev = NULL; zf->next = NULL; zf->beg = zf->data; @@ -117,9 +170,6 @@ static void zn_zf_free(ZoneFrame *z) { zn_pg_free(z, (uintptr_t)z->end - (uintptr_t)z->beg); } -#define UPTR_ALIGN(x, align) ((x)+((-x)&((align)-1))) -#define PTR_ALIGN(ptr, align) (typeof(ptr)) (((uintptr_t)ptr + (align - 1)) & -align) - void *zn_alloc_align(Zone *z, ptrdiff_t n, size_t align) { ZoneFrame *zf = z->cur; uint8_t *aligned; @@ -140,16 +190,14 @@ void *zn_alloc_align(Zone *z, ptrdiff_t n, size_t align) { } void *zn_realloc_align(Zone *z, void *ptr, ptrdiff_t oldsz, ptrdiff_t newsz, size_t align) { - goto justalloc; if (!ptr || !oldsz) return zn_alloc_align(z, newsz, align); if (z->cur && ptr == z->cur->beg - oldsz && z->cur->beg - oldsz + newsz < z->cur->end) { z->cur->beg -= oldsz; z->cur->beg += newsz; return ptr; } else { -justalloc: void *p = zn_alloc_align(z, newsz, align); - memcpy(p, ptr, oldsz); + ZONE_MEMCPY(p, ptr, oldsz); return p; } } @@ -170,7 +218,7 @@ void *zn_realloc(Zone *z, void *ptr, ptrdiff_t oldsz, ptrdiff_t newsz) { void *zn_calloc(Zone *z, size_t n, size_t size) { void *p = zn_alloc_align(z, n * size, zn_align_for(size)); - memset(p, 0, n * size); + ZONE_MEMSET(p, 0, n * size); return p; } @@ -214,15 +262,17 @@ void zn_load(Zone *z, ZoneState *m) { /* utils */ +#ifndef ZONE_NOSTDLIB char *zn_strdup(Zone *z, const char *s) { size_t n = strlen(s) + 1; char *d = zn_alloc_align(z, n, 1); - memcpy(d, s, n); + ZONE_MEMCPY(d, s, n); return d; } +#endif void *zn_zeroed(void *ptr, size_t n) { - memset(ptr, 0, n); + ZONE_MEMSET(ptr, 0, n); return ptr; } |