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 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<dyn Any + Send>)>,
obj: &mut Object<'static>,
) -> Result<(
PrimaryMap<LoweredIndex, LoweringInfo>,
PrimaryMap<LoweredIndex, FunctionInfo>,
PrimaryMap<RuntimeAlwaysTrapIndex, AlwaysTrapInfo>,
Vec<Trampoline>,
)> {
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::<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(),
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
.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))
}
}

View File

@@ -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<dyn Any + Send>)>,
obj: &mut Object<'static>,
) -> Result<(
PrimaryMap<LoweredIndex, LoweringInfo>,
PrimaryMap<LoweredIndex, FunctionInfo>,
PrimaryMap<RuntimeAlwaysTrapIndex, AlwaysTrapInfo>,
Vec<Trampoline>,
)>;

View File

@@ -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<VMCallerCheckedAnyfunc> {
unsafe {
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()
}
unsafe { self.anyfunc(self.offsets.lowering_anyfunc(idx)) }
}
/// Same as `lowering_anyfunc` except for the functions that always trap.
@@ -258,14 +252,15 @@ impl ComponentInstance {
&self,
idx: RuntimeAlwaysTrapIndex,
) -> NonNull<VMCallerCheckedAnyfunc> {
unsafe {
let ret = self
.vmctx_plus_offset::<VMCallerCheckedAnyfunc>(self.offsets.always_trap_anyfunc(idx));
unsafe { self.anyfunc(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).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::<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;
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,20 +346,23 @@ impl ComponentInstance {
func_ptr: NonNull<VMFunctionBody>,
type_index: VMSharedSignatureIndex,
) {
unsafe {
debug_assert!(
*self.vmctx_plus_offset::<usize>(self.offsets.always_trap_anyfunc(idx))
== INVALID_PTR
);
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<VMFunctionBody>,
type_index: VMSharedSignatureIndex,
) {
debug_assert!(*self.vmctx_plus_offset::<usize>(offset) == INVALID_PTR);
let vmctx = self.vmctx();
*self.vmctx_plus_offset(self.offsets.always_trap_anyfunc(idx)) =
VMCallerCheckedAnyfunc {
*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) {
*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::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<LoweredIndex, LoweringInfo>,
lowerings: PrimaryMap<LoweredIndex, FunctionInfo>,
/// 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<SignatureIndex>,
) -> Result<(
PrimaryMap<LoweredIndex, LoweringInfo>,
PrimaryMap<LoweredIndex, FunctionInfo>,
PrimaryMap<RuntimeAlwaysTrapIndex, AlwaysTrapInfo>,
Vec<Trampoline>,
wasmtime_runtime::MmapVec,
@@ -368,17 +368,17 @@ impl Component {
pub(crate) fn lowering_ptr(&self, index: LoweredIndex) -> NonNull<VMFunctionBody> {
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> {
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 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,

View File

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