This patch makes binaryen easier to call from other applications by making more errors recoverable instead of early-exiting.
The main thing it does is change three calls to exit on I/O errors into calls to Fatal(), which is an existing custom abstraction for handling unrecoverable errors. Currently Fatal's destructor calls _Exit(1).
My intent is to make it possible for Fatal to not exit, but to throw, allowing an embedding application to catch the exception.
Because the previous early exits were exiting with error code EXIT_FAILURE, I also changed Fatal to exit with EXIT_FAILURE. The test suite continues to pass so I assume this is ok.
Next I changed Fatal to buffer its error message until the destructor instead of immediately printing it to stderr. This is for ease of patching Fatal to throw instead.
Finally, I also included the patch I need to make Fatal throw when THROW_ON_FATAL is defined at compile time. I can carry this patch out of tree, but it is a small patch, so perhaps you will be willing to take it. I am happy to remove it.
The aforementioned patch throws in a dtor, which is so strongly discouraged that it requires a special noexcept(false) annotation in c++17, the pitfall being that it is easy to throw during unwinding, which causes an abort. This is a special type though that only exists on error paths, and this solution is the smallest solution that might work for my use case. I have accounted for double throws by inserting an explicit abort in that case.
I have run the test suite successfully, but have not manually tested that fatal errors print the same as previously. I have tested that the patch throws exceptions that can be recovered in my project https://github.com/brson/wasm-opt-rs
Fixes #4938