Mark emit_to_memory as unsafe, and introduce a safe emit. (#281)

* Mark emit_to_memory as unsafe, and provide a safe compile_and_emit.

Mark `Context::emit_to_memory` and `MemoryCodeSink::new` as unsafe, as
`MemoryCodeSink` does not perform bounds checking when writing to
memory.

Add a `Context::compile_and_emit` function which provides a convenient
interface for doing `compile` and `emit_to_memory` in one step, and
which can also provide a safe interface, since it allocates memory of
the needed size itself.

* Mention that `MemoryCodeSink` can't guarantee that the pointer is valid.
This commit is contained in:
Dan Gohman
2018-04-18 06:35:47 -07:00
committed by GitHub
parent 80da1a1e9f
commit d7e13284b2
5 changed files with 56 additions and 19 deletions

View File

@@ -96,19 +96,18 @@ fn handle_module(
for (func, _) in test_file.functions {
let mut context = Context::new();
context.func = func;
let size = context.compile(isa).map_err(|err| {
pretty_error(&context.func, Some(isa), err)
})?;
if flag_print {
println!("{}", context.func.display(isa));
}
// Encode the result as machine code.
// Compile and encode the result to machine code.
let mut mem = Vec::new();
let mut relocs = PrintRelocs { flag_print };
let mut traps = PrintTraps { flag_print };
mem.resize(size as usize, 0);
context.emit_to_memory(mem.as_mut_ptr(), &mut relocs, &mut traps, &*isa);
context
.compile_and_emit(isa, &mut mem, &mut relocs, &mut traps)
.map_err(|err| pretty_error(&context.func, Some(isa), err))?;
if flag_print {
println!("{}", context.func.display(isa));
}
if flag_print {
print!(".byte ");