I am using a WebAssembly based software that uses multi-threading that requires SharedArrayBuffer
. It runs fine both in Chromium local/deployed, and Firefox 89 deployed, but since the best performance is under Firefox, I want to test and tune it on my machine, so I run python -m SimpleHTTPServer
. In this situation, when I open 127.0.0.1:8000 or 0.0.0.0:8000 in Firefox, SharedArrayBuffer
is undefined. Perhaps this is a security setting, but when using localhost, I'm really not interested in Firefox's interpretation of the situation -- this should just run. How can I make it work? Do I need a different web server, different settings?
As you guessed correctly, it has to do with security restrictions. There have been changes in regards to the use of SharedArrayBuffer
that have already been implemented in Firefox 79 and will land in Chrome shortly as well (starting with Chrome 92). (Time of writing this: July 13, 2021.)
The main purpose is to restrict the use of SharedArrayBuffer
s in postMessage
. Any such attempt will throw an error unless certain restrictive COOP/COEP headers are set to prevent cross-origin attacks:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Unfortunately, without these headers, there is also no global SharedArrayBuffer
constructor. Apparently, this restriction may be lifted in the future. The objects themselves still work though (only passing them through postMessage
would throw), but you need a different way to instantiate them. You can use WebAssembly.Memory
instead:
const memory = new WebAssembly.Memory({ initial: 10, maximum: 100, shared: true })
// memory.buffer is instanceof SharedMemoryBuffer
You could now go one step further and recover the constructor from that. Therefore, with the following code as "shim", your existing code should work as long as it doesn't try to pass the buffer through postMessage
:
if (typeof SharedArrayBuffer === 'undefined') {
const dummyMemory = new WebAssembly.Memory({ initial: 0, maximum: 0, shared: true })
globalThis.SharedArrayBuffer = dummyMemory.buffer.constructor
}
// Now, `new SharedArrayBuffer(1024)` works again
Further reading: