I spent my share of time debugging errors like: null function or function signature mismatch that, as the error suggest, it's unclear to pin point.
must_throw
Preliminary proposal
Adding a new function signature, must_throw. Function with signature must_throw take no inputs, have no outputs, and must provably throw an exception.
Changes in validation rules
Functions with signature must_throw can be called with call and call_indirect of any signature without being checked, given they guarantee to throw and so are compatible with a variable amount of inputs and outputs.
Functions with signature must_throw must provably throw. A strict version could be no control flow allowed and ending up in a throw. Or only forward control flow plus throws in all path.
Use case
Primary usage I had in mind is for this feature is for having a must_throw function placed at index 0 in a function table, so that performing load + call_indirect, that is a common pattern for possibly unset virtual calls (due to null pointer dereferences), will not anymore trigger a RuntimeError due to signature mismatch BUT will call the relevant error function, that allows to customize behaviour, and allows toolchains to offer better error messages.
Alternatives
Alternative to offer a better developer or user experience currently do incur a runtime cost and this pattern is, as far as I am aware, still prevalent and somewhat of an clunky angle of WebAssembly.
Open questions
There is some design space on exact validation rules, such as:
- what control flow are allowed for
must_throw functions?
- can
must_throw call other functions? with what rules? (it becomes hard to guarantee loops can be avoided, if that is a concern)
- can a
call or call_indirect also have must_throw signature?
Single block, no further calls, and only used in declarations is enough for my scope, but they might be unnecessary restrictive and prevent further usage of this must_throw.
Does this is covered by already existing proposals or have interactions with them?
Also questions whether this in some form has a reasonable shot at standisation and feedback from toolchain developers on whether this might actually solve a problem would be cool.
Very much looking forward for feedback, thanks!
I spent my share of time debugging errors like:
null function or function signature mismatchthat, as the error suggest, it's unclear to pin point.must_throwPreliminary proposal
Adding a new function signature,
must_throw. Function with signaturemust_throwtake no inputs, have no outputs, and must provably throw an exception.Changes in validation rules
Functions with signature
must_throwcan be called withcallandcall_indirectof any signature without being checked, given they guarantee to throw and so are compatible with a variable amount of inputs and outputs.Functions with signature
must_throwmust provably throw. A strict version could be no control flow allowed and ending up in athrow. Or only forward control flow plusthrows in all path.Use case
Primary usage I had in mind is for this feature is for having a
must_throwfunction placed at index 0 in a function table, so that performingload+call_indirect, that is a common pattern for possibly unset virtual calls (due to null pointer dereferences), will not anymore trigger a RuntimeError due to signature mismatch BUT will call the relevant error function, that allows to customize behaviour, and allows toolchains to offer better error messages.Alternatives
Alternative to offer a better developer or user experience currently do incur a runtime cost and this pattern is, as far as I am aware, still prevalent and somewhat of an clunky angle of WebAssembly.
Open questions
There is some design space on exact validation rules, such as:
must_throwfunctions?must_throwcall other functions? with what rules? (it becomes hard to guarantee loops can be avoided, if that is a concern)callorcall_indirectalso havemust_throwsignature?Single block, no further calls, and only used in declarations is enough for my scope, but they might be unnecessary restrictive and prevent further usage of this
must_throw.Does this is covered by already existing proposals or have interactions with them?
Also questions whether this in some form has a reasonable shot at standisation and feedback from toolchain developers on whether this might actually solve a problem would be cool.
Very much looking forward for feedback, thanks!