fs: throw errors from sync branches instead of separate implementations
Previously to throw errors from C++ land, sync versions of the fs were created by copying C++ code from the original implementation and moving JS code to a separate file. This can lead to several problems:
- By moving code to a new file for the sake of moving, it would be harder to use git blame to trace changes and harder to backport changes to older branches.
- Scattering the async and sync versions of fs methods in different files makes it harder to keep them in sync and share code in the prologues and epilogues.
- Having two copies of code doing almost the same thing results in duplication and can be prone to out-of-sync problems when the prologue and epilogue get updated.
- There is a minor cost to startup in adding an additional file. This can add up even with the help of snapshots.
This patch moves the JS code back to lib/fs.js to stop 1, 2 & 4 and introduces C++ helpers SyncCallAndThrowIf() and SyncCallAndThrowOnError() so that the original implementations can be easily tweaked to allow throwing from C++ and stop 3.