MatthewScarpino
MatthewScarpino

Reputation: 5936

Passing data to WebAssembly

I'm trying to pass a value from JavaScript to WASM, but it's not working. Here's my C code:

extern int x;
int foo() {
  return x;
}

In JavaScript, I instantiate the module and set x equal to 5:

var importObj = {
  env: { 
    memory: new WebAssembly.Memory({initial: 256, maximum: 256}),     
    _x: 5
  }
};    

WebAssembly.instantiateStreaming(fetch('test.wasm'), importObj)
.then(result =>
    console.log('Output: ' + result.instance.exports._foo())
);

This doesn't produce any errors, but the logged message is Output: 0 instead of Output: 5. Any ideas?

Upvotes: 1

Views: 2283

Answers (2)

sbc100
sbc100

Reputation: 3032

The current lld implementation doesn't support undefined data symbols at link time. If you pass --allow-undefined you will end up with undefined symbols who's address is 0.

We have been discussing adding support for importing data symbols: https://github.com/WebAssembly/tool-conventions/issues/48

Upvotes: 1

Mauro Bringolf
Mauro Bringolf

Reputation: 538

What do you use to compile your C code to wasm? I tried to get this to work on https://webassembly.studio and found that the function foo loads the value from memory location 0. So I was able to produce Output: 5 by initializing the instances memory from JS:

WebAssembly.instantiateStreaming(fetch('test.wasm'), importObj)
  .then(result => {
    const mem = new Uint32Array(result.instance.exports.memory.buffer)
    mem[0] = 5
    console.log('Output: ' + result.instance.exports._foo())
  });

To be honest I expected the extern int x to become an imported global in wasm that can be passed via importObj. I hope this still helps to get on the right path.

Upvotes: 2

Related Questions