///|
pub impl Eq for Module with fn equal(l, r) {
let l_custom = l.custom_secs
let r_custom = r.custom_secs
if l_custom.length() != r_custom.length() {
return false
}
for lc in l_custom {
if !r_custom.contains(lc) {
return false
}
}
for rc in r_custom {
if !l_custom.contains(rc) {
return false
}
}
l.type_sec == r.type_sec &&
l.name_sec == r.name_sec &&
l.compiler_fact_custom_section == r.compiler_fact_custom_section &&
l.import_sec == r.import_sec &&
l.func_annotation_sec == r.func_annotation_sec &&
l.func_sec == r.func_sec &&
l.table_sec == r.table_sec &&
l.mem_sec == r.mem_sec &&
l.tag_sec == r.tag_sec &&
l.stringrefs_sec == r.stringrefs_sec &&
l.global_sec == r.global_sec &&
l.export_sec == r.export_sec &&
l.start_sec == r.start_sec &&
l.elem_sec == r.elem_sec &&
l.data_cnt_sec == r.data_cnt_sec &&
l.code_sec == r.code_sec &&
l.data_sec == r.data_sec
}
///|
pub impl Eq for RecType with fn equal(l, r) {
match (l, r) {
(SingleRecType(stl), GroupRecType([str])) => stl == str
(GroupRecType([stl]), SingleRecType(str)) => stl == str
(SingleRecType(stl), SingleRecType(str)) => stl == str
(GroupRecType(stl), GroupRecType(str)) => stl == str
_ => false
}
}
///|
pub impl Eq for RefType with fn equal(l, r) {
match (l, r) {
(HeapTypeRefType(l0, l1, l2), HeapTypeRefType(r0, r1, r2)) =>
l0 == r0 && l1 == r1 && l2 == r2
(AbsHeapTypeRefType(l0), AbsHeapTypeRefType(r0)) => l0 == r0
(
AbsHeapTypeRefType(l0),
HeapTypeRefType(true, false, AbsHeapTypeHeapType(r0)),
) => l0 == r0
(
HeapTypeRefType(true, false, AbsHeapTypeHeapType(l0)),
AbsHeapTypeRefType(r0),
) => l0 == r0
_ => false
}
}
///|
pub impl Eq for MemArg with fn equal(l, r) {
l.0 == r.0 &&
l.1.unwrap_or(MemIdx(0)) == r.1.unwrap_or(MemIdx(0)) &&
l.2 == r.2
}
///|
test "RecType equality edge cases" {
let st = SubType::comp_type(FuncCompType([], []))
// SingleRecType should equal GroupRecType with single element
@debug.assert_eq(SingleRecType(st), GroupRecType([st]))
@debug.assert_eq(GroupRecType([st]), SingleRecType(st))
// But different subtypes should not be equal
let st2 = SubType::comp_type(FuncCompType([NumTypeValType(I32NumType)], []))
assert_not_eq(SingleRecType(st), SingleRecType(st2))
assert_not_eq(SingleRecType(st), GroupRecType([st2]))
// Multiple elements should not equal single
assert_not_eq(GroupRecType([st, st]), SingleRecType(st))
}
///|
test "RefType equality edge cases" {
// AbsHeapTypeRefType should equal HeapTypeRefType with nullable + AbsHeapTypeHeapType
@debug.assert_eq(
AbsHeapTypeRefType(FuncAbsHeapType),
HeapTypeRefType(true, false, AbsHeapTypeHeapType(FuncAbsHeapType)),
)
@debug.assert_eq(
HeapTypeRefType(true, false, AbsHeapTypeHeapType(ExternAbsHeapType)),
AbsHeapTypeRefType(ExternAbsHeapType),
)
// Non-nullable should NOT equal AbsHeapTypeRefType
assert_not_eq(
AbsHeapTypeRefType(FuncAbsHeapType),
HeapTypeRefType(false, false, AbsHeapTypeHeapType(FuncAbsHeapType)),
)
// Different heap types should not be equal
assert_not_eq(
AbsHeapTypeRefType(FuncAbsHeapType),
AbsHeapTypeRefType(ExternAbsHeapType),
)
assert_not_eq(
AbsHeapTypeRefType(FuncAbsHeapType),
HeapTypeRefType(true, false, AbsHeapTypeHeapType(ExternAbsHeapType)),
)
}
///|
test "MemArg equality edge cases" {
// None memidx should equal Some(MemIdx(0))
@debug.assert_eq(
MemArg(U32(0), None, U64(0)),
MemArg(U32(0), Some(MemIdx(0)), U64(0)),
)
@debug.assert_eq(
MemArg(U32(4), None, U64(8)),
MemArg(U32(4), Some(MemIdx(0)), U64(8)),
)
// But Some(MemIdx(1)) should NOT equal None
assert_not_eq(
MemArg(U32(0), None, U64(0)),
MemArg(U32(0), Some(MemIdx(1)), U64(0)),
)
// Different align/offset should not be equal
assert_not_eq(MemArg(U32(0), None, U64(0)), MemArg(U32(1), None, U64(0)))
assert_not_eq(MemArg(U32(0), None, U64(0)), MemArg(U32(0), None, U64(1)))
}
///|
test "HeapType equality - verify transformer changes are detected" {
// These should NOT be equal - this is what HeapTypeSwap produces
let before : HeapType = AbsHeapTypeHeapType(FuncAbsHeapType)
let after : HeapType = AbsHeapTypeHeapType(ExternAbsHeapType)
assert_not_eq(before, after)
// TypeIdx changes should be detected
let idx_before : HeapType = HeapType(TypeIdx(0))
let idx_after : HeapType = HeapType(TypeIdx(1000))
assert_not_eq(idx_before, idx_after)
}
///|
test "RefType with transformed HeapType should not be equal" {
// The transformer changes HeapType inside RefType
let before = HeapTypeRefType(
true,
false,
AbsHeapTypeHeapType(FuncAbsHeapType),
)
let after = HeapTypeRefType(
true,
false,
AbsHeapTypeHeapType(ExternAbsHeapType),
)
assert_not_eq(before, after)
// But AbsHeapTypeRefType doesn't contain HeapType - verify these are different
let abs_func = AbsHeapTypeRefType(FuncAbsHeapType)
let abs_extern = AbsHeapTypeRefType(ExternAbsHeapType)
assert_not_eq(abs_func, abs_extern)
}