pub struct Compiler { /* private fields */ }Expand description
Accumulates functions and links them into one image.
A Compiler compiles each function you add to object code
and holds it; link places them all in a single Image.
This is the multi-function counterpart to the free compile function: use it
to build an image out of several functions, to choose the
base_address the image is laid out at, or to name the
entry point.
Functions are laid out in the order they are added. Each defines a symbol under
its own name, so two functions with the same name collide — the link then fails
with AotError::Link.
Implements Default, equivalent to Compiler::new: base address 0, no
entry point.
§Examples
Place two functions in one image, based at a load address, with a chosen entry point:
use aot_lang::Compiler;
use ir_lang::{Builder, BinOp, Type};
// fn add(a: int, b: int) -> int { a + b }
let mut add = Builder::new("add", &[Type::Int, Type::Int], Type::Int);
let a = add.block_params(add.entry())[0];
let b = add.block_params(add.entry())[1];
let sum = add.bin(BinOp::Add, a, b);
add.ret(Some(sum));
// fn one() -> int { 1 }
let mut one = Builder::new("one", &[], Type::Int);
let c = one.iconst(1);
one.ret(Some(c));
let mut compiler = Compiler::new();
compiler.base_address(0x40_0000).entry("add");
compiler.add(&add.finish()).unwrap();
compiler.add(&one.finish()).unwrap();
let image = compiler.link().unwrap();
// `add` is the entry, placed first at the base address; `one` follows it.
assert_eq!(image.entry(), Some(0x40_0000));
assert_eq!(image.symbol("add"), Some(0x40_0000));
assert!(image.symbol("one").unwrap() > 0x40_0000);Implementations§
Source§impl Compiler
impl Compiler
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates an empty compiler with the default configuration: base address 0
and no entry point. Same as Compiler::default.
Sourcepub fn base_address(&mut self, addr: u64) -> &mut Self
pub fn base_address(&mut self, addr: u64) -> &mut Self
Sets the address the image is laid out from. The first function is placed here and the rest follow; every resolved symbol address is relative to it.
§Examples
use aot_lang::Compiler;
use ir_lang::{Builder, Type};
let mut f = Builder::new("f", &[], Type::Unit);
f.ret(None);
let mut compiler = Compiler::new();
compiler.base_address(0x1000);
compiler.add(&f.finish()).unwrap();
assert_eq!(compiler.link().unwrap().symbol("f"), Some(0x1000));Sourcepub fn entry(&mut self, symbol: impl Into<String>) -> &mut Self
pub fn entry(&mut self, symbol: impl Into<String>) -> &mut Self
Sets the symbol whose address becomes the image’s entry point. The symbol
must name a function that is added before link, or the
link fails with AotError::Link.
§Examples
use aot_lang::Compiler;
use ir_lang::{Builder, Type};
let mut main = Builder::new("main", &[], Type::Unit);
main.ret(None);
let mut compiler = Compiler::new();
compiler.entry("main");
compiler.add(&main.finish()).unwrap();
assert_eq!(compiler.link().unwrap().entry(), Some(0));Sourcepub fn add(&mut self, func: &Function) -> Result<&mut Self, AotError>
pub fn add(&mut self, func: &Function) -> Result<&mut Self, AotError>
Compiles func to object code and appends it to the image being built.
The function is lowered immediately, so a malformed one is reported here
rather than deferred to link. Functions keep the order in
which they are added, which is the order they are placed in the image.
§Errors
Returns AotError::Codegen if func does not pass Function::validate.
§Examples
use aot_lang::Compiler;
use ir_lang::{Builder, Type};
let mut compiler = Compiler::new();
for name in ["a", "b", "c"] {
let mut f = Builder::new(name, &[], Type::Unit);
f.ret(None);
compiler.add(&f.finish()).unwrap();
}
assert_eq!(compiler.link().unwrap().symbols().count(), 3);Sourcepub fn link(&self) -> Result<Image, AotError>
pub fn link(&self) -> Result<Image, AotError>
Links every added function into one Image.
The functions are placed end to end from the base address, each defining a symbol under its name, and the entry point — if one was set — resolves to its address.
§Errors
Returns AotError::Link if two functions share a name
(LinkError::DuplicateSymbol), or if the configured entry point was never
added (LinkError::UndefinedEntry).
§Examples
use aot_lang::Compiler;
use ir_lang::{Builder, Type};
let mut f = Builder::new("f", &[], Type::Unit);
f.ret(None);
let mut compiler = Compiler::new();
compiler.add(&f.finish()).unwrap();
let image = compiler.link().unwrap();
assert_eq!(image.len(), 1); // one `.text` section