请求WebAssembly的br_table指令示例及结构解析
br_table Instruction Got it, let's unpack the br_table instruction in WebAssembly Text Format (WAT) step by step—this multi-way branch can feel confusing at first, but breaking down the structure makes it click.
First, let's clarify the correct syntax of br_table (there's a small syntax hiccup in your example we'll fix along the way):
(br_table <target_label_0> <target_label_1> ... <target_label_n-1> <default_target_label> <index_expression>)
Let's break down each component, then map it directly to your code:
1. Target Table: The First Sequence of Label Indices
The first set of values are the branch targets that correspond to index values starting at 0. For example, if your index evaluates to 0, you jump to the first target; index 1 jumps to the second, and so on.
In your code snippet:
(br_table 0 1 2 (i32.const 16) (get_local 0))
The target table is the first three values: 0, 1, 2. So:
- Index
0→ branch to label0 - Index
1→ branch to label1 - Index
2→ branch to label2
2. Default Target Label: The Fallback Branch
Right after the target table comes the default target—this is where you branch if the index is negative, or if it's greater than or equal to the length of the target table (in your case, if index ≥ 3).
Here's the correction for your example: The default target should be a plain label index (like 16), not an i32.const expression. i32.const creates integer values, but label indices are immediate values in WAT. Your adjusted code should look like this:
(br_table 0 1 2 16 (get_local 0))
Now, 16 is the default target label—any out-of-bounds index will trigger a branch to label 16.
3. Index Expression: The Value That Chooses the Branch
The final part is an expression that evaluates to an i32 value—this determines which branch target we use. In your code, that's (get_local 0), which loads the value from local variable 0 to act as the branch index.
A Full Working Example
To make this concrete, here's a complete WAT snippet using br_table to handle different index values:
(module (func $example (param $idx i32) (block $label0 (block $label1 (block $label2 (block $default_label ;; Use br_table to branch based on $idx (br_table 0 1 2 3 (get_local $idx)) ;; This code won't run because br_table branches away immediately (return) ) ;; Runs if we branched to $default_label (index ≥3 or <0) (i32.const 42) (drop) ) ;; Runs if we branched to $label2 (index=2) (i32.const 2) (drop) ) ;; Runs if we branched to $label1 (index=1) (i32.const 1) (drop) ) ;; Runs if we branched to $label0 (index=0) (i32.const 0) (drop) ) )
In this example:
- If
$idxis0, we jump to$label0 - If
$idxis1, jump to$label1 - If
$idxis2, jump to$label2 - Any other value jumps to
$default_label
Key Takeaway
Always remember the order: target table → default target → index expression. The index picks a target from the table, and the default catches all out-of-bounds cases.
内容的提问来源于stack exchange,提问作者Jason Yu

