Skip to content

Commit 7d857e6

Browse files
authored
Fix discriminant size of enums/variants (#12066)
* Fix discriminant size of enums/variants This fixes an off-by-one-error that's been present for lifting/lowering enums/variants for... forever I think? This means that precisely 256-variant-enums and 65536-variant-enums have been incorrectly loaded from memory historically (or stored). Discovered via the new fuzz target for roundtripping values and I expect the practical impact of this bugfix to be negligible. * Fix generation of `#[repr(..)]` in fuzzing * Fix 32-bit compile * Fix fuzzing
1 parent 5730c76 commit 7d857e6

File tree

4 files changed

+64
-7
lines changed

4 files changed

+64
-7
lines changed

crates/component-util/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ pub enum DiscriminantSize {
2121
impl DiscriminantSize {
2222
/// Calculate the size of discriminant needed to represent a variant with the specified number of cases.
2323
pub const fn from_count(count: usize) -> Option<Self> {
24-
if count <= 0xFF {
24+
if count <= 1 << 8 {
2525
Some(Self::Size1)
26-
} else if count <= 0xFFFF {
26+
} else if count <= 1 << 16 {
2727
Some(Self::Size2)
28-
} else if count <= 0xFFFF_FFFF {
28+
} else if count as u64 <= 1 << 32 {
2929
Some(Self::Size4)
3030
} else {
3131
None

crates/test-util/src/component_fuzz.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,10 +1234,10 @@ pub fn rust_type(ty: &Type, name_counter: &mut u32, declarations: &mut TokenStre
12341234
.collect::<TokenStream>();
12351235

12361236
let name = make_rust_name(name_counter);
1237-
let repr = match count.ilog2() {
1238-
0..=7 => quote!(u8),
1239-
8..=15 => quote!(u16),
1240-
_ => quote!(u32),
1237+
let repr = match DiscriminantSize::from_count(*count as usize).unwrap() {
1238+
DiscriminantSize::Size1 => quote!(u8),
1239+
DiscriminantSize::Size2 => quote!(u16),
1240+
DiscriminantSize::Size4 => quote!(u32),
12411241
};
12421242

12431243
declarations.extend(quote! {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
(component
2+
3+
(core module $m
4+
(memory (export "mem") 1)
5+
(func (export "return-two") (param i32) (result i32)
6+
i32.const 100
7+
local.get 0
8+
i32.store8 offset=0
9+
i32.const 100
10+
local.get 0
11+
i32.store8 offset=1
12+
i32.const 100)
13+
)
14+
(core instance $i (instantiate $m))
15+
(type $e' (enum
16+
"E0" "E1" "E2" "E3" "E4" "E5" "E6" "E7"
17+
"E8" "E9" "E10" "E11" "E12" "E13" "E14" "E15"
18+
"E16" "E17" "E18" "E19" "E20" "E21" "E22" "E23"
19+
"E24" "E25" "E26" "E27" "E28" "E29" "E30" "E31"
20+
"E32" "E33" "E34" "E35" "E36" "E37" "E38" "E39"
21+
"E40" "E41" "E42" "E43" "E44" "E45" "E46" "E47"
22+
"E48" "E49" "E50" "E51" "E52" "E53" "E54" "E55"
23+
"E56" "E57" "E58" "E59" "E60" "E61" "E62" "E63"
24+
"E64" "E65" "E66" "E67" "E68" "E69" "E70" "E71"
25+
"E72" "E73" "E74" "E75" "E76" "E77" "E78" "E79"
26+
"E80" "E81" "E82" "E83" "E84" "E85" "E86" "E87"
27+
"E88" "E89" "E90" "E91" "E92" "E93" "E94" "E95"
28+
"E96" "E97" "E98" "E99" "E100" "E101" "E102" "E103"
29+
"E104" "E105" "E106" "E107" "E108" "E109" "E110" "E111"
30+
"E112" "E113" "E114" "E115" "E116" "E117" "E118" "E119"
31+
"E120" "E121" "E122" "E123" "E124" "E125" "E126" "E127"
32+
"E128" "E129" "E130" "E131" "E132" "E133" "E134" "E135"
33+
"E136" "E137" "E138" "E139" "E140" "E141" "E142" "E143"
34+
"E144" "E145" "E146" "E147" "E148" "E149" "E150" "E151"
35+
"E152" "E153" "E154" "E155" "E156" "E157" "E158" "E159"
36+
"E160" "E161" "E162" "E163" "E164" "E165" "E166" "E167"
37+
"E168" "E169" "E170" "E171" "E172" "E173" "E174" "E175"
38+
"E176" "E177" "E178" "E179" "E180" "E181" "E182" "E183"
39+
"E184" "E185" "E186" "E187" "E188" "E189" "E190" "E191"
40+
"E192" "E193" "E194" "E195" "E196" "E197" "E198" "E199"
41+
"E200" "E201" "E202" "E203" "E204" "E205" "E206" "E207"
42+
"E208" "E209" "E210" "E211" "E212" "E213" "E214" "E215"
43+
"E216" "E217" "E218" "E219" "E220" "E221" "E222" "E223"
44+
"E224" "E225" "E226" "E227" "E228" "E229" "E230" "E231"
45+
"E232" "E233" "E234" "E235" "E236" "E237" "E238" "E239"
46+
"E240" "E241" "E242" "E243" "E244" "E245" "E246" "E247"
47+
"E248" "E249" "E250" "E251" "E252" "E253" "E254" "E255"
48+
))
49+
(export $e "e" (type $e'))
50+
(func (export "return-two") (param "e" $e) (result (tuple $e $e))
51+
(canon lift (core func $i "return-two") (memory $i "mem")))
52+
)
53+
54+
(assert_return (invoke "return-two" (enum.const "E1"))
55+
(tuple.const (enum.const "E1") (enum.const "E1")))

tests/misc_testsuite/component-model/resources.wast

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
;;! component_model_async = true
2+
13
;; bare bones "intrinsics work"
24
(component
35
(type $r (resource (rep i32)))

0 commit comments

Comments
 (0)