Search code examples
webassemblyassemblyscript

What's the correct way to share memory between my AssemblyScript module and my JS?


I'm following this code here, trying to share memory between my AssemblyScript code and my JS:

  let aryPtr = instance.exports.allocateF32Array(3);
  let ary = new Float32Array(instance.exports.memory.buffer, aryPtr, 3);

  ary[0] = 1.0;
  ary[1] = 2.0;
  instance.exports.addArray(aryPtr);

And my index.ts:

export function allocateF32Array(length: i32): Float32Array {
  return new Float32Array(length);
}

export function addArray(data: Float32Array): i32 {
  data[2] = data[0] + data[1];
  return data.length;
}

But this results in RuntimeError: memory access out of bounds in addArray. Have I misunderstood how this is supposed to work?


Solution

  • I recommend to use the official loader for such purposes.

    On the JavaScript side: (node.js for example)

    const fs = require("fs");
    const loader = require("@assemblyscript/loader");
    const module = loader.instantiateSync(
      fs.readFileSync("optimized.wasm"),
      {}
    );
    var ptrArr = module.__retain(module.__allocArray(module.FLOAT32ARRAY, [1, 2, 0]));
    console.log('length:', module.addArray(ptrArr));
    
    const arr = module.__getFloat32Array(ptrArr);
    console.log('result:', arr[2]);
    
    // free array
    module.__release(ptrArr);
    

    On the AssemblyScript side:

    export const FLOAT32ARRAY = idof<Float32Array>();
    
    export function addArray(data: Float32Array): i32 {
      data[2] = data[0] + data[1];
      return data.length;
    }