Skip to main content

Compiler

Struct Compiler 

Source
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

Source

pub fn new() -> Self

Creates an empty compiler with the default configuration: base address 0 and no entry point. Same as Compiler::default.

Source

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));
Source

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));
Source

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);

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

Trait Implementations§

Source§

impl Default for Compiler

Source§

fn default() -> Compiler

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.