-
Notifications
You must be signed in to change notification settings - Fork 36
Change try ... catch
+ br_on_exn
to br_on_catch{,_else}
?
#80
Comments
try ... catch
to br_on_throw
?try ... catch
+ br_on_exn
to br_on_throw{,_else}
?
try ... catch
+ br_on_exn
to br_on_throw{,_else}
?try ... catch
+ br_on_exn
to br_on_catch{,_else}
?
Edit: forgot a backtick. BTW, this also mirrors much more closely the code generated by compilers for lightweight exception handling, so they wouldn't necessarily need to alter their code generation for that as much, and it'd be a little easier to stream. (99% of the setup code in practice is on the
That
For comparison, it might be compiled like this with
And one other thing: it allows stuff like |
I don't understand. How would exceptional control flow reach |
@rossberg It wouldn't, but it wouldn't make sense for it to. Think of it like setting up traps for exceptions within a block, and the labels are just what blocks to break from when that ID is caught. The scope is specifically limited to the block it's in, and exceptions are only trapped after that instruction executes. As an alternative, I considered using |
@isiahmeadows What you are describing is basically |
@titzer Yeah, true. I was just thinking it could be a little more explicit and lower-level, but yes, it's entirely isomorphic.
Have you considered making exception IDs entirely dynamic and just putting the onus on the user to sort them out, just making it a generic mostly-untyped When compiled, a use of
And of course,
Alternatively, you could stick with
This, with dynamic IDs entirely specified by userland, would itself also allow very efficient exceptions for OCaml and other languages with lightweight exceptions: they could set the "ID" to the type value, the "value" to the instance data, and throw it with near zero overhead. And the engine could support that with a custom calling convention that makes exceptions sufficiently cheap (like what OCaml's native compiler does) - the calling convention of JIT-compiled WebAssembly bytecode is normally an implementation detail. |
@isiahmeadows How would you be able to catch exceptions from the embedder in this scheme? And also hold and release references to these exception objects? |
@binji Embedders could just throw and catch exceptions with special IDs and values of their own, more or less the same way userland code would. Of course, this could conflict with existing user IDs, but it also allows easy integration with them even from embedder code. (And compilers could offer a mechanism to remap native exceptions of particular IDs to userland exception types, if necessary. This would also inform the compiler what IDs they have to avoid internally.) As for holding and releasing references, embedders could just provide an API to free a value pointer if it requires allocation of some kind, and userland can just store it (or its contents) in allocated linear memory, locals, or similar. The exception value may need altered to be an |
The problem that generative exception IDs solve is that a language cannot confuse one of its exceptions with that from another language runtime (or another instance of the same runtime). Keep in mind that Wasm is an open, heterogeneous system, such that execution may mix multiple different languages compiled to Wasm. |
Fair. |
I'll close this for now, and I might revisit it later if I come up with a better suggestion that's a little less radical. |
The data count section has a count that must match the number of data segments. If the data count section isn't present, then `memory.init` and `data.drop` cannot be used. Fixes issue WebAssembly#73.
Uh oh!
There was an error while loading. Please reload this page.
Edit: Redid a couple things.
After reading #58 and that eventually getting merged in #71, I feel you could remove
try ... catch ... end
altogether and simplify the branching generation a lot by just unifyingtry ... catch
andbr_on_exn
with a genericbr_on_catch len ($lbl $id)+
andbr_on_catch_else len ($lbl $id)* $default_lbl
that operate more like abr_table
for exceptions. The label of the corresponding block for$default_lbl
must be a(result except_ref)
, but the rest just need to match the corresponding exception. Andexcept_ref
can only be plugged into arethrow
, manipulated as an opaque parameter, local, or result, or dropped.The
br_on_catch
is sugar forbr_on_catch_else
, just with the default branch always rethrowing. (This is very commonly the case, so I felt it was worth including.)This would make the corresponding grammar look like this:
And of course, this makes the code a lot smaller with no loss in power. (You can always organize your blocks to have shared logic as appropriate - it's roughly the same amount of code, and you'd likely need to do it anyways in the case of C++ exception handling.)
The text was updated successfully, but these errors were encountered: