diff --git a/src/riscv/lib/src/interpreter/rv32a.rs b/src/riscv/lib/src/interpreter/rv32a.rs index 79eb19d576ff64f5015a68ebc71413a76cf566c5..20150c7b5013246afcaec9ee66c61bd6a726fab5 100644 --- a/src/riscv/lib/src/interpreter/rv32a.rs +++ b/src/riscv/lib/src/interpreter/rv32a.rs @@ -219,7 +219,7 @@ where #[cfg(test)] mod test { use crate::{ - backend_test, create_backend, create_state, + backend_test, create_state, interpreter::atomics::{SC_FAILURE, SC_SUCCESS}, machine_state::{ bus::{devices::DEVICES_ADDRESS_SPACE_LENGTH, main_memory::tests::T1K}, @@ -234,8 +234,7 @@ mod test { macro_rules! test_lrsc { ($name:ident, $lr: ident, $sc: ident, $align: expr, $t: ident) => { backend_test!($name, F, { - let mut backend = create_backend!(MachineCoreStateLayout, F); - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, backend, T1K); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( @@ -277,8 +276,7 @@ mod test { macro_rules! test_amo { ($instr: ident, $f: expr, $align: expr, $t: ident) => { backend_test!($instr, F, { - let mut backend = create_backend!(MachineCoreStateLayout, F); - let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, backend, T1K); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv32c.rs b/src/riscv/lib/src/interpreter/rv32c.rs index 2fc89c6f6f343fc7e1c1cd00b0444c5cd36162c3..fb5b3b88bd9c665aef8ed83f12fc2c06866aa155 100644 --- a/src/riscv/lib/src/interpreter/rv32c.rs +++ b/src/riscv/lib/src/interpreter/rv32c.rs @@ -271,7 +271,7 @@ where #[cfg(test)] mod tests { use crate::{ - backend_test, create_backend, create_state, + backend_test, create_state, machine_state::{ bus::main_memory::tests::T1K, registers::a4, MachineCoreState, MachineCoreStateLayout, }, @@ -287,14 +287,7 @@ mod tests { (u64::MAX - 1, 100, 98_i64 as u64), ]; for (init_pc, imm, res_pc) in test_case { - let mut backend = create_backend!(MachineCoreStateLayout, F); - let mut state = create_state!( - MachineCoreState, - MachineCoreStateLayout, - F, - backend, - T1K - ); + let mut state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); state.hart.pc.write(init_pc); let new_pc = state.hart.run_cj(imm); @@ -305,14 +298,7 @@ mod tests { }); backend_test!(run_caddi, F, { - let mut backend = create_backend!(MachineCoreStateLayout, F); - let state = create_state!( - MachineCoreState, - MachineCoreStateLayout, - F, - backend, - T1K - ); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv32i.rs b/src/riscv/lib/src/interpreter/rv32i.rs index 11a4642fd5e337eb12a75aea386585ccd66e4afa..14e8f24bb950e7d6ed1ff1d7fe713bf86660b86d 100644 --- a/src/riscv/lib/src/interpreter/rv32i.rs +++ b/src/riscv/lib/src/interpreter/rv32i.rs @@ -372,7 +372,7 @@ where #[cfg(test)] mod tests { use crate::{ - backend_test, create_backend, create_state, + backend_test, create_state, machine_state::{ bus::{main_memory::tests::T1K, Address}, csregisters::{ @@ -415,8 +415,7 @@ mod tests { ]; for (imm, rs1, rd, res) in imm_rs1_rd_res { - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); state.xregisters.write(a0, rs1); state.xregisters.write(t0, imm as u64); @@ -445,8 +444,7 @@ mod tests { ]; for (init_pc, imm, res, rd) in pc_imm_res_rd { - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); // U-type immediate only has upper 20 bits set, the lower 12 being set to 0 assert_eq!(imm, ((imm >> 20) & 0xF_FFFF) << 20); @@ -489,8 +487,7 @@ mod tests { let branch_pc = init_pc.wrapping_add(imm as u64); let next_pc = init_pc.wrapping_add(4); - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); // BEQ - different test_branch_instr!(state, run_beq, imm, t1, r1_val, t2, r2_val, init_pc, next_pc); @@ -534,8 +531,7 @@ mod tests { let branch_pc = init_pc.wrapping_add(imm as u64); let next_pc = init_pc.wrapping_add(4); - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); // lhs < rhs test_branch_instr!(state, run_blt, imm, t1, 0, t2, 1, init_pc, branch_pc); @@ -566,8 +562,7 @@ mod tests { backend_test!(test_bitwise, F, { proptest!(|(val in any::(), imm in any::())| { - let mut backend = create_backend!(XRegistersLayout, F); - let mut state = create_state!(XRegisters, F, backend); + let mut state = create_state!(XRegisters, F); // The sign-extension of an immediate on 12 bits has bits 31:11 equal the sign-bit let prefix_mask = 0xFFFF_FFFF_FFFF_F800; @@ -602,8 +597,7 @@ mod tests { backend_test!(test_bitwise_reg, F, { proptest!(|(v1 in any::(), v2 in any::())| { - let mut backend = create_backend!(XRegistersLayout, F); - let mut state = create_state!(XRegisters, F, backend); + let mut state = create_state!(XRegisters, F); state.write(a0, v1); state.write(t3, v2); @@ -644,8 +638,7 @@ mod tests { let branch_pc = init_pc.wrapping_add(imm as u64); let next_pc = init_pc.wrapping_add(4); - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); // lhs < rhs test_branch_instr!(state, run_bltu, imm, t1, r1_val, t2, r2_val, init_pc, branch_pc); @@ -684,28 +677,14 @@ mod tests { }); backend_test!(test_ebreak, F, { - let mut backend = create_backend!(MachineCoreStateLayout, F); - let state = create_state!( - MachineCoreState, - MachineCoreStateLayout, - F, - backend, - T1K - ); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); let ret_val = state.hart.run_ebreak(); assert_eq!(ret_val, Exception::Breakpoint); }); backend_test!(test_fence, F, { - let mut backend = create_backend!(MachineCoreStateLayout, F); - let state = create_state!( - MachineCoreState, - MachineCoreStateLayout, - F, - backend, - T1K - ); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( @@ -727,8 +706,7 @@ mod tests { }); backend_test!(test_ecall, F, { - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); let mode_exc = [ (Mode::User, Exception::EnvCallFromUMode), @@ -767,8 +745,7 @@ mod tests { ), ]; for (init_pc, imm, init_rs1, rs1, rd, res_pc, res_rd) in ipc_imm_irs1_rs1_rd_fpc_frd { - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); state.pc.write(init_pc); state.xregisters.write(rs1, init_rs1); @@ -795,8 +772,7 @@ mod tests { ), ]; for (init_pc, imm, rd, res_pc, res_rd) in ipc_imm_rd_fpc_frd { - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); state.pc.write(init_pc); let new_pc = state.run_jal(imm, rd); @@ -809,8 +785,7 @@ mod tests { backend_test!(test_lui, F, { proptest!(|(imm in any::())| { - let mut backend = create_backend!(XRegistersLayout, F); - let mut xregs = create_state!(XRegisters, F, backend); + let mut xregs = create_state!(XRegisters, F); xregs.write(a2, 0); xregs.write(a4, 0); @@ -826,8 +801,7 @@ mod tests { }); backend_test!(test_slt, F, { - let mut backend = create_backend!(XRegistersLayout, F); - let mut xregs = create_state!(XRegisters, F, backend); + let mut xregs = create_state!(XRegisters, F); let v1_v2_exp_expu = [ (0, 0, 0, 0), @@ -856,8 +830,7 @@ mod tests { mepc in any::
(), sepc in any::
(), )| { - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); // 4-byte align let mepc = mepc & !0b11; diff --git a/src/riscv/lib/src/interpreter/rv32m.rs b/src/riscv/lib/src/interpreter/rv32m.rs index ccccf3cb55318aee39d8df9dabda98950ba78f22..966c751af950e5021a45c3ba0017fc921afb94bb 100644 --- a/src/riscv/lib/src/interpreter/rv32m.rs +++ b/src/riscv/lib/src/interpreter/rv32m.rs @@ -142,7 +142,7 @@ where #[cfg(test)] mod test { use crate::{ - backend_test, create_backend, create_state, + backend_test, create_state, machine_state::registers::{a0, a1, a2, a3, XRegisters, XRegistersLayout}, }; use proptest::{prelude::any, prop_assert_eq, proptest}; @@ -152,8 +152,7 @@ mod test { r1_val in any::(), r2_val in any::(), )| { - let mut backend = create_backend!(XRegistersLayout, F); - let mut state = create_state!(XRegisters, F, backend); + let mut state = create_state!(XRegisters, F); state.write(a0, r1_val); state.write(a1, r2_val); @@ -173,8 +172,7 @@ mod test { r1_val in any::(), r2_val in any::(), )| { - let mut backend = create_backend!(XRegistersLayout, F); - let mut state = create_state!(XRegisters, F, backend); + let mut state = create_state!(XRegisters, F); state.write(a0, r1_val); state.write(a1, r2_val); diff --git a/src/riscv/lib/src/interpreter/rv64a.rs b/src/riscv/lib/src/interpreter/rv64a.rs index 50a670adbcfa9912b3ef4c9f8e39a59248ebd0e0..8e68f5aef1b03235aa0d57df6481f5fcfbe67c21 100644 --- a/src/riscv/lib/src/interpreter/rv64a.rs +++ b/src/riscv/lib/src/interpreter/rv64a.rs @@ -219,7 +219,7 @@ where #[cfg(test)] mod test { use crate::{ - backend_test, create_backend, create_state, + backend_test, create_state, interpreter::atomics::{SC_FAILURE, SC_SUCCESS}, machine_state::{ bus::{devices::DEVICES_ADDRESS_SPACE_LENGTH, main_memory::tests::T1K}, diff --git a/src/riscv/lib/src/interpreter/rv64d.rs b/src/riscv/lib/src/interpreter/rv64d.rs index c74058c8ea57ee09e27ca28124746dc1bd905bb6..4a7a642302a12cb1cb6cb3e1b58b1dc8826ec61b 100644 --- a/src/riscv/lib/src/interpreter/rv64d.rs +++ b/src/riscv/lib/src/interpreter/rv64d.rs @@ -549,7 +549,7 @@ mod tests { use crate::{ backend_test, bits::Bits64, - create_backend, create_state, + create_state, machine_state::{ bus::{devices::DEVICES_ADDRESS_SPACE_LENGTH, main_memory::tests::T1K}, csregisters::{ @@ -566,8 +566,7 @@ mod tests { use proptest::prelude::*; backend_test!(test_fmv_d, F, { - let mut backend = create_backend!(HartStateLayout, F); - let state = create_state!(HartState, HartStateLayout, F, backend); + let state = create_state!(HartState, HartStateLayout, F); let state_cell = std::cell::RefCell::new(state); proptest!(|( @@ -595,14 +594,7 @@ mod tests { }); backend_test!(test_load_store, F, { - let mut backend = create_backend!(MachineCoreStateLayout, F); - let state = create_state!( - MachineCoreState, - MachineCoreStateLayout, - F, - backend, - T1K - ); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv64dc.rs b/src/riscv/lib/src/interpreter/rv64dc.rs index 7ba7a2d83f3800b6d61910e1e4bb24866ac1e1c7..0cb3ab8f09890f0f9147072a24062795f8033f3f 100644 --- a/src/riscv/lib/src/interpreter/rv64dc.rs +++ b/src/riscv/lib/src/interpreter/rv64dc.rs @@ -76,7 +76,7 @@ mod test { use crate::{ backend_test, bits::Bits64, - create_backend, create_state, + create_state, machine_state::{ bus::{devices::DEVICES_ADDRESS_SPACE_LENGTH, main_memory::tests::T1K}, csregisters::{ @@ -95,14 +95,7 @@ mod test { const OUT_OF_BOUNDS_OFFSET: i64 = 1024; backend_test!(test_cfsd_cfld, F, { - let mut backend = create_backend!(MachineCoreStateLayout, F); - let state = create_state!( - MachineCoreState, - MachineCoreStateLayout, - F, - backend, - T1K - ); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( @@ -141,14 +134,7 @@ mod test { }); backend_test!(test_cfsdsp_cfldsp, F, { - let mut backend = create_backend!(MachineCoreStateLayout, F); - let state = create_state!( - MachineCoreState, - MachineCoreStateLayout, - F, - backend, - T1K - ); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv64f.rs b/src/riscv/lib/src/interpreter/rv64f.rs index ac55d22301a45eae72dace34e4ae8009568aa753..0886011bbc295b8d4ac8c24c43a0a07cf817a89f 100644 --- a/src/riscv/lib/src/interpreter/rv64f.rs +++ b/src/riscv/lib/src/interpreter/rv64f.rs @@ -555,7 +555,7 @@ mod tests { use crate::{ backend_test, bits::Bits64, - create_backend, create_state, + create_state, machine_state::{ bus::{devices::DEVICES_ADDRESS_SPACE_LENGTH, main_memory::tests::T1K}, csregisters::{ @@ -581,8 +581,7 @@ mod tests { rs1_f in (1_u8..31).prop_map(u5::new).prop_map(parse_fregister), rs2 in (1_u8..31).prop_map(u5::new).prop_map(parse_xregister), )| { - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, HartStateLayout, F, backend); + let mut state = create_state!(HartState, HartStateLayout, F); // Turn fs on let mstatus = MStatus::from_bits(0u64).with_fs(ExtensionValue::Dirty); @@ -613,14 +612,7 @@ mod tests { }); backend_test!(test_load_store, F, { - let mut backend = create_backend!(MachineCoreStateLayout, F); - let state = create_state!( - MachineCoreState, - MachineCoreStateLayout, - F, - backend, - T1K - ); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv64i.rs b/src/riscv/lib/src/interpreter/rv64i.rs index 0beb2c1e8f856d8b48d0def8d3f98564a90093a2..953de30988474ea8ad3543d97a9ef7d77e44d553 100644 --- a/src/riscv/lib/src/interpreter/rv64i.rs +++ b/src/riscv/lib/src/interpreter/rv64i.rs @@ -351,7 +351,7 @@ where #[cfg(test)] mod tests { use crate::{ - backend_test, create_backend, create_state, + backend_test, create_state, machine_state::{ bus::{devices::DEVICES_ADDRESS_SPACE_LENGTH, main_memory::tests::T1K}, hart_state::{HartState, HartStateLayout}, @@ -367,8 +367,7 @@ mod tests { imm in any::(), reg_val in any::())| { - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); state.xregisters.write(a0, reg_val as u64); state.xregisters.write(t0, imm as u64); @@ -393,8 +392,7 @@ mod tests { v1 in any::(), v2 in any::())| { - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); state.xregisters.write(t0, v1 as u64); state.xregisters.write(a0, v2 as u64); @@ -464,8 +462,7 @@ mod tests { } backend_test!(test_shift, F, { - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); // imm = 0 test_both_shift_instr!( @@ -609,8 +606,7 @@ mod tests { }); backend_test!(test_shift_w, F, { - let mut backend = create_backend!(HartStateLayout, F); - let mut state = create_state!(HartState, F, backend); + let mut state = create_state!(HartState, F); // imm = 0 test_both_shift_instr!( @@ -755,14 +751,7 @@ mod tests { }); backend_test!(test_load_store, F, { - let mut backend = create_backend!(MachineCoreStateLayout, F); - let state = create_state!( - MachineCoreState, - MachineCoreStateLayout, - F, - backend, - T1K - ); + let state = create_state!(MachineCoreState, MachineCoreStateLayout, F, T1K); let state_cell = std::cell::RefCell::new(state); proptest!(|( diff --git a/src/riscv/lib/src/interpreter/rv64m.rs b/src/riscv/lib/src/interpreter/rv64m.rs index cbcd8541ee754edefa14cae2c0cdbe2c84eb614e..29ce258317ec95c44115b9475dfda0375ecf5c0d 100644 --- a/src/riscv/lib/src/interpreter/rv64m.rs +++ b/src/riscv/lib/src/interpreter/rv64m.rs @@ -102,7 +102,7 @@ where #[cfg(test)] mod test { use crate::{ - backend_test, create_backend, create_state, + backend_test, create_state, machine_state::registers::{a0, a1, a2, a3, XRegisters, XRegistersLayout}, }; use proptest::{prelude::any, prop_assert_eq, proptest}; @@ -112,8 +112,7 @@ mod test { r1_val in any::(), r2_val in any::(), )| { - let mut backend = create_backend!(XRegistersLayout, F); - let mut state = create_state!(XRegisters, F, backend); + let mut state = create_state!(XRegisters, F); state.write(a0, r1_val); state.write(a1, r2_val); @@ -133,8 +132,7 @@ mod test { r1_val in any::(), r2_val in any::(), )| { - let mut backend = create_backend!(XRegistersLayout, F); - let mut state = create_state!(XRegisters, F, backend); + let mut state = create_state!(XRegisters, F); state.write(a0, r1_val); state.write(a1, r2_val); diff --git a/src/riscv/lib/src/interpreter/rv64priv.rs b/src/riscv/lib/src/interpreter/rv64priv.rs index d4af32035ae32e71bf4ddd4659d2e9810bfd1256..87197a46b45f9665b54d17ac11001d3bc757764f 100644 --- a/src/riscv/lib/src/interpreter/rv64priv.rs +++ b/src/riscv/lib/src/interpreter/rv64priv.rs @@ -137,7 +137,7 @@ where #[cfg(test)] mod tests { use crate::{ - backend_test, create_backend, create_state, + backend_test, create_state, machine_state::{ bus::main_memory::tests::T1K, csregisters::{xstatus, CSRRepr, CSRegister}, @@ -150,8 +150,7 @@ mod tests { backend_test!(test_sfence, F, { type L = MachineCoreStateLayout; - let mut backend = create_backend!(L, F); - let mut state = create_state!(MachineCoreState, L, F, backend, T1K); + let mut state = create_state!(MachineCoreState, L, F, T1K); let run_test = |state: &mut MachineCoreState<_, _>, mode: Mode, diff --git a/src/riscv/lib/src/machine_state.rs b/src/riscv/lib/src/machine_state.rs index 2e1c6f447b98452d60f8c7fa814a86cba218d0ff..eaccda469286a9aa01fc3539e87a58b06ee986d3 100644 --- a/src/riscv/lib/src/machine_state.rs +++ b/src/riscv/lib/src/machine_state.rs @@ -1052,7 +1052,7 @@ mod tests { use crate::{ backend_test, bits::{Bits64, FixedWidthBits}, - create_backend, create_state, + create_state, machine_state::{ address_translation::pte::{PPNField, PageTableEntry}, bus::{main_memory::M1M, start_of_main_memory, AddressableWrite}, @@ -1069,6 +1069,7 @@ mod tests { instruction::{CIBTypeArgs, ITypeArgs, Instr, InstrCacheable, SBTypeArgs}, parse_block, }, + state_backend::test_helpers::{assert_eq_struct, copy_via_serde, TestBackendFactory}, traps::{EnvironException, Exception, TrapContext}, }; use crate::{bits::u64, machine_state::bus::main_memory::M1K}; @@ -1083,8 +1084,7 @@ mod tests { } backend_test!(test_step, F, { - let mut backend = create_backend!(MachineStateLayout, F); - let state = create_state!(MachineState, MachineStateLayout, F, backend, T1K, TestCacheLayouts); + let state = create_state!(MachineState, MachineStateLayout, F, T1K, TestCacheLayouts); let state_cell = std::cell::RefCell::new(state); proptest!(|( @@ -1131,8 +1131,7 @@ mod tests { }); backend_test!(test_step_env_exc, F, { - let mut backend = create_backend!(MachineStateLayout, F); - let state = create_state!(MachineState, MachineStateLayout, F, backend, T1K, TestCacheLayouts); + let state = create_state!(MachineState, MachineStateLayout, F, T1K, TestCacheLayouts); let state_cell = std::cell::RefCell::new(state); proptest!(|( @@ -1168,8 +1167,7 @@ mod tests { }); backend_test!(test_step_exc_mm, F, { - let mut backend = create_backend!(MachineStateLayout, F); - let state = create_state!(MachineState, MachineStateLayout, F, backend, T1K, TestCacheLayouts); + let state = create_state!(MachineState, MachineStateLayout, F, T1K, TestCacheLayouts); let state_cell = std::cell::RefCell::new(state); proptest!(|( @@ -1212,8 +1210,7 @@ mod tests { }); backend_test!(test_step_exc_us, F, { - let mut backend = create_backend!(MachineStateLayout, F); - let state = create_state!(MachineState, MachineStateLayout, F, backend, T1K, TestCacheLayouts); + let state = create_state!(MachineState, MachineStateLayout, F, T1K, TestCacheLayouts); let state_cell = std::cell::RefCell::new(state); proptest!(|( @@ -1262,11 +1259,7 @@ mod tests { // Test that the machine state does not behave differently when potential ephermeral state is // reset that may impact instruction caching. - #[test] - fn test_instruction_cache() { - // TODO: RV-210: Generalise for all testable backends. - type F = crate::state_backend::memory_backend::test_helpers::InMemoryBackendFactory; - + backend_test!(test_instruction_cache, F, { // Instruction that writes the value in t1 to the address t0. const I_WRITE_T1_TO_ADDRESS_T0: u32 = 0b0011000101010000000100011; assert_eq!( @@ -1300,11 +1293,14 @@ mod tests { }))] ); - let mut backend = create_backend!(MachineStateLayout, F); + type LocalLayout = MachineStateLayout; + + type LocalMachineState = + MachineState::Manager>; // Configure the machine state. - { - let mut state = create_state!(MachineState, MachineStateLayout, F, backend, M1K, TestCacheLayouts); + let base_state = { + let mut state = create_state!(MachineState, LocalLayout, F, M1K, TestCacheLayouts); state.reset(); let start_ram = start_of_main_memory::(); @@ -1329,46 +1325,53 @@ mod tests { .hart .xregisters .write(t1, I_LOAD_6_INTO_T2 as u64); - } - let mut alt_backend = backend.clone(); + state + }; // Perform 2 steps consecutively in one backend. - let result = { - let mut state = create_state!(MachineState, MachineStateLayout, F, backend, M1K, TestCacheLayouts); + let state = { + let mut state = LocalMachineState::::bind(copy_via_serde::( + &base_state.struct_ref(), + )); + state.step().unwrap(); state.step().unwrap(); - state.core.hart.xregisters.read(t2) + + state }; // Perform 2 steps separately in another backend by re-binding the state between steps. - let alt_result = { - { - let mut state = create_state!(MachineState, MachineStateLayout, F, alt_backend, M1K, TestCacheLayouts); + let alt_state = { + let alt_state = { + let mut state = LocalMachineState::::bind(copy_via_serde::( + &base_state.struct_ref(), + )); state.step().unwrap(); - } + state + }; { - let mut state = create_state!(MachineState, MachineStateLayout, F, alt_backend, M1K, TestCacheLayouts); + let mut state = LocalMachineState::::bind(copy_via_serde::( + &alt_state.struct_ref(), + )); state.step().unwrap(); - state.core.hart.xregisters.read(t2) + state } }; // The two backends should have the same state. - assert_eq!(result, alt_result); - assert_eq!(backend, alt_backend); - } + assert_eq!( + state.core.hart.xregisters.read(t2), + alt_state.core.hart.xregisters.read(t2) + ); + + assert_eq_struct(&state.struct_ref(), &alt_state.struct_ref()); + }); // Test that the machine state does not behave differently when potential ephermeral state is // reset that may impact instruction address translation caching. - #[test] - fn test_instruction_address_cache() { - // TODO: RV-210: Generalise for all testable backends. - type F = crate::state_backend::memory_backend::test_helpers::InMemoryBackendFactory; - - let mut backend = create_backend!(MachineStateLayout, F); - + backend_test!(test_instruction_address_cache, F, { // Specify the physcal memory layout. let main_mem_addr = start_of_main_memory::(); let code0_addr = main_mem_addr; @@ -1520,9 +1523,15 @@ mod tests { ] ); + type LocalLayout = MachineStateLayout; + + type LocalMachineState = + MachineState::Manager>; + // Configure the state backend. - { - let mut state = create_state!(MachineState, MachineStateLayout, F, backend, M1M, TestCacheLayouts); + let base_state = { + let mut state: LocalMachineState = + create_state!(MachineState, LocalLayout, F, M1M, TestCacheLayouts); state.reset(); state @@ -1544,34 +1553,49 @@ mod tests { .hart .xregisters .write(t1, root_page_table_virt_addr); - } - let mut alt_backend = backend.clone(); + state + }; + + // Run 2 steps consecutively against one backend. + let state = { + let mut state: LocalMachineState = + MachineState::bind(copy_via_serde::( + &base_state.struct_ref(), + )); - // 2 steps consecutively against one backend. - let result = { - let mut state = create_state!(MachineState, MachineStateLayout, F, backend, M1M, TestCacheLayouts); state.step().unwrap(); state.step().unwrap(); - state.core.hart.xregisters.read(a0) + + state }; // Perform 2 steps separately in another backend by re-binding the state between steps. - let alt_result = { - { - let mut state = create_state!(MachineState, MachineStateLayout, F, alt_backend, M1M, TestCacheLayouts); + let alt_state = { + let alt_state = { + let mut state: LocalMachineState = + MachineState::bind(copy_via_serde::( + &base_state.struct_ref(), + )); state.step().unwrap(); - } + state + }; { - let mut state = create_state!(MachineState, MachineStateLayout, F, alt_backend, M1M, TestCacheLayouts); + let mut state: LocalMachineState = + MachineState::bind(copy_via_serde::( + &alt_state.struct_ref(), + )); state.step().unwrap(); - state.core.hart.xregisters.read(a0) + state } }; // Both backends should have transitioned to the same state. - assert_eq!(result, 1); - assert_eq!(result, alt_result); - assert_eq!(backend, alt_backend); - } + assert_eq!(state.core.hart.xregisters.read(a0), 1); + assert_eq!( + state.core.hart.xregisters.read(a0), + alt_state.core.hart.xregisters.read(a0) + ); + assert_eq_struct(&state.struct_ref(), &alt_state.struct_ref()); + }); } diff --git a/src/riscv/lib/src/machine_state/bus/main_memory.rs b/src/riscv/lib/src/machine_state/bus/main_memory.rs index 0f952fe8dda575e5e34033a8204d103e031d66b7..190b9d74f559dc62940ac68e14b388ad3078246f 100644 --- a/src/riscv/lib/src/machine_state/bus/main_memory.rs +++ b/src/riscv/lib/src/machine_state/bus/main_memory.rs @@ -310,19 +310,14 @@ impl PartialEq for MainMemory(); memory.write(0, 0x1122334455667788u64).unwrap(); diff --git a/src/riscv/lib/src/machine_state/csregisters.rs b/src/riscv/lib/src/machine_state/csregisters.rs index 51a77620c6a7103bb8dccdb468bc05bdefb3494a..95ef15e67ca8a9ff92c949faace3fa7b80ef8efa 100644 --- a/src/riscv/lib/src/machine_state/csregisters.rs +++ b/src/riscv/lib/src/machine_state/csregisters.rs @@ -1670,7 +1670,7 @@ mod tests { use crate::{ backend_test, bits::Bits64, - create_backend, create_state, + create_state, machine_state::{ backend::tests::test_determinism, csregisters::{ @@ -1894,8 +1894,7 @@ mod tests { } backend_test!(test_write_read, F, { - let mut backend = create_backend!(CSRegistersLayout, F); - let mut csrs = create_state!(CSRegisters, CSRegistersLayout, F, backend); + let mut csrs = create_state!(CSRegisters, CSRegistersLayout, F); // write to MBE, SXL, UXL, MPP, MPIE, XS, SPP (through mstatus) csrs.write( @@ -1975,8 +1974,7 @@ mod tests { }); backend_test!(test_xip_xie, F, { - let mut backend = create_backend!(CSRegistersLayout, F); - let mut csrs = create_state!(CSRegisters, CSRegistersLayout, F, backend); + let mut csrs = create_state!(CSRegisters, CSRegistersLayout, F); let mtip: u64 = 1 << Interrupt::MachineTimer.exception_code(); let msip: u64 = 1 << Interrupt::MachineSoftware.exception_code(); @@ -2003,8 +2001,7 @@ mod tests { } backend_test!(test_fcsr, F, { - let mut backend = create_backend!(CSRegistersLayout, F); - let mut csrs = create_state!(CSRegisters, CSRegistersLayout, F, backend); + let mut csrs = create_state!(CSRegisters, CSRegistersLayout, F); // check starting values assert_eq!(0, csrs.read::(CSRegister::fcsr)); diff --git a/src/riscv/lib/src/machine_state/instruction_cache.rs b/src/riscv/lib/src/machine_state/instruction_cache.rs index 7dd97c561e37a736690bb86793f1234a07240dfd..e0f657d4d4e0f5af96c6874ed55a2d4edcd74901 100644 --- a/src/riscv/lib/src/machine_state/instruction_cache.rs +++ b/src/riscv/lib/src/machine_state/instruction_cache.rs @@ -336,9 +336,10 @@ const fn cacheable_uncompressed(phys_addr: Address) -> bool { mod tests { use super::*; use crate::{ - backend_test, create_backend, create_state, + backend_test, create_state, machine_state::registers::{a0, t0, t1}, parser::instruction::{CIBTypeArgs, InstrCacheable, SBTypeArgs}, + state_backend::test_helpers::copy_via_serde, }; pub type TestInstructionCacheLayout = Layout; @@ -348,12 +349,10 @@ mod tests { // `UnknownInstr` being executed, rather than an `OutOfBounds` error (for reading from // devices). backend_test!(test_fetch_before_cache_misses, F, { - let mut backend = create_backend!(TestInstructionCacheLayout, F); let mut state = create_state!( InstructionCache, TestInstructionCacheLayout, F, - backend, TestInstructionCacheLayout ); @@ -369,12 +368,10 @@ mod tests { // we do not invalidate the instruction cache, although the physical address of // the second half of the instruction does actually change! backend_test!(test_never_cache_across_page_boundaries, F, { - let mut backend = create_backend!(TestInstructionCacheLayout, F); let mut state = create_state!( InstructionCache, TestInstructionCacheLayout, F, - backend, TestInstructionCacheLayout ); @@ -398,13 +395,7 @@ mod tests { // Ensure // - on rebind the cached instructions are still present // - able to cache possibly overlapping instructions - #[test] - fn test_rebind() { - // TODO: RV-210: Generalise for all testable backends. - type F = crate::state_backend::memory_backend::test_helpers::InMemoryBackendFactory; - - let mut backend = create_backend!(TestInstructionCacheLayout, F); - + backend_test!(test_rebind, F, { let compressed_bytes = 0x4505; let compressed = InstrCacheable::CLi(CIBTypeArgs { rd_rs1: a0, imm: 1 }); @@ -418,12 +409,11 @@ mod tests { let phys_addr_uncompressed = 6; let phys_addr_compressed = 8; - { + let space: AllocatedOf = { let mut state = create_state!( InstructionCache, TestInstructionCacheLayout, F, - backend, TestInstructionCacheLayout ); @@ -435,17 +425,14 @@ mod tests { Some(&uncompressed), state.fetch_instr(phys_addr_uncompressed) ); - } + + copy_via_serde::(&state.struct_ref()) + }; // Rebind state { - let mut state = create_state!( - InstructionCache, - TestInstructionCacheLayout, - F, - backend, - TestInstructionCacheLayout - ); + let mut state: InstructionCache = + InstructionCache::bind(space); assert_eq!(Some(&compressed), state.fetch_instr(phys_addr_compressed)); assert_eq!( @@ -453,5 +440,5 @@ mod tests { state.fetch_instr(phys_addr_uncompressed) ); } - } + }); } diff --git a/src/riscv/lib/src/machine_state/mode.rs b/src/riscv/lib/src/machine_state/mode.rs index 0e977cdb44b187bc005b8e2c322e6b41e341d3b4..60091eef25d366de825ccf97c725ac742ea9fe58 100644 --- a/src/riscv/lib/src/machine_state/mode.rs +++ b/src/riscv/lib/src/machine_state/mode.rs @@ -79,7 +79,7 @@ impl TrapMode { #[cfg(test)] mod tests { use crate::{ - backend_test, create_backend, create_state, + backend_test, create_state, machine_state::{ backend::tests::test_determinism, mode::{Mode, ModeCell, ModeLayout}, @@ -96,12 +96,10 @@ mod tests { } backend_test!(test_mode_read_write, F, { - let mut backend = create_backend!(ModeLayout, F); - Mode::iter().for_each(|mode| { let first_value = mode; - let mut inst = create_state!(ModeCell, ModeLayout, F, backend); + let mut inst = create_state!(ModeCell, ModeLayout, F); inst.write(first_value); assert_eq!(inst.read(), first_value); diff --git a/src/riscv/lib/src/machine_state/registers.rs b/src/riscv/lib/src/machine_state/registers.rs index 30e19c9fd5b0bac44233d1f9bc0afd33a76135dc..7a876b9b5c07a52b54c830ec332568f37d2312e9 100644 --- a/src/riscv/lib/src/machine_state/registers.rs +++ b/src/riscv/lib/src/machine_state/registers.rs @@ -435,15 +435,12 @@ impl Clone for FRegisters { #[cfg(test)] mod tests { use super::*; - use crate::{ - backend_test, create_backend, create_state, machine_state::backend::tests::test_determinism, - }; + use crate::{backend_test, create_state, machine_state::backend::tests::test_determinism}; use arbitrary_int::Number; use strum::IntoEnumIterator; backend_test!(test_zero, F, { - let mut backend = create_backend!(XRegistersLayout, F); - let mut registers = create_state!(XRegisters, XRegistersLayout, F, backend); + let mut registers = create_state!(XRegisters, XRegistersLayout, F); // x0 should always read 0. assert_eq!(registers.read(x0), 0); @@ -459,8 +456,7 @@ mod tests { ]; backend_test!(test_arbitrary_register, F, { - let mut backend = create_backend!(XRegistersLayout, F); - let mut registers = create_state!(XRegisters, XRegistersLayout, F, backend); + let mut registers = create_state!(XRegisters, XRegistersLayout, F); // Initialise the registers with something. for reg in NONZERO_REGISTERS { diff --git a/src/riscv/lib/src/state_backend.rs b/src/riscv/lib/src/state_backend.rs index 9272a68d585b7f507f0eb804f9048dafeba407f6..df7ed2b7a0578b27aaece7fe93edc9b5f5ed2f16 100644 --- a/src/riscv/lib/src/state_backend.rs +++ b/src/riscv/lib/src/state_backend.rs @@ -301,8 +301,11 @@ impl ManagerRead for Ref<'_, M> { } } -pub mod test_helpers { - use super::{AllocatedOf, Layout, ManagerReadWrite, ManagerSerialise, PlacedOf}; +#[cfg(test)] +pub(crate) mod test_helpers { + use super::{ + AllocatedOf, Layout, ManagerClone, ManagerDeserialise, ManagerReadWrite, ManagerSerialise, + }; /// Generate a test against all test backends. #[macro_export] @@ -315,51 +318,62 @@ pub mod test_helpers { $expr } - inner::<$crate::state_backend::memory_backend::test_helpers::InMemoryBackendFactory>(); inner::<$crate::state_backend::owned_backend::test_helpers::OwnedTestBackendFactory>(); } }; } - /// Equivalent to [`BackendBase`] but for testing purposes - pub trait TestBackendBase { - type Manager<'backend>: ManagerReadWrite + ManagerSerialise; - } + /// This lets you construct backends for any layout. + pub trait TestBackendFactory { + /// Manager used in testing + type Manager: ManagerReadWrite + ManagerSerialise + ManagerDeserialise + ManagerClone; - /// Equivalent to [`Backend`] but for testing purposes - pub trait TestBackend: TestBackendBase { - type Layout: Layout; + /// Allocate using the test backend manager. + fn allocate() -> AllocatedOf; + } - fn allocate( - &mut self, - placed: PlacedOf, - ) -> AllocatedOf>; + /// Copy the allocated space by serialising and deserialising it. + pub fn copy_via_serde(refs: &AllocatedOf) -> AllocatedOf + where + L: Layout, + N: ManagerSerialise, + AllocatedOf: serde::Serialize, + M: ManagerDeserialise, + AllocatedOf: serde::de::DeserializeOwned, + { + let data = crate::storage::binary::serialise(refs).unwrap(); + crate::storage::binary::deserialise(&data).unwrap() } - /// This lets you construct backends for any layout. - pub trait TestBackendFactory { - type Backend: TestBackend; + /// Assert that two values are different. If they differ, offer a command to run that shows the + /// structural differences between the values. + pub fn assert_eq_struct(lhs: &T, rhs: &T) + where + T: serde::Serialize + PartialEq, + { + if lhs != rhs { + let (file_lhs, path_lhs) = tempfile::NamedTempFile::new().unwrap().keep().unwrap(); + serde_json::to_writer_pretty(file_lhs, lhs).unwrap(); + eprintln!("Lhs is located at {}", path_lhs.display()); + + let (file_rhs, path_rhs) = tempfile::NamedTempFile::new().unwrap().keep().unwrap(); + serde_json::to_writer_pretty(file_rhs, rhs).unwrap(); + eprintln!("Rhs is located at {}", path_rhs.display()); - /// Construct a backend for the given layout `L`. - fn new() -> Self::Backend; + eprintln!("Run the following to diff them:"); + eprintln!("jd {} {}", path_lhs.display(), path_rhs.display()); + + panic!("Assertion failed: values are different"); + } } } #[cfg(test)] pub mod tests { - use super::{ - random_backend::Randomised, - test_helpers::{TestBackendBase, TestBackendFactory}, - *, - }; + use super::{random_backend::Randomised, *}; use crate::backend_test; use std::{collections::hash_map::RandomState, hash::BuildHasher}; - /// Construct the manager for a given backend lifetime `'a`, a test backend - /// factory `F` and a specific layout `L`. - pub type ManagerFor<'a, F, L> = - <::Backend as TestBackendBase>::Manager<'a>; - /// Run `f` twice against two different randomised backends and see if the /// resulting backend state is the same afterwards. pub fn test_determinism(f: T) @@ -401,52 +415,28 @@ pub mod tests { assert_eq!(snapshot1, snapshot2); } - /// Given a `StateLayout` and a [`TestBackendFactory`] type, - /// create the backend for that layout. - #[macro_export] - macro_rules! create_backend { - ($StateLayout:ty, $Factory:ty) => { - <$Factory as $crate::state_backend::test_helpers::TestBackendFactory>::new::<$StateLayout>() - }; - } - /// Given a `State`, optionally its `StateLayout`, /// a [`TestBackendFactory`] type, a `backend` created with `create_backend!` macro, /// create the location and return the created `State`. #[macro_export] macro_rules! create_state { // For an extra generic in the state (MachineState for example) - ($State:tt, $StateLayout:ty, $Factory:ty, $backend:ident $(, $ExtraGenerics:ty)*) => { + ($State:tt, $StateLayout:ty, $Factory:ty $(, $ExtraGenerics:ty)*) => { { - use $crate::state_backend::{test_helpers::TestBackend, Layout}; - let loc = <$StateLayout>::placed().into_location(); let new_state = $State::< $($ExtraGenerics,)* - <<$Factory as $crate::state_backend::test_helpers::TestBackendFactory>::Backend<$StateLayout> as $crate::state_backend::test_helpers::TestBackendBase>::Manager<'_> + <$Factory as $crate::state_backend::test_helpers::TestBackendFactory>::Manager, >::bind( - $backend.allocate(loc), - ); - - new_state - } - }; - - ($State:tt, $StateLayout:ty, $Factory:ty, $backend:ident) => { - { - use $crate::state_backend::{Backend, BackendManagement, Layout}; - let loc = <$StateLayout>::placed().into_location(); - let new_state = - $State::<<<$Factory as $crate::state_backend::test_helpers::TestBackendFactory>::Backend<$StateLayout> as BackendManagement>::Manager<'_>>::bind( - $backend.allocate(loc), + <$Factory as $crate::state_backend::test_helpers::TestBackendFactory>::allocate::<$StateLayout>(), ); new_state } }; - ($State:tt, $Factory:ty, $backend:ident) => { - create_state!($State, paste::paste!([<$State Layout>]), $Factory, $backend) + ($State:tt, $Factory:ty) => { + create_state!($State, paste::paste!([<$State Layout>]), $Factory) }; } @@ -467,8 +457,6 @@ pub mod tests { } } - let mut backend = create_backend!(ExampleLayout, F); - let (first_loc, second_loc) = ExampleLayout::placed().into_location(); let first_loc = first_loc.as_array(); @@ -481,7 +469,7 @@ pub mod tests { let first_value: u64 = rand::random(); let second_value: [u32; 4] = rand::random(); - let mut instance = create_state!(Example, ExampleLayout, F, backend); + let mut instance = create_state!(Example, ExampleLayout, F); instance.first.write(first_value); assert_eq!(instance.first.read(), first_value); diff --git a/src/riscv/lib/src/state_backend/memory_backend.rs b/src/riscv/lib/src/state_backend/memory_backend.rs index 3c54f4acf17862c6c65baa560ab0993debdd46c2..09b9ba38fd3ca4d3a45ed929c63d4b5263564b66 100644 --- a/src/riscv/lib/src/state_backend/memory_backend.rs +++ b/src/riscv/lib/src/state_backend/memory_backend.rs @@ -547,39 +547,6 @@ impl backend::ManagerSerialise for SliceManagerRO<'_> { } } -pub mod test_helpers { - use super::{InMemoryBackend, SliceManager}; - use crate::state_backend::{ - test_helpers::{TestBackend, TestBackendBase, TestBackendFactory}, - Backend, Layout, - }; - - impl TestBackendBase for InMemoryBackend { - type Manager<'backend> = SliceManager<'backend>; - } - - impl TestBackend for InMemoryBackend { - type Layout = L; - - fn allocate( - &mut self, - placed: crate::state_backend::PlacedOf, - ) -> crate::state_backend::AllocatedOf> { - Backend::allocate(self, placed) - } - } - - pub struct InMemoryBackendFactory; - - impl TestBackendFactory for InMemoryBackendFactory { - type Backend = InMemoryBackend; - - fn new() -> Self::Backend { - InMemoryBackend::::new().0 - } - } -} - #[cfg(test)] pub mod tests { use super::*; diff --git a/src/riscv/lib/src/state_backend/owned_backend.rs b/src/riscv/lib/src/state_backend/owned_backend.rs index 8aa9c35b9f2e3729299aa4dd3558ca7585a73d31..a021f70994e6c399238d790091e847823e737c15 100644 --- a/src/riscv/lib/src/state_backend/owned_backend.rs +++ b/src/riscv/lib/src/state_backend/owned_backend.rs @@ -288,37 +288,16 @@ impl ManagerClone for Owned { #[cfg(test)] pub mod test_helpers { use super::*; - use crate::state_backend::{ - test_helpers::{TestBackend, TestBackendBase, TestBackendFactory}, - Cell, Cells, DynCells, - }; - - /// Test backend for the owned state manager - pub struct OwnedTestBackend(PhantomData); - - impl TestBackendBase for OwnedTestBackend { - type Manager<'backend> = Owned; - } - - impl TestBackend for OwnedTestBackend { - type Layout = L; - - fn allocate( - &mut self, - _placed: crate::state_backend::PlacedOf, - ) -> AllocatedOf> { - Owned::allocate::() - } - } + use crate::state_backend::{test_helpers::TestBackendFactory, Cell, Cells, DynCells}; /// Test backend factory for the owned state manager pub struct OwnedTestBackendFactory; impl TestBackendFactory for OwnedTestBackendFactory { - type Backend = OwnedTestBackend; + type Manager = Owned; - fn new() -> Self::Backend { - OwnedTestBackend(PhantomData) + fn allocate() -> AllocatedOf { + Owned::allocate::() } } diff --git a/src/riscv/lib/src/state_backend/region.rs b/src/riscv/lib/src/state_backend/region.rs index 048556f069331429a6f6b07c00ae5b0c5c8c9870..de938c5be3621d417e4d1d36c385a1e529d4c92b 100644 --- a/src/riscv/lib/src/state_backend/region.rs +++ b/src/riscv/lib/src/state_backend/region.rs @@ -509,12 +509,12 @@ impl Clone for DynCells { #[cfg(test)] pub(crate) mod tests { use crate::{ - backend_test, create_backend, + backend_test, state_backend::{ layout::{Atom, Layout}, - test_helpers::TestBackend, + test_helpers::copy_via_serde, Array, CellRead, CellReadWrite, CellWrite, Choreographer, DynCells, Elem, LazyCell, - Location, ManagerAlloc, ManagerBase, + Location, ManagerAlloc, ManagerBase, Ref, }, }; use serde::ser::SerializeTuple; @@ -567,8 +567,7 @@ pub(crate) mod tests { const LEN: usize = 64; type OurLayout = (Array, Array); - let mut backend = create_backend!(OurLayout, F); - let (mut array1, mut array2) = backend.allocate(OurLayout::placed().into_location()); + let (mut array1, mut array2) = F::allocate::(); // Allocate two consecutive arrays // let mut array1 = manager.allocate_region(array1_place); @@ -610,8 +609,7 @@ pub(crate) mod tests { backend_test!(test_cell_overlap, F, { type OurLayout = (Atom<[u64; 4]>, Atom<[u64; 4]>); - let mut backend = create_backend!(OurLayout, F); - let (mut cell1, mut cell2) = backend.allocate(OurLayout::placed().into_location()); + let (mut cell1, mut cell2) = F::allocate::(); // Cell should be zero-initialised. assert_eq!(cell1.read(), [0; 4]); @@ -634,11 +632,7 @@ pub(crate) mod tests { assert_eq!(cell1.read(), cell1_value); }); - #[test] - fn test_lazy_cell() { - // TODO: RV-210: Generalise for all testable backends. - type F = crate::state_backend::memory_backend::test_helpers::InMemoryBackendFactory; - + backend_test!(test_lazy_cell, F, { #[derive(Debug, Clone, Copy, PartialEq, Eq)] struct Wrapper(u64); @@ -656,10 +650,8 @@ pub(crate) mod tests { type OurLayout = Atom; - let mut backend = create_backend!(OurLayout, F); - - let expected = { - let cell = backend.allocate(OurLayout::placed().into_location()); + let (expected, space) = { + let cell = F::allocate::(); // Cell should be zero-initialised. assert_eq!(cell.read(), 0); @@ -677,13 +669,15 @@ pub(crate) mod tests { let new = Wrapper(rand::random()); assert_eq!(old, lazy.replace(new)); - new.0 + let space = + copy_via_serde::, F::Manager>(&lazy.struct_ref()); + + (new.0, space) }; // Rebinding, check cell contents - let cell = backend.allocate(OurLayout::placed().into_location()); - assert_eq!(cell.read(), expected); - } + assert_eq!(space.read(), expected); + }); backend_test!( #[should_panic] @@ -711,8 +705,7 @@ pub(crate) mod tests { } } - let mut backend = create_backend!(FlipperLayout, F); - let mut state = backend.allocate(FlipperLayout::placed().into_location()); + let mut state = F::allocate::(); // This should panic because we are trying to write an element at the address which // corresponds to the end of the buffer. @@ -740,10 +733,8 @@ pub(crate) mod tests { } } - let mut backend = create_backend!(FlipperLayout, F); - // Writing to one item of the region must convert to stored format. - let mut region = backend.allocate(FlipperLayout::placed().into_location()); + let mut region = F::allocate::(); region.write(0, Flipper { a: 13, b: 37 }); assert_eq!(region.read::(0), Flipper { a: 13, b: 37 }); @@ -781,10 +772,8 @@ pub(crate) mod tests { backend_test!(test_region_stored_format, F, { type FlipperLayout = Array; - let mut backend = create_backend!(FlipperLayout, F); - // Writing to one item of the region must convert to stored format. - let mut region = backend.allocate(FlipperLayout::placed().into_location()); + let mut region = F::allocate::(); region.write(0, Flipper { a: 13, b: 37 }); assert_eq!(region.read(0), Flipper { a: 13, b: 37 });