compiler: Grow initialized scalar match destinations

9a2a5d6dd9ab089ac98ff1da9b51d501b5bfb5f898274fbf988dfc5920246f12
Alexis Sellier committed ago 1 parent 84ff2d4f
lib/std/lang/lower.rad +3 -3
3719 3719
    return try finalizeBlocks(self);
3720 3720
}
3721 3721
3722 3722
/// Lower a scalar match as a switch instruction.
3723 3723
unsafe fn lowerMatchSwitch 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, prongs: *[*ast::Node], subject: &MatchSubject, mergeBlock: &mut ?BlockId) throws (LowerError) where 'arena: 'phase, 'phase: 'function {
3724 -
    let mut blocks: [BlockId; 32] = undefined;
3724 +
    let mut blocks: *mut [BlockId] = &mut [];
3725 3725
    let mut cases: *unsafe mut [il::SwitchCase] = &mut [];
3726 3726
    let mut defaultIdx: u32 = 0;
3727 3727
    let entry = currentBlock(self);
3728 3728
3729 3729
    for p, i in prongs {
3730 3730
        let case ast::NodeValue::MatchProng(prong) = p.value
3731 3731
            else throw LowerError::UnexpectedNodeValue(p);
3732 3732
3733 3733
        match prong.arm {
3734 3734
            case ast::ProngArm::Binding(_), ast::ProngArm::Else => {
3735 -
                set blocks[i] = try createBlock(self, "default");
3735 +
                blocks.append(try createBlock(self, "default"), alloc::arenaAllocator(self.arena));
3736 3736
                set defaultIdx = i;
3737 3737
            }
3738 3738
            case ast::ProngArm::Case(pats) => {
3739 -
                set blocks[i] = try createBlock(self, "case");
3739 +
                blocks.append(try createBlock(self, "case"), alloc::arenaAllocator(self.arena));
3740 3740
                for pat in pats {
3741 3741
                    let cv = resolver::constValueEntry(self.low.resolver, pat)
3742 3742
                        else throw LowerError::MissingConst(pat);
3743 3743
3744 3744
                    cases.append(il::SwitchCase {
test/tests/match.switch.capacity.rad added +161 -0
1 +
//! returns: 0
2 +
//! Scalar match destinations cover table boundaries and large matches.
3 +
4 +
/// Select among 31 scalar cases and a fallback.
5 +
fn select31(value: u32) -> u32 {
6 +
    match value {
7 +
        case 0 => return 100,
8 +
        case 1 => return 101,
9 +
        case 2 => return 102,
10 +
        case 3 => return 103,
11 +
        case 4 => return 104,
12 +
        case 5 => return 105,
13 +
        case 6 => return 106,
14 +
        case 7 => return 107,
15 +
        case 8 => return 108,
16 +
        case 9 => return 109,
17 +
        case 10 => return 110,
18 +
        case 11 => return 111,
19 +
        case 12 => return 112,
20 +
        case 13 => return 113,
21 +
        case 14 => return 114,
22 +
        case 15 => return 115,
23 +
        case 16 => return 116,
24 +
        case 17 => return 117,
25 +
        case 18 => return 118,
26 +
        case 19 => return 119,
27 +
        case 20 => return 120,
28 +
        case 21 => return 121,
29 +
        case 22 => return 122,
30 +
        case 23 => return 123,
31 +
        case 24 => return 124,
32 +
        case 25 => return 125,
33 +
        case 26 => return 126,
34 +
        case 27 => return 127,
35 +
        case 28 => return 128,
36 +
        case 29 => return 129,
37 +
        case 30 => return 130,
38 +
        else => return 999,
39 +
    }
40 +
}
41 +
42 +
/// Select among 32 scalar cases and a fallback.
43 +
fn select32(value: u32) -> u32 {
44 +
    match value {
45 +
        case 0 => return 100,
46 +
        case 1 => return 101,
47 +
        case 2 => return 102,
48 +
        case 3 => return 103,
49 +
        case 4 => return 104,
50 +
        case 5 => return 105,
51 +
        case 6 => return 106,
52 +
        case 7 => return 107,
53 +
        case 8 => return 108,
54 +
        case 9 => return 109,
55 +
        case 10 => return 110,
56 +
        case 11 => return 111,
57 +
        case 12 => return 112,
58 +
        case 13 => return 113,
59 +
        case 14 => return 114,
60 +
        case 15 => return 115,
61 +
        case 16 => return 116,
62 +
        case 17 => return 117,
63 +
        case 18 => return 118,
64 +
        case 19 => return 119,
65 +
        case 20 => return 120,
66 +
        case 21 => return 121,
67 +
        case 22 => return 122,
68 +
        case 23 => return 123,
69 +
        case 24 => return 124,
70 +
        case 25 => return 125,
71 +
        case 26 => return 126,
72 +
        case 27 => return 127,
73 +
        case 28 => return 128,
74 +
        case 29 => return 129,
75 +
        case 30 => return 130,
76 +
        case 31 => return 131,
77 +
        else => return 999,
78 +
    }
79 +
}
80 +
81 +
/// Select among 64 scalar cases and a fallback.
82 +
fn select64(value: u32) -> u32 {
83 +
    match value {
84 +
        case 0 => return 100,
85 +
        case 1 => return 101,
86 +
        case 2 => return 102,
87 +
        case 3 => return 103,
88 +
        case 4 => return 104,
89 +
        case 5 => return 105,
90 +
        case 6 => return 106,
91 +
        case 7 => return 107,
92 +
        case 8 => return 108,
93 +
        case 9 => return 109,
94 +
        case 10 => return 110,
95 +
        case 11 => return 111,
96 +
        case 12 => return 112,
97 +
        case 13 => return 113,
98 +
        case 14 => return 114,
99 +
        case 15 => return 115,
100 +
        case 16 => return 116,
101 +
        case 17 => return 117,
102 +
        case 18 => return 118,
103 +
        case 19 => return 119,
104 +
        case 20 => return 120,
105 +
        case 21 => return 121,
106 +
        case 22 => return 122,
107 +
        case 23 => return 123,
108 +
        case 24 => return 124,
109 +
        case 25 => return 125,
110 +
        case 26 => return 126,
111 +
        case 27 => return 127,
112 +
        case 28 => return 128,
113 +
        case 29 => return 129,
114 +
        case 30 => return 130,
115 +
        case 31 => return 131,
116 +
        case 32 => return 132,
117 +
        case 33 => return 133,
118 +
        case 34 => return 134,
119 +
        case 35 => return 135,
120 +
        case 36 => return 136,
121 +
        case 37 => return 137,
122 +
        case 38 => return 138,
123 +
        case 39 => return 139,
124 +
        case 40 => return 140,
125 +
        case 41 => return 141,
126 +
        case 42 => return 142,
127 +
        case 43 => return 143,
128 +
        case 44 => return 144,
129 +
        case 45 => return 145,
130 +
        case 46 => return 146,
131 +
        case 47 => return 147,
132 +
        case 48 => return 148,
133 +
        case 49 => return 149,
134 +
        case 50 => return 150,
135 +
        case 51 => return 151,
136 +
        case 52 => return 152,
137 +
        case 53 => return 153,
138 +
        case 54 => return 154,
139 +
        case 55 => return 155,
140 +
        case 56 => return 156,
141 +
        case 57 => return 157,
142 +
        case 58 => return 158,
143 +
        case 59 => return 159,
144 +
        case 60 => return 160,
145 +
        case 61 => return 161,
146 +
        case 62 => return 162,
147 +
        case 63 => return 163,
148 +
        else => return 999,
149 +
    }
150 +
}
151 +
152 +
/// Exercise every case and each fallback.
153 +
@default fn main() -> u32 {
154 +
    for value in 0..31 { assert select31(value) == value + 100; }
155 +
    assert select31(31) == 999;
156 +
    for value in 0..32 { assert select32(value) == value + 100; }
157 +
    assert select32(32) == 999;
158 +
    for value in 0..64 { assert select64(value) == value + 100; }
159 +
    assert select64(64) == 999;
160 +
    return 0;
161 +
}