use miden_assembly::package::Package;
use super::*;
use crate::test_utils::TestHost;
#[test]
fn test_advice_provider() {
let kernel_source = "
pub proc foo
push.2323 mem_store.100 push.11 emit drop
end
";
let program_source = "
@locals(4)
proc truncate_stack
loc_storew_be.0 dropw movupw.3
sdepth neq.16
while.true
dropw movupw.3
sdepth neq.16
end
loc_loadw_be.0
end
# mainly used to break basic blocks
proc noop
swap swap
end
# tests different cases of batch sizes
proc basic_block
# batch with 1 group
swap drop swap push.1 emit drop
call.noop
# batch with 2 groups
push.1 drop push.2 emit drop
call.noop
# batch with 3 groups (rounded up to 4)
push.1 push.2 drop drop push.3 emit drop
call.noop
# batch with 5 groups (rounded up to 8)
push.1 push.2 push.3 push.4 drop drop drop drop push.4 emit drop
call.noop
# batch with 8 pushes (which forces a noop to be inserted in the last position of the batch)
push.0 push.1 push.2 push.3 push.4 push.5 push.6 push.7 push.5 emit drop
call.noop
# basic block with >1 batches (where clk needs to be incremented in-between batches due to the inserted RESPAN)
push.0 push.1 push.2 push.3 push.4 push.5 push.6 push.6 emit drop
drop drop drop drop drop drop drop drop drop push.7 emit drop
end
proc exec_me
push.22 mem_store.0
push.9 emit drop
end
proc dyncall_me
push.23 mem_store.0
push.100 emit drop
end
proc dynexec_me
push.24 mem_store.0
push.101 emit drop
end
proc will_syscall
syscall.foo
end
proc control_flow
# if true
push.1 push.16 emit drop if.true
swap swap push.17 emit drop
else
swap swap
end
# if false
push.0 push.18 emit drop if.true
swap swap
else
swap swap push.19 emit drop
end
# loop
push.3 push.1
while.true
push.20 emit drop
sub.1 dup neq.0
end
push.21 emit drop
end
begin
# check that initial state is consistent
push.0 emit drop push.10 add drop push.1 emit drop
# check that basic blocks are handled correctly
exec.basic_block
# check that memory state is restored properly after call
push.42 mem_store.0 push.8 emit drop
exec.exec_me
push.10 emit drop
# check that syscalls are handled correctly
call.will_syscall
push.12 emit drop
# check that dyncalls are handled correctly
procref.dyncall_me mem_storew_le.4 dropw push.4 dyncall push.13 emit drop
procref.will_syscall mem_storew_le.8 dropw push.8 dyncall push.14 emit drop
# check that dynexecs are handled correctly
procref.dynexec_me mem_storew_le.4 dropw push.4 dynexec push.15 emit drop
# check that control flow operations are handled correctly
exec.control_flow
exec.truncate_stack
push.22 emit drop
end
";
let (program, kernel_lib) = {
let source_manager = Arc::new(DefaultSourceManager::default());
let kernel = parse_kernel_source(source_manager.clone(), kernel_source);
let kernel_lib = Assembler::new(source_manager.clone())
.assemble_kernel("kernel", kernel, None)
.map(Arc::<Package>::from)
.unwrap();
let program = Assembler::with_kernel(source_manager, kernel_lib.clone())
.unwrap()
.assemble_program("program", program_source)
.unwrap()
.unwrap_program();
(program, kernel_lib)
};
let mut fast_host = TestHost::with_kernel_forest(kernel_lib.mast_forest().clone());
let processor = FastProcessor::new(StackInputs::default())
.with_advice(AdviceInputs::default())
.expect("advice inputs should fit advice map limits");
let fast_stack_outputs = processor.execute_sync(&program, &mut fast_host).unwrap().stack;
insta::assert_debug_snapshot!("stack_outputs", fast_stack_outputs);
insta::assert_debug_snapshot!("event_checkpoints", fast_host.snapshots());
}