Skip to content

Commit

Permalink
Display closure args, various fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Gui-Yom committed Jul 18, 2022
1 parent 66fabb9 commit 967c0f1
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 8 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Handle expressions and statements
- Generate code with proper indentation
- Handle branches and while loops
- Handle early returns, constructors and closures
- Handle early returns, constructors, closures and methods
- break and continue statements
- Partial result with \[missing expr]
- Initial support for primitive array accesses
- Decompile whole classes
- Anonymous structures
- Initial support for enums

### Changed

- Callgraph generation is now a default feature
- Improve opcode display
- Make bytecode elements serialization and deserialization functions public
- Global function indexes are resolved through a vec instead of a map
- Return a custom error type instead of using anyhow
14 changes: 9 additions & 5 deletions src/decompiler/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ impl Method {
fmtools::fmt! { move
{opts} if self.static_ { "static " } if self.dynamic { "dynamic " }
"function "{fun.name(ctx).unwrap()}"("
{fmtools::join(", ", fun.ty(ctx).args.iter().enumerate().skip(if self.static_ { 0 } else { 1 })
{fmtools::join(", ", fun.args(ctx).iter().enumerate().skip(if self.static_ { 0 } else { 1 })
.map(move |(i, arg)| fmtools::fmt! {move
{fun.arg_name(ctx, i).unwrap_or("_")}": "{to_haxe_type(fun.ty(ctx).ret.resolve(&ctx.types), ctx)}
{fun.arg_name(ctx, i).unwrap_or("_")}": "{to_haxe_type(arg.resolve(&ctx.types), ctx)}
}))}
")" if !fun.ty(ctx).ret.is_void() { ": "{to_haxe_type(fun.ty(ctx).ret.resolve(&ctx.types), ctx)} } " {"

Expand Down Expand Up @@ -188,11 +188,15 @@ impl Expr {
"new "{ty.display(code)}"("{fmtools::join(", ", args.iter().map(|e| disp!(e)))}");"
}
Expr::Closure(f, stmts) => {
// TODO display closure args
"() -> {\n"
let fun = f.resolve_as_fn(code).unwrap();
"("{fmtools::join(", ", fun.ty(code).args.iter().enumerate().map(move |(i, arg)|
fmtools::fmt! { move
{fun.arg_name(code, i).unwrap_or("_")}": "{to_haxe_type(arg.resolve(&code.types), code)}
}
))}") -> {\n"
let indent2 = indent.inc_nesting();
for stmt in stmts {
{indent2}{stmt.display(&indent2, code, f.resolve_as_fn(code).unwrap())}"\n"
{indent2}{stmt.display(&indent2, code, fun)}"\n"
}
{indent}"}"
}
Expand Down
12 changes: 10 additions & 2 deletions src/decompiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,11 @@ pub fn decompile_function(code: &Bytecode, f: &Function) -> Vec<Statement> {

let mut start = 0;
// First argument / First register is 'this'
if f.is_method() || f.name.unwrap().resolve(&code.strings) == "__constructor__" {
if f.is_method()
|| f.name
.map(|n| n.resolve(&code.strings) == "__constructor__")
.unwrap_or(false)
{
reg_state.insert(Reg(0), cst_this());
start = 1;
}
Expand Down Expand Up @@ -591,7 +595,11 @@ pub fn decompile_function(code: &Bytecode, f: &Function) -> Vec<Statement> {
dst,
Expr::Field(
Box::new(expr!(obj)),
fun.resolve_as_fn(code).unwrap().name.unwrap().display(code),
fun.resolve_as_fn(code)
.unwrap()
.name(code)
.unwrap_or("_")
.to_owned(),
)
);
}
Expand Down
8 changes: 8 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,14 @@ impl Function {
self.t.resolve_as_fun(&code.types).expect("Unknown type ?")
}

pub fn args<'a>(&self, code: &'a Bytecode) -> &'a [RefType] {
&self.ty(code).args
}

pub fn ret<'a>(&self, code: &'a Bytecode) -> &'a Type {
self.ty(code).ret.resolve(&code.types)
}

/// Uses the assigns to find the name of an argument
pub fn arg_name<'a>(&self, code: &'a Bytecode, pos: usize) -> Option<&'a str> {
self.assigns.as_ref().and_then(|a| {
Expand Down

0 comments on commit 967c0f1

Please sign in to comment.