compiler/
kernel/
lib/
scripts/
seed/
sublime/
test/
acceptance/
boot/
bootstrap/
cycles/
dispatch/
loader/
mmio/
modules/
native/
packages/
app.rad
271 B
check.rad
3.9 KiB
run
1.1 KiB
support.rad
390 B
pages/
runtime/
scheduling/
shared/
slots/
smp/
sync/
termination/
tests/
trap/
run
2.7 KiB
runner.rad
10.3 KiB
vim/
.gitignore
336 B
.gitsigners
112 B
CONTRIBUTING
2.1 KiB
LICENSE
1.1 KiB
Makefile
10.2 KiB
README
2.5 KiB
STYLE
2.5 KiB
std.lib
1.5 KiB
std.lib.test
551 B
test/packages/check.rad
raw
| 1 | //! Verify compiler-emitted binary RIL package boundaries. |
| 2 | |
| 3 | use std::sys; |
| 4 | use std::sys::unix; |
| 5 | use std::mem; |
| 6 | use std::lang::alloc; |
| 7 | use std::lang::il; |
| 8 | use std::lang::il::binary; |
| 9 | use std::lang::il::binary::program; |
| 10 | |
| 11 | /// Maximum fixture image size. |
| 12 | constant IMAGE_SIZE: u32 = 4096; |
| 13 | /// Arena capacity for both decoded fixture packages. |
| 14 | constant ARENA_SIZE: u32 = 32768; |
| 15 | /// Input image storage. |
| 16 | static IMAGE: [u8; IMAGE_SIZE] = [0; IMAGE_SIZE]; |
| 17 | /// Decoded package storage. |
| 18 | static MEMORY: [u8; ARENA_SIZE] = [0; ARENA_SIZE]; |
| 19 | |
| 20 | /// Decode one compiler output file. |
| 21 | unsafe fn load(path: *[u8], arena: &mut alloc::Arena) -> binary::Package { |
| 22 | let length = unix::readFile(path, &mut IMAGE[..]) else panic "load: cannot read fixture"; |
| 23 | return try! program::decode(&IMAGE[..length], arena, binary::Limits { registers: 8192, blocks: 4096 }); |
| 24 | } |
| 25 | |
| 26 | /// Check identity, ownership, linkage, and source exports for two packages. |
| 27 | @default unsafe fn main(env: *sys::Env) -> i32 { |
| 28 | assert env.args.len == 3, "main: expected two package paths"; |
| 29 | let mut arena = alloc::new(&mut MEMORY[..]); |
| 30 | let support = load(env.args[1], &mut arena); |
| 31 | let app = load(env.args[2], &mut arena); |
| 32 | assert mem::eq(support.name, "support"), "main: mem::eq(support.name, \"support\")"; |
| 33 | assert mem::eq(app.name, "app"), "main: mem::eq(app.name, \"app\")"; |
| 34 | assert support.dependencies.len == 0, "main: support.dependencies.len == 0"; |
| 35 | assert app.dependencies.len == 1, "main: app.dependencies.len == 1"; |
| 36 | assert mem::eq(app.dependencies[0], "support"), "main: mem::eq(app.dependencies[0], \"support\")"; |
| 37 | assert support.program.fns.len == 2, "main: support.program.fns.len == 2"; |
| 38 | assert support.program.data.len == 3, "main: support.program.data.len == 3"; |
| 39 | assert mem::eq(support.program.fns[0].name, "support::read"), "main: mem::eq(support.program.fns[0].name, \"support::read\")"; |
| 40 | assert mem::eq(support.program.data[0].name, "support::value"), "main: mem::eq(support.program.data[0].name, \"support::value\")"; |
| 41 | assert app.program.fns.len == 1, "main: app.program.fns.len == 1"; |
| 42 | assert app.program.data.len == 2, "main: app.program.data.len == 2"; |
| 43 | assert not mem::eq(support.program.data[1].name, app.program.data[0].name), "main: package-local literals"; |
| 44 | assert not mem::eq(support.program.data[2].name, app.program.data[1].name), "main: package-local arrays"; |
| 45 | assert mem::eq(app.program.fns[0].name, "app::main"), "main: mem::eq(app.program.fns[0].name, \"app::main\")"; |
| 46 | assert support.exports.len == 2, "main: support.exports.len == 2"; |
| 47 | let mut fenceFound = false; |
| 48 | for block in support.program.fns[0].blocks { |
| 49 | for instr in block.instrs { |
| 50 | if let case il::Instr::MemoryFence = instr { set fenceFound = true; } |
| 51 | } |
| 52 | } |
| 53 | assert fenceFound, "main: intrinsic instruction"; |
| 54 | assert app.exports.len == 1, "main: app.exports.len == 1"; |
| 55 | assert app.exports[0].kind == binary::ExportKind::Function, "main: app.exports[0].kind == binary::ExportKind::Function"; |
| 56 | let entry = app.entry else panic "main: missing package entry"; |
| 57 | assert mem::eq(entry, "app::main"), "main: mem::eq(entry, \"app::main\")"; |
| 58 | let mut callFound = false; |
| 59 | let mut dataFound = false; |
| 60 | for block in app.program.fns[0].blocks { |
| 61 | for instr in block.instrs { |
| 62 | match instr { |
| 63 | case il::Instr::Call { func, .. } => { |
| 64 | if let case il::Val::FnAddr(name) = func { |
| 65 | if mem::eq(name, "support::read") { set callFound = true; } |
| 66 | } |
| 67 | }, |
| 68 | case il::Instr::Copy { val, .. } => { |
| 69 | if let case il::Val::DataSym(name) = val { |
| 70 | if mem::eq(name, "support::value") { set dataFound = true; } |
| 71 | } |
| 72 | }, |
| 73 | else => {}, |
| 74 | } |
| 75 | } |
| 76 | } |
| 77 | assert callFound and dataFound, "main: callFound and dataFound"; |
| 78 | return 0; |
| 79 | } |