compiler: Check owned decoder parameter construction

d96dc5900323a23a806021dd3b3645e7cf1ccb23f83a6c794da7f70f446ddd27
Alexis Sellier committed ago 1 parent 9c0b2546
lib/std/lang/il/binary/decodeTests.rad +15 -1
51 51
    try testing::expect(decoded.dependencies.len == package.dependencies.len);
52 52
    try testing::expect(decoded.exports.len == package.exports.len);
53 53
    try testing::expect(decoded.program.fns.len == package.program.fns.len);
54 54
    for original, i in package.program.fns {
55 55
        let restored = decoded.program.fns[i];
56 +
        assert restored.params.len == original.params.len;
57 +
        for param, j in original.params {
58 +
            assert restored.params[j].value.n == param.value.n;
59 +
            assert restored.params[j].type == param.type;
60 +
        }
56 61
        assert restored.blocks.len == original.blocks.len;
57 62
        for block, j in original.blocks {
58 63
            let rebuilt = &restored.blocks[j];
59 64
            try testing::expectBytesEq(rebuilt.label, block.label);
60 65
            assert rebuilt.loopDepth == block.loopDepth;
139 144
    ]);
140 145
}
141 146
142 147
/// Check functions, dependencies, exports, initializers, and block metadata.
143 148
@test unsafe fn fullPackage() throws (testing::TestError) {
144 -
    let params: *unsafe [il::Param] = &[il::Param { value: il::Reg { n: 1 }, type: il::Type::W64 }];
149 +
    let params: *unsafe [il::Param] = &[
150 +
        il::Param { value: il::Reg { n: 1 }, type: il::Type::W8 },
151 +
        il::Param { value: il::Reg { n: 4 }, type: il::Type::W16 },
152 +
        il::Param { value: il::Reg { n: 5 }, type: il::Type::W32 },
153 +
        il::Param { value: il::Reg { n: 6 }, type: il::Type::W64 },
154 +
    ];
145 155
    let mut instrs = [
146 156
        il::Instr::Call {
147 157
            retTy: il::Type::W64, dst: il::Reg { n: 2 }, func: il::Val::FnAddr("dep::fn"),
148 158
            args: &[il::Val::Reg(il::Reg { n: 1 })],
149 159
        },
372 382
    try rejected(&package, LIMITS);
373 383
    set func.isExtern = false;
374 384
    set func.params = &[il::Param { value: il::Reg { n: 16 }, type: il::Type::W64 }];
375 385
    try rejected(&package, LIMITS);
376 386
    set func.params = &[];
387 +
    set block.params = &[il::Param { value: il::Reg { n: 16 }, type: il::Type::W32 }];
388 +
    set func.blocks = &[block];
389 +
    try rejected(&package, LIMITS);
390 +
    set block.params = &[];
377 391
    set block.preds = &[1];
378 392
    set func.blocks = &[block];
379 393
    try rejected(&package, LIMITS);
380 394
}
381 395
lib/std/lang/il/binary/program.rad +8 -2
141 141
/// Read typed SSA parameters with checked register indices.
142 142
unsafe fn readParams 'input (input: &mut reader::Reader 'input) -> *unsafe [il::Param] throws (binary::Error) {
143 143
    let n = try reader::count(input, 5);
144 144
    let params = try reader::storage(input, @sizeOf(il::Param), @alignOf(il::Param), n)
145 145
        as *mut [il::Param];
146 -
    for i in 0..n {
146 +
    let initialized = try fillParams(input, params);
147 +
    return (&initialized[..]) as *unsafe [il::Param];
148 +
}
149 +
150 +
/// Fill owned parameter storage from checked register indices and type tags.
151 +
fn fillParams 'input (input: &mut reader::Reader 'input, params: *mut [il::Param]) -> *[il::Param] throws (binary::Error) {
152 +
    for i in 0..params.len {
147 153
        let value = try reader::reg(input);
148 154
        let t = try reader::typ(input);
149 155
        set params[i] = il::Param { value, type: t };
150 156
    }
151 -
    return (&params[..]) as *unsafe [il::Param];
157 +
    return params;
152 158
}
153 159
154 160
/// Extend an initializer extent without exceeding its declared storage.
155 161
fn extendDataExtent(extent: u64, value: il::DataValue, size: u32) -> u64 throws (binary::Error) {
156 162
    let mut width: u32 = 0;