Some minor cleanups/refactorings in components (#4582)

This is a collection of some minor renamings, refactorings, sharing of
code, etc. This was all discovered during my addition of string support
to adapter functions and I figured it'd be best to frontload this and
land it ahead of the full patch since it's getting complex.
This commit is contained in:
Alex Crichton
2022-08-03 11:21:55 -05:00
committed by GitHub
parent 0a6baeddf4
commit 9f82644cc3
5 changed files with 66 additions and 76 deletions

View File

@@ -8,9 +8,10 @@ use cranelift_codegen::ir::{self, InstBuilder, MemFlags};
use cranelift_frontend::FunctionBuilder; use cranelift_frontend::FunctionBuilder;
use object::write::Object; use object::write::Object;
use std::any::Any; use std::any::Any;
use std::ops::Range;
use wasmtime_environ::component::{ use wasmtime_environ::component::{
AlwaysTrapInfo, CanonicalOptions, Component, ComponentCompiler, ComponentTypes, LowerImport, AlwaysTrapInfo, CanonicalOptions, Component, ComponentCompiler, ComponentTypes, FunctionInfo,
LoweredIndex, LoweringInfo, RuntimeAlwaysTrapIndex, VMComponentOffsets, LowerImport, LoweredIndex, RuntimeAlwaysTrapIndex, VMComponentOffsets,
}; };
use wasmtime_environ::{PrimaryMap, SignatureIndex, Trampoline, TrapCode, WasmFuncType}; use wasmtime_environ::{PrimaryMap, SignatureIndex, Trampoline, TrapCode, WasmFuncType};
@@ -187,28 +188,29 @@ impl ComponentCompiler for Compiler {
trampolines: Vec<(SignatureIndex, Box<dyn Any + Send>)>, trampolines: Vec<(SignatureIndex, Box<dyn Any + Send>)>,
obj: &mut Object<'static>, obj: &mut Object<'static>,
) -> Result<( ) -> Result<(
PrimaryMap<LoweredIndex, LoweringInfo>, PrimaryMap<LoweredIndex, FunctionInfo>,
PrimaryMap<RuntimeAlwaysTrapIndex, AlwaysTrapInfo>, PrimaryMap<RuntimeAlwaysTrapIndex, AlwaysTrapInfo>,
Vec<Trampoline>, Vec<Trampoline>,
)> { )> {
let module = Default::default(); let module = Default::default();
let mut text = ModuleTextBuilder::new(obj, &module, &*self.isa); 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::<CompiledFunction>().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 { let range2info = |range: Range<u64>| FunctionInfo {
start: u32::try_from(range.start).unwrap(), start: u32::try_from(range.start).unwrap(),
length: u32::try_from(range.end - range.start).unwrap(), length: u32::try_from(range.end - range.start).unwrap(),
}); };
assert_eq!(i, idx); let ret_lowerings = lowerings
} .iter()
.map(|(i, lowering)| {
let lowering = lowering.downcast_ref::<CompiledFunction>().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 let ret_always_trap = always_trap
.iter() .iter()
.map(|(i, func)| { .map(|(i, func)| {
@@ -217,11 +219,8 @@ impl ComponentCompiler for Compiler {
assert_eq!(func.traps[0].trap_code, TrapCode::AlwaysTrapAdapter); assert_eq!(func.traps[0].trap_code, TrapCode::AlwaysTrapAdapter);
let name = format!("_wasmtime_always_trap{}", i.as_u32()); let name = format!("_wasmtime_always_trap{}", i.as_u32());
let range = text.named_func(&name, func); let range = text.named_func(&name, func);
let start = u32::try_from(range.start).unwrap();
let end = u32::try_from(range.end).unwrap();
AlwaysTrapInfo { AlwaysTrapInfo {
start: start, info: range2info(range),
length: end - start,
trap_offset: func.traps[0].code_offset, trap_offset: func.traps[0].code_offset,
} }
}) })
@@ -238,6 +237,6 @@ impl ComponentCompiler for Compiler {
text.finish()?; text.finish()?;
Ok((ret, ret_always_trap, ret_trampolines)) Ok((ret_lowerings, ret_always_trap, ret_trampolines))
} }
} }

View File

@@ -10,7 +10,7 @@ use std::any::Any;
/// Description of where a trampoline is located in the text section of a /// Description of where a trampoline is located in the text section of a
/// compiled image. /// compiled image.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct LoweringInfo { pub struct FunctionInfo {
/// The byte offset from the start of the text section where this trampoline /// The byte offset from the start of the text section where this trampoline
/// starts. /// starts.
pub start: u32, pub start: u32,
@@ -22,11 +22,8 @@ pub struct LoweringInfo {
/// `ComponentCompiler::compile_always_trap`. /// `ComponentCompiler::compile_always_trap`.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct AlwaysTrapInfo { pub struct AlwaysTrapInfo {
/// The byte offset from the start of the text section where this trampoline /// Information about the extent of this generated function.
/// starts. pub info: FunctionInfo,
pub start: u32,
/// The byte length of this trampoline's function body.
pub length: u32,
/// The offset from `start` of where the trapping instruction is located. /// The offset from `start` of where the trapping instruction is located.
pub trap_offset: u32, pub trap_offset: u32,
} }
@@ -79,7 +76,7 @@ pub trait ComponentCompiler: Send + Sync {
tramplines: Vec<(SignatureIndex, Box<dyn Any + Send>)>, tramplines: Vec<(SignatureIndex, Box<dyn Any + Send>)>,
obj: &mut Object<'static>, obj: &mut Object<'static>,
) -> Result<( ) -> Result<(
PrimaryMap<LoweredIndex, LoweringInfo>, PrimaryMap<LoweredIndex, FunctionInfo>,
PrimaryMap<RuntimeAlwaysTrapIndex, AlwaysTrapInfo>, PrimaryMap<RuntimeAlwaysTrapIndex, AlwaysTrapInfo>,
Vec<Trampoline>, Vec<Trampoline>,
)>; )>;

View File

@@ -244,13 +244,7 @@ impl ComponentInstance {
/// This can only be called after `idx` has been initialized at runtime /// This can only be called after `idx` has been initialized at runtime
/// during the instantiation process of a component. /// during the instantiation process of a component.
pub fn lowering_anyfunc(&self, idx: LoweredIndex) -> NonNull<VMCallerCheckedAnyfunc> { pub fn lowering_anyfunc(&self, idx: LoweredIndex) -> NonNull<VMCallerCheckedAnyfunc> {
unsafe { unsafe { self.anyfunc(self.offsets.lowering_anyfunc(idx)) }
let ret = self
.vmctx_plus_offset::<VMCallerCheckedAnyfunc>(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()
}
} }
/// Same as `lowering_anyfunc` except for the functions that always trap. /// Same as `lowering_anyfunc` except for the functions that always trap.
@@ -258,14 +252,15 @@ impl ComponentInstance {
&self, &self,
idx: RuntimeAlwaysTrapIndex, idx: RuntimeAlwaysTrapIndex,
) -> NonNull<VMCallerCheckedAnyfunc> { ) -> NonNull<VMCallerCheckedAnyfunc> {
unsafe { unsafe { self.anyfunc(self.offsets.always_trap_anyfunc(idx)) }
let ret = self }
.vmctx_plus_offset::<VMCallerCheckedAnyfunc>(self.offsets.always_trap_anyfunc(idx));
unsafe fn anyfunc(&self, offset: u32) -> NonNull<VMCallerCheckedAnyfunc> {
let ret = self.vmctx_plus_offset::<VMCallerCheckedAnyfunc>(offset);
debug_assert!((*ret).func_ptr.as_ptr() as usize != INVALID_PTR); debug_assert!((*ret).func_ptr.as_ptr() as usize != INVALID_PTR);
debug_assert!((*ret).vmctx as usize != INVALID_PTR); debug_assert!((*ret).vmctx as usize != INVALID_PTR);
NonNull::new(ret).unwrap() NonNull::new(ret).unwrap()
} }
}
/// Stores the runtime memory pointer at the index specified. /// Stores the runtime memory pointer at the index specified.
/// ///
@@ -335,16 +330,12 @@ impl ComponentInstance {
debug_assert!( debug_assert!(
*self.vmctx_plus_offset::<usize>(self.offsets.lowering_data(idx)) == INVALID_PTR *self.vmctx_plus_offset::<usize>(self.offsets.lowering_data(idx)) == INVALID_PTR
); );
debug_assert!(
*self.vmctx_plus_offset::<usize>(self.offsets.lowering_anyfunc(idx)) == INVALID_PTR
);
*self.vmctx_plus_offset(self.offsets.lowering(idx)) = lowering; *self.vmctx_plus_offset(self.offsets.lowering(idx)) = lowering;
let vmctx = self.vmctx(); self.set_anyfunc(
*self.vmctx_plus_offset(self.offsets.lowering_anyfunc(idx)) = VMCallerCheckedAnyfunc { self.offsets.lowering_anyfunc(idx),
func_ptr: anyfunc_func_ptr, anyfunc_func_ptr,
type_index: anyfunc_type_index, anyfunc_type_index,
vmctx: VMOpaqueContext::from_vmcomponent(vmctx), );
};
} }
} }
@@ -355,20 +346,23 @@ impl ComponentInstance {
func_ptr: NonNull<VMFunctionBody>, func_ptr: NonNull<VMFunctionBody>,
type_index: VMSharedSignatureIndex, type_index: VMSharedSignatureIndex,
) { ) {
unsafe { unsafe { self.set_anyfunc(self.offsets.always_trap_anyfunc(idx), func_ptr, type_index) }
debug_assert!( }
*self.vmctx_plus_offset::<usize>(self.offsets.always_trap_anyfunc(idx))
== INVALID_PTR unsafe fn set_anyfunc(
); &mut self,
offset: u32,
func_ptr: NonNull<VMFunctionBody>,
type_index: VMSharedSignatureIndex,
) {
debug_assert!(*self.vmctx_plus_offset::<usize>(offset) == INVALID_PTR);
let vmctx = self.vmctx(); let vmctx = self.vmctx();
*self.vmctx_plus_offset(self.offsets.always_trap_anyfunc(idx)) = *self.vmctx_plus_offset(offset) = VMCallerCheckedAnyfunc {
VMCallerCheckedAnyfunc {
func_ptr, func_ptr,
type_index, type_index,
vmctx: VMOpaqueContext::from_vmcomponent(vmctx), vmctx: VMOpaqueContext::from_vmcomponent(vmctx),
}; };
} }
}
unsafe fn initialize_vmctx(&mut self, store: *mut dyn Store) { unsafe fn initialize_vmctx(&mut self, store: *mut dyn Store) {
*self.vmctx_plus_offset(self.offsets.magic()) = VMCOMPONENT_MAGIC; *self.vmctx_plus_offset(self.offsets.magic()) = VMCOMPONENT_MAGIC;

View File

@@ -10,7 +10,7 @@ use std::path::Path;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::sync::Arc; use std::sync::Arc;
use wasmtime_environ::component::{ use wasmtime_environ::component::{
AlwaysTrapInfo, ComponentTypes, GlobalInitializer, LoweredIndex, LoweringInfo, AlwaysTrapInfo, ComponentTypes, FunctionInfo, GlobalInitializer, LoweredIndex,
RuntimeAlwaysTrapIndex, StaticModuleIndex, Translator, RuntimeAlwaysTrapIndex, StaticModuleIndex, Translator,
}; };
use wasmtime_environ::{PrimaryMap, ScopeVec, SignatureIndex, Trampoline, TrapCode}; use wasmtime_environ::{PrimaryMap, ScopeVec, SignatureIndex, Trampoline, TrapCode};
@@ -56,7 +56,7 @@ struct ComponentInner {
/// These trampolines are the function pointer within the /// These trampolines are the function pointer within the
/// `VMCallerCheckedAnyfunc` and will delegate indirectly to a host function /// `VMCallerCheckedAnyfunc` and will delegate indirectly to a host function
/// pointer when called. /// pointer when called.
lowerings: PrimaryMap<LoweredIndex, LoweringInfo>, lowerings: PrimaryMap<LoweredIndex, FunctionInfo>,
/// Where the "always trap" functions are located within the `text` section /// Where the "always trap" functions are located within the `text` section
/// of `trampoline_obj`. /// of `trampoline_obj`.
@@ -205,7 +205,7 @@ impl Component {
.values() .values()
.as_slice() .as_slice()
.windows(2) .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); crate::module::register_component(code.text, &always_trap);
Ok(Component { Ok(Component {
@@ -229,7 +229,7 @@ impl Component {
types: &ComponentTypes, types: &ComponentTypes,
provided_trampolines: &HashSet<SignatureIndex>, provided_trampolines: &HashSet<SignatureIndex>,
) -> Result<( ) -> Result<(
PrimaryMap<LoweredIndex, LoweringInfo>, PrimaryMap<LoweredIndex, FunctionInfo>,
PrimaryMap<RuntimeAlwaysTrapIndex, AlwaysTrapInfo>, PrimaryMap<RuntimeAlwaysTrapIndex, AlwaysTrapInfo>,
Vec<Trampoline>, Vec<Trampoline>,
wasmtime_runtime::MmapVec, wasmtime_runtime::MmapVec,
@@ -368,17 +368,17 @@ impl Component {
pub(crate) fn lowering_ptr(&self, index: LoweredIndex) -> NonNull<VMFunctionBody> { pub(crate) fn lowering_ptr(&self, index: LoweredIndex) -> NonNull<VMFunctionBody> {
let info = &self.inner.lowerings[index]; 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<VMFunctionBody> { pub(crate) fn always_trap_ptr(&self, index: RuntimeAlwaysTrapIndex) -> NonNull<VMFunctionBody> {
let info = &self.inner.always_trap[index]; 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<VMFunctionBody> { fn func(&self, info: &FunctionInfo) -> NonNull<VMFunctionBody> {
let text = self.text(); 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() NonNull::new(trampoline.as_ptr() as *mut VMFunctionBody).unwrap()
} }
@@ -393,7 +393,7 @@ impl Component {
.always_trap .always_trap
.values() .values()
.as_slice() .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), Ok(_) => Some(TrapCode::AlwaysTrapAdapter),
Err(_) => None, Err(_) => None,

View File

@@ -287,7 +287,7 @@ pub fn register_component(text: &[u8], traps: &PrimaryMap<RuntimeAlwaysTrapIndex
let info = Arc::new( let info = Arc::new(
traps traps
.iter() .iter()
.map(|(_, info)| info.start + info.trap_offset) .map(|(_, info)| info.info.start + info.trap_offset)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
); );
let prev = GLOBAL_MODULES let prev = GLOBAL_MODULES