compiler: Check owned decoder parameter construction
d96dc5900323a23a806021dd3b3645e7cf1ccb23f83a6c794da7f70f446ddd27
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 (¶ms[..]) 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; |