Skip to content

Commit 66c0672

Browse files
authored
Merge pull request #72 from peterhuene/fix-dup-imports
Fix duplicate imports that may occur from implicitly imported items.
2 parents 922d225 + d560df7 commit 66c0672

7 files changed

Lines changed: 239 additions & 150 deletions

File tree

crates/wac-graph/src/encoding.rs

Lines changed: 40 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ impl Default for Encodable {
9696

9797
#[derive(Default)]
9898
pub struct Scope {
99-
/// The map of types to their encoded indexes.
99+
/// The map from types to encoded type index.
100100
pub type_indexes: IndexMap<Type, u32>,
101-
/// The map of imported instances in this scope.
102-
pub instances: IndexMap<InterfaceId, u32>,
101+
/// The map from interface name (i.e. id) to encoded instance index.
102+
pub instances: IndexMap<String, u32>,
103103
/// The map of import/export name to their alias indexes.
104104
type_aliases: IndexMap<String, u32>,
105105
/// The map of resource names to their encoded indexes.
@@ -215,7 +215,7 @@ impl<'a> TypeEncoder<'a> {
215215
}
216216

217217
fn func_type(&self, state: &mut State, id: FuncTypeId) -> u32 {
218-
log::debug!("encoding function {id}");
218+
log::debug!("encoding function type");
219219
let ty = &self.0[id];
220220

221221
let params = ty
@@ -246,12 +246,12 @@ impl<'a> TypeEncoder<'a> {
246246
}
247247
}
248248

249-
log::debug!("function {id} encoded to type index {index}");
249+
log::debug!("function type encoded to type index {index}");
250250
index
251251
}
252252

253253
fn defined(&self, state: &mut State, id: DefinedTypeId) -> u32 {
254-
log::debug!("encoding defined type {id}");
254+
log::debug!("encoding defined type");
255255
let ty = &self.0[id];
256256
let index = match ty {
257257
DefinedType::Tuple(types) => self.tuple(state, types),
@@ -268,7 +268,7 @@ impl<'a> TypeEncoder<'a> {
268268
DefinedType::Alias(ValueType::Defined(id)) => self.defined(state, *id),
269269
};
270270

271-
log::debug!("defined type {id} encoded to type index {index}");
271+
log::debug!("defined type encoded to type index {index}");
272272
index
273273
}
274274

@@ -277,7 +277,8 @@ impl<'a> TypeEncoder<'a> {
277277

278278
for (name, used) in uses {
279279
let interface = &self.0[used.interface];
280-
let instance = state.current.instances[&used.interface];
280+
let iid = interface.id.as_ref().expect("interface should have an id");
281+
let instance = state.current.instances[iid];
281282
let index = state.current.encodable.type_count();
282283
let export: &String = used.name.as_ref().unwrap_or(name);
283284
let kind = interface.exports.get(export).unwrap();
@@ -288,15 +289,16 @@ impl<'a> TypeEncoder<'a> {
288289
});
289290

290291
log::debug!(
291-
"aliased export `{export}` ({kind:?}) of instance {instance} to type index {index}"
292+
"aliased {kind} export `{export}` of instance index {instance} ({iid}) to type index {index}",
293+
kind = kind.desc(self.0)
292294
);
293295

294296
state.current.type_aliases.insert(name.clone(), index);
295297
}
296298
}
297299

298300
fn instance(&self, state: &mut State, id: InterfaceId, types_only: bool) -> u32 {
299-
log::debug!("encoding instance type for interface {id}");
301+
log::debug!("encoding instance type");
300302
let interface = &self.0[id];
301303
for used in interface.uses.values() {
302304
self.import_deps(state, used.interface);
@@ -324,15 +326,15 @@ impl<'a> TypeEncoder<'a> {
324326
Encodable::Instance(ty) => {
325327
let index = state.current.encodable.type_count();
326328
state.current.encodable.ty().instance(&ty);
327-
log::debug!("instance {id} encoded to type index {index}");
329+
log::debug!("instance type encoded to type index {index}");
328330
index
329331
}
330332
_ => panic!("expected the pushed encodable to be an instance type"),
331333
}
332334
}
333335

334336
pub fn component(&self, state: &mut State, id: WorldId) -> u32 {
335-
log::debug!("encoding component type for world {id}");
337+
log::debug!("encoding component type");
336338
let world = &self.0[id];
337339

338340
state.push(Encodable::Component(ComponentType::default()));
@@ -355,15 +357,16 @@ impl<'a> TypeEncoder<'a> {
355357
Encodable::Component(ty) => {
356358
let index = state.current.encodable.type_count();
357359
state.current.encodable.ty().component(&ty);
358-
log::debug!("world {id} encoded to type index {index}");
360+
log::debug!("component type encoded to type index {index}");
359361
index
360362
}
361363
_ => panic!("expected the pushed encodable to be a component type"),
362364
}
363365
}
364366

365367
fn import_deps(&self, state: &mut State, id: InterfaceId) {
366-
if state.current.instances.contains_key(&id) {
368+
let iid = self.0[id].id.as_ref().expect("interface should have an id");
369+
if state.current.instances.contains_key(iid) {
367370
return;
368371
}
369372

@@ -374,32 +377,26 @@ impl<'a> TypeEncoder<'a> {
374377
self.import_deps(state, used.interface);
375378
}
376379

377-
let name = self.0[id]
378-
.id
379-
.as_deref()
380-
.expect("interface should have an id");
381-
382-
log::debug!("encoding dependency on interface {id}");
380+
log::debug!("encoding dependency on interface `{iid}`");
383381

384382
let index = self.instance(state, id, !state.scopes.is_empty());
385383
let import_index = state.current.encodable.instance_count();
386384

387385
state
388386
.current
389387
.encodable
390-
.import_type(name, ComponentTypeRef::Instance(index));
391-
392-
log::debug!("interface {id} is available for aliasing as instance {import_index}");
388+
.import_type(iid, ComponentTypeRef::Instance(index));
393389

394-
state.current.instances.insert(id, import_index);
390+
log::debug!(
391+
"interface `{iid}` is available for aliasing from instance index {import_index}"
392+
);
393+
state.current.instances.insert(iid.clone(), import_index);
395394
}
396395

397396
pub fn interface(&self, state: &mut State, id: InterfaceId) -> u32 {
398397
let interface = &self.0[id];
399-
log::debug!(
400-
"encoding interface definition of `{name}` ({id})",
401-
name = interface.id.as_deref().unwrap_or("")
402-
);
398+
let iid = interface.id.as_deref().expect("interface must have an id");
399+
log::debug!("encoding interface definition of `{iid}`");
403400
assert!(state.scopes.is_empty());
404401
state.push(Encodable::Component(ComponentType::default()));
405402

@@ -408,21 +405,13 @@ impl<'a> TypeEncoder<'a> {
408405
}
409406

410407
let index = self.instance(state, id, false);
411-
412-
Self::export_type(
413-
state,
414-
interface.id.as_deref().expect("interface must have an id"),
415-
ComponentTypeRef::Instance(index),
416-
);
408+
Self::export_type(state, iid, ComponentTypeRef::Instance(index));
417409

418410
match state.pop() {
419411
Encodable::Component(ty) => {
420412
let (index, encoder) = state.builder().ty();
421413
encoder.component(&ty);
422-
log::debug!(
423-
"encoded interface definition of `{id}` to type index {index}",
424-
id = interface.id.as_deref().unwrap_or("")
425-
);
414+
log::debug!("encoded interface definition of `{iid}` to type index {index}",);
426415
index
427416
}
428417
_ => panic!("expected the pushed encodable to be a component type"),
@@ -432,7 +421,6 @@ impl<'a> TypeEncoder<'a> {
432421
pub fn world(&self, state: &mut State, id: WorldId) -> u32 {
433422
let world = &self.0[id];
434423
let world_id = world.id.as_deref().expect("world must have an id");
435-
436424
log::debug!("encoding world definition of `{world_id}`");
437425

438426
assert!(state.scopes.is_empty());
@@ -645,13 +633,8 @@ impl<'a> TypeEncoder<'a> {
645633
return self.import_resource(state, name, id);
646634
}
647635

636+
log::debug!("encoding {kind} import `{name}`", kind = kind.desc(self.0));
648637
let ty = kind.ty();
649-
log::debug!(
650-
"encoding import of `{name}` ({kind})",
651-
name = name,
652-
kind = kind.desc(self.0)
653-
);
654-
655638
let index = self.ty(state, ty, Some(name));
656639

657640
match kind {
@@ -677,8 +660,10 @@ impl<'a> TypeEncoder<'a> {
677660
.current
678661
.encodable
679662
.import_type(name, ComponentTypeRef::Instance(index));
680-
log::debug!("instance {import_index} is available for aliasing as interface {id}");
681-
state.current.instances.insert(id, import_index);
663+
if let Some(iid) = &self.0[id].id {
664+
log::debug!("instance index {import_index} ({iid}) is available for aliasing");
665+
state.current.instances.insert(iid.clone(), import_index);
666+
}
682667
}
683668
_ => panic!("expected only types, functions, and instance types"),
684669
}
@@ -689,7 +674,7 @@ impl<'a> TypeEncoder<'a> {
689674
return;
690675
}
691676

692-
log::debug!("encoding import of resource `{name}` ({id})");
677+
log::debug!("encoding import of resource `{name}`");
693678

694679
let resource = &self.0[id];
695680
let index = if let Some(outer) = state.used_type_index(name) {
@@ -700,7 +685,7 @@ impl<'a> TypeEncoder<'a> {
700685
.encodable
701686
.import_type(name, ComponentTypeRef::Type(TypeBounds::Eq(outer)));
702687

703-
log::debug!("encoded outer alias for resource `{name}` ({id}) to type index {index}");
688+
log::debug!("encoded outer alias for resource `{name}` to type index {index}");
704689
index
705690
} else if let Some(alias_of) = resource.alias_of {
706691
// This is an alias to another resource at the same scope
@@ -734,13 +719,12 @@ impl<'a> TypeEncoder<'a> {
734719
return self.export_resource(state, name, id);
735720
}
736721

737-
let ty = kind.ty();
738722
log::debug!(
739-
"encoding export of `{name}` ({kind})",
740-
name = name,
723+
"encoding {kind} export of `{name}`",
741724
kind = kind.desc(self.0)
742725
);
743726

727+
let ty = kind.ty();
744728
let index = self.ty(state, ty, Some(name));
745729
let index = Self::export_type(
746730
state,
@@ -762,7 +746,7 @@ impl<'a> TypeEncoder<'a> {
762746
}
763747

764748
fn export_resource(&self, state: &mut State, name: &str, id: ResourceId) -> u32 {
765-
log::debug!("encoding export of resource `{name}` ({id})");
749+
log::debug!("encoding export of resource `{name}`");
766750

767751
if let Some(existing) = state.current.resources.get(name) {
768752
return *existing;
@@ -773,21 +757,21 @@ impl<'a> TypeEncoder<'a> {
773757
// This is an alias to an outer resource type
774758
let index =
775759
Self::export_type(state, name, ComponentTypeRef::Type(TypeBounds::Eq(outer)));
776-
log::debug!("encoded outer alias for resource `{name}` ({id}) as type index {index}");
760+
log::debug!("encoded outer alias for resource `{name}` as type index {index}");
777761
index
778762
} else if let Some(alias_of) = resource.alias_of {
779763
// This is an alias to another resource at the same scope
780764
let index =
781765
state.current.resources[self.0[self.0.resolve_resource(alias_of)].name.as_str()];
782766
let index =
783767
Self::export_type(state, name, ComponentTypeRef::Type(TypeBounds::Eq(index)));
784-
log::debug!("encoded alias for resource `{name}` ({id}) as type index {index}");
768+
log::debug!("encoded alias for resource `{name}` as type index {index}");
785769
index
786770
} else {
787771
// Otherwise, this is a new resource type, export with a subtype bounds
788772
let index =
789773
Self::export_type(state, name, ComponentTypeRef::Type(TypeBounds::SubResource));
790-
log::debug!("encoded export of resource `{name}` ({id}) as type index {index}");
774+
log::debug!("encoded export of resource `{name}` as type index {index}");
791775
index
792776
};
793777

0 commit comments

Comments
 (0)