tiborvass opened Issue #1225:
Out of curiosity I was wondering why the BrIf instruction has an else_ target when the it could simply be moving on to the next instruction.
Vurich commented on Issue #1225:
Great question! So basically, it's a way to make dealing with control flow easier. So basically in Wasm there are 2 kinds of intra-function control flow - conditional (you might jump or you might not) and unconditional (you always jump). However, since these are both control flow, all the same conditions apply. If you had a
br_table
with 1 target and 1 default, that's exactly the same as abr_if
except that it jumps unconditionally, for example. So we make all control flow unconditional and we model conditional control flow by creating a new block directly after the current one and then emitting an unconditional jump where the "then" is the Wasmbr_if
's target, and the "else" is that newly-created block. By unconditional I here mean that we _must_ jump, but _where_ we jump is defined at runtime. Doing it this way means that we don't have any special-cases, we handle both unconditional and conditional control flow the same, which has a few added benefits. For example, unconditional control flow where one of the targets is the location directly after the jump (for example, abr
orbr_table
followed immediately by anend
) can be compiled to "fall through" just asbr_if
is, which produces better code while only having a single code-path.Hope that helps, I'm actually writing up some documents describing some of the design decisions, constraints, and proposals for Lightbeam over at https://github.com/paritytech/lightbeam-stammtisch, but it's very unfinished and doesn't have a great deal of information on Microwasm itself right now.
Vurich edited a comment on Issue #1225:
Great question! So basically, it's a way to make dealing with control flow easier. So basically in Wasm there are 2 kinds of intra-function control flow - conditional (you might jump or you might not) and unconditional (you always jump). However, since these are both control flow, all the same conditions apply. If you had a
br_table
with 1 target and 1 default, that's exactly the same as abr_if
except that it jumps unconditionally, for example. So we make all control flow unconditional and we model conditional control flow by creating a new block directly after the current one and then emitting an unconditional jump where the "then" is the Wasmbr_if
's target, and the "else" is that newly-created block. By unconditional I here mean that we _must_ jump, but _where_ we jump is defined at runtime. Doing it this way means that we don't have any special-cases, we handle both unconditional and conditional control flow the same, which has a few added benefits. For example, unconditional control flow where one of the targets is the location directly after the jump (for example, abr
orbr_table
followed immediately by anend
) can be compiled to "fall through" just asbr_if
is, which produces better code while only having a single code-path.Hope that helps, I'm actually writing up some documents describing some of the design decisions, constraints, and proposals for Lightbeam over at https://github.com/paritytech/lightbeam-stammtisch, but it's very unfinished and doesn't have a great deal of information on Microwasm itself right now.
Since this is a question and not an issue, I'm going to close it, but if you have further questions about Lightbeam's design I highly recommend that you post an issue over at
lightbeam-stammtisch
since it will help me learn what I haven't explained properly, or other holes that need to be filled.
Vurich closed Issue #1225:
Out of curiosity I was wondering why the BrIf instruction has an else_ target when the it could simply be moving on to the next instruction.
Last updated: Dec 23 2024 at 12:05 UTC