diff --git a/crates/cranelift/src/compiler/component.rs b/crates/cranelift/src/compiler/component.rs index f45862f0c8..803a5629a3 100644 --- a/crates/cranelift/src/compiler/component.rs +++ b/crates/cranelift/src/compiler/component.rs @@ -8,9 +8,10 @@ use cranelift_codegen::ir::{self, InstBuilder, MemFlags}; use cranelift_frontend::FunctionBuilder; use object::write::Object; use std::any::Any; +use std::ops::Range; use wasmtime_environ::component::{ - AlwaysTrapInfo, CanonicalOptions, Component, ComponentCompiler, ComponentTypes, LowerImport, - LoweredIndex, LoweringInfo, RuntimeAlwaysTrapIndex, VMComponentOffsets, + AlwaysTrapInfo, CanonicalOptions, Component, ComponentCompiler, ComponentTypes, FunctionInfo, + LowerImport, LoweredIndex, RuntimeAlwaysTrapIndex, VMComponentOffsets, }; use wasmtime_environ::{PrimaryMap, SignatureIndex, Trampoline, TrapCode, WasmFuncType}; @@ -187,28 +188,29 @@ impl ComponentCompiler for Compiler { trampolines: Vec<(SignatureIndex, Box)>, obj: &mut Object<'static>, ) -> Result<( - PrimaryMap, + PrimaryMap, PrimaryMap, Vec, )> { let module = Default::default(); let mut text = ModuleTextBuilder::new(obj, &module, &*self.isa); - let mut ret = PrimaryMap::new(); - for (idx, lowering) in lowerings.iter() { - let lowering = lowering.downcast_ref::().unwrap(); - assert!(lowering.traps.is_empty()); - let (_symbol, range) = text.append_func( - false, - format!("_wasm_component_lowering_trampoline{}", idx.as_u32()).into_bytes(), - &lowering, - ); - let i = ret.push(LoweringInfo { - start: u32::try_from(range.start).unwrap(), - length: u32::try_from(range.end - range.start).unwrap(), - }); - assert_eq!(i, idx); - } + let range2info = |range: Range| FunctionInfo { + start: u32::try_from(range.start).unwrap(), + length: u32::try_from(range.end - range.start).unwrap(), + }; + let ret_lowerings = lowerings + .iter() + .map(|(i, lowering)| { + let lowering = lowering.downcast_ref::().unwrap(); + assert!(lowering.traps.is_empty()); + let range = text.named_func( + &format!("_wasm_component_lowering_trampoline{}", i.as_u32()), + &lowering, + ); + range2info(range) + }) + .collect(); let ret_always_trap = always_trap .iter() .map(|(i, func)| { @@ -217,11 +219,8 @@ impl ComponentCompiler for Compiler { assert_eq!(func.traps[0].trap_code, TrapCode::AlwaysTrapAdapter); let name = format!("_wasmtime_always_trap{}", i.as_u32()); let range = text.named_func(&name, func); - let start = u32::try_from(range.start).unwrap(); - let end = u32::try_from(range.end).unwrap(); AlwaysTrapInfo { - start: start, - length: end - start, + info: range2info(range), trap_offset: func.traps[0].code_offset, } }) @@ -238,6 +237,6 @@ impl ComponentCompiler for Compiler { text.finish()?; - Ok((ret, ret_always_trap, ret_trampolines)) + Ok((ret_lowerings, ret_always_trap, ret_trampolines)) } } diff --git a/crates/environ/src/component/compiler.rs b/crates/environ/src/component/compiler.rs index c93000bc76..ac07a3c1d5 100644 --- a/crates/environ/src/component/compiler.rs +++ b/crates/environ/src/component/compiler.rs @@ -10,7 +10,7 @@ use std::any::Any; /// Description of where a trampoline is located in the text section of a /// compiled image. #[derive(Serialize, Deserialize)] -pub struct LoweringInfo { +pub struct FunctionInfo { /// The byte offset from the start of the text section where this trampoline /// starts. pub start: u32, @@ -22,11 +22,8 @@ pub struct LoweringInfo { /// `ComponentCompiler::compile_always_trap`. #[derive(Serialize, Deserialize)] pub struct AlwaysTrapInfo { - /// The byte offset from the start of the text section where this trampoline - /// starts. - pub start: u32, - /// The byte length of this trampoline's function body. - pub length: u32, + /// Information about the extent of this generated function. + pub info: FunctionInfo, /// The offset from `start` of where the trapping instruction is located. pub trap_offset: u32, } @@ -79,7 +76,7 @@ pub trait ComponentCompiler: Send + Sync { tramplines: Vec<(SignatureIndex, Box)>, obj: &mut Object<'static>, ) -> Result<( - PrimaryMap, + PrimaryMap, PrimaryMap, Vec, )>; diff --git a/crates/runtime/src/component.rs b/crates/runtime/src/component.rs index 58f0f85006..f324ff9dca 100644 --- a/crates/runtime/src/component.rs +++ b/crates/runtime/src/component.rs @@ -244,13 +244,7 @@ impl ComponentInstance { /// This can only be called after `idx` has been initialized at runtime /// during the instantiation process of a component. pub fn lowering_anyfunc(&self, idx: LoweredIndex) -> NonNull { - unsafe { - let ret = self - .vmctx_plus_offset::(self.offsets.lowering_anyfunc(idx)); - debug_assert!((*ret).func_ptr.as_ptr() as usize != INVALID_PTR); - debug_assert!((*ret).vmctx as usize != INVALID_PTR); - NonNull::new(ret).unwrap() - } + unsafe { self.anyfunc(self.offsets.lowering_anyfunc(idx)) } } /// Same as `lowering_anyfunc` except for the functions that always trap. @@ -258,13 +252,14 @@ impl ComponentInstance { &self, idx: RuntimeAlwaysTrapIndex, ) -> NonNull { - unsafe { - let ret = self - .vmctx_plus_offset::(self.offsets.always_trap_anyfunc(idx)); - debug_assert!((*ret).func_ptr.as_ptr() as usize != INVALID_PTR); - debug_assert!((*ret).vmctx as usize != INVALID_PTR); - NonNull::new(ret).unwrap() - } + unsafe { self.anyfunc(self.offsets.always_trap_anyfunc(idx)) } + } + + unsafe fn anyfunc(&self, offset: u32) -> NonNull { + let ret = self.vmctx_plus_offset::(offset); + debug_assert!((*ret).func_ptr.as_ptr() as usize != INVALID_PTR); + debug_assert!((*ret).vmctx as usize != INVALID_PTR); + NonNull::new(ret).unwrap() } /// Stores the runtime memory pointer at the index specified. @@ -335,16 +330,12 @@ impl ComponentInstance { debug_assert!( *self.vmctx_plus_offset::(self.offsets.lowering_data(idx)) == INVALID_PTR ); - debug_assert!( - *self.vmctx_plus_offset::(self.offsets.lowering_anyfunc(idx)) == INVALID_PTR - ); *self.vmctx_plus_offset(self.offsets.lowering(idx)) = lowering; - let vmctx = self.vmctx(); - *self.vmctx_plus_offset(self.offsets.lowering_anyfunc(idx)) = VMCallerCheckedAnyfunc { - func_ptr: anyfunc_func_ptr, - type_index: anyfunc_type_index, - vmctx: VMOpaqueContext::from_vmcomponent(vmctx), - }; + self.set_anyfunc( + self.offsets.lowering_anyfunc(idx), + anyfunc_func_ptr, + anyfunc_type_index, + ); } } @@ -355,19 +346,22 @@ impl ComponentInstance { func_ptr: NonNull, type_index: VMSharedSignatureIndex, ) { - unsafe { - debug_assert!( - *self.vmctx_plus_offset::(self.offsets.always_trap_anyfunc(idx)) - == INVALID_PTR - ); - let vmctx = self.vmctx(); - *self.vmctx_plus_offset(self.offsets.always_trap_anyfunc(idx)) = - VMCallerCheckedAnyfunc { - func_ptr, - type_index, - vmctx: VMOpaqueContext::from_vmcomponent(vmctx), - }; - } + unsafe { self.set_anyfunc(self.offsets.always_trap_anyfunc(idx), func_ptr, type_index) } + } + + unsafe fn set_anyfunc( + &mut self, + offset: u32, + func_ptr: NonNull, + type_index: VMSharedSignatureIndex, + ) { + debug_assert!(*self.vmctx_plus_offset::(offset) == INVALID_PTR); + let vmctx = self.vmctx(); + *self.vmctx_plus_offset(offset) = VMCallerCheckedAnyfunc { + func_ptr, + type_index, + vmctx: VMOpaqueContext::from_vmcomponent(vmctx), + }; } unsafe fn initialize_vmctx(&mut self, store: *mut dyn Store) { diff --git a/crates/wasmtime/src/component/component.rs b/crates/wasmtime/src/component/component.rs index c60713f26d..f60aa99fb2 100644 --- a/crates/wasmtime/src/component/component.rs +++ b/crates/wasmtime/src/component/component.rs @@ -10,7 +10,7 @@ use std::path::Path; use std::ptr::NonNull; use std::sync::Arc; use wasmtime_environ::component::{ - AlwaysTrapInfo, ComponentTypes, GlobalInitializer, LoweredIndex, LoweringInfo, + AlwaysTrapInfo, ComponentTypes, FunctionInfo, GlobalInitializer, LoweredIndex, RuntimeAlwaysTrapIndex, StaticModuleIndex, Translator, }; use wasmtime_environ::{PrimaryMap, ScopeVec, SignatureIndex, Trampoline, TrapCode}; @@ -56,7 +56,7 @@ struct ComponentInner { /// These trampolines are the function pointer within the /// `VMCallerCheckedAnyfunc` and will delegate indirectly to a host function /// pointer when called. - lowerings: PrimaryMap, + lowerings: PrimaryMap, /// Where the "always trap" functions are located within the `text` section /// of `trampoline_obj`. @@ -205,7 +205,7 @@ impl Component { .values() .as_slice() .windows(2) - .all(|window| { window[0].start < window[1].start })); + .all(|window| { window[0].info.start < window[1].info.start })); crate::module::register_component(code.text, &always_trap); Ok(Component { @@ -229,7 +229,7 @@ impl Component { types: &ComponentTypes, provided_trampolines: &HashSet, ) -> Result<( - PrimaryMap, + PrimaryMap, PrimaryMap, Vec, wasmtime_runtime::MmapVec, @@ -368,17 +368,17 @@ impl Component { pub(crate) fn lowering_ptr(&self, index: LoweredIndex) -> NonNull { let info = &self.inner.lowerings[index]; - self.func(info.start, info.length) + self.func(info) } pub(crate) fn always_trap_ptr(&self, index: RuntimeAlwaysTrapIndex) -> NonNull { let info = &self.inner.always_trap[index]; - self.func(info.start, info.length) + self.func(&info.info) } - fn func(&self, start: u32, len: u32) -> NonNull { + fn func(&self, info: &FunctionInfo) -> NonNull { let text = self.text(); - let trampoline = &text[start as usize..][..len as usize]; + let trampoline = &text[info.start as usize..][..info.length as usize]; NonNull::new(trampoline.as_ptr() as *mut VMFunctionBody).unwrap() } @@ -393,7 +393,7 @@ impl Component { .always_trap .values() .as_slice() - .binary_search_by_key(&offset, |info| info.start + info.trap_offset) + .binary_search_by_key(&offset, |info| info.info.start + info.trap_offset) { Ok(_) => Some(TrapCode::AlwaysTrapAdapter), Err(_) => None, diff --git a/crates/wasmtime/src/module/registry.rs b/crates/wasmtime/src/module/registry.rs index 732df96141..cb221ff15c 100644 --- a/crates/wasmtime/src/module/registry.rs +++ b/crates/wasmtime/src/module/registry.rs @@ -287,7 +287,7 @@ pub fn register_component(text: &[u8], traps: &PrimaryMap>(), ); let prev = GLOBAL_MODULES