Skip to content

Commit 1ac82c6

Browse files
Merge pull request #194 from sumleo/fix/subtype-checker-missing-checks
Add missing subtype checks for table, memory, and global fields
2 parents 4f9043f + c90c0f3 commit 1ac82c6

File tree

1 file changed

+116
-8
lines changed

1 file changed

+116
-8
lines changed

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)