compiler: Retain ownership of variable metadata
2707105e33393212dc33d4b05228be48e0db8ac1f3d39d96fb1e88565d75ee57
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 | + | } |