change Module::define_function to take TrapSink instances
Experience with the `define_function` API has shown that returning borrowed slices of `TrapSite` is not ideal: the returned slice represents a borrow on the entire `Module`, which makes calling back into methods taking `&mut self` a bit tricky. To eliminate the problem, let's require the callers of `define_function` to provide `TrapSink` instances. This style of API enables them to control when and how traps are collected, and makes the `object` and `faerie` backends simpler/more efficient by not having to worry about trap collection.
This commit is contained in:
@@ -2,13 +2,13 @@
|
||||
|
||||
use crate::memory::Memory;
|
||||
use cranelift_codegen::binemit::{
|
||||
Addend, CodeOffset, NullTrapSink, Reloc, RelocSink, Stackmap, StackmapSink,
|
||||
Addend, CodeOffset, Reloc, RelocSink, Stackmap, StackmapSink, TrapSink,
|
||||
};
|
||||
use cranelift_codegen::isa::TargetIsa;
|
||||
use cranelift_codegen::{self, ir, settings};
|
||||
use cranelift_module::{
|
||||
Backend, DataContext, DataDescription, DataId, FuncId, Init, Linkage, ModuleNamespace,
|
||||
ModuleResult, TrapSite,
|
||||
ModuleResult,
|
||||
};
|
||||
use cranelift_native;
|
||||
#[cfg(not(windows))]
|
||||
@@ -271,14 +271,18 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
fn define_function(
|
||||
fn define_function<TS>(
|
||||
&mut self,
|
||||
_id: FuncId,
|
||||
name: &str,
|
||||
ctx: &cranelift_codegen::Context,
|
||||
_namespace: &ModuleNamespace<Self>,
|
||||
code_size: u32,
|
||||
) -> ModuleResult<(Self::CompiledFunction, &[TrapSite])> {
|
||||
trap_sink: &mut TS,
|
||||
) -> ModuleResult<Self::CompiledFunction>
|
||||
where
|
||||
TS: TrapSink,
|
||||
{
|
||||
let size = code_size as usize;
|
||||
let ptr = self
|
||||
.memory
|
||||
@@ -289,28 +293,22 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
|
||||
self.record_function_for_perf(ptr, size, name);
|
||||
|
||||
let mut reloc_sink = SimpleJITRelocSink::new();
|
||||
// Ignore traps for now. For now, frontends should just avoid generating code
|
||||
// that traps.
|
||||
let mut trap_sink = NullTrapSink {};
|
||||
let mut stackmap_sink = SimpleJITStackmapSink::new();
|
||||
unsafe {
|
||||
ctx.emit_to_memory(
|
||||
&*self.isa,
|
||||
ptr,
|
||||
&mut reloc_sink,
|
||||
&mut trap_sink,
|
||||
trap_sink,
|
||||
&mut stackmap_sink,
|
||||
)
|
||||
};
|
||||
|
||||
Ok((
|
||||
Self::CompiledFunction {
|
||||
code: ptr,
|
||||
size,
|
||||
relocs: reloc_sink.relocs,
|
||||
},
|
||||
&[],
|
||||
))
|
||||
Ok(Self::CompiledFunction {
|
||||
code: ptr,
|
||||
size,
|
||||
relocs: reloc_sink.relocs,
|
||||
})
|
||||
}
|
||||
|
||||
fn define_function_bytes(
|
||||
@@ -319,8 +317,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
|
||||
name: &str,
|
||||
bytes: &[u8],
|
||||
_namespace: &ModuleNamespace<Self>,
|
||||
_traps: Vec<TrapSite>,
|
||||
) -> ModuleResult<(Self::CompiledFunction, &[TrapSite])> {
|
||||
) -> ModuleResult<Self::CompiledFunction> {
|
||||
let size = bytes.len();
|
||||
let ptr = self
|
||||
.memory
|
||||
@@ -334,14 +331,11 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend {
|
||||
ptr::copy_nonoverlapping(bytes.as_ptr(), ptr, size);
|
||||
}
|
||||
|
||||
Ok((
|
||||
Self::CompiledFunction {
|
||||
code: ptr,
|
||||
size,
|
||||
relocs: vec![],
|
||||
},
|
||||
&[],
|
||||
))
|
||||
Ok(Self::CompiledFunction {
|
||||
code: ptr,
|
||||
size,
|
||||
relocs: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
fn define_data(
|
||||
|
||||
Reference in New Issue
Block a user