Expand description
jdc-core — machine-neutral decompiler core.
A decompiler is a pipeline: machine code → CFG → per-block expressions → control-flow structuring → statement tree → refinement passes → source.
Only the first two steps know anything about the source machine (JVM .class
operand stack, DEX registers, …). Everything after them operates on the
machine-neutral IR defined here, and that is what this crate provides.
front-end (machine-specific) jdc-core (machine-neutral)
────────────────────────── ──────────────────────────
parse bytes / decode cfg::Cfg blocks + edges
build expressions per block ──────────► ir::BlockResult stmts + term
synthesize a VarTable structure::Structurer / sese
machine idioms (javac / d8 / R8 / ...) ──► convert::Converter (Region → Stmt)
your refinement passes ───────────────────► emit::Printer Java source text
(the shared pass suite is the last
piece still living front-end-side)The front-end implements ctx::Ctx (naming, type queries, nested method
bodies) and fills cfg::Cfg + ir::BlockResult. See docs/CONTRACT.md
for the exact obligations, and tests/toy_frontend.rs for a complete
non-JVM example.
Re-exports§
pub use ctx::ctx_method_body;pub use ctx::Ctx;pub use ctx::Family;pub use ctx::MethodBody;pub use ctx::NestedClass;pub use ctx::NestedKind;pub use ctx::NullCtx;pub use ir::BlockResult;pub use ir::Expr;pub use ir::Stmt;pub use ir::SwitchTargets;pub use ir::Term;
Modules§
- analysis
- Machine-neutral statement/CFG predicates shared by the structuring and emission layers.
- cfg
- Machine-neutral control-flow graph.
- convert
- Region tree → Stmt tree conversion.
- ctx
- What the core needs to ask the front-end.
- dbg
- Process-lifetime caches for debug environment flags.
- emit
- Java source emission from the statement/expression tree.
- ir
- Machine-neutral IR: expressions, statements, and the per-block build result.
- rename
- Case-collision class renames. Obfuscators emit class pairs differing
only in letter case (
X/CUAvsX/Cua); on case-insensitive filesystems both map to one physical file — one class’s output was lost. The front-end driver computes a deterministic rename (suffix_2,_3, … on the simple name, first-in-sorted-group unchanged) and installs it here before workers spawn; declarations, references and file names then all agree. - sese
- From-scratch SESE / dominator-tree control-flow structurer.
- structure
- Control flow structuring: CFG of basic blocks → nested region tree.
- types
- Machine-neutral type model.
- typeutil
- Pure helpers over the generic type model.
- var
- Local variable allocation: maps bytecode slots (possibly reused across disjoint pc ranges) to named variables. Variable table: what the front-end knows about a method’s locals.