Skip to content

Commit 53a909d

Browse files
Merge branch 'main' into new_wasm_tools
2 parents be22e82 + 45487dc commit 53a909d

File tree

11 files changed

+297
-56
lines changed

11 files changed

+297
-56
lines changed

crates/wac-graph/src/graph.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,15 @@ impl CompositionGraph {
543543
"invalid package id"
544544
);
545545

546+
// Remove exports and definitions associated with the package before
547+
// removing nodes, as retain_nodes invalidates the node indices.
548+
self.exports
549+
.retain(|_, n| self.graph[*n].package != Some(package));
550+
self.defined
551+
.retain(|_, n| self.graph[*n].package != Some(package));
552+
self.imports
553+
.retain(|_, n| self.graph[*n].package != Some(package));
554+
546555
// Remove all nodes associated with the package
547556
self.graph
548557
.retain_nodes(|g, i| g[i].package != Some(package));
@@ -1959,4 +1968,34 @@ mod test {
19591968
UnexportError::MustExportDefinition
19601969
));
19611970
}
1971+
1972+
#[test]
1973+
fn it_cleans_up_exports_on_unregister_package() {
1974+
let mut graph = CompositionGraph::new();
1975+
let bytes = wat::parse_str(
1976+
r#"(component
1977+
(import "f" (func))
1978+
(export "g" (func 0))
1979+
)"#,
1980+
)
1981+
.unwrap();
1982+
1983+
let package =
1984+
wac_types::Package::from_bytes("test:pkg", None, bytes, graph.types_mut()).unwrap();
1985+
let pkg_id = graph.register_package(package).unwrap();
1986+
1987+
// Create an instantiation and export an alias
1988+
let inst_id = graph.instantiate(pkg_id);
1989+
let alias_id = graph.alias_instance_export(inst_id, "g").unwrap();
1990+
graph.export(alias_id, "g").unwrap();
1991+
1992+
assert!(graph.get_export("g").is_some());
1993+
1994+
// Unregistering the package should clean up exports
1995+
graph.unregister_package(pkg_id);
1996+
assert!(
1997+
graph.get_export("g").is_none(),
1998+
"exports should be cleaned up after unregister_package"
1999+
);
2000+
}
19622001
}

crates/wac-parser/src/resolution.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2553,7 +2553,8 @@ impl<'a> AstResolver<'a> {
25532553
}
25542554

25552555
// Otherwise, project into the parent based on the current segment
2556-
let export = match found.unwrap() {
2556+
let Some(parent) = found else { break };
2557+
let export = match parent {
25572558
// The parent is an interface or instance
25582559
ItemKind::Type(Type::Interface(id)) | ItemKind::Instance(id) => {
25592560
state.graph.types()[id].exports.get(segment).copied()
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package test:comp;
2+
3+
interface i {
4+
use foo:bar/nonexistent.{a};
5+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
failed to resolve document
2+
3+
× package `foo:bar` has no export named `nonexistent`
4+
╭─[tests/resolution/fail/missing-package-definition.wac:4:17]
5+
3 │ interface i {
6+
4 │ use foo:bar/nonexistent.{a};
7+
· ─────┬─────
8+
· ╰── unknown export `nonexistent`
9+
5 │ }
10+
╰────
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
(component
2+
(import "foo" (func))
3+
)

crates/wac-resolver/src/registry.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,9 @@ impl RegistryPackageResolver {
153153
let mut finished = 0;
154154

155155
while let Some(res) = tasks.next().await {
156-
let (index, download) = res.unwrap()?;
156+
let (index, download) = res.map_err(|e| Error::RegistryDownloadFailure {
157+
source: anyhow::anyhow!("download task panicked: {e}"),
158+
})??;
157159

158160
finished += 1;
159161

crates/wac-types/src/aggregator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ impl TypeAggregator {
227227
// We'll remap the source below and replace
228228
checker
229229
.is_subtype(*source_kind, types, target_kind, &self.types)
230-
.with_context(|| format!("mismatched type for export `{name}`"))?;
230+
.with_context(|| format!("mismatched type for import `{name}`"))?;
231231
}
232232

233233
let remapped = self.remap_item_kind(types, *source_kind, checker)?;

crates/wac-types/src/checker.rs

Lines changed: 116 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -411,15 +411,15 @@ impl<'a> SubtypeChecker<'a> {
411411
element_type: ae,
412412
initial: ai,
413413
maximum: am,
414-
table64: _a64,
415-
shared: _ashared,
414+
table64: a64,
415+
shared: ashared,
416416
},
417417
CoreExtern::Table {
418418
element_type: be,
419419
initial: bi,
420420
maximum: bm,
421-
table64: _b64,
422-
shared: _bshared,
421+
table64: b64,
422+
shared: bshared,
423423
},
424424
) => {
425425
if ae != be {
@@ -431,6 +431,14 @@ impl<'a> SubtypeChecker<'a> {
431431
bail!("mismatched table limits");
432432
}
433433

434+
if a64 != b64 {
435+
bail!("mismatched table64 flag for tables");
436+
}
437+
438+
if ashared != bshared {
439+
bail!("mismatched shared flag for tables");
440+
}
441+
434442
Ok(())
435443
}
436444
(
@@ -439,14 +447,14 @@ impl<'a> SubtypeChecker<'a> {
439447
shared: ashared,
440448
initial: ai,
441449
maximum: am,
442-
page_size_log2: _apsl,
450+
page_size_log2: apsl,
443451
},
444452
CoreExtern::Memory {
445453
memory64: b64,
446454
shared: bshared,
447455
initial: bi,
448456
maximum: bm,
449-
page_size_log2: _bpsl,
457+
page_size_log2: bpsl,
450458
},
451459
) => {
452460
if ashared != bshared {
@@ -461,18 +469,22 @@ impl<'a> SubtypeChecker<'a> {
461469
bail!("mismatched memory limits");
462470
}
463471

472+
if apsl != bpsl {
473+
bail!("mismatched page_size_log2 for memories");
474+
}
475+
464476
Ok(())
465477
}
466478
(
467479
CoreExtern::Global {
468480
val_type: avt,
469481
mutable: am,
470-
shared: _ashared,
482+
shared: ashared,
471483
},
472484
CoreExtern::Global {
473485
val_type: bvt,
474486
mutable: bm,
475-
shared: _bshared,
487+
shared: bshared,
476488
},
477489
) => {
478490
if am != bm {
@@ -484,6 +496,10 @@ impl<'a> SubtypeChecker<'a> {
484496
bail!("expected global type {expected}, found {found}");
485497
}
486498

499+
if ashared != bshared {
500+
bail!("mismatched shared flag for globals");
501+
}
502+
487503
Ok(())
488504
}
489505
(CoreExtern::Tag(a), CoreExtern::Tag(b)) => self.core_func(a, at, b, bt),
@@ -795,3 +811,95 @@ impl<'a> SubtypeChecker<'a> {
795811
Ok(())
796812
}
797813
}
814+
815+
#[cfg(test)]
816+
mod tests {
817+
use super::*;
818+
use crate::{CoreRefType, CoreType, HeapType};
819+
820+
fn check_core_extern(a: &CoreExtern, b: &CoreExtern) -> Result<()> {
821+
let types = Types::default();
822+
let mut cache = HashSet::new();
823+
let checker = SubtypeChecker::new(&mut cache);
824+
checker.core_extern(a, &types, b, &types)
825+
}
826+
827+
fn base_table() -> CoreExtern {
828+
CoreExtern::Table {
829+
element_type: CoreRefType {
830+
nullable: true,
831+
heap_type: HeapType::Func,
832+
},
833+
initial: 1,
834+
maximum: None,
835+
table64: false,
836+
shared: false,
837+
}
838+
}
839+
840+
#[test]
841+
fn mismatched_table64_is_rejected() {
842+
let a = base_table();
843+
let mut b = base_table();
844+
if let CoreExtern::Table { table64, .. } = &mut b {
845+
*table64 = true;
846+
}
847+
assert!(
848+
check_core_extern(&a, &b).is_err(),
849+
"mismatched table64 should be rejected"
850+
);
851+
}
852+
853+
#[test]
854+
fn mismatched_table_shared_is_rejected() {
855+
let a = base_table();
856+
let mut b = base_table();
857+
if let CoreExtern::Table { shared, .. } = &mut b {
858+
*shared = true;
859+
}
860+
assert!(
861+
check_core_extern(&a, &b).is_err(),
862+
"mismatched table shared should be rejected"
863+
);
864+
}
865+
866+
#[test]
867+
fn mismatched_memory_page_size_log2_is_rejected() {
868+
let a = CoreExtern::Memory {
869+
memory64: false,
870+
shared: false,
871+
initial: 1,
872+
maximum: None,
873+
page_size_log2: Some(16),
874+
};
875+
let b = CoreExtern::Memory {
876+
memory64: false,
877+
shared: false,
878+
initial: 1,
879+
maximum: None,
880+
page_size_log2: Some(14),
881+
};
882+
assert!(
883+
check_core_extern(&a, &b).is_err(),
884+
"mismatched page_size_log2 should be rejected"
885+
);
886+
}
887+
888+
#[test]
889+
fn mismatched_global_shared_is_rejected() {
890+
let a = CoreExtern::Global {
891+
val_type: CoreType::I32,
892+
mutable: false,
893+
shared: false,
894+
};
895+
let b = CoreExtern::Global {
896+
val_type: CoreType::I32,
897+
mutable: false,
898+
shared: true,
899+
};
900+
assert!(
901+
check_core_extern(&a, &b).is_err(),
902+
"mismatched global shared should be rejected"
903+
);
904+
}
905+
}

0 commit comments

Comments
 (0)