fill: Wasm table instruction

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since November 2021.

The table.fill Table instruction sets a range of table elements to the same value.

Try it

(module
  ;; Define function type
  (type $ret_i32 (func (result i32)))

  ;; Define table with 3 function slots
  (table $my_table 3 funcref)

  ;; Define basic function that returns an i32
  (func $f1 (result i32)
    (i32.const 42)
  )

  (elem declare func $f1)

  (func (export "run") (result i32)
    ;; Set the function referenced in every table element to $f1
    (table.fill $my_table
      (i32.const 0)
      (ref.func $f1)
      (i32.const 3)
    )

    ;; Call the function referenced in slot 2
    (call_indirect (type $ret_i32) (i32.const 2))
  )
)
WebAssembly.instantiateStreaming(fetch("{%wasm-url%}")).then((result) => {
  const value = result.instance.exports.run();
  console.log(value);
});

Syntax

table.fill identifier
table.fill

The table.fill instruction type. Must always be included first.

identifier Optional

The identifier for the table you want to fill. This can be one of the following:

name

An identifying name set for the table when it was first created. This must begin with a $ symbol, for example $my_table.

index Optional

The table's index number, for example 0 for the first table in the wasm module, 1 for the second, etc.

If the identifier is omitted, it will default to 0.

Type

[index, value, length] -> []
index

The index of the first element to store the reference in. This must be an i32 value, for example (i32.const 0).

value

The reference to store in the table. This must be of the same type that the table is defined with.

length

The number of elements to store the value to, starting at index. This must be an i32 value.

Traps

table.fill traps if:

Opcodes

Instruction Binary opcode
table.fill 𝟶𝚡𝙵𝙲 17:𝚞𝟹𝟸 (variable-width LEB128)

Examples

Demonstrating table.fill behavior

This example demonstrates that, when all of the elements of a table are referenced in a table.fill instruction, all of those elements will reference the same value.

JavaScript

In our script, we start by grabbing a reference to a <p> element that we will output results to. We then define an obj object containing a function called output() that adds a given value to the textContent of a given element.

We then compile and instantiate our Wasm module using the WebAssembly.instantiateStreaming() method, importing the obj object in the process.

When the result is returned, we invoke the exported Wasm run() function available on the WebAssembly Instance exports object, passing it the outputElem element as a parameter.

js
const outputElem = document.querySelector("p");

const obj = {
  output: function (elem, val) {
    elem.textContent += `${val} `;
  },
};

WebAssembly.instantiateStreaming(fetch("{%wasm-url%}"), {
  obj,
}).then((result) => {
  value = result.instance.exports.run(outputElem);
});

Wasm

In our Wasm module, we first import the JavaScript output() function, making sure to declare that it has two parameters, an externref and an i32.

Next, we define a function type called $ret_i32 that returns an i32, and a table that stores function references (hence funcref being specified) and has three elements.

We now define a basic function that returns an i32, and forward-declare it using (elem declare func $f1) so it can be referenced later on.

Finally, we export the run() function, which takes an externref named $elem as a parameter. Inside the function body, we:

  • Use table.fill to store a reference to the $f1 function in every table slot. Note how we've set the starting_index to 0 and the element_span to the result of the table.size instruction to guarantee that we'll fill all of the table elements.
  • Call the imported $output function, passing it as parameters the $elem externref passed into the output() function, and the return value of the function referenced in the first table slot. This results in the value being outputted to the DOM.
  • Repeat the last step another couple of times to output the return values of the functions stored in the other table elements to the DOM.
wat
(module
  ;; Import output function
  (import "obj" "output" (func $output (param externref) (param i32)))

  ;; Define function type
  (type $ret_i32 (func (result i32)))

  ;; Define an initially empty table of funcrefs with three slots
  (table $func_table 3 funcref)

  ;; Define basic function that returns an i32
  (func $f1 (result i32)
    (i32.const 42)
  )

  (elem declare func $f1)

  (func (export "run") (param $elem externref)
    ;; Set the function referenced in every table element to $f1
    (table.fill $func_table
      (i32.const 0) ;; starting index
      (ref.func $f1)
      (table.size $func_table) ;; Number of slots, not end index
    )

    ;; Call the output function, to output the return values of
    ;; the functions referenced in each table element to the DOM
    (call $output
      (local.get $elem)
      (call_indirect (type $ret_i32) (i32.const 0))
    )

    (call $output
      (local.get $elem)
      (call_indirect (type $ret_i32) (i32.const 1))
    )

    (call $output
      (local.get $elem)
      (call_indirect (type $ret_i32) (i32.const 2))
    )
  )
)

Result

The output is as follows:

This proves that all of the table elements now reference the $f1 function, which returns 42.

Specifications

Specification
Unknown specification
# syntax-instr-table

Browser compatibility

See also