Make rodata test framework more robust

Previously `test rodata` would cause failures when compiling Cranelift IR that had assertions about the current sink offset (e.g. multiple blocks, see `emit_function` in `binemit/mod.rs`).
This commit is contained in:
Andrew Brown
2020-03-23 14:59:04 -07:00
parent 98ff36bfed
commit 1c339f35e7

View File

@@ -52,10 +52,7 @@ impl SubTest for TestRodata {
); );
// Verify that the returned code size matches the emitted bytes. // Verify that the returned code size matches the emitted bytes.
let mut sink = RodataSink { let mut sink = RodataSink::default();
rodata: Vec::new(),
in_rodata: false,
};
binemit::emit_function( binemit::emit_function(
&comp_ctx.func, &comp_ctx.func,
|func, inst, div, sink, isa| isa.emit_inst(func, inst, div, sink), |func, inst, div, sink, isa| isa.emit_inst(func, inst, div, sink),
@@ -71,35 +68,41 @@ impl SubTest for TestRodata {
} }
/// Code sink that only captures emitted rodata /// Code sink that only captures emitted rodata
#[derive(Default)]
struct RodataSink { struct RodataSink {
in_rodata: bool, offset: usize,
rodata: Vec<u8>, rodata: Vec<u8>,
in_rodata: bool,
} }
impl binemit::CodeSink for RodataSink { impl binemit::CodeSink for RodataSink {
fn offset(&self) -> binemit::CodeOffset { fn offset(&self) -> binemit::CodeOffset {
0 self.offset as u32
} }
fn put1(&mut self, byte: u8) { fn put1(&mut self, byte: u8) {
self.offset += 1;
if self.in_rodata { if self.in_rodata {
self.rodata.push(byte); self.rodata.push(byte);
} }
} }
fn put2(&mut self, bytes: u16) { fn put2(&mut self, bytes: u16) {
self.offset += 2;
if self.in_rodata { if self.in_rodata {
self.rodata.extend_from_slice(&bytes.to_be_bytes()); self.rodata.extend_from_slice(&bytes.to_be_bytes());
} }
} }
fn put4(&mut self, bytes: u32) { fn put4(&mut self, bytes: u32) {
self.offset += 4;
if self.in_rodata { if self.in_rodata {
self.rodata.extend_from_slice(&bytes.to_be_bytes()); self.rodata.extend_from_slice(&bytes.to_be_bytes());
} }
} }
fn put8(&mut self, bytes: u64) { fn put8(&mut self, bytes: u64) {
self.offset += 8;
if self.in_rodata { if self.in_rodata {
self.rodata.extend_from_slice(&bytes.to_be_bytes()); self.rodata.extend_from_slice(&bytes.to_be_bytes());
} }
@@ -111,13 +114,16 @@ impl binemit::CodeSink for RodataSink {
fn reloc_jt(&mut self, _reloc: binemit::Reloc, _jt: ir::JumpTable) {} fn reloc_jt(&mut self, _reloc: binemit::Reloc, _jt: ir::JumpTable) {}
fn trap(&mut self, _code: ir::TrapCode, _srcloc: ir::SourceLoc) {} fn trap(&mut self, _code: ir::TrapCode, _srcloc: ir::SourceLoc) {}
fn begin_jumptables(&mut self) { fn begin_jumptables(&mut self) {
assert!(!self.in_rodata); assert!(!self.in_rodata, "Jump tables must be emitted before rodata");
} }
fn begin_rodata(&mut self) { fn begin_rodata(&mut self) {
self.in_rodata = true; self.in_rodata = true;
} }
fn end_codegen(&mut self) { fn end_codegen(&mut self) {
assert!(self.in_rodata); assert!(
self.in_rodata,
"Expected rodata to be emitted before the end of codegen"
);
} }
fn add_stackmap(&mut self, _: &[Value], _: &Function, _: &dyn TargetIsa) {} fn add_stackmap(&mut self, _: &[Value], _: &Function, _: &dyn TargetIsa) {}
} }