0

My .wat file has the following 2 lines of code.

(memory $buf 1)
(data (i32.const 0) "hello")

I would like to pass $buf as an argument to an imported Javascript function. The code on the Javascript side looks like this:

 function consoleLogString(memory, offset,length){
        var bytes = new Uint8Array(memory.buffer, 0, 5);
        var string = new TextDecoder('utf8').decode(bytes);
        console.log(string);
    }
    var importObj = {console : {log: consoleLogString}};
    fetchAndInstantiate('stringLogger2.wasm',importObj).then(function(instance) {
        instance.exports.writeHi();
    });
}

On the wasm side I would like to be able to do something like

(import "console" "log" (func $log (param i32 i32 i32)))
(export "writeHi" (func $writeHi))
(memory $buf 1)
(data (i32.const 0) "hello")
(func $writeHi
      ;; how do I push my buffer onto the stack so it can be passed to the function?
      i32.const 0
      i32.const 5
      call $log
)
kablaa
  • 1

1 Answers1

0

As I know WebAssembly only supports i32 / i64 / f32 / f64, so this means that you can't pass in pointers.

Pass a JavaScript array as argument to a WebAssembly function

But you can import memory to the wasm instance, and you can link you log function with imported memory

function consoleLogString(memory, offset, length) {
    var bytes = new Uint8Array(memory.buffer, offset, length);
    var string = new TextDecoder('utf8').decode(bytes);
    console.log(string);
}
const memory = new WebAssembly.Memory({ initial: 2 });
const consoleLogStringWrapper = memory => (offset, length) => consoleLogString(memory, offset, length);
var importObj = {
    imp : {
        mem: memory,
        log: consoleLogStringWrapper(memory)
    }
};
fetchAndInstantiate('stringLogger2.wasm', importObj).then(function(instance) {
    instance.exports.writeHi();
});

Your wat will be similar to this:

    (module
        (import "imp" "log" (func $log (param i32 i32)))
        (memory (import "imp" "mem") 1)
        (func $writeHi
             i32.const 0
             i32.const 5
             call $log
        )
        (data (i32.const 0) "hello")
        (export "writeHi" (func $writeHi))
    )

Tested on wat2wasm with following js:

function consoleLogString(memory, offset, length) {
    var bytes = new Uint8Array(memory.buffer, offset, length);
    var string = new TextDecoder('utf8').decode(bytes);
    console.log(string);
}
const memory = new WebAssembly.Memory({ initial: 2 });
const consoleLogStringWrapper = memory => (offset, length) => consoleLogString(memory, offset, length);
var importObj = {
    imp : {
        mem: memory,
        log: consoleLogStringWrapper(memory)
    }
};

const wasmInstance = new WebAssembly.Instance(wasmModule, importObj);
const { writeHi } = wasmInstance.exports;
writeHi();
  • Ok so I can't return a pointer. That makes sense. But If you don't mind clarifying one more thing that would be awesome. In your example you are creating the memory in javascript, filling it in wasm, and accessing it (logging it) in javascript. I'm wondering how to I access the memory from within web assembly. So after I do `(data (i32.const 0) "hello")`, how do I access various offsets of the data segment. – kablaa Jan 11 '18 at 21:36
  • @kablaa to access memory within WebAssembly you can use load/store operators https://github.com/WebAssembly/design/blob/master/Semantics.md#linear-memory-accesses. Value added by **data** will be stored with offset **0** that is set in (data (i32.const 0) "hello") – Alexandr Skachkov Jan 11 '18 at 21:53
  • When I try to do `i32.load` it's expecting an instruction and I can't seem to figure out with one to pass it. So like If I wanted to change the 'h' in 'hello' to an 'H' from within my function, how can I do that? – kablaa Jan 11 '18 at 23:39
  • Hm, not sure that I got why do you need i32.load. To change value in memory you need to use i32.store. See simple example for change first letter h -> H(72). `(i32.store8 (i32.const 0) (i32.const 72) )` https://gist.github.com/gskachkov/6ef172698137ab378231ece6b09e0a9b – Alexandr Skachkov Jan 12 '18 at 08:17