HashX bugfix and error path refactoring, for issue 40794
The main purpose of this is to fix a segfault bug that shows when mprotect() fails to set a memory page read-execute. This is documented in issue 40794. To fix this without introducing unsatisfactory side-effects like surprise tor_assert()s or infinite loops, it was necessary to refactor the API a bit so that error conditions can be uniquely identified and the interpreter can be easily and efficiently used any time the compiler is unavailable.
This also makes a couple related quality-of-life improvements: On solve, REND logging indicates the effort, time taken, and the implementation that was chosen. There's also a new torrc config option (CompiledProofOfWorkHash) for manually enabling and disabling the HashX compiler, which would have been useful for diagnosing and working around a problem like this.