Skip to content

Commit 43d39bc

Browse files
committed
wasmtime-wit-bindgen: add typechecking on construction of Indices struct
1 parent 034b82b commit 43d39bc

File tree

1 file changed

+37
-11
lines changed

1 file changed

+37
-11
lines changed

crates/wit-bindgen/src/lib.rs

+37-11
Original file line numberDiff line numberDiff line change
@@ -621,18 +621,36 @@ impl Wasmtime {
621621
let body = mem::take(&mut generator.src).into();
622622
load = generator.extract_typed_function(func).1;
623623
assert!(generator.src.is_empty());
624-
self.exports.funcs.push(body);
624+
generator.generator.exports.funcs.push(body);
625625
ty_index = format!("{wt}::component::ComponentExportIndex");
626626
field = func_field_name(resolve, func);
627627
ty = format!("{wt}::component::Func");
628+
let sig = generator.typedfunc_sig(func, TypeMode::AllBorrowed("'_"));
629+
let typecheck = format!(
630+
"match item {{
631+
{wt}::component::types::ComponentItem::ComponentFunc(func) => {{
632+
anyhow::Context::context(
633+
func.typecheck::<{sig}>(&_instance_type),
634+
\"type-checking export func `{0}`\"
635+
)?;
636+
index
637+
}}
638+
_ => Err(anyhow::anyhow!(\"export `{0}` is not a function\"))?,
639+
}}",
640+
func.name
641+
);
628642
get_index_from_component = format!(
629-
"_component.get_export_index(None, \"{}\")
630-
.ok_or_else(|| anyhow::anyhow!(\"no function export `{0}` found\"))?",
643+
"{{ let (item, index) = _component.get_export(None, \"{}\")
644+
.ok_or_else(|| anyhow::anyhow!(\"no export `{0}` found\"))?;
645+
{typecheck}
646+
}}",
631647
func.name
632648
);
633649
get_index_from_instance = format!(
634-
"_instance.get_export_index(&mut store, None, \"{}\")
635-
.ok_or_else(|| anyhow::anyhow!(\"no function export `{0}` found\"))?",
650+
"{{ let (item, index) = _instance.get_export(&mut store, None, \"{}\")
651+
.ok_or_else(|| anyhow::anyhow!(\"no function export `{0}` found\"))?;
652+
{typecheck}
653+
}}",
636654
func.name
637655
);
638656
}
@@ -685,10 +703,11 @@ impl Wasmtime {
685703
/// within a component.
686704
pub fn new(
687705
component: &{wt}::component::Component,
706+
instance_type: &{wt}::component::__internal::InstanceType,
688707
) -> {wt}::Result<{struct_name}Indices> {{
689708
let instance = component.get_export_index(None, \"{instance_name}\")
690709
.ok_or_else(|| anyhow::anyhow!(\"no exported instance named `{instance_name}`\"))?;
691-
Self::_new(|name| component.get_export_index(Some(&instance), name))
710+
Self::_new(instance_type, |name| component.get_export_index(Some(&instance), name))
692711
}}
693712
694713
/// This constructor is similar to [`{struct_name}Indices::new`] except that it
@@ -699,10 +718,12 @@ pub fn new_instance(
699718
) -> {wt}::Result<{struct_name}Indices> {{
700719
let instance_export = instance.get_export_index(&mut store, None, \"{instance_name}\")
701720
.ok_or_else(|| anyhow::anyhow!(\"no exported instance named `{instance_name}`\"))?;
702-
Self::_new(|name| instance.get_export_index(&mut store, Some(&instance_export), name))
721+
let instance_type = instance.instance_type(&mut store);
722+
Self::_new(&instance_type, |name| instance.get_export_index(&mut store, Some(&instance_export), name))
703723
}}
704724
705725
fn _new(
726+
_instance_type: &{wt}::component::__internal::InstanceType,
706727
mut lookup: impl FnMut (&str) -> Option<{wt}::component::ComponentExportIndex>,
707728
) -> {wt}::Result<{struct_name}Indices> {{
708729
let mut lookup = move |name| {{
@@ -740,6 +761,7 @@ fn _new(
740761
let mut store = store.as_context_mut();
741762
let _ = &mut store;
742763
let _instance = instance;
764+
let _instance_type = _instance.instance_type(&mut store);
743765
"
744766
);
745767
let mut fields = Vec::new();
@@ -844,7 +866,7 @@ fn _new(
844866
));
845867
ty_index = format!("{path}Indices");
846868
ty = path;
847-
get_index_from_component = format!("{ty_index}::new(_component)?");
869+
get_index_from_component = format!("{ty_index}::new(_component, _instance_type)?");
848870
get_index_from_instance =
849871
format!("{ty_index}::new_instance(&mut store, _instance)?");
850872
}
@@ -903,7 +925,7 @@ impl<_T> {camel}Pre<_T> {{
903925
/// This method may fail if the component behind `instance_pre`
904926
/// does not have the required exports.
905927
pub fn new(instance_pre: {wt}::component::InstancePre<_T>) -> {wt}::Result<Self> {{
906-
let indices = {camel}Indices::new(instance_pre.component())?;
928+
let indices = {camel}Indices::new(instance_pre.component(), instance_pre.instance_type())?;
907929
Ok(Self {{ instance_pre, indices }})
908930
}}
909931
@@ -1013,8 +1035,11 @@ impl<_T> {camel}Pre<_T> {{
10131035
///
10141036
/// This method may fail if the component does not have the
10151037
/// required exports.
1016-
pub fn new(component: &{wt}::component::Component) -> {wt}::Result<Self> {{
1038+
pub fn new(component: &{wt}::component::Component,
1039+
instance_type: &{wt}::component::__internal::InstanceType,
1040+
) -> {wt}::Result<Self> {{
10171041
let _component = component;
1042+
let _instance_type = instance_type;
10181043
",
10191044
);
10201045
for (name, field) in self.exports.fields.iter() {
@@ -1042,6 +1067,7 @@ impl<_T> {camel}Pre<_T> {{
10421067
instance: &{wt}::component::Instance,
10431068
) -> {wt}::Result<Self> {{
10441069
let _instance = instance;
1070+
let _instance_type = _instance.instance_type(&mut store);
10451071
",
10461072
);
10471073
for (name, field) in self.exports.fields.iter() {
@@ -1104,7 +1130,7 @@ impl<_T> {camel}Pre<_T> {{
11041130
instance: &{wt}::component::Instance,
11051131
) -> {wt}::Result<{camel}> {{
11061132
let indices = {camel}Indices::new_instance(&mut store, instance)?;
1107-
indices.load(store, instance)
1133+
indices.load(&mut store, instance)
11081134
}}
11091135
",
11101136
);

0 commit comments

Comments
 (0)