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:
@@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>,
|
||||||
)>;
|
)>;
|
||||||
|
|||||||
@@ -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,13 +252,14 @@ 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));
|
|
||||||
debug_assert!((*ret).func_ptr.as_ptr() as usize != INVALID_PTR);
|
unsafe fn anyfunc(&self, offset: u32) -> NonNull<VMCallerCheckedAnyfunc> {
|
||||||
debug_assert!((*ret).vmctx as usize != INVALID_PTR);
|
let ret = self.vmctx_plus_offset::<VMCallerCheckedAnyfunc>(offset);
|
||||||
NonNull::new(ret).unwrap()
|
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.
|
/// 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,19 +346,22 @@ 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,
|
||||||
let vmctx = self.vmctx();
|
offset: u32,
|
||||||
*self.vmctx_plus_offset(self.offsets.always_trap_anyfunc(idx)) =
|
func_ptr: NonNull<VMFunctionBody>,
|
||||||
VMCallerCheckedAnyfunc {
|
type_index: VMSharedSignatureIndex,
|
||||||
func_ptr,
|
) {
|
||||||
type_index,
|
debug_assert!(*self.vmctx_plus_offset::<usize>(offset) == INVALID_PTR);
|
||||||
vmctx: VMOpaqueContext::from_vmcomponent(vmctx),
|
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) {
|
unsafe fn initialize_vmctx(&mut self, store: *mut dyn Store) {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user