use super::*;
#[test]
fn decompile_infers_entry_stack_argument_for_syscall_only_helper() {
let nef_bytes = build_nef(&[
0x0C, 0x01, b'x', 0x34, 0x03, 0x40, 0x41, 0xCF, 0xE7, 0x47, 0x96, 0x40, ]);
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("fn sub_0x0006(arg0)"),
"syscall-only helper should infer one entry-stack argument: {high_level}"
);
assert!(
high_level.contains("syscall(\"System.Runtime.Log\", arg0)"),
"syscall-only helper should consume inferred argument instead of ???: {high_level}"
);
assert!(
!decompilation
.warnings
.iter()
.any(|warning| warning
.contains("missing syscall argument values for System.Runtime.Log")),
"syscall-only helper should not emit missing-argument warnings: {:?}",
decompilation.warnings
);
}
#[test]
fn decompile_infers_entry_stack_arguments_for_packmap_helper() {
let nef_bytes = build_nef(&[
0x14, 0x13, 0x12, 0x11, 0x34, 0x03, 0x40, 0x12, 0xBE, 0x40, ]);
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("fn sub_0x0007(arg0, arg1, arg2, arg3)"),
"PACKMAP helper should infer four entry-stack arguments: {high_level}"
);
assert!(
high_level.contains("Map("),
"PACKMAP helper should render a map expression: {high_level}"
);
assert!(
!high_level.contains("???"),
"PACKMAP helper should consume inferred arguments instead of placeholders: {high_level}"
);
}
#[test]
fn decompile_infers_entry_stack_arguments_for_memcpy_helper() {
let nef_bytes = build_nef(&[
0x11, 0x11, 0x11, 0x11, 0x11, 0x34, 0x03, 0x40, 0x89, 0x40, ]);
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("fn sub_0x0008(arg0, arg1, arg2, arg3, arg4)"),
"MEMCPY helper should infer five entry-stack arguments: {high_level}"
);
assert!(
high_level.contains("memcpy("),
"MEMCPY helper should render the memcpy helper call: {high_level}"
);
assert!(
!high_level.contains("???"),
"MEMCPY helper should consume inferred arguments instead of placeholders: {high_level}"
);
}
#[test]
fn decompile_infers_entry_stack_argument_for_popitem_helper() {
let nef_bytes = build_nef(&[
0xC2, 0x34, 0x03, 0x40, 0xD4, 0x40, ]);
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("fn sub_0x0004(arg0)"),
"POPITEM helper should infer one entry-stack argument: {high_level}"
);
assert!(
high_level.contains("pop_item(arg0)"),
"POPITEM helper should consume the inferred collection argument: {high_level}"
);
assert!(
!high_level.contains("???"),
"POPITEM helper should not invent a second argument placeholder: {high_level}"
);
}
#[test]
fn decompile_infers_entry_stack_arguments_for_pick_helper() {
let nef_bytes = build_nef(&[
0x12, 0x11, 0x34, 0x03, 0x40, 0x11, 0x4D, 0x40, ]);
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("fn sub_0x0005(arg0, arg1)"),
"PICK helper should infer two entry-stack arguments: {high_level}"
);
assert!(
!high_level.contains("???"),
"PICK helper should consume inferred arguments instead of placeholders: {high_level}"
);
}
#[test]
fn decompile_infers_entry_stack_arguments_for_roll_helper() {
let nef_bytes = build_nef(&[
0x12, 0x11, 0x34, 0x03, 0x40, 0x11, 0x52, 0x40, ]);
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("fn sub_0x0005(arg0, arg1)"),
"ROLL helper should infer two entry-stack arguments: {high_level}"
);
assert!(
!high_level.contains("???"),
"ROLL helper should consume inferred arguments instead of placeholders: {high_level}"
);
}
#[test]
fn decompile_infers_entry_stack_arguments_for_xdrop_helper() {
let nef_bytes = build_nef(&[
0x12, 0x11, 0x34, 0x03, 0x40, 0x11, 0x48, 0x40, ]);
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("fn sub_0x0005(arg0, arg1)"),
"XDROP helper should infer two entry-stack arguments: {high_level}"
);
assert!(
!high_level.contains("???"),
"XDROP helper should consume inferred arguments instead of placeholders: {high_level}"
);
}
#[test]
fn decompile_infers_entry_stack_arguments_for_reversen_helper() {
let nef_bytes = build_nef(&[
0x13, 0x12, 0x11, 0x34, 0x03, 0x40, 0x13, 0x55, 0x40, ]);
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("fn sub_0x0006(arg0, arg1, arg2)"),
"REVERSEN helper should infer three entry-stack arguments: {high_level}"
);
assert!(
!high_level.contains("???"),
"REVERSEN helper should consume inferred arguments instead of placeholders: {high_level}"
);
}