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
65
compiler/gen_dev/src/lib.rs
Normal file
65
compiler/gen_dev/src/lib.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
#![warn(clippy::all, clippy::dbg_macro)]
|
||||
// I'm skeptical that clippy:large_enum_variant is a good lint to have globally enabled.
|
||||
//
|
||||
// It warns about a performance problem where the only quick remediation is
|
||||
// to allocate more on the heap, which has lots of tradeoffs - including making it
|
||||
// long-term unclear which allocations *need* to happen for compilation's sake
|
||||
// (e.g. recursive structures) versus those which were only added to appease clippy.
|
||||
//
|
||||
// Effectively optimizing data struture memory layout isn't a quick fix,
|
||||
// and encouraging shortcuts here creates bad incentives. I would rather temporarily
|
||||
// re-enable this when working on performance optimizations than have it block PRs.
|
||||
#![allow(clippy::large_enum_variant)]
|
||||
|
||||
use bumpalo::Bump;
|
||||
use object::write::Object;
|
||||
use roc_collections::all::{MutMap, MutSet};
|
||||
use roc_module::symbol::{Interns, Symbol};
|
||||
use roc_mono::ir::Proc;
|
||||
use roc_mono::layout::Layout;
|
||||
use target_lexicon::{BinaryFormat, Triple};
|
||||
|
||||
pub mod elf;
|
||||
pub mod run_roc;
|
||||
pub mod x86_64;
|
||||
|
||||
pub struct Env<'a> {
|
||||
pub arena: &'a Bump,
|
||||
pub interns: Interns,
|
||||
pub exposed_to_host: MutSet<Symbol>,
|
||||
}
|
||||
|
||||
/// build_module is the high level builder/delegator.
|
||||
/// It takes the request to build a module and output the object file for the module.
|
||||
pub fn build_module<'a>(
|
||||
env: &'a Env,
|
||||
target: &Triple,
|
||||
procedures: MutMap<(Symbol, Layout<'a>), Proc<'a>>,
|
||||
) -> Result<Object, String> {
|
||||
match target.binary_format {
|
||||
BinaryFormat::Elf => elf::build_module(env, target, procedures),
|
||||
x => Err(format! {
|
||||
"the binary format, {:?}, is not yet implemented",
|
||||
x}),
|
||||
}
|
||||
}
|
||||
|
||||
trait Backend {
|
||||
/// new creates a new backend that will output to the specific Object.
|
||||
fn new() -> Self;
|
||||
|
||||
/// reset resets any registers or other values that may be occupied at the end of a procedure.
|
||||
fn reset(&mut self);
|
||||
|
||||
/// build_proc creates a procedure and outputs it to the wrapped object writer.
|
||||
/// This will need to return the list of relocations because they have to be added differently based on file format.
|
||||
/// Also, assembly will of course be generated by individual calls on backend like may setup_stack.
|
||||
fn build_proc<'a>(&mut self, env: &'a Env, _proc: Proc<'a>) -> &'a [u8] {
|
||||
let mut out = bumpalo::vec![in env.arena; 0x55, 0x48, 0x89, 0xE5];
|
||||
let body = [0xb8, 0x06, 0x00, 0x00, 0x00];
|
||||
out.extend(body.iter());
|
||||
out.push(0x5D);
|
||||
out.push(0xC3);
|
||||
out.into_bump_slice()
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue