mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
only unwrap lambda set at the last moment
This commit is contained in:
parent
22722a3cf4
commit
bd7ce52e26
2 changed files with 46 additions and 44 deletions
|
@ -10,7 +10,7 @@ use inkwell::types::{BasicType, BasicTypeEnum};
|
|||
use inkwell::values::{BasicValue, BasicValueEnum, CallSiteValue, FunctionValue, InstructionValue};
|
||||
use inkwell::AddressSpace;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_mono::layout::{Layout, LayoutIds, UnionLayout};
|
||||
use roc_mono::layout::{LambdaSet, Layout, LayoutIds, UnionLayout};
|
||||
|
||||
pub fn call_bitcode_fn<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
|
@ -189,7 +189,7 @@ fn build_has_tag_id_help<'a, 'ctx, 'env>(
|
|||
pub fn build_transform_caller<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
function: FunctionValue<'ctx>,
|
||||
closure_data_layout: Layout<'a>,
|
||||
closure_data_layout: LambdaSet<'a>,
|
||||
argument_layouts: &[Layout<'a>],
|
||||
) -> FunctionValue<'ctx> {
|
||||
let fn_name: &str = &format!(
|
||||
|
@ -212,7 +212,7 @@ pub fn build_transform_caller<'a, 'ctx, 'env>(
|
|||
fn build_transform_caller_help<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
roc_function: FunctionValue<'ctx>,
|
||||
closure_data_layout: Layout<'a>,
|
||||
closure_data_layout: LambdaSet<'a>,
|
||||
argument_layouts: &[Layout<'a>],
|
||||
fn_name: &str,
|
||||
) -> FunctionValue<'ctx> {
|
||||
|
@ -270,7 +270,7 @@ fn build_transform_caller_help<'a, 'ctx, 'env>(
|
|||
arguments_cast.push(argument);
|
||||
}
|
||||
|
||||
match closure_data_layout {
|
||||
match closure_data_layout.runtime_representation() {
|
||||
Layout::Struct(&[]) => {
|
||||
// nothing to add
|
||||
}
|
||||
|
@ -529,7 +529,7 @@ pub fn build_eq_wrapper<'a, 'ctx, 'env>(
|
|||
pub fn build_compare_wrapper<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
roc_function: FunctionValue<'ctx>,
|
||||
closure_data_layout: Layout<'a>,
|
||||
closure_data_layout: LambdaSet<'a>,
|
||||
layout: &Layout<'a>,
|
||||
) -> FunctionValue<'ctx> {
|
||||
let block = env.builder.get_insert_block().expect("to be in a function");
|
||||
|
@ -595,7 +595,7 @@ pub fn build_compare_wrapper<'a, 'ctx, 'env>(
|
|||
|
||||
let default = [value1, value2];
|
||||
|
||||
let arguments_cast = match closure_data_layout {
|
||||
let arguments_cast = match closure_data_layout.runtime_representation() {
|
||||
Layout::Struct(&[]) => {
|
||||
// nothing to add
|
||||
&default
|
||||
|
|
|
@ -2609,6 +2609,18 @@ pub fn load_symbol_and_layout<'a, 'ctx, 'b>(
|
|||
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_symbol_and_lambda_set<'a, 'ctx, 'b>(
|
||||
scope: &'b Scope<'a, 'ctx>,
|
||||
symbol: &Symbol,
|
||||
) -> (BasicValueEnum<'ctx>, LambdaSet<'a>) {
|
||||
match scope.get(symbol) {
|
||||
Some((Layout::LambdaSet(lambda_set), ptr)) => (*ptr, *lambda_set),
|
||||
Some((other, ptr)) => panic!("Not a lambda set: {:?}, {:?}", other, ptr),
|
||||
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
|
||||
}
|
||||
}
|
||||
|
||||
fn access_index_struct_value<'ctx>(
|
||||
builder: &Builder<'ctx>,
|
||||
from_value: StructValue<'ctx>,
|
||||
|
@ -4102,31 +4114,26 @@ fn roc_function_call<'a, 'ctx, 'env>(
|
|||
layout_ids: &mut LayoutIds<'a>,
|
||||
transform: FunctionValue<'ctx>,
|
||||
closure_data: BasicValueEnum<'ctx>,
|
||||
closure_data_layout: Layout<'a>,
|
||||
lambda_set: LambdaSet<'a>,
|
||||
closure_data_is_owned: bool,
|
||||
argument_layouts: &[Layout<'a>],
|
||||
) -> RocFunctionCall<'ctx> {
|
||||
use crate::llvm::bitcode::{build_inc_n_wrapper, build_transform_caller};
|
||||
|
||||
let closure_data_layout = match closure_data_layout {
|
||||
Layout::LambdaSet(lambda_set) => lambda_set.runtime_representation(),
|
||||
_ => panic!("closure argument is not a lambda set!"),
|
||||
};
|
||||
|
||||
let closure_data_ptr = env
|
||||
.builder
|
||||
.build_alloca(closure_data.get_type(), "closure_data_ptr");
|
||||
env.builder.build_store(closure_data_ptr, closure_data);
|
||||
|
||||
let stepper_caller =
|
||||
build_transform_caller(env, transform, closure_data_layout, argument_layouts)
|
||||
.as_global_value()
|
||||
.as_pointer_value();
|
||||
|
||||
let inc_closure_data = build_inc_n_wrapper(env, layout_ids, &closure_data_layout)
|
||||
let stepper_caller = build_transform_caller(env, transform, lambda_set, argument_layouts)
|
||||
.as_global_value()
|
||||
.as_pointer_value();
|
||||
|
||||
let inc_closure_data =
|
||||
build_inc_n_wrapper(env, layout_ids, &lambda_set.runtime_representation())
|
||||
.as_global_value()
|
||||
.as_pointer_value();
|
||||
|
||||
let closure_data_is_owned = env
|
||||
.context
|
||||
.bool_type()
|
||||
|
@ -4180,7 +4187,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let function = passed_function_at_index!(2);
|
||||
|
||||
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[3]);
|
||||
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[3]);
|
||||
|
||||
match list_layout {
|
||||
Layout::Builtin(Builtin::EmptyList) => default,
|
||||
|
@ -4192,7 +4199,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
*closure_layout,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
);
|
||||
|
@ -4222,7 +4229,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let function = passed_function_at_index!(1);
|
||||
|
||||
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[2]);
|
||||
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]);
|
||||
|
||||
match (list_layout, return_layout) {
|
||||
(Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
|
||||
|
@ -4237,7 +4244,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
*closure_layout,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
);
|
||||
|
@ -4254,7 +4261,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
let (list2, list2_layout) = load_symbol_and_layout(scope, &args[1]);
|
||||
|
||||
let function = passed_function_at_index!(2);
|
||||
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[3]);
|
||||
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[3]);
|
||||
|
||||
match (list1_layout, list2_layout, return_layout) {
|
||||
(
|
||||
|
@ -4269,7 +4276,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
*closure_layout,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
);
|
||||
|
@ -4298,7 +4305,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
let (list3, list3_layout) = load_symbol_and_layout(scope, &args[2]);
|
||||
|
||||
let function = passed_function_at_index!(3);
|
||||
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[4]);
|
||||
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[4]);
|
||||
|
||||
match (list1_layout, list2_layout, list3_layout, return_layout) {
|
||||
(
|
||||
|
@ -4315,7 +4322,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
*closure_layout,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
);
|
||||
|
@ -4347,7 +4354,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let function = passed_function_at_index!(1);
|
||||
|
||||
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[2]);
|
||||
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]);
|
||||
|
||||
match (list_layout, return_layout) {
|
||||
(Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
|
||||
|
@ -4362,7 +4369,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
*closure_layout,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
);
|
||||
|
@ -4380,7 +4387,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let function = passed_function_at_index!(1);
|
||||
|
||||
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[2]);
|
||||
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]);
|
||||
|
||||
match list_layout {
|
||||
Layout::Builtin(Builtin::EmptyList) => empty_list(env),
|
||||
|
@ -4392,7 +4399,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
*closure_layout,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
);
|
||||
|
@ -4410,7 +4417,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let function = passed_function_at_index!(1);
|
||||
|
||||
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[2]);
|
||||
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]);
|
||||
|
||||
match (list_layout, return_layout) {
|
||||
(_, Layout::Builtin(Builtin::EmptyList))
|
||||
|
@ -4426,7 +4433,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
*closure_layout,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
);
|
||||
|
@ -4454,7 +4461,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let function = passed_function_at_index!(1);
|
||||
|
||||
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[2]);
|
||||
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]);
|
||||
|
||||
match (list_layout, return_layout) {
|
||||
(_, Layout::Builtin(Builtin::EmptyList))
|
||||
|
@ -4470,7 +4477,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
*closure_layout,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
);
|
||||
|
@ -4507,7 +4514,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let function = passed_function_at_index!(1);
|
||||
|
||||
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[2]);
|
||||
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]);
|
||||
|
||||
match list_layout {
|
||||
Layout::Builtin(Builtin::EmptyList) => empty_list(env),
|
||||
|
@ -4516,13 +4523,8 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let argument_layouts = &[**element_layout, **element_layout];
|
||||
|
||||
let closure_data_layout = match closure_layout {
|
||||
Layout::LambdaSet(lambda_set) => lambda_set.runtime_representation(),
|
||||
_ => panic!("closure argument is not a lambda set!"),
|
||||
};
|
||||
|
||||
let compare_wrapper =
|
||||
build_compare_wrapper(env, function, closure_data_layout, element_layout)
|
||||
build_compare_wrapper(env, function, closure_layout, element_layout)
|
||||
.as_global_value()
|
||||
.as_pointer_value();
|
||||
|
||||
|
@ -4531,7 +4533,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
*closure_layout,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
);
|
||||
|
@ -4553,7 +4555,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
let (dict, dict_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||
let (default, default_layout) = load_symbol_and_layout(scope, &args[1]);
|
||||
let function = passed_function_at_index!(2);
|
||||
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[3]);
|
||||
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[3]);
|
||||
|
||||
match dict_layout {
|
||||
Layout::Builtin(Builtin::EmptyDict) => {
|
||||
|
@ -4568,7 +4570,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
|||
layout_ids,
|
||||
function,
|
||||
closure,
|
||||
*closure_layout,
|
||||
closure_layout,
|
||||
function_owns_closure_data,
|
||||
argument_layouts,
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue