Skip to content

Commit ba47bdf

Browse files
committed
Improve encoding of used types.
This commit fixes encoding of used types such that renamed types now properly encode. Used types are now stored in a map from export/import name to used interface (along with the original export name when renamed). Additionally, `todo!` placeholders were added for merging non-interface imports, which will be needed in the near future. Also removed some redundant code in package decoding and improved the debug log output of the local package resolver.
1 parent 2dcd267 commit ba47bdf

9 files changed

Lines changed: 218 additions & 227 deletions

File tree

crates/wac-parser/src/resolution.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,6 @@ where
3232
s.end()
3333
}
3434

35-
fn serialize_id_key_map<T, V, S>(
36-
map: &IndexMap<Id<T>, V>,
37-
serializer: S,
38-
) -> std::result::Result<S::Ok, S::Error>
39-
where
40-
S: Serializer,
41-
T: Serialize,
42-
V: Serialize,
43-
{
44-
use serde::ser::SerializeMap;
45-
46-
let mut s = serializer.serialize_map(Some(map.len()))?;
47-
for (k, v) in map {
48-
s.serialize_entry(&k.index(), v)?;
49-
}
50-
51-
s.end()
52-
}
53-
5435
fn serialize_id_value_map<K, T, S>(
5536
map: &IndexMap<K, Id<T>>,
5637
serializer: S,

crates/wac-parser/src/resolution/ast.rs

Lines changed: 53 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use super::{
44
FuncResult, Interface, InterfaceId, ItemKind, PrimitiveType, Record, ResolutionResult,
55
Resource, ResourceId, SubtypeChecker, Type, ValueType, Variant, World, WorldId,
66
};
7-
use crate::{ast, method_extern_name, Item, ItemId, PackageId};
7+
use crate::{ast, method_extern_name, Item, ItemId, PackageId, UsedType};
88
use anyhow::Context;
99
use id_arena::Arena;
1010
use indexmap::{IndexMap, IndexSet};
@@ -856,7 +856,7 @@ impl<'a> AstResolver<'a> {
856856
&mut self,
857857
state: &mut State<'a>,
858858
use_type: &'a ast::Use<'a>,
859-
uses: &mut IndexMap<InterfaceId, IndexSet<usize>>,
859+
uses: &mut IndexMap<String, UsedType>,
860860
externs: &mut IndexMap<String, ItemKind>,
861861
in_world: bool,
862862
) -> ResolutionResult<()> {
@@ -888,9 +888,9 @@ impl<'a> AstResolver<'a> {
888888

889889
for item in &use_type.items {
890890
let ident = item.as_id.unwrap_or(item.id);
891-
let (index, _, kind) = self.definitions.interfaces[interface]
891+
let kind = self.definitions.interfaces[interface]
892892
.exports
893-
.get_full(item.id.string)
893+
.get(item.id.string)
894894
.ok_or(Error::UndefinedInterfaceType {
895895
name: item.id.string.to_string(),
896896
interface_name: name.to_string(),
@@ -916,7 +916,13 @@ impl<'a> AstResolver<'a> {
916916
});
917917
}
918918

919-
uses.entry(interface).or_default().insert(index);
919+
uses.insert(
920+
ident.string.into(),
921+
UsedType {
922+
interface,
923+
name: item.as_id.map(|_| item.id.string.to_string()),
924+
},
925+
);
920926
externs.insert(ident.string.into(), *kind);
921927

922928
let id = state.current.items.alloc(Item::Use(*kind));
@@ -1772,10 +1778,36 @@ impl<'a> AstResolver<'a> {
17721778
});
17731779
};
17741780

1775-
// Ensure the import and the existing import are instances, otherwise
1776-
// we cannot merge them
1777-
let id = match (kind, state.current.items[import.item].kind()) {
1778-
(ItemKind::Instance(id), ItemKind::Instance(_)) => id,
1781+
// Merge the existing import item with the given one
1782+
return match (kind, state.current.items[import.item].kind()) {
1783+
(ItemKind::Instance(id), ItemKind::Instance(_)) => {
1784+
log::debug!(
1785+
"merging implicit interface import `{name}` ({id})",
1786+
id = id.index(),
1787+
);
1788+
1789+
let item = import.item;
1790+
self.merge_instance_import(state, &name, id, span)?;
1791+
Ok(item)
1792+
}
1793+
(ItemKind::Component(_), ItemKind::Component(_)) => {
1794+
todo!("merge component imports")
1795+
}
1796+
(ItemKind::Func(_), ItemKind::Func(_)) => {
1797+
todo!("merge func imports")
1798+
}
1799+
(ItemKind::Module(_), ItemKind::Module(_)) => {
1800+
todo!("merge module imports")
1801+
}
1802+
(ItemKind::Resource(_), ItemKind::Resource(_)) => {
1803+
todo!("merge resource imports")
1804+
}
1805+
(ItemKind::Type(_), ItemKind::Type(_)) => {
1806+
todo!("merge type imports")
1807+
}
1808+
(ItemKind::Value(_), ItemKind::Value(_)) => {
1809+
todo!("merge value imports")
1810+
}
17791811
(_, kind) => {
17801812
return Err(Error::UnmergeableInstantiationArg {
17811813
name: name.to_owned(),
@@ -1786,15 +1818,6 @@ impl<'a> AstResolver<'a> {
17861818
});
17871819
}
17881820
};
1789-
1790-
log::debug!(
1791-
"merging implicit interface import `{name}` ({id})",
1792-
id = id.index(),
1793-
);
1794-
1795-
let item = import.item;
1796-
self.merge_instance_import(state, &name, id, span)?;
1797-
return Ok(item);
17981821
}
17991822

18001823
log::debug!(
@@ -1806,7 +1829,7 @@ impl<'a> AstResolver<'a> {
18061829
// might be merged in the future with other interface definitions.
18071830
if let ItemKind::Instance(id) = kind {
18081831
let mut target = self.definitions.interfaces[id].clone();
1809-
target.uses = self.remap_uses(state, target.uses);
1832+
self.remap_uses(state, &mut target.uses);
18101833
let id = self.definitions.interfaces.alloc(target);
18111834
log::debug!(
18121835
"creating new interface definition ({id}) for implicit import `{name}`",
@@ -1914,46 +1937,34 @@ impl<'a> AstResolver<'a> {
19141937
let source = &self.definitions.interfaces[source_id];
19151938

19161939
// Merge the source and target usings
1917-
for (dep, exports) in &source.uses {
1918-
target.uses.entry(*dep).or_default().extend(exports);
1940+
for (name, used) in &source.uses {
1941+
if target.uses.contains_key(name) {
1942+
continue;
1943+
}
1944+
1945+
target.uses.insert(name.clone(), used.clone());
19191946
}
19201947

19211948
// Remap the usings to point at imported interfaces
1922-
target.uses = self.remap_uses(state, target.uses);
1949+
self.remap_uses(state, &mut target.uses);
19231950
self.definitions.interfaces[target_id] = target;
19241951
}
19251952

1926-
fn remap_uses(
1927-
&self,
1928-
state: &State,
1929-
uses: IndexMap<InterfaceId, IndexSet<usize>>,
1930-
) -> IndexMap<InterfaceId, IndexSet<usize>> {
1953+
fn remap_uses(&self, state: &State, uses: &mut IndexMap<String, UsedType>) {
19311954
// Now update all the interface ids in the usings
1932-
let mut remapped: IndexMap<InterfaceId, IndexSet<usize>> =
1933-
IndexMap::with_capacity(uses.len());
1934-
for (old_id, exports) in uses {
1935-
let old = &self.definitions.interfaces[old_id];
1955+
for used in uses.values_mut() {
1956+
let old = &self.definitions.interfaces[used.interface];
19361957
let import = &state.imports[old.id.as_deref().unwrap()];
19371958
match &state.current.items[import.item] {
19381959
super::Item::Import(super::Import {
19391960
kind: ItemKind::Instance(new_id),
19401961
..
19411962
}) => {
1942-
let new = &self.definitions.interfaces[*new_id];
1943-
remapped
1944-
.entry(*new_id)
1945-
.or_default()
1946-
.extend(exports.into_iter().map(|old_index| {
1947-
new.exports
1948-
.get_index_of(old.exports.get_index(old_index).unwrap().0)
1949-
.unwrap()
1950-
}));
1963+
used.interface = *new_id;
19511964
}
19521965
_ => unreachable!(),
19531966
}
19541967
}
1955-
1956-
remapped
19571968
}
19581969

19591970
fn named_instantiation_arg(

0 commit comments

Comments
 (0)