Skip to content

Commit a24c691

Browse files
authored
fix: WASM signature mismatch in block fractional-indexing allocator (#42)
cloudsync_memory_alloc (dbmem_alloc, uint64_t) was cast directly into fractional_indexing_allocator.malloc (void *(*)(size_t)). Native size_t is 64-bit so the cast is a no-op, but WASM size_t is 32-bit and call_indirect enforces strict typing: the function is registered as (i64)->i32 and called as (i32)->i32, crashing cloudsync_set_column on a table with pre-existing rows during the block-index migration. Bridge via fi_malloc_wrapper, mirroring the existing fi_calloc_wrapper pattern. Native builds are unaffected. Bumps CLOUDSYNC_VERSION to 1.0.16.
1 parent 79a3496 commit a24c691

3 files changed

Lines changed: 14 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

7+
## [1.0.16] - 2026-04-16
8+
9+
### Fixed
10+
11+
- **WASM crash in `cloudsync_set_column` on existing rows**: Calling `cloudsync_set_column(table, col, 'lww', 'block')` on a table with pre-existing rows crashed the WASM build with a `RuntimeError: function signature mismatch` as soon as the block-index migration tried to allocate memory. `block_init_allocator` was casting `cloudsync_memory_alloc` (a `uint64_t size` function) directly to the fractional-indexing allocator's `void *(*)(size_t)` slot. The cast is a no-op on native platforms where `size_t` is 64-bit, but WASM's `call_indirect` enforces strict type checking — the function is registered as `(i64) -> i32` and called as `(i32) -> i32`, triggering an immediate runtime error. A thin `fi_malloc_wrapper` (mirroring the existing `fi_calloc_wrapper`) now bridges the signatures. Native builds are unaffected.
12+
713
## [1.0.15] - 2026-04-16
814

915
### Fixed

src/block.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,20 @@ block_list_t *block_split(const char *text, const char *delimiter) {
127127

128128
// MARK: - Fractional indexing (via fractional-indexing submodule) -
129129

130+
// Wrapper for malloc: fractional_indexing expects size_t (32-bit on WASM) but cloudsync_memory_alloc takes uint64_t.
131+
// A direct cast passes strict call_indirect type checking in WASM and triggers a RuntimeError.
132+
static void *fi_malloc_wrapper(size_t size) {
133+
return cloudsync_memory_alloc((uint64_t)size);
134+
}
135+
130136
// Wrapper for calloc: fractional_indexing expects (count, size) but cloudsync_memory_zeroalloc takes a single size.
131137
static void *fi_calloc_wrapper(size_t count, size_t size) {
132138
return cloudsync_memory_zeroalloc((uint64_t)(count * size));
133139
}
134140

135141
void block_init_allocator(void) {
136142
fractional_indexing_allocator alloc = {
137-
.malloc = (void *(*)(size_t))cloudsync_memory_alloc,
143+
.malloc = fi_malloc_wrapper,
138144
.calloc = fi_calloc_wrapper,
139145
.free = cloudsync_memory_free
140146
};

src/cloudsync.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
extern "C" {
1919
#endif
2020

21-
#define CLOUDSYNC_VERSION "1.0.15"
21+
#define CLOUDSYNC_VERSION "1.0.16"
2222
#define CLOUDSYNC_MAX_TABLENAME_LEN 512
2323

2424
#define CLOUDSYNC_VALUE_NOTSET -1

0 commit comments

Comments
 (0)