Working with ArrayBuffers

122 views
Skip to first unread message

Andrew Varga

unread,
Oct 22, 2017, 10:35:09 AM10/22/17
to emscripten-discuss
Hi,

I'm having a hard time achieving something that sounds easy:
- create an ArrayBufferView instance in JavaScript eg.: new Uint8Array([1,2,3]
- pass this to a function in a wasm module that will operate on it and change some of the values (it will not create a new array)
- be able to access the modified array in JavaScript

I'm trying to achieve this with as little glue-code as possible, my setup is here:
https://github.com/andrewvarga/wasm_test

When I run index.html, the console output is 29 which I believe comes from 23 + 6 (see buffertest.c), so I must be doing something very wrong.

What I'm looking for is the simplest, smallest, fastest way to allow wasm module to change an array (like adding 6 to each element that I tried to do here).

Any help would be very much appreciated!

Thank you,
Andrew


Andrew Varga

unread,
Oct 23, 2017, 8:11:41 AM10/23/17
to emscripte...@googlegroups.com
This actually looks very helpful, but I wonder if there is a "cleaner looking" way to actually "pass" an arraybuffer from js to a wasm module:
https://stackoverflow.com/questions/46861475/how-can-i-find-out-the-address-of-a-webassembly-buffer-and-return-it-to-javascri

--
You received this message because you are subscribed to a topic in the Google Groups "emscripten-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/emscripten-discuss/ecAgoEwK2ME/unsubscribe.
To unsubscribe from this group and all its topics, send an email to emscripten-discuss+unsub...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jukka Jylänki

unread,
Oct 24, 2017, 8:01:31 AM10/24/17
to emscripte...@googlegroups.com
It is not possible to pass ArrayBuffers or ArrayBufferViews from
JavaScript to WebAssembly. WebAssembly operates only on a single
linear heap that is bound as its own memory space, so it's only
possible to pass pointers (indices) to that one memory buffer. So
currently you would have Wasm operate on its own memory, and then
going out to JS, copy the data from the singleton Wasm memory out to
other JavaScript ArrayBuffers.

There have been talks about expanding Wasm to be able to operate on
multiple ArrayBuffers at a time, by expanding the opcode list to allow
specifying one of multiple ArrayBuffers which to manipulate, but
currently that kind of feature does not yet exist.
>> emscripten-disc...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "emscripten-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to emscripten-disc...@googlegroups.com.

Andrew Varga

unread,
Oct 24, 2017, 9:25:27 AM10/24/17
to emscripte...@googlegroups.com
Thank you for the explanation! 

So I will have to copy the data from js into the Wasm module's memory, call the Wasm function to operate on the data, and then finally copy it back to javascript.
In this case I wonder if using Wasm over js will yield in any performance improvements, so I will test it out.

It seems it could be worth doing this since this is what they are doing here in the WebAssembly Video Editor, but I'm getting much lower framerate for Wasm compared to js in both Chrome and Firefox:
https://github.com/shamadee/web-dsp
https://d2jta7o2zej4pf.cloudfront.net/




>> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "emscripten-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an

> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to a topic in the Google Groups "emscripten-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/emscripten-discuss/ecAgoEwK2ME/unsubscribe.
To unsubscribe from this group and all its topics, send an email to emscripten-discuss+unsub...@googlegroups.com.

Charles Vaughn

unread,
Oct 24, 2017, 2:31:18 PM10/24/17
to emscripten-discuss
You might be better off malloc'ing the buffer then using subarray [1] to avoid copying back and forth.

Andrew Varga

unread,
Oct 29, 2017, 1:09:10 PM10/29/17
to emscripte...@googlegroups.com
I have updated my test code now, and it works but I still have a few questions:

https://github.com/andrewvarga/wasm_test/blob/master/index.html

What I do here is I generate an array in JS, I call HEAPU8.set (so this copies it from JS to Wasm), manipulate it (just adding 1 to each element now) and then getting the result by creating a Uint8Array view.

How/why would I use "subarray"? As far as I see it, subarray doesn't copy the actual underlying ArrayBuffer data, it only creates a new TypedArrayView for that same ArrayBuffer. So now I just create a new Uint8Array which is also just a view on the data.
If I really want to copy the actual data, I could do that with eg. buffer.slice (the last lines of index.html).

My use case is that I have a Uint8Array which is pixel data acquired from a canvas, I manipulate it (the length doesn't change) and add draw it back onto the canvas, so the data I have initially is in JS, and I'm not sure how malloc would help me?

My memory calculations are wrong I think, if I increase the array length from 1000*1000*4 to say 10,000*4,000*4 that results in a runtime Wasm out of bounds memory error. Did I calculate the requiredPages incorrectly?

If there's anything else wrong in the code, or if there's a more efficient way of doing this, please let me know!

Thanks!





>> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "emscripten-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an

> For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to a topic in the Google Groups "emscripten-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/emscripten-discuss/ecAgoEwK2ME/unsubscribe.
To unsubscribe from this group and all its topics, send an email to emscripten-discuss+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Andrew Varga

unread,
Nov 10, 2017, 9:24:58 PM11/10/17
to emscripte...@googlegroups.com
Any help on this would still be hugely appreciated! :)

Thank you

To unsubscribe from this group and all its topics, send an email to emscripten-discuss+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages