mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
Merge pull request #2109 from rtfeldman/refactor-passed-function
refactor passed (to higher order lowlevel) funcion
This commit is contained in:
commit
e6bec46898
5 changed files with 95 additions and 88 deletions
|
@ -955,7 +955,7 @@ pub fn build_exp_call<'a, 'ctx, 'env>(
|
||||||
}
|
}
|
||||||
|
|
||||||
CallType::HigherOrder(higher_order) => {
|
CallType::HigherOrder(higher_order) => {
|
||||||
let bytes = higher_order.specialization_id.to_bytes();
|
let bytes = higher_order.passed_function.specialization_id.to_bytes();
|
||||||
let callee_var = CalleeSpecVar(&bytes);
|
let callee_var = CalleeSpecVar(&bytes);
|
||||||
let func_spec = func_spec_solutions.callee_spec(callee_var).unwrap();
|
let func_spec = func_spec_solutions.callee_spec(callee_var).unwrap();
|
||||||
|
|
||||||
|
@ -4686,20 +4686,23 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
func_spec: FuncSpec,
|
func_spec: FuncSpec,
|
||||||
higher_order: &HigherOrderLowLevel<'a>,
|
higher_order: &HigherOrderLowLevel<'a>,
|
||||||
) -> BasicValueEnum<'ctx> {
|
) -> BasicValueEnum<'ctx> {
|
||||||
|
use roc_mono::ir::PassedFunction;
|
||||||
use roc_mono::low_level::HigherOrder::*;
|
use roc_mono::low_level::HigherOrder::*;
|
||||||
|
|
||||||
let HigherOrderLowLevel {
|
let HigherOrderLowLevel {
|
||||||
op,
|
op,
|
||||||
arg_layouts: argument_layouts,
|
passed_function,
|
||||||
ret_layout: result_layout,
|
|
||||||
function_owns_closure_data,
|
|
||||||
function_name,
|
|
||||||
function_env,
|
|
||||||
..
|
..
|
||||||
} = higher_order;
|
} = higher_order;
|
||||||
|
|
||||||
let function_owns_closure_data = *function_owns_closure_data;
|
let PassedFunction {
|
||||||
let function_name = *function_name;
|
argument_layouts,
|
||||||
|
return_layout: result_layout,
|
||||||
|
owns_captured_environment: function_owns_closure_data,
|
||||||
|
name: function_name,
|
||||||
|
captured_environment,
|
||||||
|
..
|
||||||
|
} = *passed_function;
|
||||||
|
|
||||||
// macros because functions cause lifetime issues related to the `env` or `layout_ids`
|
// macros because functions cause lifetime issues related to the `env` or `layout_ids`
|
||||||
macro_rules! function_details {
|
macro_rules! function_details {
|
||||||
|
@ -4712,7 +4715,8 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
return_layout,
|
return_layout,
|
||||||
);
|
);
|
||||||
|
|
||||||
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, function_env);
|
let (closure, closure_layout) =
|
||||||
|
load_symbol_and_lambda_set(scope, &captured_environment);
|
||||||
|
|
||||||
(function, closure, closure_layout)
|
(function, closure, closure_layout)
|
||||||
}};
|
}};
|
||||||
|
@ -4737,14 +4741,14 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
*result_layout,
|
result_layout,
|
||||||
);
|
);
|
||||||
|
|
||||||
crate::llvm::build_list::list_walk_generic(
|
crate::llvm::build_list::list_walk_generic(
|
||||||
env,
|
env,
|
||||||
layout_ids,
|
layout_ids,
|
||||||
roc_function_call,
|
roc_function_call,
|
||||||
result_layout,
|
&result_layout,
|
||||||
list,
|
list,
|
||||||
element_layout,
|
element_layout,
|
||||||
default,
|
default,
|
||||||
|
@ -4974,7 +4978,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
*result_layout,
|
result_layout,
|
||||||
);
|
);
|
||||||
|
|
||||||
list_keep_if(env, layout_ids, roc_function_call, list, element_layout)
|
list_keep_if(env, layout_ids, roc_function_call, list, element_layout)
|
||||||
|
@ -5003,14 +5007,14 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
*result_layout,
|
result_layout,
|
||||||
);
|
);
|
||||||
|
|
||||||
list_keep_oks(
|
list_keep_oks(
|
||||||
env,
|
env,
|
||||||
layout_ids,
|
layout_ids,
|
||||||
roc_function_call,
|
roc_function_call,
|
||||||
result_layout,
|
&result_layout,
|
||||||
list,
|
list,
|
||||||
before_layout,
|
before_layout,
|
||||||
after_layout,
|
after_layout,
|
||||||
|
@ -5042,14 +5046,14 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
*result_layout,
|
result_layout,
|
||||||
);
|
);
|
||||||
|
|
||||||
list_keep_errs(
|
list_keep_errs(
|
||||||
env,
|
env,
|
||||||
layout_ids,
|
layout_ids,
|
||||||
roc_function_call,
|
roc_function_call,
|
||||||
result_layout,
|
&result_layout,
|
||||||
list,
|
list,
|
||||||
before_layout,
|
before_layout,
|
||||||
after_layout,
|
after_layout,
|
||||||
|
@ -5094,7 +5098,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
*result_layout,
|
result_layout,
|
||||||
);
|
);
|
||||||
|
|
||||||
list_sort_with(
|
list_sort_with(
|
||||||
|
@ -5197,7 +5201,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
|
||||||
closure_layout,
|
closure_layout,
|
||||||
function_owns_closure_data,
|
function_owns_closure_data,
|
||||||
argument_layouts,
|
argument_layouts,
|
||||||
*result_layout,
|
result_layout,
|
||||||
);
|
);
|
||||||
|
|
||||||
dict_walk(
|
dict_walk(
|
||||||
|
|
|
@ -702,30 +702,30 @@ fn call_spec(
|
||||||
call.arguments,
|
call.arguments,
|
||||||
),
|
),
|
||||||
HigherOrder(HigherOrderLowLevel {
|
HigherOrder(HigherOrderLowLevel {
|
||||||
specialization_id,
|
|
||||||
closure_env_layout,
|
closure_env_layout,
|
||||||
update_mode,
|
update_mode,
|
||||||
op,
|
op,
|
||||||
arg_layouts,
|
passed_function,
|
||||||
ret_layout,
|
|
||||||
function_name,
|
|
||||||
function_env,
|
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
use crate::low_level::HigherOrder::*;
|
use crate::low_level::HigherOrder::*;
|
||||||
|
|
||||||
let array = specialization_id.to_bytes();
|
let array = passed_function.specialization_id.to_bytes();
|
||||||
let spec_var = CalleeSpecVar(&array);
|
let spec_var = CalleeSpecVar(&array);
|
||||||
|
|
||||||
let mode = update_mode.to_bytes();
|
let mode = update_mode.to_bytes();
|
||||||
let update_mode_var = UpdateModeVar(&mode);
|
let update_mode_var = UpdateModeVar(&mode);
|
||||||
|
|
||||||
let it = arg_layouts.iter().copied();
|
let it = passed_function.argument_layouts.iter().copied();
|
||||||
let bytes = func_name_bytes_help(*function_name, it, ret_layout);
|
let bytes =
|
||||||
|
func_name_bytes_help(passed_function.name, it, &passed_function.return_layout);
|
||||||
let name = FuncName(&bytes);
|
let name = FuncName(&bytes);
|
||||||
let module = MOD_APP;
|
let module = MOD_APP;
|
||||||
|
|
||||||
let closure_env = env.symbols[function_env];
|
let closure_env = env.symbols[&passed_function.captured_environment];
|
||||||
|
|
||||||
|
let return_layout = &passed_function.return_layout;
|
||||||
|
let argument_layouts = passed_function.argument_layouts;
|
||||||
|
|
||||||
macro_rules! call_function {
|
macro_rules! call_function {
|
||||||
($builder: expr, $block:expr, [$($arg:expr),+ $(,)?]) => {{
|
($builder: expr, $block:expr, [$($arg:expr),+ $(,)?]) => {{
|
||||||
|
@ -757,7 +757,7 @@ fn call_spec(
|
||||||
Ok(new_state)
|
Ok(new_state)
|
||||||
};
|
};
|
||||||
|
|
||||||
let state_layout = arg_layouts[0];
|
let state_layout = argument_layouts[0];
|
||||||
let state_type = layout_spec(builder, &state_layout)?;
|
let state_type = layout_spec(builder, &state_layout)?;
|
||||||
let init_state = state;
|
let init_state = state;
|
||||||
|
|
||||||
|
@ -778,7 +778,7 @@ fn call_spec(
|
||||||
Ok(new_state)
|
Ok(new_state)
|
||||||
};
|
};
|
||||||
|
|
||||||
let state_layout = arg_layouts[0];
|
let state_layout = argument_layouts[0];
|
||||||
let state_type = layout_spec(builder, &state_layout)?;
|
let state_type = layout_spec(builder, &state_layout)?;
|
||||||
let init_state = state;
|
let init_state = state;
|
||||||
|
|
||||||
|
@ -802,7 +802,7 @@ fn call_spec(
|
||||||
Ok(new_state)
|
Ok(new_state)
|
||||||
};
|
};
|
||||||
|
|
||||||
let state_layout = arg_layouts[0];
|
let state_layout = argument_layouts[0];
|
||||||
let state_type = layout_spec(builder, &state_layout)?;
|
let state_type = layout_spec(builder, &state_layout)?;
|
||||||
let init_state = state;
|
let init_state = state;
|
||||||
|
|
||||||
|
@ -823,9 +823,9 @@ fn call_spec(
|
||||||
list_append(builder, block, update_mode_var, state, new_element)
|
list_append(builder, block, update_mode_var, state, new_element)
|
||||||
};
|
};
|
||||||
|
|
||||||
let output_element_type = layout_spec(builder, ret_layout)?;
|
let output_element_type = layout_spec(builder, return_layout)?;
|
||||||
|
|
||||||
let state_layout = Layout::Builtin(Builtin::List(ret_layout));
|
let state_layout = Layout::Builtin(Builtin::List(return_layout));
|
||||||
let state_type = layout_spec(builder, &state_layout)?;
|
let state_type = layout_spec(builder, &state_layout)?;
|
||||||
|
|
||||||
let init_state = new_list(builder, block, output_element_type)?;
|
let init_state = new_list(builder, block, output_element_type)?;
|
||||||
|
@ -846,9 +846,9 @@ fn call_spec(
|
||||||
list_append(builder, block, update_mode_var, state, new_element)
|
list_append(builder, block, update_mode_var, state, new_element)
|
||||||
};
|
};
|
||||||
|
|
||||||
let output_element_type = layout_spec(builder, ret_layout)?;
|
let output_element_type = layout_spec(builder, return_layout)?;
|
||||||
|
|
||||||
let state_layout = Layout::Builtin(Builtin::List(ret_layout));
|
let state_layout = Layout::Builtin(Builtin::List(return_layout));
|
||||||
let state_type = layout_spec(builder, &state_layout)?;
|
let state_type = layout_spec(builder, &state_layout)?;
|
||||||
|
|
||||||
let init_state = new_list(builder, block, output_element_type)?;
|
let init_state = new_list(builder, block, output_element_type)?;
|
||||||
|
@ -873,7 +873,7 @@ fn call_spec(
|
||||||
with_new_heap_cell(builder, block, bag)
|
with_new_heap_cell(builder, block, bag)
|
||||||
};
|
};
|
||||||
|
|
||||||
let state_layout = Layout::Builtin(Builtin::List(&arg_layouts[0]));
|
let state_layout = Layout::Builtin(Builtin::List(&argument_layouts[0]));
|
||||||
let state_type = layout_spec(builder, &state_layout)?;
|
let state_type = layout_spec(builder, &state_layout)?;
|
||||||
let init_state = list;
|
let init_state = list;
|
||||||
|
|
||||||
|
@ -898,9 +898,9 @@ fn call_spec(
|
||||||
list_append(builder, block, update_mode_var, state, new_element)
|
list_append(builder, block, update_mode_var, state, new_element)
|
||||||
};
|
};
|
||||||
|
|
||||||
let output_element_type = layout_spec(builder, ret_layout)?;
|
let output_element_type = layout_spec(builder, return_layout)?;
|
||||||
|
|
||||||
let state_layout = Layout::Builtin(Builtin::List(ret_layout));
|
let state_layout = Layout::Builtin(Builtin::List(return_layout));
|
||||||
let state_type = layout_spec(builder, &state_layout)?;
|
let state_type = layout_spec(builder, &state_layout)?;
|
||||||
|
|
||||||
let init_state = new_list(builder, block, output_element_type)?;
|
let init_state = new_list(builder, block, output_element_type)?;
|
||||||
|
@ -931,9 +931,9 @@ fn call_spec(
|
||||||
list_append(builder, block, update_mode_var, state, new_element)
|
list_append(builder, block, update_mode_var, state, new_element)
|
||||||
};
|
};
|
||||||
|
|
||||||
let output_element_type = layout_spec(builder, ret_layout)?;
|
let output_element_type = layout_spec(builder, return_layout)?;
|
||||||
|
|
||||||
let state_layout = Layout::Builtin(Builtin::List(ret_layout));
|
let state_layout = Layout::Builtin(Builtin::List(return_layout));
|
||||||
let state_type = layout_spec(builder, &state_layout)?;
|
let state_type = layout_spec(builder, &state_layout)?;
|
||||||
|
|
||||||
let init_state = new_list(builder, block, output_element_type)?;
|
let init_state = new_list(builder, block, output_element_type)?;
|
||||||
|
@ -970,9 +970,9 @@ fn call_spec(
|
||||||
list_append(builder, block, update_mode_var, state, new_element)
|
list_append(builder, block, update_mode_var, state, new_element)
|
||||||
};
|
};
|
||||||
|
|
||||||
let output_element_type = layout_spec(builder, ret_layout)?;
|
let output_element_type = layout_spec(builder, return_layout)?;
|
||||||
|
|
||||||
let state_layout = Layout::Builtin(Builtin::List(ret_layout));
|
let state_layout = Layout::Builtin(Builtin::List(return_layout));
|
||||||
let state_type = layout_spec(builder, &state_layout)?;
|
let state_type = layout_spec(builder, &state_layout)?;
|
||||||
|
|
||||||
let init_state = new_list(builder, block, output_element_type)?;
|
let init_state = new_list(builder, block, output_element_type)?;
|
||||||
|
@ -1004,7 +1004,7 @@ fn call_spec(
|
||||||
with_new_heap_cell(builder, block, new_bag)
|
with_new_heap_cell(builder, block, new_bag)
|
||||||
};
|
};
|
||||||
|
|
||||||
let state_layout = Layout::Builtin(Builtin::List(&arg_layouts[0]));
|
let state_layout = Layout::Builtin(Builtin::List(&argument_layouts[0]));
|
||||||
let state_type = layout_spec(builder, &state_layout)?;
|
let state_type = layout_spec(builder, &state_layout)?;
|
||||||
let init_state = list;
|
let init_state = list;
|
||||||
|
|
||||||
|
@ -1019,7 +1019,7 @@ fn call_spec(
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let result_repr = ResultRepr::from_layout(ret_layout);
|
let result_repr = ResultRepr::from_layout(return_layout);
|
||||||
|
|
||||||
let output_element_layout = match (keep_result, result_repr) {
|
let output_element_layout = match (keep_result, result_repr) {
|
||||||
(KeepResult::Errs, ResultRepr::ResultConcrete { err, .. }) => err,
|
(KeepResult::Errs, ResultRepr::ResultConcrete { err, .. }) => err,
|
||||||
|
@ -1132,7 +1132,7 @@ fn call_spec(
|
||||||
let list = env.symbols[xs];
|
let list = env.symbols[xs];
|
||||||
|
|
||||||
// ListFindUnsafe returns { value: v, found: Bool=Int1 }
|
// ListFindUnsafe returns { value: v, found: Bool=Int1 }
|
||||||
let output_layouts = vec![arg_layouts[0], Layout::Builtin(Builtin::Bool)];
|
let output_layouts = vec![argument_layouts[0], Layout::Builtin(Builtin::Bool)];
|
||||||
let output_layout = Layout::Struct(&output_layouts);
|
let output_layout = Layout::Struct(&output_layouts);
|
||||||
let output_type = layout_spec(builder, &output_layout)?;
|
let output_type = layout_spec(builder, &output_layout)?;
|
||||||
|
|
||||||
|
|
|
@ -595,20 +595,17 @@ impl<'a> BorrowInfState<'a> {
|
||||||
|
|
||||||
HigherOrder(HigherOrderLowLevel {
|
HigherOrder(HigherOrderLowLevel {
|
||||||
op,
|
op,
|
||||||
arg_layouts,
|
passed_function,
|
||||||
ret_layout,
|
|
||||||
function_name,
|
|
||||||
function_env,
|
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
use crate::low_level::HigherOrder::*;
|
use crate::low_level::HigherOrder::*;
|
||||||
|
|
||||||
let closure_layout = ProcLayout {
|
let closure_layout = ProcLayout {
|
||||||
arguments: arg_layouts,
|
arguments: passed_function.argument_layouts,
|
||||||
result: *ret_layout,
|
result: passed_function.return_layout,
|
||||||
};
|
};
|
||||||
|
|
||||||
let function_ps = match param_map.get_symbol(*function_name, closure_layout) {
|
let function_ps = match param_map.get_symbol(passed_function.name, closure_layout) {
|
||||||
Some(function_ps) => function_ps,
|
Some(function_ps) => function_ps,
|
||||||
None => unreachable!(),
|
None => unreachable!(),
|
||||||
};
|
};
|
||||||
|
@ -692,7 +689,7 @@ impl<'a> BorrowInfState<'a> {
|
||||||
// own the closure environment if the function needs to own it
|
// own the closure environment if the function needs to own it
|
||||||
let function_env_position = op.function_arity();
|
let function_env_position = op.function_arity();
|
||||||
if let Some(false) = function_ps.get(function_env_position).map(|p| p.borrow) {
|
if let Some(false) = function_ps.get(function_env_position).map(|p| p.borrow) {
|
||||||
self.own_var(*function_env);
|
self.own_var(passed_function.captured_environment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -468,12 +468,8 @@ impl<'a> Context<'a> {
|
||||||
HigherOrder(HigherOrderLowLevel {
|
HigherOrder(HigherOrderLowLevel {
|
||||||
op,
|
op,
|
||||||
closure_env_layout,
|
closure_env_layout,
|
||||||
specialization_id,
|
|
||||||
update_mode,
|
update_mode,
|
||||||
arg_layouts,
|
passed_function,
|
||||||
ret_layout,
|
|
||||||
function_name,
|
|
||||||
function_env,
|
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
// setup
|
// setup
|
||||||
|
@ -483,16 +479,14 @@ impl<'a> Context<'a> {
|
||||||
($borrows:expr) => {
|
($borrows:expr) => {
|
||||||
Expr::Call(crate::ir::Call {
|
Expr::Call(crate::ir::Call {
|
||||||
call_type: if let Some(OWNED) = $borrows.map(|p| p.borrow) {
|
call_type: if let Some(OWNED) = $borrows.map(|p| p.borrow) {
|
||||||
|
let mut passed_function = *passed_function;
|
||||||
|
passed_function.owns_captured_environment = true;
|
||||||
|
|
||||||
let higher_order = HigherOrderLowLevel {
|
let higher_order = HigherOrderLowLevel {
|
||||||
op: *op,
|
op: *op,
|
||||||
closure_env_layout: *closure_env_layout,
|
closure_env_layout: *closure_env_layout,
|
||||||
function_owns_closure_data: true,
|
|
||||||
specialization_id: *specialization_id,
|
|
||||||
update_mode: *update_mode,
|
update_mode: *update_mode,
|
||||||
function_name: *function_name,
|
passed_function,
|
||||||
function_env: *function_env,
|
|
||||||
arg_layouts,
|
|
||||||
ret_layout: *ret_layout,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CallType::HigherOrder(self.arena.alloc(higher_order))
|
CallType::HigherOrder(self.arena.alloc(higher_order))
|
||||||
|
@ -521,11 +515,14 @@ impl<'a> Context<'a> {
|
||||||
const CLOSURE_DATA: bool = BORROWED;
|
const CLOSURE_DATA: bool = BORROWED;
|
||||||
|
|
||||||
let function_layout = ProcLayout {
|
let function_layout = ProcLayout {
|
||||||
arguments: arg_layouts,
|
arguments: passed_function.argument_layouts,
|
||||||
result: *ret_layout,
|
result: passed_function.return_layout,
|
||||||
};
|
};
|
||||||
|
|
||||||
let function_ps = match self.param_map.get_symbol(*function_name, function_layout) {
|
let function_ps = match self
|
||||||
|
.param_map
|
||||||
|
.get_symbol(passed_function.name, function_layout)
|
||||||
|
{
|
||||||
Some(function_ps) => function_ps,
|
Some(function_ps) => function_ps,
|
||||||
None => unreachable!(),
|
None => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1346,31 +1346,35 @@ pub enum CallType<'a> {
|
||||||
HigherOrder(&'a HigherOrderLowLevel<'a>),
|
HigherOrder(&'a HigherOrderLowLevel<'a>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
pub struct PassedFunction<'a> {
|
||||||
|
/// name of the top-level function that is passed as an argument
|
||||||
|
/// e.g. in `List.map xs Num.abs` this would be `Num.abs`
|
||||||
|
pub name: Symbol,
|
||||||
|
|
||||||
|
pub argument_layouts: &'a [Layout<'a>],
|
||||||
|
pub return_layout: Layout<'a>,
|
||||||
|
|
||||||
|
pub specialization_id: CallSpecId,
|
||||||
|
|
||||||
|
/// Symbol of the environment captured by the function argument
|
||||||
|
pub captured_environment: Symbol,
|
||||||
|
|
||||||
|
pub owns_captured_environment: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct HigherOrderLowLevel<'a> {
|
pub struct HigherOrderLowLevel<'a> {
|
||||||
pub op: crate::low_level::HigherOrder,
|
pub op: crate::low_level::HigherOrder,
|
||||||
|
|
||||||
|
/// TODO I _think_ we can get rid of this, perhaps only keeping track of
|
||||||
/// the layout of the closure argument, if any
|
/// the layout of the closure argument, if any
|
||||||
pub closure_env_layout: Option<Layout<'a>>,
|
pub closure_env_layout: Option<Layout<'a>>,
|
||||||
|
|
||||||
/// name of the top-level function that is passed as an argument
|
|
||||||
/// e.g. in `List.map xs Num.abs` this would be `Num.abs`
|
|
||||||
pub function_name: Symbol,
|
|
||||||
|
|
||||||
/// Symbol of the environment captured by the function argument
|
|
||||||
pub function_env: Symbol,
|
|
||||||
|
|
||||||
/// does the function argument need to own the closure data
|
|
||||||
pub function_owns_closure_data: bool,
|
|
||||||
|
|
||||||
/// specialization id of the function argument, used for name generation
|
|
||||||
pub specialization_id: CallSpecId,
|
|
||||||
|
|
||||||
/// update mode of the higher order lowlevel itself
|
/// update mode of the higher order lowlevel itself
|
||||||
pub update_mode: UpdateModeId,
|
pub update_mode: UpdateModeId,
|
||||||
|
|
||||||
/// function layout, used for name generation
|
pub passed_function: PassedFunction<'a>,
|
||||||
pub arg_layouts: &'a [Layout<'a>],
|
|
||||||
pub ret_layout: Layout<'a>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
@ -4193,16 +4197,21 @@ pub fn with_hole<'a>(
|
||||||
op,
|
op,
|
||||||
closure_data_symbol,
|
closure_data_symbol,
|
||||||
|(top_level_function, closure_data, closure_env_layout, specialization_id, update_mode)| {
|
|(top_level_function, closure_data, closure_env_layout, specialization_id, update_mode)| {
|
||||||
|
let passed_function = PassedFunction {
|
||||||
|
name: top_level_function,
|
||||||
|
captured_environment: closure_data_symbol,
|
||||||
|
owns_captured_environment: false,
|
||||||
|
specialization_id,
|
||||||
|
argument_layouts: arg_layouts,
|
||||||
|
return_layout: ret_layout,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
let higher_order = HigherOrderLowLevel {
|
let higher_order = HigherOrderLowLevel {
|
||||||
op: crate::low_level::HigherOrder::$ho { $($x,)* },
|
op: crate::low_level::HigherOrder::$ho { $($x,)* },
|
||||||
closure_env_layout,
|
closure_env_layout,
|
||||||
specialization_id,
|
|
||||||
update_mode,
|
update_mode,
|
||||||
function_owns_closure_data: false,
|
passed_function,
|
||||||
function_env: closure_data_symbol,
|
|
||||||
function_name: top_level_function,
|
|
||||||
arg_layouts,
|
|
||||||
ret_layout,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self::Call {
|
self::Call {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue