| bcode-flow | ||
| common | ||
| parser-raw | ||
| parser-resolve | ||
| test-utils | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| README.md | ||
Ferrobean is a project aiming to turn java code into Rust code. At the moment, this is accomplished by parsing the bytecode and decompiling it into the Rust source.
Curent state
java.base
- parses all the bytecode
- parses most of the control flow
Diversions from the spec
In my model, return never throws. As per spec, return can throw InvalidMonitorStateException, while existing from a synchronized method without a held monitor.
In my model, InvalidMonitorState is thrown by the calling scope.
javac on my machine generates exception handling tables such that they avoid handling exceptions thrown by return. However, the bytecode technically can be written such that these exceptions are handled, and in this case, generated Rust code will exhibit different behavior.
At the moment, following limitations apply to exception handling:
- Handler handling exception thrown by itself will not work correctly: it will try to handle it exactly once.
- Handlers are assumed to be blocks of code, i.e. range of thee code covered by a single handler is assumed to be a contiguous code block.
- Limitation above has some consequences alleviated: if there are several ranges or code covered by a single handler, they still will be merged into a single
tryblock, but the "gaps" in this range, will be wrapped into special "negative try" blocks, specifically disabling some of the handlers. - However, handling still can work incorrectly, even with them. Consider the following handling table:
| start | end | handler |
|---|---|---|
| 1 | 6 | 6 |
| 2 | 5 | 7 |
| 3 | 4 | 6 |
With current implementation, it instead behaves like
| start | end | handler |
|---|---|---|
| 1 | 6 | 6 |
| 2 | 5 | 7 |
i.e. a fully-contained handler is ignored, and assumed to be a part of the bigger handler. from my experimentation, there's no way to generate such table with javac, but the possibility of forging a bytecode such that it handles exceptions in a spec-non-compliant way is out there.
My model also assumes that there can be two handlers with identical full range, but different gap ranges.
- I assume there can be no direct jumps to handlers