Merge remote-tracking branch 'origin/main' into Frame-Limited

This commit is contained in:
J.Teeuwissen 2023-04-12 09:08:40 +02:00
commit a3cea59bb6
No known key found for this signature in database
GPG key ID: DB5F7A1ED8D478AD
63 changed files with 3552 additions and 846 deletions

View file

@ -18,7 +18,7 @@ use roc_mono::ir::{
SelfRecursive, Stmt,
};
use roc_mono::layout::{
Builtin, InLayout, Layout, LayoutId, LayoutIds, LayoutInterner, STLayoutInterner, TagIdIntType,
Builtin, InLayout, Layout, LayoutIds, LayoutInterner, STLayoutInterner, TagIdIntType,
UnionLayout,
};
use roc_mono::list_element_layout;
@ -79,8 +79,40 @@ trait Backend<'a> {
&mut CodeGenHelp<'a>,
);
fn symbol_to_string(&self, symbol: Symbol, layout_id: LayoutId) -> String {
layout_id.to_symbol_string(symbol, self.interns())
fn function_symbol_to_string<'b, I>(
&self,
symbol: Symbol,
arguments: I,
_lambda_set: Option<InLayout>,
result: InLayout,
) -> String
where
I: Iterator<Item = InLayout<'b>>,
{
use std::hash::{BuildHasher, Hash, Hasher};
// NOTE: due to randomness, this will not be consistent between runs
let mut state = roc_collections::all::BuildHasher::default().build_hasher();
for a in arguments {
a.hash(&mut state);
}
// lambda set should not matter; it should already be added as an argument
// lambda_set.hash(&mut state);
result.hash(&mut state);
let interns = self.interns();
let ident_string = symbol.as_str(interns);
let module_string = interns.module_ids.get_name(symbol.module_id()).unwrap();
// the functions from the generates #help module (refcounting, equality) is always suffixed
// with 1. That is fine, they are always unique anyway.
if ident_string.contains("#help") {
format!("{}_{}_1", module_string, ident_string)
} else {
format!("{}_{}_{}", module_string, ident_string, state.finish())
}
}
fn defined_in_app_module(&self, symbol: Symbol) -> bool {
@ -119,8 +151,13 @@ trait Backend<'a> {
proc: Proc<'a>,
layout_ids: &mut LayoutIds<'a>,
) -> (Vec<u8>, Vec<Relocation>, Vec<'a, (Symbol, String)>) {
let layout_id = layout_ids.get(proc.name.name(), &proc.ret_layout);
let proc_name = self.symbol_to_string(proc.name.name(), layout_id);
let proc_name = self.function_symbol_to_string(
proc.name.name(),
proc.args.iter().map(|t| t.0),
proc.closure_data_layout,
proc.ret_layout,
);
self.reset(proc_name, proc.is_self_recursive);
self.load_args(proc.args, &proc.ret_layout);
for (layout, sym) in proc.args {
@ -213,6 +250,7 @@ trait Backend<'a> {
self.free_symbols(stmt);
}
Stmt::Jump(id, args) => {
self.load_literal_symbols(args);
let mut arg_layouts: bumpalo::collections::Vec<InLayout<'a>> =
bumpalo::vec![in self.env().arena];
arg_layouts.reserve(args.len());
@ -303,8 +341,12 @@ trait Backend<'a> {
);
}
let layout_id = LayoutIds::default().get(func_sym.name(), layout);
let fn_name = self.symbol_to_string(func_sym.name(), layout_id);
let fn_name = self.function_symbol_to_string(
func_sym.name(),
arg_layouts.iter().copied(),
None,
*ret_layout,
);
// Now that the arguments are needed, load them if they are literals.
self.load_literal_symbols(arguments);
@ -1080,8 +1122,12 @@ trait Backend<'a> {
}
Symbol::LIST_GET | Symbol::LIST_SET | Symbol::LIST_REPLACE | Symbol::LIST_APPEND => {
// TODO: This is probably simple enough to be worth inlining.
let layout_id = LayoutIds::default().get(func_sym, ret_layout);
let fn_name = self.symbol_to_string(func_sym, layout_id);
let fn_name = self.function_symbol_to_string(
func_sym,
arg_layouts.iter().copied(),
None,
*ret_layout,
);
// Now that the arguments are needed, load them if they are literals.
self.load_literal_symbols(args);
self.build_fn_call(sym, fn_name, args, arg_layouts, ret_layout)
@ -1100,8 +1146,12 @@ trait Backend<'a> {
}
Symbol::STR_IS_VALID_SCALAR => {
// just call the function
let layout_id = LayoutIds::default().get(func_sym, ret_layout);
let fn_name = self.symbol_to_string(func_sym, layout_id);
let fn_name = self.function_symbol_to_string(
func_sym,
arg_layouts.iter().copied(),
None,
*ret_layout,
);
// Now that the arguments are needed, load them if they are literals.
self.load_literal_symbols(args);
self.build_fn_call(sym, fn_name, args, arg_layouts, ret_layout)
@ -1110,8 +1160,12 @@ trait Backend<'a> {
eprintln!("maybe {other:?} should have a custom implementation?");
// just call the function
let layout_id = LayoutIds::default().get(func_sym, ret_layout);
let fn_name = self.symbol_to_string(func_sym, layout_id);
let fn_name = self.function_symbol_to_string(
func_sym,
arg_layouts.iter().copied(),
None,
*ret_layout,
);
// Now that the arguments are needed, load them if they are literals.
self.load_literal_symbols(args);
self.build_fn_call(sym, fn_name, args, arg_layouts, ret_layout)
@ -1130,6 +1184,9 @@ trait Backend<'a> {
ret_layout: &InLayout<'a>,
);
/// Move a returned value into `dst`
fn move_return_value(&mut self, dst: &Symbol, ret_layout: &InLayout<'a>);
/// build_num_abs stores the absolute value of src into dst.
fn build_num_abs(&mut self, dst: &Symbol, src: &Symbol, layout: &InLayout<'a>);