Skip to content

Commit

Permalink
[WIP][compiler-v2] Ast generator from stackless bytecode
Browse files Browse the repository at this point in the history
Converter from stackless bytecode into Model AST. We already have one from binary format to stackless.

This will be useful in many places in the stack, not at least for debugging, but also as a potential different approach to decompilation. For the later, we still need to create an AST -> Move translator, today we have only debug dump.
  • Loading branch information
wrwg committed Sep 2, 2024
1 parent 2dc4e05 commit 8394da1
Show file tree
Hide file tree
Showing 7 changed files with 842 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// -- Model dump before bytecode pipeline
module 0x815::m {
private fun some_f(x: u64): u64 {
x
}
private fun t1(c: bool): bool {
c
}
private fun t2(c: bool): bool {
if c {
false
} else {
true
}
}
private fun t3(c: u64) {
loop {
if Gt<u64>(c, 0) {
c: u64 = m::some_f(c)
} else {
break
}
}
}
} // end 0x815::m

============ initial bytecode ================

[variant baseline]
fun m::some_f($t0: u64): u64 {
var $t1: u64
0: $t1 := infer($t0)
1: return $t1
}


[variant baseline]
fun m::t1($t0: bool): bool {
var $t1: bool
0: $t1 := infer($t0)
1: return $t1
}


[variant baseline]
fun m::t2($t0: bool): bool {
var $t1: bool
0: if ($t0) goto 1 else goto 4
1: label L0
2: $t1 := false
3: goto 6
4: label L1
5: $t1 := true
6: label L2
7: return $t1
}


[variant baseline]
fun m::t3($t0: u64) {
var $t1: bool
var $t2: u64
var $t3: u64
0: label L0
1: $t2 := 0
2: $t1 := >($t0, $t2)
3: if ($t1) goto 4 else goto 8
4: label L2
5: $t3 := m::some_f($t0)
6: $t0 := infer($t3)
7: goto 10
8: label L3
9: goto 12
10: label L4
11: goto 0
12: label L1
13: return ()
}

generated AST for some_f:
return x
generated AST for t1:
return c
generated AST for t2:
if c {

} else {
NoOp()
}
generated AST for t3:
$t2: u64 = m::some_f(c);
$t2: u64 = 0;
if $t1 {

} else {
NoOp()
}

============ bytecode verification succeeded ========
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module 0x815::m {

fun some_f(x: u64): u64 {
x
}

fun t1(c: bool): bool {
c
}

fun t2(c: bool): bool {
if (c) false else true
}

fun t3(c: u64) {
while (c > 0) c = some_f(c)
}

fun t4(c: u64) {
while (c > 0) {
if (c > 10) {
c = some_f(c)
}
}
}

}
18 changes: 17 additions & 1 deletion third_party/move/move-compiler-v2/tests/testsuite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use move_compiler_v2::{
};
use move_model::{metadata::LanguageVersion, model::GlobalEnv};
use move_prover_test_utils::{baseline_test, extract_test_directives};
use move_stackless_bytecode::function_target_pipeline::FunctionTargetPipeline;
use move_stackless_bytecode::{ast_generator, function_target_pipeline::FunctionTargetPipeline};
use once_cell::unsync::Lazy;
use std::{
cell::{RefCell, RefMut},
Expand Down Expand Up @@ -690,6 +690,7 @@ fn run_test(path: &Path, config: TestConfig) -> datatest_stable::Result<()> {
logging::setup_logging_for_testing();
let path_str = path.display().to_string();
let mut options = config.options.clone();
let run_ast_generator = path_str.contains("/ast-generator/");
options.warn_unused = path_str.contains("/unused/");
options.warn_deprecated = path_str.contains("/deprecated/");
options.compile_verify_code = path_str.contains("/verification/verify/");
Expand Down Expand Up @@ -812,6 +813,21 @@ fn run_test(path: &Path, config: TestConfig) -> datatest_stable::Result<()> {
}
},
);
if run_ast_generator {
let out = &mut test_output.borrow_mut();
for (fun_id, variant) in targets.get_funs_and_variants() {
let fun_env = env.get_function(fun_id);
let target = targets.get_target(&fun_env, &variant);
if let Some(exp) = ast_generator::generate_ast(&target) {
out.push_str(&format!(
"generated AST for {}:\n{}\n",
target.func_env.get_name_str(),
exp.display(&env)
));
}
}
}

if *ok.borrow() && config.stop_after == StopAfter::FileFormat {
let units = run_file_format_gen(&mut env, &targets);
let out = &mut test_output.borrow_mut();
Expand Down
Loading

0 comments on commit 8394da1

Please sign in to comment.