test/packages/check.rad 4.0 KiB 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 {
51
                set fenceFound = true;
52
            }
53
        }
54
    }
55
    assert fenceFound, "main: intrinsic instruction";
56
    assert app.exports.len == 1, "main: app.exports.len == 1";
57
    assert app.exports[0].kind == binary::ExportKind::Function, "main: app.exports[0].kind == binary::ExportKind::Function";
58
    let entry = app.entry else panic "main: missing package entry";
59
    assert mem::eq(entry, "app::main"), "main: mem::eq(entry, \"app::main\")";
60
    let mut callFound = false;
61
    let mut dataFound = false;
62
    for block in app.program.fns[0].blocks {
63
        for instr in block.instrs {
64
            match instr {
65
                case il::Instr::Call { func, .. } => {
66
                    if let case il::Val::FnAddr(name) = func {
67
                        if mem::eq(name, "support::read") {
68
                            set callFound = true;
69
                        }
70
                    }
71
                },
72
                case il::Instr::Copy { val, .. } => {
73
                    if let case il::Val::DataSym(name) = val {
74
                        if mem::eq(name, "support::value") {
75
                            set dataFound = true;
76
                        }
77
                    }
78
                },
79
                else => {
80
                },
81
            }
82
        }
83
    }
84
    assert callFound and dataFound, "main: callFound and dataFound";
85
    return 0;
86
}