Erased functions do not take a func spec

This commit is contained in:
Ayaz Hafiz 2023-07-06 15:08:07 -05:00
parent 7c8e7bbea3
commit 13d1232f7d
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
9 changed files with 185 additions and 28 deletions

View file

@ -0,0 +1,80 @@
use bumpalo::collections::CollectIn;
use inkwell::{
types::{FunctionType, PointerType},
values::{BasicValueEnum, FunctionValue},
AddressSpace,
};
use roc_error_macros::internal_error;
use roc_mono::layout::{
FunctionPointer, InLayout, LambdaName, LayoutInterner, LayoutRepr, STLayoutInterner,
};
use super::{
build::{function_value_by_func_spec, Env, FuncBorrowSpec, FunctionSpec, RocReturn},
convert::basic_type_from_layout,
};
fn function_type<'a, 'ctx>(
env: &Env<'a, 'ctx, '_>,
layout_interner: &STLayoutInterner<'a>,
function_pointer: FunctionPointer<'a>,
) -> FunctionType<'ctx> {
let FunctionPointer { args, ret } = function_pointer;
let args = args
.iter()
.map(|arg| basic_type_from_layout(env, layout_interner, layout_interner.get_repr(*arg)));
let ret_repr = layout_interner.get_repr(ret);
let ret = basic_type_from_layout(env, layout_interner, ret_repr);
let roc_return = RocReturn::from_layout(layout_interner, ret_repr);
let fn_spec = FunctionSpec::fastcc(env, roc_return, ret, args.collect_in(env.arena));
fn_spec.typ
}
pub fn pointer_type<'a, 'ctx>(
env: &Env<'a, 'ctx, '_>,
layout_interner: &STLayoutInterner<'a>,
function_pointer: FunctionPointer<'a>,
) -> PointerType<'ctx> {
let function_type = function_type(env, layout_interner, function_pointer);
function_type.ptr_type(AddressSpace::default())
}
#[track_caller]
pub fn pointer_type_expecting_layout<'a, 'ctx>(
env: &Env<'a, 'ctx, '_>,
layout_interner: &STLayoutInterner<'a>,
layout: InLayout<'a>,
) -> PointerType<'ctx> {
let function_pointer = match layout_interner.get_repr(layout) {
LayoutRepr::FunctionPointer(function_pointer) => function_pointer,
_ => internal_error!("expected function pointer"),
};
pointer_type(env, layout_interner, function_pointer)
}
pub fn build<'a, 'ctx>(
env: &Env<'a, 'ctx, '_>,
layout_interner: &STLayoutInterner<'a>,
lambda_name: LambdaName<'a>,
function_ptr_type: PointerType<'ctx>,
) -> BasicValueEnum<'ctx> {
let alloca = env
.builder
.build_alloca(function_ptr_type, "function_pointer_alloca");
let func_value: FunctionValue<'ctx> = function_value_by_func_spec(
env,
FuncBorrowSpec::Erased,
lambda_name.name(),
lambda_name.niche(),
);
env.builder
.build_store(alloca, func_value.as_global_value().as_pointer_value());
alloca.into()
}