You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
v8.deserialize on WebAssembly module fails with "Unable to deserialize cloned data" #18265
Using the experimental Serialization API calling v8.serialize(module) on a WebAssembly module works, however trying to then deserialize it v8.deserialize(buffer) fails with Error: Unable to deserialize cloned data..
From what I gather, node is using a newly exposed API from v8, so it's possible that exposed API is to blame. Although, v8 itself supports it within its internal APIs and the --wasm_disable_structured_cloning flag is exposed in node v9.4.0 with the expected value of false (don't disable aka is enabled)
node --v8-options
...
--wasm_disable_structured_cloning (disable wasm structured cloning)
type: bool default: false
# false means structured cloning aka serialization is NOT disabled AFAIK -jayphelps
constv8=require('v8');// only putting a simple wasm binary inline so it's easy to reproduceconsttheModule=newWebAssembly.Module(newUint8Array([0x00,0x61,0x73,0x6d,0x01,0x00,0x00,0x00]));constbuffer=v8.serialize(theModule);v8.deserialize(buffer);// "Error: Unable to deserialize cloned data."
This is supported in browsers via postMessage or saving them into IndexedDB
No urgency on my part, just logging mostly curious if someone can point me in the right direction codewise and I'll take a peek. I went down the rabbit hole on my own and didn't immediately see anything that would have prohibited support.
Some printf debugging reveals that explicitly allowing WASM deserialization from source (over in-memory transfer) is necessary for this to work. I can't see why we can't allow it by default for v8.Deserializer.
Just flipping the flag isn't enough, we also need to implement ValueSerializer::GetWasmModuleTransferId().
We can probably do that the same way we implement ValueSerializer::GetSharedArrayBufferId(), by punting it to the user (through the serializer._getSharedArrayBufferId() callback.)
That said, I remember there were a bunch of issues with WASM serialization. I don't know if V8 6.2 is in a shape where it actually works.
It looks like this has regressed, the testcase here does not work on v14.1.0.
Same testcase, but with adding
console.log('serlialized length:',buffer.length);
between the serialization and deserialization, shows that with v14.1.0 the serialized size is just 2 bytes. I see the same for all modules, regardless of the size, using Emscripten's code caching option that is built on this.
For comparison on v12.9.1 everything works properly (and the serialized size is 38 bytes in this example).
@kripken@saschanaz This has happened due to large changes to how the V8 API deals with compiled WASM modules – the new interfaces here are quite complex, and I’m not sure whether the APIs can be mapped against each other easily (and, in particular, synchronously).
Activity
TimothyGu commentedon Jan 20, 2018
Some printf debugging reveals that explicitly allowing WASM deserialization from source (over in-memory transfer) is necessary for this to work. I can't see why we can't allow it by default for
v8.Deserializer./cc @addaleax
bnoordhuis commentedon Jan 20, 2018
Just flipping the flag isn't enough, we also need to implement
ValueSerializer::GetWasmModuleTransferId().We can probably do that the same way we implement
ValueSerializer::GetSharedArrayBufferId(), by punting it to the user (through theserializer._getSharedArrayBufferId()callback.)That said, I remember there were a bunch of issues with WASM serialization. I don't know if V8 6.2 is in a shape where it actually works.
saschanaz commentedon Mar 10, 2019
Looks like this has been fixed now. https://runkit.com/saschanaz/5c84667c6e2ea0001222a59f
jayphelps commentedon Mar 10, 2019
Woot woot! Thanks for letting us know—and to whoever fixed it.
kripken commentedon May 2, 2020
It looks like this has regressed, the testcase here does not work on
v14.1.0.Same testcase, but with adding
between the serialization and deserialization, shows that with
v14.1.0the serialized size is just 2 bytes. I see the same for all modules, regardless of the size, using Emscripten's code caching option that is built on this.For comparison on
v12.9.1everything works properly (and the serialized size is 38 bytes in this example).Should I file a new issue?
saschanaz commentedon May 2, 2020
True, it doesn't work anymore in v14.1.0 while it works on v13.14.0. https://runkit.com/saschanaz/5ead9385cf032a001e521bc9
addaleax commentedon May 2, 2020
@kripken @saschanaz This has happened due to large changes to how the V8 API deals with compiled WASM modules – the new interfaces here are quite complex, and I’m not sure whether the APIs can be mapped against each other easily (and, in particular, synchronously).
kripken commentedon May 3, 2020
@addaleax Oh, that's too bad... this was really useful.
An async API would be fine for the emscripten use cases, if that's possible!
NODE_CODE_CACHING followups (#11077)
Disable test_node_code_caching which fail on recent versions of node.
Disable test_node_code_caching which fail on recent versions of node. (…
sbc100 commentedon Sep 17, 2026
Looping back, emscripten still has the
NODE_CODE_CACHINGsetting in emscripten but its been broken for the last 6 years now.Is there any chance
v8.serialize(wasmModule)will ever work again? Right now it just produces 2 bytes.If not, then I guess we should just remove this setting.
Remove NODE_CODE_CACHING setting (#27740)