4

Most of the demos in WebAssembly are still in C/C++ and don't show much wat. The few examples so far show things such as this:

;; Convert this to add.wasm by running:
;;
;;   wat2wasm add.wat -o add.wasm
;;
(module
  (func (export "add") (param i32 i32) (result i32)
    get_local 0
    get_local 1
    i32.add))

That uses local variables and calls a native function. I know there's get_global and such too.

What I'm wondering is how to use load and store to manage global(?) memory. I am having trouble understanding how to use the functions.

As an example, how would you load in an array of strings from JavaScript into WebAssembly, then print them out. Something like this:

const fs = require('fs')
const buf = fs.readFileSync('./add.wasm')
WebAssembly.instantiate(new Uint8Array(buf)).then(function(results){
  var lib = results.instance.exports
  lib.storeArray(['hello', 'world'])
  lib.logArray()
  // hello
  // world
})

With assembly along the lines of:

(module
  (func (export "storeArray") (param ?) (result ?)
    iterate and i32.store somehow)

  (func (export "logArray") (param ?) (result ?)
    i32.load ? iterate through something
    console.log(item)))

Specifically wondering how to reference the memory addresses (loading/storing values) and use that feature.

Lance
  • 75,200
  • 93
  • 289
  • 503
  • Possible duplicate of [How can I return a JavaScript string from a WebAssembly function](https://stackoverflow.com/questions/41353389/how-can-i-return-a-javascript-string-from-a-webassembly-function) – JF Bastien Apr 25 '18 at 03:58

1 Answers1

7

You'll need to write quite a lot of WebAssembly code to achieve what you are asking. WebAssembly doesn't support strings, or arrays. It just has four numeric types and linear memory.

To point you in the right direction, this code has a logArray function that logs the first 50 bytes of linear memory, showing you the basics of loops and the load instruction:

(import "console" "log" (func $log (param i32)))

(memory (export "memory") 1)

;; utility function for incrementing a value
(func $increment (param $value i32) (result i32)
  (i32.add 
    (get_local $value)
    (i32.const 1)
  )
)

(func $logArray
  (local $x i32)

  (set_local $x (i32.const 0))

  (block 
    (loop 

      (call $log
         ;; load a single unsigned byte from memory location $x
         (i32.load8_u (get_local $x))
      )

      (set_local $x (call $increment (get_local $x)))
      ;; break to a depth of 1 if x equals 50
      (br_if 1 (i32.eq (get_local $x) (i32.const 50)))
      ;; break to a depth of zero, continuing the loop
      (br 0)
    )
  )
)

I'll leave you to work out how you manage memory in order to store strings (e.g. how you terminate them)

ColinE
  • 68,894
  • 15
  • 164
  • 232