How to pass array by reference from Javascript to C++ via WebIDL & WebIDL binder?

What’s the idioamtic way to define a function that takes an array as an argument in WebIDL such that WebIDL binder generates Javascript bindings that are “pass by reference”?

So I could do something like this:

void Foo::process_array(float array[], int num_frames)
{    
  for (int i = 0; i < num_frames; i++) {
    array[i] *= 0.5;
  }  
}

and call it like this in js

const arr = [1, 2, 3]
foo.process_array(arr, arr.length)
console.debug(arr)
// > [0.5, 1., 1.5]

One way to pass arrays using WebIDL is this:

interface.idl:

interface Foo {
  void Foo();
  void process_array(sequence<float> foo, long num_frames);
};

main.hpp:

struct Foo {
  Foo();
  void process_array(float foo[], int num_frames);
};

If calling the generated wrapper code like this, in accordance to the docs, the array gets passed by value – the array gets copied in, but not copied out, of the heap.

Then there’s frozen arrays that appear to do what I like, but they can only be used as attributes of objects, not parameters.

I could just copy the output buffer to an attribute, but then I have to

  1. wrap the C++ method in an object just to keep the output buffer
  2. wrap the js method to get back the behaviour I’d like to have:
const arr = [1, 2, 3]
foo.process_array(arr, arr.length)
arr = [...foo.output]
console.debug(arr)