diff --git a/cranelift/faerie/src/backend.rs b/cranelift/faerie/src/backend.rs index 40cca8eddc..2518893974 100644 --- a/cranelift/faerie/src/backend.rs +++ b/cranelift/faerie/src/backend.rs @@ -152,10 +152,11 @@ impl Backend for FaerieBackend { ctx: &cranelift_codegen::Context, namespace: &ModuleNamespace, total_size: u32, - ) -> ModuleResult { + ) -> ModuleResult<(FaerieCompiledFunction, &[TrapSite])> { let mut code: Vec = vec![0; total_size as usize]; // TODO: Replace this with FaerieStackmapSink once it is implemented. let mut stackmap_sink = NullStackmapSink {}; + let mut traps: &[TrapSite] = &[]; // Non-lexical lifetimes would obviate the braces here. { @@ -178,7 +179,7 @@ impl Backend for FaerieBackend { &mut stackmap_sink, ) }; - trap_manifest.add_sink(trap_sink); + traps = trap_manifest.add_sink(trap_sink); } else { let mut trap_sink = NullTrapSink {}; unsafe { @@ -200,7 +201,7 @@ impl Backend for FaerieBackend { .define(name, code) .expect("inconsistent declaration"); - Ok(FaerieCompiledFunction { code_length }) + Ok((FaerieCompiledFunction { code_length }, traps)) } fn define_function_bytes( @@ -210,22 +211,23 @@ impl Backend for FaerieBackend { bytes: &[u8], _namespace: &ModuleNamespace, traps: Vec, - ) -> ModuleResult { + ) -> ModuleResult<(FaerieCompiledFunction, &[TrapSite])> { let code_length: u32 = match bytes.len().try_into() { Ok(code_length) => code_length, _ => Err(ModuleError::FunctionTooLarge(name.to_string()))?, }; + let mut ret_traps: &[TrapSite] = &[]; if let Some(ref mut trap_manifest) = self.trap_manifest { let trap_sink = FaerieTrapSink::new_with_sites(name, code_length, traps); - trap_manifest.add_sink(trap_sink); + ret_traps = trap_manifest.add_sink(trap_sink); } self.artifact .define(name, bytes.to_vec()) .expect("inconsistent declaration"); - Ok(FaerieCompiledFunction { code_length }) + Ok((FaerieCompiledFunction { code_length }, ret_traps)) } fn define_data( diff --git a/cranelift/faerie/src/traps.rs b/cranelift/faerie/src/traps.rs index b84f171955..d3bd041d94 100644 --- a/cranelift/faerie/src/traps.rs +++ b/cranelift/faerie/src/traps.rs @@ -59,7 +59,8 @@ impl FaerieTrapManifest { } /// Put a `FaerieTrapSink` into manifest - pub fn add_sink(&mut self, sink: FaerieTrapSink) { + pub fn add_sink(&mut self, sink: FaerieTrapSink) -> &[TrapSite] { self.sinks.push(sink); + &self.sinks.last().unwrap().sites } } diff --git a/cranelift/module/src/backend.rs b/cranelift/module/src/backend.rs index 0fd8724afa..9333e5f570 100644 --- a/cranelift/module/src/backend.rs +++ b/cranelift/module/src/backend.rs @@ -86,7 +86,7 @@ where ctx: &Context, namespace: &ModuleNamespace, code_size: u32, - ) -> ModuleResult; + ) -> ModuleResult<(Self::CompiledFunction, &[TrapSite])>; /// Define a function, taking the function body from the given `bytes`. /// @@ -98,7 +98,7 @@ where bytes: &[u8], namespace: &ModuleNamespace, traps: Vec, - ) -> ModuleResult; + ) -> ModuleResult<(Self::CompiledFunction, &[TrapSite])>; /// Define a zero-initialized data object of the given size. /// diff --git a/cranelift/module/src/module.rs b/cranelift/module/src/module.rs index 5df095b610..daa83c2956 100644 --- a/cranelift/module/src/module.rs +++ b/cranelift/module/src/module.rs @@ -352,6 +352,11 @@ where backend: B, } +pub struct ModuleCompiledFunction<'a> { + pub size: binemit::CodeOffset, + pub traps: &'a [TrapSite], +} + impl Module where B: Backend, @@ -557,7 +562,7 @@ where &mut self, func: FuncId, ctx: &mut Context, - ) -> ModuleResult { + ) -> ModuleResult { info!( "defining function {}: {}", func, @@ -572,7 +577,7 @@ where return Err(ModuleError::InvalidImportDefinition(info.decl.name.clone())); } - let compiled = Some(self.backend.define_function( + let (compiled, traps) = self.backend.define_function( func, &info.decl.name, ctx, @@ -580,11 +585,14 @@ where contents: &self.contents, }, total_size, - )?); + )?; - self.contents.functions[func].compiled = compiled; + self.contents.functions[func].compiled = Some(compiled); self.functions_to_finalize.push(func); - Ok(total_size) + Ok(ModuleCompiledFunction { + size: total_size, + traps, + }) } /// Define a function, taking the function body from the given `bytes`. @@ -599,7 +607,7 @@ where func: FuncId, bytes: &[u8], traps: Vec, - ) -> ModuleResult { + ) -> ModuleResult { info!("defining function {} with bytes", func); let info = &self.contents.functions[func]; if info.compiled.is_some() { @@ -614,7 +622,7 @@ where _ => Err(ModuleError::FunctionTooLarge(info.decl.name.clone()))?, }; - let compiled = Some(self.backend.define_function_bytes( + let (compiled, traps) = self.backend.define_function_bytes( func, &info.decl.name, bytes, @@ -622,11 +630,14 @@ where contents: &self.contents, }, traps, - )?); + )?; - self.contents.functions[func].compiled = compiled; + self.contents.functions[func].compiled = Some(compiled); self.functions_to_finalize.push(func); - Ok(total_size) + Ok(ModuleCompiledFunction { + size: total_size, + traps, + }) } /// Define a data object, producing the data contents from the given `DataContext`. diff --git a/cranelift/object/src/backend.rs b/cranelift/object/src/backend.rs index dae26ea230..c65dfe0024 100644 --- a/cranelift/object/src/backend.rs +++ b/cranelift/object/src/backend.rs @@ -17,6 +17,7 @@ use object::write::{ use object::{RelocationEncoding, RelocationKind, SymbolFlags, SymbolKind, SymbolScope}; use std::collections::HashMap; use std::mem; +use std::ops::IndexMut; use target_lexicon::{BinaryFormat, PointerWidth}; #[derive(Debug)] @@ -188,7 +189,7 @@ impl Backend for ObjectBackend { ctx: &cranelift_codegen::Context, _namespace: &ModuleNamespace, code_size: u32, - ) -> ModuleResult { + ) -> ModuleResult<(ObjectCompiledFunction, &[TrapSite])> { let mut code: Vec = vec![0; code_size as usize]; let mut reloc_sink = ObjectRelocSink::new(self.object.format()); let mut trap_sink = ObjectTrapSink::default(); @@ -229,8 +230,9 @@ impl Backend for ObjectBackend { relocs: reloc_sink.relocs, }); } - self.traps[func_id] = trap_sink.sites; - Ok(ObjectCompiledFunction) + let trapref = self.traps.index_mut(func_id); + *trapref = trap_sink.sites; + Ok((ObjectCompiledFunction, trapref)) } fn define_function_bytes( @@ -240,14 +242,15 @@ impl Backend for ObjectBackend { bytes: &[u8], _namespace: &ModuleNamespace, traps: Vec, - ) -> ModuleResult { + ) -> ModuleResult<(ObjectCompiledFunction, &[TrapSite])> { let symbol = self.functions[func_id].unwrap(); let section = self.object.section_id(StandardSection::Text); let _offset = self .object .add_symbol_data(symbol, section, bytes, self.function_alignment); - self.traps[func_id] = traps; - Ok(ObjectCompiledFunction) + let trapref = self.traps.index_mut(func_id); + *trapref = traps; + Ok((ObjectCompiledFunction, trapref)) } fn define_data( diff --git a/cranelift/simplejit/src/backend.rs b/cranelift/simplejit/src/backend.rs index 08bc565133..22a7c4b36b 100644 --- a/cranelift/simplejit/src/backend.rs +++ b/cranelift/simplejit/src/backend.rs @@ -278,7 +278,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { ctx: &cranelift_codegen::Context, _namespace: &ModuleNamespace, code_size: u32, - ) -> ModuleResult { + ) -> ModuleResult<(Self::CompiledFunction, &[TrapSite])> { let size = code_size as usize; let ptr = self .memory @@ -303,11 +303,14 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { ) }; - Ok(Self::CompiledFunction { - code: ptr, - size, - relocs: reloc_sink.relocs, - }) + Ok(( + Self::CompiledFunction { + code: ptr, + size, + relocs: reloc_sink.relocs, + }, + &[], + )) } fn define_function_bytes( @@ -317,7 +320,7 @@ impl<'simple_jit_backend> Backend for SimpleJITBackend { bytes: &[u8], _namespace: &ModuleNamespace, _traps: Vec, - ) -> ModuleResult { + ) -> ModuleResult<(Self::CompiledFunction, &[TrapSite])> { let size = bytes.len(); let ptr = self .memory @@ -331,11 +334,14 @@ 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(