Add interpreter support for the exception handling proposal (#1749)
Details about the implementation approach:
* Try blocks generate metadata tracking the instruction ranges for the
handlers and which exception tags are handled (or if a `catch_all` is
present). The metadata is stored in a function's `FuncDesc`, and is
transferred into the `Frame` when a function call is executed.
* The stack is unwound when a `throw` is executed. This unwinding also
handles tag dispatch to the appropriate catch. The metadata to find
the matching handler is looked up in the call `Frame` stack.
* If a `try-delegate` is present, it is used in the stack unwinding
process to skip over to the relevant handler.
* A separate `exceptions_` stack in call frames tracks caught
exceptions that can be accessed via a `rethrow`. The stack is popped
on exit from a try block or when exiting via control instructions
like `br`.
* Because stack unwinding relies on finding metadata in the call
frame, `return_call` needs to be modified slightly to adjust the
current frame when executing the call, rather than re-using the
frame completely as-is.