compiler: Retain ownership of variable metadata

2707105e33393212dc33d4b05228be48e0db8ac1f3d39d96fb1e88565d75ee57
Alexis Sellier committed ago 1 parent e0736f02
lib/std/lang/lower.rad +3 -3
999 999
    set self.currentMod = nil;
1000 1000
    set self.packageDataStart = self.data.len;
1001 1001
}
1002 1002
1003 1003
/// Allocate initialized variable metadata for one function.
1004 -
unsafe fn variableStorage(arena: &mut alloc::Arena, count: u32) -> *unsafe mut [VarData] {
1005 -
    let entries = try! alloc::allocRawSlice(arena, @sizeOf(VarData), @alignOf(VarData), count)
1006 -
        as *unsafe mut [VarData];
1004 +
unsafe fn variableStorage(arena: &mut alloc::Arena, count: u32) -> *mut [VarData] {
1005 +
    let entries = try! alloc::allocSlice(arena, @sizeOf(VarData), @alignOf(VarData), count)
1006 +
        as *mut [VarData];
1007 1007
    for i in 0..count {
1008 1008
        set entries[i] = VarData { name: nil, type: il::Type::W64, mutable: false, addressTaken: false };
1009 1009
    }
1010 1010
    return entries;
1011 1011
}
test/tests/variable.slots.scopes.rad added +57 -0
1 +
//! returns: 0
2 +
3 +
/// Aggregate metadata must remain distinct from scalar metadata.
4 +
record Pair: Copy {
5 +
    /// First field.
6 +
    first: u32,
7 +
    /// Full-width field.
8 +
    second: u64,
9 +
}
10 +
11 +
/// Mutate an addressed full-width local.
12 +
fn increment(value: &mut u64) {
13 +
    set *value += 1;
14 +
}
15 +
16 +
/// Exercise reused lexical slots with different types and address modes.
17 +
fn check(seed: u32) -> u32 {
18 +
    let value = seed;
19 +
    let mut result: u32 = 0;
20 +
    {
21 +
        let mut value: u64 = 0x100000000 + seed as u64;
22 +
        increment(&mut value);
23 +
        assert value == 0x100000001 + seed as u64;
24 +
        set result += value as u32;
25 +
    }
26 +
    assert value == seed;
27 +
    {
28 +
        let value = Pair { first: seed + 2, second: 0x200000000 + seed as u64 };
29 +
        assert value.second == 0x200000000 + seed as u64;
30 +
        set result += value.first;
31 +
    }
32 +
    {
33 +
        let mut value = seed % 2 == 0;
34 +
        set value = not value;
35 +
        assert value == (seed % 2 == 1);
36 +
    }
37 +
    {
38 +
        let mut value = seed + 3;
39 +
        set value += 1;
40 +
        set result += value;
41 +
    }
42 +
    assert value == seed;
43 +
    return result;
44 +
}
45 +
46 +
/// Check repeated invocations and slot initialization in an empty function.
47 +
fn empty() {}
48 +
49 +
/// Verify scoped metadata over several argument values.
50 +
@default fn main() -> u32 {
51 +
    empty();
52 +
    for seed in 0..16 {
53 +
        assert check(seed) == seed * 3 + 7;
54 +
    }
55 +
    empty();
56 +
    return 0;
57 +
}