From 16a455480754b347fd49873464782464b466eaca Mon Sep 17 00:00:00 2001 From: Vasily Chekalkin Date: Wed, 18 Mar 2026 07:59:32 +1100 Subject: [PATCH 1/3] Fix new-delete-type-mismatch in WASM_DEFINE_OWN and re-enable C tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit wasm.hh types (FuncType, GlobalType, etc.) are empty pimpl handles — sizeof is 1. The actual allocated object is the concrete impl (e.g. FuncTypeImpl, 40 bytes). Using `delete x` on the derived wrapper struct triggered ASAN new-delete-type-mismatch because the sized operator delete received sizeof(wasm_functype_t)=1 instead of sizeof(FuncTypeImpl)=40. Fix: use destroyer{}(static_cast(x)) which routes through Name::destroy() -> delete impl(this), the correct cleanup path. Re-enable `make c` in CI now that the memory management issue is fixed. Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/main.yml | 5 ++--- src/wasm-c.cc | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5cd75a2..5d5c5a1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,6 +23,5 @@ jobs: run: make wasm - name: Run C++ tests run: make cc - # TODO: C memory management seems to have broken entirely for yet unknown reasons - #- name: Run C tests - # run: make c + - name: Run C tests + run: make c diff --git a/src/wasm-c.cc b/src/wasm-c.cc index fdf2448..313b7d0 100644 --- a/src/wasm-c.cc +++ b/src/wasm-c.cc @@ -29,7 +29,7 @@ struct borrowed_vec { struct wasm_##name##_t : Name {}; \ \ void wasm_##name##_delete(wasm_##name##_t* x) { \ - delete x; \ + if (x) destroyer{}(static_cast(x)); \ } \ \ extern "C++" inline auto hide_##name(Name* x) -> wasm_##name##_t* { \ From 0943363f2aebe1facc01d66bc51a75e314d0c551 Mon Sep 17 00:00:00 2001 From: Vasily Chekalkin Date: Wed, 18 Mar 2026 08:07:16 +1100 Subject: [PATCH 2/3] example/hostref: fix resource leaks on early error exits Use goto-based cleanup to ensure engine/store/binary are always freed on all error paths. Also fix fclose missing before goto on fread failure. Co-Authored-By: Claude Sonnet 4.6 --- example/hostref.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/example/hostref.c b/example/hostref.c index ae23584..bb0b831 100644 --- a/example/hostref.c +++ b/example/hostref.c @@ -123,6 +123,8 @@ void check(own wasm_ref_t* actual, const wasm_ref_t* expected) { int main(int argc, const char* argv[]) { + int rc = 0; + // Initialize. printf("Initializing...\n"); wasm_engine_t* engine = wasm_engine_new(); @@ -130,32 +132,33 @@ int main(int argc, const char* argv[]) { // Load binary. printf("Loading binary...\n"); + wasm_byte_vec_t binary = WASM_EMPTY_VEC; FILE* file = fopen("hostref.wasm", "rb"); if (!file) { printf("> Error loading module!\n"); - return 1; + rc = 1; goto cleanup; } fseek(file, 0L, SEEK_END); size_t file_size = ftell(file); fseek(file, 0L, SEEK_SET); - wasm_byte_vec_t binary; wasm_byte_vec_new_uninitialized(&binary, file_size); if (fread(binary.data, file_size, 1, file) != 1) { printf("> Error loading module!\n"); - return 1; + fclose(file); + rc = 1; goto cleanup; } fclose(file); // Compile. printf("Compiling module...\n"); own wasm_module_t* module = wasm_module_new(store, &binary); + wasm_byte_vec_delete(&binary); + binary = (wasm_byte_vec_t)WASM_EMPTY_VEC; if (!module) { printf("> Error compiling module!\n"); - return 1; + rc = 1; goto cleanup; } - wasm_byte_vec_delete(&binary); - // Create external callback function. printf("Creating callback...\n"); own wasm_functype_t* callback_type = wasm_functype_new_1_1( @@ -173,7 +176,7 @@ int main(int argc, const char* argv[]) { wasm_instance_new(store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); - return 1; + rc = 1; goto cleanup; } wasm_func_delete(callback_func); @@ -259,12 +262,14 @@ int main(int argc, const char* argv[]) { wasm_extern_vec_delete(&exports); +cleanup: // Shut down. printf("Shutting down...\n"); + wasm_byte_vec_delete(&binary); wasm_store_delete(store); wasm_engine_delete(engine); // All done. - printf("Done.\n"); - return 0; + if (!rc) printf("Done.\n"); + return rc; } From 0d3ff9fce562821a5031bde7b9c1e5e019cb554f Mon Sep 17 00:00:00 2001 From: Vasily Chekalkin Date: Wed, 18 Mar 2026 08:22:55 +1100 Subject: [PATCH 3/3] Enable --experimental-wasm-typed-funcref in V8 Set experimental_wasm_typed_funcref flag in flags_init() so externref wasm modules compile correctly. Update hostref.wat to use typed ref.null syntax (ref.null extern) required by the typed funcref proposal, and regenerate hostref.wasm. Co-Authored-By: Claude Sonnet 4.6 --- example/hostref.wasm | Bin 231 -> 184 bytes example/hostref.wat | 2 +- src/wasm-v8-lowlevel.cc | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/example/hostref.wasm b/example/hostref.wasm index 7bfc7288e9b46fa466a6ad202b8963fdfa1e6d15..b1786ed85c03c71455303e31bd36dffaf1362271 100644 GIT binary patch delta 91 zcmaFPxPy_4A+b1@k%57MQDP#Wq&yoV17jKk12Y>dBNHg?w)I nfQgZTsw%8(3z-d8f&47Pxz{0IZ7O$V>kBDuaJ1J