mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
gen_dev: add basic function support
This commit is contained in:
parent
cc81c6e5ba
commit
846c82961f
6 changed files with 164 additions and 45 deletions
|
@ -4,11 +4,11 @@
|
|||
|
||||
use bumpalo::{collections::Vec, Bump};
|
||||
use roc_collections::all::{MutMap, MutSet};
|
||||
use roc_module::ident::TagName;
|
||||
use roc_module::ident::{ModuleName, TagName};
|
||||
use roc_module::low_level::LowLevel;
|
||||
use roc_module::symbol::{Interns, Symbol};
|
||||
use roc_mono::ir::{CallType, Expr, JoinPointId, Literal, Proc, Stmt};
|
||||
use roc_mono::layout::{Builtin, Layout};
|
||||
use roc_mono::layout::{Builtin, Layout, LayoutIds};
|
||||
use target_lexicon::Triple;
|
||||
|
||||
mod generic64;
|
||||
|
@ -33,8 +33,9 @@ const INLINED_SYMBOLS: [Symbol; 4] = [
|
|||
|
||||
// These relocations likely will need a length.
|
||||
// They may even need more definition, but this should be at least good enough for how we will use elf.
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub enum Relocation<'a> {
|
||||
pub enum Relocation {
|
||||
LocalData {
|
||||
offset: u64,
|
||||
// This should probably technically be a bumpalo::Vec.
|
||||
|
@ -43,11 +44,11 @@ pub enum Relocation<'a> {
|
|||
},
|
||||
LinkedFunction {
|
||||
offset: u64,
|
||||
name: &'a str,
|
||||
name: String,
|
||||
},
|
||||
LinkedData {
|
||||
offset: u64,
|
||||
name: &'a str,
|
||||
name: String,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -67,10 +68,10 @@ where
|
|||
/// finalize does setup because things like stack size and jump locations are not know until the function is written.
|
||||
/// For example, this can store the frame pionter and setup stack space.
|
||||
/// finalize is run at the end of build_proc when all internal code is finalized.
|
||||
fn finalize(&mut self) -> Result<(&'a [u8], &[&Relocation]), String>;
|
||||
fn finalize(&mut self) -> Result<(&'a [u8], &[Relocation]), String>;
|
||||
|
||||
/// build_proc creates a procedure and outputs it to the wrapped object writer.
|
||||
fn build_proc(&mut self, proc: Proc<'a>) -> Result<(&'a [u8], &[&Relocation]), String> {
|
||||
fn build_proc(&mut self, proc: Proc<'a>) -> Result<(&'a [u8], &[Relocation]), String> {
|
||||
self.reset();
|
||||
// TODO: let the backend know of all the arguments.
|
||||
// let start = std::time::Instant::now();
|
||||
|
@ -136,7 +137,12 @@ where
|
|||
arguments,
|
||||
}) => {
|
||||
match call_type {
|
||||
CallType::ByName { name: func_sym, .. } => {
|
||||
CallType::ByName {
|
||||
name: func_sym,
|
||||
arg_layouts,
|
||||
ret_layout,
|
||||
..
|
||||
} => {
|
||||
match *func_sym {
|
||||
Symbol::NUM_ABS => {
|
||||
// Instead of calling the function, just inline it.
|
||||
|
@ -154,6 +160,15 @@ where
|
|||
// Instead of calling the function, just inline it.
|
||||
self.build_run_low_level(sym, &LowLevel::Eq, arguments, layout)
|
||||
}
|
||||
x if x
|
||||
.module_string(&self.env().interns)
|
||||
.starts_with(ModuleName::APP) =>
|
||||
{
|
||||
let fn_name = LayoutIds::default()
|
||||
.get(*func_sym, layout)
|
||||
.to_symbol_string(*func_sym, &self.env().interns);
|
||||
self.build_fn_call(sym, fn_name, arguments, arg_layouts, ret_layout)
|
||||
}
|
||||
x => Err(format!("the function, {:?}, is not yet implemented", x)),
|
||||
}
|
||||
}
|
||||
|
@ -218,6 +233,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// build_fn_call creates a call site for a function.
|
||||
/// This includes dealing with things like saving regs and propagating the returned value.
|
||||
fn build_fn_call(
|
||||
&mut self,
|
||||
dst: &Symbol,
|
||||
fn_name: String,
|
||||
args: &'a [Symbol],
|
||||
arg_layouts: &[Layout<'a>],
|
||||
ret_layout: &Layout<'a>,
|
||||
) -> Result<(), String>;
|
||||
|
||||
/// build_num_abs_i64 stores the absolute value of src into dst.
|
||||
/// It only deals with inputs and outputs of i64 type.
|
||||
fn build_num_abs_i64(&mut self, dst: &Symbol, src: &Symbol) -> Result<(), String>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue