I want to provide a memory to share with Javascript. In C and Rust there are malloc() and free() (for Rust wbindgen provides it). I couldn't find something similar in Go? How can I reserve memory, get the pointer of it and free it after using it?
A usage example. Do something with the image bitmap (Javascript):
const context = canvas.getContext("2d");
const size = canvas.width * canvas.height * 4;
// allocate memory in Go
const ptr = window.wasm.go.malloc(size);
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
const dataGo = new Uint8ClampedArray(window.wasm.goMem.buffer, ptr, size);
const imageDataGo = new ImageData(dataGo, canvas.width, canvas.height);
imageDataGo.data.set(imageData.data);
// run function in Go using the pointer to the memory
window.wasm.go.convolve_mem(ptr, canvas.width, canvas.height);
context.putImageData(imageDataGo, 0, 0);
// free the memory
window.wasm.go.free(size);
I tried this (Go):
exports["malloc"] = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
size := args[0].Int()
mem := make([]byte, size)
ptr := uintptr(unsafe.Pointer(&mem))
return uint64(ptr)
})
make
should initialize all elements of the byte array with 0. But in JS I get a random array. Therefore I assume this is not working as expected. I also assume the garbage collector frees the memory right after the function returns.
How to reserve memory in Go the way I can do it in C?
go version go1.12.1 linux/amd64
I didn't find a solution in Go but I can use other Wasm modules with the same Wasm memory. In C I can use malloc and there is a Wasm module. See code comments.
const go = new window.Go();
// use the same WASM memory for all Wasm instances
const memory = new WebAssembly.Memory({initial: 1024});
Promise.all([
// The main WASM module with my photo filter
WebAssembly.instantiateStreaming(fetch('some-go-wasm-module.wasm'), {
env: {memory},
...go.importObject
}),
// the memory library written in C provides: abort, calloc, free, malloc, memcoy, memset, sbrk
// source: https://github.com/guybedford/wasm-stdlib-hack/blob/master/dist/memory.wasm
WebAssembly.instantiateStreaming(fetch("memory.wasm"), {
env: {memory}
})
])
.then(module => {
go.run(module[0].instance);
window.wasm.memHelper = {
memory,
...module[1].instance.exports
};
});
Now I can allocate and free memory and access it in Go functions using the pointer. This sample is from another question - to show how it works:
const context = canvas.getContext("2d");
const size = canvas.width * canvas.height * 4;
// allocate memory for the image bitmap
const ptr = window.wasm.memHelper.malloc(size);
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
// create a new ImageData object from this memory
const dataGo = new Uint8ClampedArray(window.wasm.memHelper.memory.buffer, ptr, size);
const imageDataGo = new ImageData(dataGo, canvas.width, canvas.height);
// copy the image from JS context to the WASM context
imageDataGo.data.set(imageData.data);
// run my Go filter
window.wasm.go.convolve_mem(ptr, canvas.width, canvas.height);
// copy the image bitmap from Wasm context back to the canvas
context.putImageData(imageDataGo, 0, 0);
// free memory
window.wasm.memHelper.free(ptr);