use rwasm::{
always_failing_syscall_handler, instruction_set, ExecutionEngine, ImportLinker, InstructionSet,
RwasmModuleBuilder, RwasmStore, TrapCode,
};
fn execute(code_section: InstructionSet, data: &[u8], elem: &[u32]) -> Result<(), TrapCode> {
let module = RwasmModuleBuilder::new(code_section)
.with_data_section(data)
.with_elem_section(elem)
.build();
let engine = ExecutionEngine::new();
let mut store = RwasmStore::new(
ImportLinker::default().into(),
(),
always_failing_syscall_handler,
None,
None,
);
engine
.execute(&mut store, &module, &[], &mut [])
.map(|_| ())
}
fn data_drop_code(dropped: &[u32]) -> InstructionSet {
let mut code = instruction_set! {
I32Const(1)
MemoryGrow
Drop
};
for segment in dropped {
code.op_data_drop(*segment);
}
code.op_i32_const(0); code.op_i32_const(0); code.op_i32_const(1); code.op_memory_init(5);
code.op_return();
code
}
fn elem_drop_code(dropped: &[u32]) -> InstructionSet {
let mut code = instruction_set! {
I32Const(0) I32Const(1) TableGrow(0)
Drop
};
for segment in dropped {
code.op_elem_drop(*segment);
}
code.op_i32_const(0); code.op_i32_const(0); code.op_i32_const(1); code.op_table_init(5);
code.op_table_get(0); code.op_return();
code
}
#[test]
fn test_data_drop_keeps_higher_dropped_segments() {
let data = &[0xaa, 0xbb, 0xcc, 0xdd];
assert_eq!(execute(data_drop_code(&[]), data, &[]), Ok(()));
assert_eq!(
execute(data_drop_code(&[5]), data, &[]),
Err(TrapCode::MemoryOutOfBounds),
);
assert_eq!(
execute(data_drop_code(&[5, 2]), data, &[]),
Err(TrapCode::MemoryOutOfBounds),
);
}
#[test]
fn test_elem_drop_keeps_higher_dropped_segments() {
let elem = &[1u32, 2, 3, 4];
assert_eq!(execute(elem_drop_code(&[]), &[], elem), Ok(()));
assert_eq!(
execute(elem_drop_code(&[5]), &[], elem),
Err(TrapCode::TableOutOfBounds),
);
assert_eq!(
execute(elem_drop_code(&[5, 2]), &[], elem),
Err(TrapCode::TableOutOfBounds),
);
}