diff --git a/cranelift/faerie/src/backend.rs b/cranelift/faerie/src/backend.rs index 40cca8eddc..2520515cd7 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, Option<&Vec>)> { 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 = None; // 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 = Some(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, Option<&Vec>)> { let code_length: u32 = match bytes.len().try_into() { Ok(code_length) => code_length, _ => Err(ModuleError::FunctionTooLarge(name.to_string()))?, }; + let mut ret_traps = None; 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 = Some(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..f98a4384bc 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) -> &Vec { 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..bc10d30a54 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, Option<&Vec>)>; /// 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, Option<&Vec>)>; /// 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..56d4593440 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: Option<&'a Vec>, +} + 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..60570ae794 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, Option<&Vec>)> { 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, Some(trapref))) } fn define_function_bytes( @@ -240,14 +242,15 @@ impl Backend for ObjectBackend { bytes: &[u8], _namespace: &ModuleNamespace, traps: Vec, - ) -> ModuleResult { + ) -> ModuleResult<(ObjectCompiledFunction, Option<&Vec>)> { 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, Some(trapref))) } fn define_data( diff --git a/cranelift/simplejit/src/backend.rs b/cranelift/simplejit/src/backend.rs index 08bc565133..0e9b49dbcd 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, Option<&Vec>)> { 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, + }, + None, + )) } 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, Option<&Vec>)> { 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![], + }, + None, + )) } fn define_data(