Compare commits

...

6 Commits

Author SHA1 Message Date
zach
91d41d83b6 cleanup: implement more type checks 2024-12-03 16:40:51 -08:00
zach
6350f6e746 wip: fix import validation check 2024-12-02 17:21:53 -08:00
zach
783b32266a wip: improve error messages 2024-12-02 17:05:58 -08:00
zach
097079fab9 wip: check for missing functions when linking 2024-12-02 16:57:52 -08:00
zach
91b7cd7d3a fix: wiggle bounds 2024-12-02 16:57:52 -08:00
zach
198a63044e chore: fix clippy 2024-12-02 16:57:52 -08:00

View File

@@ -1,6 +1,6 @@
use std::{
any::Any,
collections::{BTreeMap, BTreeSet},
collections::{BTreeMap, BTreeSet, HashMap},
};
use anyhow::Context;
@@ -242,7 +242,7 @@ impl<'a> From<&'a Vec<u8>> for WasmInput<'a> {
}
fn add_module<T: 'static>(
store: &mut Store<T>,
mut store: &mut Store<T>,
linker: &mut Linker<T>,
linked: &mut BTreeSet<String>,
modules: &BTreeMap<String, Module>,
@@ -253,6 +253,59 @@ fn add_module<T: 'static>(
return Ok(());
}
let mut imports: HashMap<&str, Vec<(&str, ExternType)>> = HashMap::new();
for module_import in module.imports() {
let import_module = module_import.module();
let import_name = module_import.name();
let import_type = module_import.ty();
if imports.contains_key(import_module) {
imports
.get_mut(import_module)
.unwrap()
.push((import_name, import_type));
} else {
imports.insert(import_module, vec![(import_name, import_type)]);
}
}
for (m, v) in imports.into_iter() {
if let Some(src) = modules.get(m) {
for (name, ty) in v {
match src
.get_export(name)
.or_else(|| linker.get(&mut store, m, name).map(|x| x.ty(&store)))
{
None => anyhow::bail!("missing import: {m}::{name}"),
Some(ex) => match (&ex, &ty) {
(ExternType::Func(a), ExternType::Func(b)) => {
if !a.matches(b) {
anyhow::bail!(
"function type mismatch {m}::{name}, got {ty:?} expected {ex:?}"
)
}
}
(ExternType::Global(a), ExternType::Global(b)) => {
if !a.content().matches(b.content()) {
anyhow::bail!(
"global type mismatch {m}::{name}, got {ty:?} expected {ex:?}"
)
}
}
(ExternType::Memory(_), ExternType::Memory(_)) => (),
(ExternType::Table(a), ExternType::Table(b)) => {
if !a.element().matches(b.element()) {
anyhow::bail!(
"table type mismatch {m}::{name}, got {ty:?} expected {ex:?}"
)
}
}
(a, b) => anyhow::bail!("import type mismatch: {a:?} != {b:?}"),
},
}
}
}
}
for import in module.imports() {
let module = import.module();