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.fillinstruction type. Must always be included first. identifierOptional-
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. indexOptional-
The table's index number, for example
0for the first table in the wasm module,1for the second, etc.
If the
identifieris omitted, it will default to0.
Type
[index, value, length] -> []
index-
The index of the first element to store the reference in. This must be an
i32value, 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 ani32value.
Traps
table.fill traps if:
index+lengthis greater thantable.size.
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.
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.fillto store a reference to the$f1function in every table slot. Note how we've set thestarting_indexto0and theelement_spanto the result of thetable.sizeinstruction to guarantee that we'll fill all of the table elements. - Call the imported
$outputfunction, passing it as parameters the$elemexternrefpassed into theoutput()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.
(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> |