compiler: Check package symbol collection sequencing
9e6185409d2e0bedf18daeb29cbd9053b85906473ca79484632e26748a74130b
1 parent
da81577b
lib/std/lang/il/binary/collect.rad
+18 -5
| 230 | 230 | owner: *[u8], |
|
| 231 | 231 | program: il::Program, |
|
| 232 | 232 | exports: &[binary::Export], |
|
| 233 | 233 | entry: ?*[u8] |
|
| 234 | 234 | ) -> binary::Package throws (binary::Error) { |
|
| 235 | + | try collectNames(names, owner, &program, exports, entry); |
|
| 236 | + | return binary::Package { |
|
| 237 | + | symbols: &names.symbols[..names.symbolCount], name: owner, |
|
| 238 | + | dependencies: &names.dependencies[..names.dependencyCount], exports: exports as *unsafe [binary::Export], entry, program, |
|
| 239 | + | }; |
|
| 240 | + | } |
|
| 241 | + | ||
| 242 | + | /// Collect package metadata before data and function references. |
|
| 243 | + | fn collectNames 'tables ( |
|
| 244 | + | names: &mut Names 'tables, |
|
| 245 | + | owner: *[u8], |
|
| 246 | + | program: &il::Program, |
|
| 247 | + | exports: &[binary::Export], |
|
| 248 | + | entry: ?*[u8], |
|
| 249 | + | ) throws (binary::Error) { |
|
| 235 | 250 | try add(names, owner); |
|
| 236 | 251 | for item in exports { |
|
| 237 | 252 | try definition(names, owner, item.name); |
|
| 238 | 253 | } |
|
| 239 | 254 | if let name = entry { |
|
| 240 | 255 | try definition(names, owner, name); |
|
| 241 | 256 | } |
|
| 242 | 257 | try collectData(names, owner, &program.data[..]); |
|
| 243 | - | try collectFunctions(names, owner, program.fns); |
|
| 244 | - | return binary::Package { |
|
| 245 | - | symbols: &names.symbols[..names.symbolCount], name: owner, |
|
| 246 | - | dependencies: &names.dependencies[..names.dependencyCount], exports: exports as *unsafe [binary::Export], entry, program, |
|
| 247 | - | }; |
|
| 258 | + | unsafe { |
|
| 259 | + | try collectFunctions(names, owner, program.fns); |
|
| 260 | + | } |
|
| 248 | 261 | } |
lib/std/lang/il/binary/decodeTests.rad
+32 -0
| 564 | 564 | } |
|
| 565 | 565 | for i in capacity..symbols.len { assert symbols[i].len == 0; } |
|
| 566 | 566 | } |
|
| 567 | 567 | } |
|
| 568 | 568 | ||
| 569 | + | /// Exports precede the entry name, and entry definitions belong to the package. |
|
| 570 | + | @test unsafe fn entryCollectionOrder() throws (testing::TestError) { |
|
| 571 | + | let local = il::Program { data: &[], fns: &[] }; |
|
| 572 | + | let exports = [ |
|
| 573 | + | binary::Export { name: "p::second", kind: binary::ExportKind::Function }, |
|
| 574 | + | binary::Export { name: "p::first", kind: binary::ExportKind::Function }, |
|
| 575 | + | binary::Export { name: "p::second", kind: binary::ExportKind::Function }, |
|
| 576 | + | ]; |
|
| 577 | + | let entries: [?*[u8]; 5] = [nil, "p::first", "p::start", "other::start", "p::"]; |
|
| 578 | + | for entry, index in entries { |
|
| 579 | + | let mut symbols: [*[u8]; 4] = [""; 4]; |
|
| 580 | + | let mut dependencies: [*[u8]; 1] = [""; 1]; |
|
| 581 | + | let symbolTable: 'tables = &mut symbols[..], dependencyTable = &mut dependencies[..] in { |
|
| 582 | + | let mut names = collect::new(symbolTable, dependencyTable); |
|
| 583 | + | let package = try collect::package(&mut names, "p", local, &exports[..], entry) catch err { |
|
| 584 | + | assert index >= 3; |
|
| 585 | + | assert err == binary::Error::Invalid; |
|
| 586 | + | continue; |
|
| 587 | + | }; |
|
| 588 | + | assert index < 3; |
|
| 589 | + | assert package.symbols.len == (4 if index == 2 else 3); |
|
| 590 | + | for name, i in ["p", "p::second", "p::first"] { |
|
| 591 | + | try testing::expectBytesEq(package.symbols[i], name); |
|
| 592 | + | } |
|
| 593 | + | if index == 2 { try testing::expectBytesEq(package.symbols[3], "p::start"); } |
|
| 594 | + | assert package.dependencies.len == 0; |
|
| 595 | + | assert package.exports.len == 3; |
|
| 596 | + | assert package.entry == entry; |
|
| 597 | + | } |
|
| 598 | + | } |
|
| 599 | + | } |
|
| 600 | + | ||
| 569 | 601 | /// Data collection retains first-use order and unique dependencies. |
|
| 570 | 602 | @test unsafe fn dataCollectionOrder() throws (testing::TestError) { |
|
| 571 | 603 | let item = il::Data { |
|
| 572 | 604 | name: "p::data", size: 64, alignment: 8, readOnly: true, isZeroInit: false, |
|
| 573 | 605 | values: &[ |