Skip to content

Commit 934d924

Browse files
committed
Refactor wasmtime::FuncType to hold a handle to its registered type
Rather than holding a copy of the type directly, it now holds a `RegisteredType` which internally is * A `VMSharedTypeIndex` pointing into the engine's types registry. * An `Arc` handle to the engine's type registry. * An `Arc` handle to the actual type. The last exists only to keep it so that accessing a `wasmtime::FuncType`'s parameters and results fast, avoiding any new locking on call hot paths. This is helping set the stage for further types and `TypeRegistry` refactors needed for Wasm GC.
1 parent 74a303a commit 934d924

24 files changed

Lines changed: 660 additions & 433 deletions

crates/fuzzing/src/oracles.rs

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -616,36 +616,34 @@ pub fn table_ops(
616616
// NB: use `Func::new` so that this can still compile on the old x86
617617
// backend, where `IntoFunc` isn't implemented for multi-value
618618
// returns.
619-
let func = Func::new(
620-
&mut store,
621-
FuncType::new(
622-
vec![],
623-
vec![ValType::ExternRef, ValType::ExternRef, ValType::ExternRef],
624-
),
625-
{
626-
let num_dropped = num_dropped.clone();
627-
let expected_drops = expected_drops.clone();
628-
let num_gcs = num_gcs.clone();
629-
move |mut caller: Caller<'_, StoreLimits>, _params, results| {
630-
log::info!("table_ops: GC");
631-
if num_gcs.fetch_add(1, SeqCst) < MAX_GCS {
632-
caller.gc();
633-
}
619+
let func_ty = FuncType::new(
620+
store.engine(),
621+
vec![],
622+
vec![ValType::ExternRef, ValType::ExternRef, ValType::ExternRef],
623+
);
624+
let func = Func::new(&mut store, func_ty, {
625+
let num_dropped = num_dropped.clone();
626+
let expected_drops = expected_drops.clone();
627+
let num_gcs = num_gcs.clone();
628+
move |mut caller: Caller<'_, StoreLimits>, _params, results| {
629+
log::info!("table_ops: GC");
630+
if num_gcs.fetch_add(1, SeqCst) < MAX_GCS {
631+
caller.gc();
632+
}
634633

635-
let a = ExternRef::new(CountDrops(num_dropped.clone()));
636-
let b = ExternRef::new(CountDrops(num_dropped.clone()));
637-
let c = ExternRef::new(CountDrops(num_dropped.clone()));
634+
let a = ExternRef::new(CountDrops(num_dropped.clone()));
635+
let b = ExternRef::new(CountDrops(num_dropped.clone()));
636+
let c = ExternRef::new(CountDrops(num_dropped.clone()));
638637

639-
log::info!("table_ops: make_refs() -> ({:p}, {:p}, {:p})", a, b, c);
638+
log::info!("table_ops: make_refs() -> ({:p}, {:p}, {:p})", a, b, c);
640639

641-
expected_drops.fetch_add(3, SeqCst);
642-
results[0] = Some(a).into();
643-
results[1] = Some(b).into();
644-
results[2] = Some(c).into();
645-
Ok(())
646-
}
647-
},
648-
);
640+
expected_drops.fetch_add(3, SeqCst);
641+
results[0] = Some(a).into();
642+
results[1] = Some(b).into();
643+
results[2] = Some(c).into();
644+
Ok(())
645+
}
646+
});
649647
linker.define(&store, "", "gc", func).unwrap();
650648

651649
linker
@@ -691,25 +689,23 @@ pub fn table_ops(
691689
// NB: use `Func::new` so that this can still compile on the old
692690
// x86 backend, where `IntoFunc` isn't implemented for
693691
// multi-value returns.
694-
let func = Func::new(
695-
&mut store,
696-
FuncType::new(
697-
vec![],
698-
vec![ValType::ExternRef, ValType::ExternRef, ValType::ExternRef],
699-
),
700-
{
701-
let num_dropped = num_dropped.clone();
702-
let expected_drops = expected_drops.clone();
703-
move |_caller, _params, results| {
704-
log::info!("table_ops: make_refs");
705-
expected_drops.fetch_add(3, SeqCst);
706-
results[0] = Some(ExternRef::new(CountDrops(num_dropped.clone()))).into();
707-
results[1] = Some(ExternRef::new(CountDrops(num_dropped.clone()))).into();
708-
results[2] = Some(ExternRef::new(CountDrops(num_dropped.clone()))).into();
709-
Ok(())
710-
}
711-
},
692+
let func_ty = FuncType::new(
693+
store.engine(),
694+
vec![],
695+
vec![ValType::ExternRef, ValType::ExternRef, ValType::ExternRef],
712696
);
697+
let func = Func::new(&mut store, func_ty, {
698+
let num_dropped = num_dropped.clone();
699+
let expected_drops = expected_drops.clone();
700+
move |_caller, _params, results| {
701+
log::info!("table_ops: make_refs");
702+
expected_drops.fetch_add(3, SeqCst);
703+
results[0] = Some(ExternRef::new(CountDrops(num_dropped.clone()))).into();
704+
results[1] = Some(ExternRef::new(CountDrops(num_dropped.clone()))).into();
705+
results[2] = Some(ExternRef::new(CountDrops(num_dropped.clone()))).into();
706+
Ok(())
707+
}
708+
});
713709
linker.define(&store, "", "make_refs", func).unwrap();
714710

715711
let instance = linker.instantiate(&mut store, &module).unwrap();

crates/fuzzing/src/oracles/dummy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ mod tests {
114114
#[test]
115115
fn dummy_function_import() {
116116
let mut store = store();
117-
let func_ty = FuncType::new(vec![ValType::I32], vec![ValType::I64]);
117+
let func_ty = FuncType::new(store.engine(), vec![ValType::I32], vec![ValType::I64]);
118118
let func = dummy_func(&mut store, func_ty.clone());
119119
assert_eq!(func.ty(&store), func_ty);
120120
}

crates/wasmtime/src/runtime/component/types.rs

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::component::matching::InstanceType;
44
use crate::component::values::{self, Val};
5-
use crate::{ExternType, FuncType};
5+
use crate::{Engine, ExternType, FuncType};
66
use anyhow::{anyhow, Result};
77
use std::fmt;
88
use std::mem;
@@ -799,24 +799,30 @@ impl Module {
799799
}
800800

801801
/// Iterates over imports of the module
802-
pub fn imports(&self) -> impl ExactSizeIterator<Item = ((&str, &str), ExternType)> {
802+
pub fn imports<'a>(
803+
&'a self,
804+
engine: &'a Engine,
805+
) -> impl ExactSizeIterator<Item = ((&str, &str), ExternType)> + 'a {
803806
self.0.types[self.0.index]
804807
.imports
805808
.iter()
806809
.map(|((namespace, name), ty)| {
807810
(
808811
(namespace.as_str(), name.as_str()),
809-
ExternType::from_wasmtime(self.0.types.module_types(), ty),
812+
ExternType::from_wasmtime(engine, self.0.types.module_types(), ty),
810813
)
811814
})
812815
}
813816

814817
/// Iterates over exports of the module
815-
pub fn exports(&self) -> impl ExactSizeIterator<Item = (&str, ExternType)> {
818+
pub fn exports<'a>(
819+
&'a self,
820+
engine: &'a Engine,
821+
) -> impl ExactSizeIterator<Item = (&str, ExternType)> + 'a {
816822
self.0.types[self.0.index].exports.iter().map(|(name, ty)| {
817823
(
818824
name.as_str(),
819-
ExternType::from_wasmtime(self.0.types.module_types(), ty),
825+
ExternType::from_wasmtime(engine, self.0.types.module_types(), ty),
820826
)
821827
})
822828
}
@@ -832,35 +838,45 @@ impl Component {
832838
}
833839

834840
/// Returns import associated with `name`, if such exists in the component
835-
pub fn get_import(&self, name: &str) -> Option<ComponentItem> {
841+
pub fn get_import(&self, engine: &Engine, name: &str) -> Option<ComponentItem> {
836842
self.0.types[self.0.index]
837843
.imports
838844
.get(name)
839-
.map(|ty| ComponentItem::from(ty, &self.0.instance()))
845+
.map(|ty| ComponentItem::from(engine, ty, &self.0.instance()))
840846
}
841847

842848
/// Iterates over imports of the component
843-
pub fn imports(&self) -> impl ExactSizeIterator<Item = (&str, ComponentItem)> {
844-
self.0.types[self.0.index]
845-
.imports
846-
.iter()
847-
.map(|(name, ty)| (name.as_str(), ComponentItem::from(ty, &self.0.instance())))
849+
pub fn imports<'a>(
850+
&'a self,
851+
engine: &'a Engine,
852+
) -> impl ExactSizeIterator<Item = (&str, ComponentItem)> + 'a {
853+
self.0.types[self.0.index].imports.iter().map(|(name, ty)| {
854+
(
855+
name.as_str(),
856+
ComponentItem::from(engine, ty, &self.0.instance()),
857+
)
858+
})
848859
}
849860

850861
/// Returns export associated with `name`, if such exists in the component
851-
pub fn get_export(&self, name: &str) -> Option<ComponentItem> {
862+
pub fn get_export(&self, engine: &Engine, name: &str) -> Option<ComponentItem> {
852863
self.0.types[self.0.index]
853864
.exports
854865
.get(name)
855-
.map(|ty| ComponentItem::from(ty, &self.0.instance()))
866+
.map(|ty| ComponentItem::from(engine, ty, &self.0.instance()))
856867
}
857868

858869
/// Iterates over exports of the component
859-
pub fn exports(&self) -> impl ExactSizeIterator<Item = (&str, ComponentItem)> {
860-
self.0.types[self.0.index]
861-
.exports
862-
.iter()
863-
.map(|(name, ty)| (name.as_str(), ComponentItem::from(ty, &self.0.instance())))
870+
pub fn exports<'a>(
871+
&'a self,
872+
engine: &'a Engine,
873+
) -> impl ExactSizeIterator<Item = (&str, ComponentItem)> + 'a {
874+
self.0.types[self.0.index].exports.iter().map(|(name, ty)| {
875+
(
876+
name.as_str(),
877+
ComponentItem::from(engine, ty, &self.0.instance()),
878+
)
879+
})
864880
}
865881
}
866882

@@ -874,19 +890,24 @@ impl ComponentInstance {
874890
}
875891

876892
/// Returns export associated with `name`, if such exists in the component instance
877-
pub fn get_export(&self, name: &str) -> Option<ComponentItem> {
893+
pub fn get_export(&self, engine: &Engine, name: &str) -> Option<ComponentItem> {
878894
self.0.types[self.0.index]
879895
.exports
880896
.get(name)
881-
.map(|ty| ComponentItem::from(ty, &self.0.instance()))
897+
.map(|ty| ComponentItem::from(engine, ty, &self.0.instance()))
882898
}
883899

884900
/// Iterates over exports of the component instance
885-
pub fn exports(&self) -> impl ExactSizeIterator<Item = (&str, ComponentItem)> {
886-
self.0.types[self.0.index]
887-
.exports
888-
.iter()
889-
.map(|(name, ty)| (name.as_str(), ComponentItem::from(ty, &self.0.instance())))
901+
pub fn exports<'a>(
902+
&'a self,
903+
engine: &'a Engine,
904+
) -> impl ExactSizeIterator<Item = (&str, ComponentItem)> {
905+
self.0.types[self.0.index].exports.iter().map(|(name, ty)| {
906+
(
907+
name.as_str(),
908+
ComponentItem::from(engine, ty, &self.0.instance()),
909+
)
910+
})
890911
}
891912
}
892913

@@ -910,7 +931,7 @@ pub enum ComponentItem {
910931
}
911932

912933
impl ComponentItem {
913-
pub(crate) fn from(def: &TypeDef, ty: &InstanceType<'_>) -> Self {
934+
pub(crate) fn from(engine: &Engine, def: &TypeDef, ty: &InstanceType<'_>) -> Self {
914935
match def {
915936
TypeDef::Component(idx) => Self::Component(Component::from(*idx, ty)),
916937
TypeDef::ComponentInstance(idx) => {
@@ -920,7 +941,7 @@ impl ComponentItem {
920941
TypeDef::Interface(iface_ty) => Self::Type(Type::from(iface_ty, ty)),
921942
TypeDef::Module(idx) => Self::Module(Module::from(*idx, ty)),
922943
TypeDef::CoreFunc(idx) => {
923-
Self::CoreFunc(FuncType::from_wasm_func_type(ty.types[*idx].clone()))
944+
Self::CoreFunc(FuncType::from_wasm_func_type(engine, &ty.types[*idx]))
924945
}
925946
TypeDef::Resource(idx) => Self::Resource(ty.resources[ty.types[*idx].ty]),
926947
}

0 commit comments

Comments
 (0)