mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 23:31:12 +00:00
Add base structure for dev compiler backend
Currently we only generate a single static function, but it is probably loaded and run with jit. This is the base to start generating proper code.
This commit is contained in:
parent
2204ee82d5
commit
86c3c0a409
10 changed files with 1341 additions and 20 deletions
73
compiler/gen_dev/src/elf.rs
Normal file
73
compiler/gen_dev/src/elf.rs
Normal file
|
@ -0,0 +1,73 @@
|
|||
use crate::x86_64::X86_64Backend;
|
||||
use crate::{Backend, Env};
|
||||
use bumpalo::collections::Vec;
|
||||
use object::write::{Object, StandardSection, Symbol, SymbolSection};
|
||||
use object::{
|
||||
Architecture, BinaryFormat, Endianness, SectionKind, SymbolFlags, SymbolKind, SymbolScope,
|
||||
};
|
||||
use roc_collections::all::MutMap;
|
||||
use roc_module::symbol;
|
||||
use roc_mono::ir::Proc;
|
||||
use roc_mono::layout::Layout;
|
||||
use target_lexicon::Triple;
|
||||
|
||||
const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
||||
pub fn build_module<'a>(
|
||||
env: &'a Env,
|
||||
target: &Triple,
|
||||
procedures: MutMap<(symbol::Symbol, Layout<'a>), Proc<'a>>,
|
||||
) -> Result<Object, String> {
|
||||
match target.architecture {
|
||||
target_lexicon::Architecture::X86_64 => {
|
||||
let mut output =
|
||||
Object::new(BinaryFormat::Elf, Architecture::X86_64, Endianness::Little);
|
||||
let text = output.section_id(StandardSection::Text);
|
||||
let comment = output.add_section(vec![], b"comment".to_vec(), SectionKind::OtherString);
|
||||
output.append_section_data(
|
||||
comment,
|
||||
format!("\0roc dev backend version {} \0", VERSION).as_bytes(),
|
||||
1,
|
||||
);
|
||||
|
||||
// Setup layout_ids for procedure calls.
|
||||
let mut layout_ids = roc_mono::layout::LayoutIds::default();
|
||||
let mut procs = Vec::with_capacity_in(procedures.len(), env.arena);
|
||||
for ((symbol, layout), proc) in procedures {
|
||||
let fn_name = layout_ids
|
||||
.get(symbol, &layout)
|
||||
.to_symbol_string(symbol, &env.interns);
|
||||
|
||||
let proc_symbol = Symbol {
|
||||
name: fn_name.as_bytes().to_vec(),
|
||||
value: 0,
|
||||
size: 0,
|
||||
kind: SymbolKind::Text,
|
||||
// TODO: Depending on whether we are building a static or dynamic lib, this should change.
|
||||
// We should use Dynamic -> anyone, Linkage -> static link, Compilation -> this module only.
|
||||
scope: if env.exposed_to_host.contains(&symbol) {
|
||||
SymbolScope::Dynamic
|
||||
} else {
|
||||
SymbolScope::Linkage
|
||||
},
|
||||
weak: false,
|
||||
section: SymbolSection::Section(text),
|
||||
flags: SymbolFlags::None,
|
||||
};
|
||||
let proc_id = output.add_symbol(proc_symbol);
|
||||
procs.push((proc_id, proc));
|
||||
}
|
||||
|
||||
// Build procedures.
|
||||
let mut backend: X86_64Backend = Backend::new();
|
||||
for (proc_id, proc) in procs {
|
||||
let proc_data = backend.build_proc(env, proc);
|
||||
output.add_symbol_data(proc_id, text, proc_data, 16);
|
||||
}
|
||||
Ok(output)
|
||||
}
|
||||
x => Err(format! {
|
||||
"the architecture, {:?}, is not yet implemented for elf",
|
||||
x}),
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue