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::values::{BasicValue, BasicValueEnum, CallSiteValue, FunctionValue, InstructionValue};
|
||||||
use inkwell::AddressSpace;
|
use inkwell::AddressSpace;
|
||||||
use roc_module::symbol::Symbol;
|
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>(
|
pub fn call_bitcode_fn<'a, 'ctx, 'env>(
|
||||||
env: &Env<'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>(
|
pub fn build_transform_caller<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
function: FunctionValue<'ctx>,
|
function: FunctionValue<'ctx>,
|
||||||
closure_data_layout: Layout<'a>,
|
closure_data_layout: LambdaSet<'a>,
|
||||||
argument_layouts: &[Layout<'a>],
|
argument_layouts: &[Layout<'a>],
|
||||||
) -> FunctionValue<'ctx> {
|
) -> FunctionValue<'ctx> {
|
||||||
let fn_name: &str = &format!(
|
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>(
|
fn build_transform_caller_help<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
roc_function: FunctionValue<'ctx>,
|
roc_function: FunctionValue<'ctx>,
|
||||||
closure_data_layout: Layout<'a>,
|
closure_data_layout: LambdaSet<'a>,
|
||||||
argument_layouts: &[Layout<'a>],
|
argument_layouts: &[Layout<'a>],
|
||||||
fn_name: &str,
|
fn_name: &str,
|
||||||
) -> FunctionValue<'ctx> {
|
) -> FunctionValue<'ctx> {
|
||||||
|
@ -270,7 +270,7 @@ fn build_transform_caller_help<'a, 'ctx, 'env>(
|
||||||
arguments_cast.push(argument);
|
arguments_cast.push(argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
match closure_data_layout {
|
match closure_data_layout.runtime_representation() {
|
||||||
Layout::Struct(&[]) => {
|
Layout::Struct(&[]) => {
|
||||||
// nothing to add
|
// nothing to add
|
||||||
}
|
}
|
||||||
|
@ -529,7 +529,7 @@ pub fn build_eq_wrapper<'a, 'ctx, 'env>(
|
||||||
pub fn build_compare_wrapper<'a, 'ctx, 'env>(
|
pub fn build_compare_wrapper<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
roc_function: FunctionValue<'ctx>,
|
roc_function: FunctionValue<'ctx>,
|
||||||
closure_data_layout: Layout<'a>,
|
closure_data_layout: LambdaSet<'a>,
|
||||||
layout: &Layout<'a>,
|
layout: &Layout<'a>,
|
||||||
) -> FunctionValue<'ctx> {
|
) -> FunctionValue<'ctx> {
|
||||||
let block = env.builder.get_insert_block().expect("to be in a function");
|
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 default = [value1, value2];
|
||||||
|
|
||||||
let arguments_cast = match closure_data_layout {
|
let arguments_cast = match closure_data_layout.runtime_representation() {
|
||||||
Layout::Struct(&[]) => {
|
Layout::Struct(&[]) => {
|
||||||
// nothing to add
|
// nothing to add
|
||||||
&default
|
&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),
|
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>(
|
fn access_index_struct_value<'ctx>(
|
||||||
builder: &Builder<'ctx>,
|
builder: &Builder<'ctx>,
|
||||||
from_value: StructValue<'ctx>,
|
from_value: StructValue<'ctx>,
|
||||||
|
@ -4102,31 +4114,26 @@ fn roc_function_call<'a, 'ctx, 'env>(
|
||||||
layout_ids: &mut LayoutIds<'a>,
|
layout_ids: &mut LayoutIds<'a>,
|
||||||
transform: FunctionValue<'ctx>,
|
transform: FunctionValue<'ctx>,
|
||||||
closure_data: BasicValueEnum<'ctx>,
|
closure_data: BasicValueEnum<'ctx>,
|
||||||
closure_data_layout: Layout<'a>,
|
lambda_set: LambdaSet<'a>,
|
||||||
closure_data_is_owned: bool,
|
closure_data_is_owned: bool,
|
||||||
argument_layouts: &[Layout<'a>],
|
argument_layouts: &[Layout<'a>],
|
||||||
) -> RocFunctionCall<'ctx> {
|
) -> RocFunctionCall<'ctx> {
|
||||||
use crate::llvm::bitcode::{build_inc_n_wrapper, build_transform_caller};
|
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
|
let closure_data_ptr = env
|
||||||
.builder
|
.builder
|
||||||
.build_alloca(closure_data.get_type(), "closure_data_ptr");
|
.build_alloca(closure_data.get_type(), "closure_data_ptr");
|
||||||
env.builder.build_store(closure_data_ptr, closure_data);
|
env.builder.build_store(closure_data_ptr, closure_data);
|
||||||
|
|
||||||
let stepper_caller =
|
let stepper_caller = build_transform_caller(env, transform, lambda_set, argument_layouts)
|
||||||
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)
|
|
||||||
.as_global_value()
|
.as_global_value()
|
||||||
.as_pointer_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
|
let closure_data_is_owned = env
|
||||||
.context
|
.context
|
||||||
.bool_type()
|
.bool_type()
|
||||||
|
@ -4180,7 +4187,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let function = passed_function_at_index!(2);
|
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 {
|
match list_layout {
|
||||||
Layout::Builtin(Builtin::EmptyList) => default,
|
Layout::Builtin(Builtin::EmptyList) => default,
|
||||||
|
@ -4192,7 +4199,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
function,
|
function,
|
||||||
closure,
|
closure,
|
||||||
*closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
);
|
);
|
||||||
|
@ -4222,7 +4229,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let function = passed_function_at_index!(1);
|
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) {
|
match (list_layout, return_layout) {
|
||||||
(Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
|
(Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
|
||||||
|
@ -4237,7 +4244,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
function,
|
function,
|
||||||
closure,
|
closure,
|
||||||
*closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
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 (list2, list2_layout) = load_symbol_and_layout(scope, &args[1]);
|
||||||
|
|
||||||
let function = passed_function_at_index!(2);
|
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) {
|
match (list1_layout, list2_layout, return_layout) {
|
||||||
(
|
(
|
||||||
|
@ -4269,7 +4276,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
function,
|
function,
|
||||||
closure,
|
closure,
|
||||||
*closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
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 (list3, list3_layout) = load_symbol_and_layout(scope, &args[2]);
|
||||||
|
|
||||||
let function = passed_function_at_index!(3);
|
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) {
|
match (list1_layout, list2_layout, list3_layout, return_layout) {
|
||||||
(
|
(
|
||||||
|
@ -4315,7 +4322,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
function,
|
function,
|
||||||
closure,
|
closure,
|
||||||
*closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
);
|
);
|
||||||
|
@ -4347,7 +4354,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let function = passed_function_at_index!(1);
|
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) {
|
match (list_layout, return_layout) {
|
||||||
(Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
|
(Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
|
||||||
|
@ -4362,7 +4369,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
function,
|
function,
|
||||||
closure,
|
closure,
|
||||||
*closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
);
|
);
|
||||||
|
@ -4380,7 +4387,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let function = passed_function_at_index!(1);
|
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 {
|
match list_layout {
|
||||||
Layout::Builtin(Builtin::EmptyList) => empty_list(env),
|
Layout::Builtin(Builtin::EmptyList) => empty_list(env),
|
||||||
|
@ -4392,7 +4399,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
function,
|
function,
|
||||||
closure,
|
closure,
|
||||||
*closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
);
|
);
|
||||||
|
@ -4410,7 +4417,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let function = passed_function_at_index!(1);
|
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) {
|
match (list_layout, return_layout) {
|
||||||
(_, Layout::Builtin(Builtin::EmptyList))
|
(_, Layout::Builtin(Builtin::EmptyList))
|
||||||
|
@ -4426,7 +4433,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
function,
|
function,
|
||||||
closure,
|
closure,
|
||||||
*closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
);
|
);
|
||||||
|
@ -4454,7 +4461,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let function = passed_function_at_index!(1);
|
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) {
|
match (list_layout, return_layout) {
|
||||||
(_, Layout::Builtin(Builtin::EmptyList))
|
(_, Layout::Builtin(Builtin::EmptyList))
|
||||||
|
@ -4470,7 +4477,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
function,
|
function,
|
||||||
closure,
|
closure,
|
||||||
*closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
);
|
);
|
||||||
|
@ -4507,7 +4514,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
|
|
||||||
let function = passed_function_at_index!(1);
|
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 {
|
match list_layout {
|
||||||
Layout::Builtin(Builtin::EmptyList) => empty_list(env),
|
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 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 =
|
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_global_value()
|
||||||
.as_pointer_value();
|
.as_pointer_value();
|
||||||
|
|
||||||
|
@ -4531,7 +4533,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
function,
|
function,
|
||||||
closure,
|
closure,
|
||||||
*closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
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 (dict, dict_layout) = load_symbol_and_layout(scope, &args[0]);
|
||||||
let (default, default_layout) = load_symbol_and_layout(scope, &args[1]);
|
let (default, default_layout) = load_symbol_and_layout(scope, &args[1]);
|
||||||
let function = passed_function_at_index!(2);
|
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 {
|
match dict_layout {
|
||||||
Layout::Builtin(Builtin::EmptyDict) => {
|
Layout::Builtin(Builtin::EmptyDict) => {
|
||||||
|
@ -4568,7 +4570,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
function,
|
function,
|
||||||
closure,
|
closure,
|
||||||
*closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue