How to deallocate WASM heap memory that is exported to Javascript

⚓ rust    📅 2025-05-24    👤 surdeus    👁️ 3      

surdeus

Warning

This post was published 35 days ago. The information described in this article may have changed.

I was trying to find a way to export vector or other heap alocated data to Javascript. I tried this:

use wasm_bindgen::prelude::*;
use std::alloc::{Layout, dealloc};

#[wasm_bindgen]
pub struct ArrayBuffer {
    ptr: *const u8,
    len: usize,
}

#[wasm_bindgen]
impl ArrayBuffer {
    #[wasm_bindgen(getter)]
    pub fn ptr(&self) -> *const u8 {
        self.ptr
    }

    #[wasm_bindgen(getter)]
    pub fn len(&self) -> usize {
        self.len
    }
}

#[wasm_bindgen]
pub fn get_array() -> ArrayBuffer {
    let data = vec![1, 2, 3, 4, 5];
    let ptr = data.as_ptr();
    let len = data.len();

    std::mem::forget(data);

    ArrayBuffer { ptr, len }
}

#[wasm_bindgen]
pub fn free_array_raw(ptr: *mut u8, len: usize) {
    unsafe {
        let mut v = Vec::from_raw_parts(ptr, len, len);
        v.fill(0); 
        drop(v);  
    }
}

The I compile with wasm-pack targetting nodejs

wasm-pack build --target nodejs

Here is my Javascript code I used to test it

const wasm = require('./pkg/wasm.js');

async function run() {
  const arrayBuffer = wasm.get_array();
  const ptr = arrayBuffer.ptr;
  const len = arrayBuffer.len;

  const memory = wasm.__wasm.memory;

  const uint8Array = new Uint8Array(memory.buffer, ptr, len);

  console.log(uint8Array);

  arrayBuffer.free();
  wasm.free_array_raw(ptr, len);
  
  console.log(uint8Array);
}

run().catch(console.error);

The memory does not get deallocated, I still can access the data

[root@localhost wasm]# node ./main.js
Uint8Array(5) [ 1, 2, 3, 4, 5 ]
Uint8Array(5) [ 1, 2, 3, 4, 5 ]

How is the correct way to deallocate the heap memory?

2 posts - 2 participants

Read full topic

🏷️ rust_feed