use super::super::super::*;
use crate::instruction::OpCode;
#[test]
fn high_level_lifts_rot_operation() {
let script = [
OpCode::Push1.byte(),
OpCode::Push2.byte(),
OpCode::Push3.byte(),
OpCode::Rot.byte(),
OpCode::Ret.byte(),
];
let nef_bytes = build_nef(&script);
let decompilation = Decompiler::new()
.decompile_bytes(&nef_bytes)
.expect("decompile succeeds");
let high_level = decompilation
.high_level
.as_deref()
.expect("high-level output");
assert!(
high_level.contains("return 1;") || high_level.contains("return t0;"),
"ROT should expose the rotated-to-top value via return: {high_level}",
);
}
#[test]
fn high_level_lifts_tuck_operation() {
let script = [
OpCode::Push1.byte(),
OpCode::Push2.byte(),
OpCode::Tuck.byte(),
OpCode::Ret.byte(),
];
let nef_bytes = build_nef(&script);
let decompilation = Decompiler::new()
.decompile_bytes(&nef_bytes)
.expect("decompile succeeds");
let high_level = decompilation
.high_level
.as_deref()
.expect("high-level output");
let returns_any_temp_or_two = ["return 2;", "return t1;", "return t2;"]
.iter()
.any(|needle| high_level.contains(needle));
assert!(
returns_any_temp_or_two,
"TUCK should leave PUSH2's value (or its copy) as the top of the lifted return: {high_level}",
);
}