rethrow's immediate arguments #74
Description
In the current spec, rethrow
does not take any immediate argument, and only pops except_ref
from the top of stack and rethrows it.
I'm planning to add two immediate arguments to rethrow
. These two are not new; they have been discussed previously.
Depths to break out of
Branches can break out of arbitrary number of block
s and loop
s thanks to their immediate depth argument, but rethrow
currently does not have it. So I am planning to add a depth immediate argument to rethrow
, which was first proposed in #29 (comment).
One thing we should consider is, depth calculation should be slightly different from that of branches. I'd like to make the depth calculation for rethrow
the same as that of branches, but for branches, the depth is increased at block start instructions (block
, loop
, and try
) and is decreased at block end instruction (end
), whereas for rethrow
s, the depth should be decreased not at block end instruction (end
) but at catch
instruction. For example,
try
try
br 0 // branches to (2)
rethrow 0 // rethrows to (1)
catch <-- (1)
br 0 // branches to (2)
rethrow 0 // rethrows to (3)
end
... <-- (2)
catch <-- (3)
end
Here two br
instructions are within the same try
~end
scope, so they branch to the same place. But two rethrow
instructions rethrow to different places, because the level is decreased not at end
but at catch
.
To resolve this, the current LLVM toolchain implemenation maintains separate EH stack for rethrow depth calculation, in the way that EH stack depth is only incremented with try and decremented with catch and does not count other blocks or loops. As in the example below, rethrow does not count all block
s when computing depth.
try
block
block
block
block
try
rethrow 0 // rethrows to (1)
rethrow 1 // rethrows to (2)
catch <-- (1)
end
end
end
end
end
catch
end <-- (2)
@mstarzinger and I discussed how to compute rethrow's depth argument over email chain a little, and I'm also not sure if we settled on a conclusion.
Which exception to rethrow
The first version of EH proposal had an immediate argument to specify which exceptions on the stack to rethrow. So
try
...
catch 1
...
block
...
try
...
catch 2
...
try
...
catch 3
...
rethrow N
end
end
end
...
end
In this example, N is used to disambiguate which caught exception is being rethrown. It could rethrow any of the three caught exceptions. Hence, rethrow 0 corresponds to the exception caught by catch 3, rethrow 1 corresponds to the exception caught by catch 2, and rethrow 3 corresponds to the exception caught by catch 1.
I don't see any use cases of this in C++, but I recall @rossberg suggested to keep this for other languages. Is that right?