compiler: Read block descriptors through checked slices

06628001e2e58e8e5ec178187d8fe2b48da38885c774992acefb2c7627632bfe
Alexis Sellier committed ago 1 parent cb284e73
lib/std/lang/lower.rad +7 -7
2214 2214
unsafe fn switchToAndSeal 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, block: BlockId) throws (LowerError) where 'arena: 'phase, 'phase: 'function {
2215 2215
    try sealBlock(self, block);
2216 2216
    switchToBlock(self, block);
2217 2217
}
2218 2218
2219 -
/// Get block data by block id.
2220 -
unsafe fn getBlock 'arena 'phase 'function (self: &FnLowerer 'arena 'phase 'function, block: BlockId) -> *unsafe BlockData where 'arena: 'phase, 'phase: 'function {
2221 -
    return &self.blockData[*block];
2219 +
/// Get a snapshot of a block's descriptors by block id.
2220 +
fn getBlock(blocks: &[BlockData], block: BlockId) -> BlockData {
2221 +
    return blocks[*block];
2222 2222
}
2223 2223
2224 2224
/// Get mutable block data by block id.
2225 2225
unsafe fn getBlockMut 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, block: BlockId) -> *unsafe mut BlockData where 'arena: 'phase, 'phase: 'function {
2226 2226
    return &mut self.blockData[*block];
2673 2673
    try sealBlock(self, target);
2674 2674
}
2675 2675
2676 2676
/// Check if the current block already has a terminator instruction.
2677 2677
unsafe fn blockHasTerminator 'arena 'phase 'function (self: &FnLowerer 'arena 'phase 'function) -> bool where 'arena: 'phase, 'phase: 'function {
2678 -
    let blk = getBlock(self, currentBlock(self));
2678 +
    let blk = getBlock(&self.blockData[..], currentBlock(self));
2679 2679
    if blk.instrs.len == 0 {
2680 2680
        return false;
2681 2681
    }
2682 2682
    match blk.instrs[blk.instrs.len - 1] {
2683 2683
        case il::Instr::Ret { .. },
3074 3074
///
3075 3075
/// This representation avoids the need for phi nodes to reference their
3076 3076
/// predecessor blocks explicitly, since the control flow edges already encode
3077 3077
/// that information.
3078 3078
unsafe fn resolveBlockArgs 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, block: BlockId, v: Var, paramIdx: u32) throws (LowerError) where 'arena: 'phase, 'phase: 'function {
3079 -
    let blk = getBlock(self, block);
3079 +
    let blk = getBlock(&self.blockData[..], block);
3080 3080
3081 3081
    // For each predecessor, recursively look up the variable's reaching definition
3082 3082
    // in that block, then patch the predecessor's terminator to pass that value
3083 3083
    // as an argument to this block's parameter.
3084 3084
    for predId in blk.preds {
3092 3092
}
3093 3093
3094 3094
/// Check if a block parameter is trivial, i.e. all predecessors provide
3095 3095
/// the same value. Returns the trivial value if so.
3096 3096
unsafe fn getTrivialPhiVal 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, block: BlockId, v: Var) -> ?il::Val throws (LowerError) where 'arena: 'phase, 'phase: 'function {
3097 -
    let blk = getBlock(self, block);
3097 +
    let blk = getBlock(&self.blockData[..], block);
3098 3098
    // Get the block parameter register.
3099 3099
    let paramReg = blk.vars[*v];
3100 3100
    // Check if all predecessors provide the same value.
3101 3101
    let mut sameVal: ?il::Val = nil;
3102 3102
5721 5721
    exitLoop(self);
5722 5722
5723 5723
    // Only seal end block if it's actually reachable (ie. has predecessors).
5724 5724
    // If the loop has no breaks and only exits via return, the end block
5725 5725
    // remains unreachable and isn't added to the CFG.
5726 -
    if getBlock(self, endBlock).preds.len > 0 {
5726 +
    if getBlock(&self.blockData[..], endBlock).preds.len > 0 {
5727 5727
        try switchToAndSeal(self, endBlock);
5728 5728
    }
5729 5729
}
5730 5730
5731 5731
/// Lower a while loop: `while <cond> { <body> }`.