This commit is contained in:
Folkert 2021-06-09 19:21:24 +02:00
parent 3c8d675378
commit 9476f63e07
4 changed files with 55 additions and 20 deletions

View file

@ -825,16 +825,25 @@ pub fn build_exp_call<'a, 'ctx, 'env>(
op, op,
closure_layout, closure_layout,
function_owns_closure_data, function_owns_closure_data,
} => run_higher_order_low_level( specialization_id,
} => {
let bytes = specialization_id.to_bytes();
let callee_var = CalleeSpecVar(&bytes);
let func_spec = func_spec_solutions.callee_spec(callee_var).unwrap();
// let fn_val = function_value_by_func_spec(env, func_spec, symbol, *layout);
run_higher_order_low_level(
env, env,
layout_ids, layout_ids,
scope, scope,
layout, layout,
*op, *op,
*closure_layout, *closure_layout,
func_spec,
*function_owns_closure_data, *function_owns_closure_data,
arguments, arguments,
), )
}
CallType::Foreign { CallType::Foreign {
foreign_symbol, foreign_symbol,
@ -3793,6 +3802,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
return_layout: &Layout<'a>, return_layout: &Layout<'a>,
op: LowLevel, op: LowLevel,
function_layout: Layout<'a>, function_layout: Layout<'a>,
func_spec: FuncSpec,
function_owns_closure_data: bool, function_owns_closure_data: bool,
args: &[Symbol], args: &[Symbol],
) -> BasicValueEnum<'ctx> { ) -> BasicValueEnum<'ctx> {

View file

@ -414,7 +414,7 @@ fn call_spec(
*update_mode, *update_mode,
call.arguments, call.arguments,
), ),
HigherOrderLowLevel { .. } => { HigherOrderLowLevel { op, .. } => {
// TODO overly pessimstic // TODO overly pessimstic
// filter_map because one of the arguments is a function name, which // filter_map because one of the arguments is a function name, which
// is not defined in the env // is not defined in the env

View file

@ -454,7 +454,10 @@ impl<'a> Context<'a> {
} }
HigherOrderLowLevel { HigherOrderLowLevel {
op, closure_layout, .. op,
closure_layout,
specialization_id,
..
} => { } => {
macro_rules! create_call { macro_rules! create_call {
($borrows:expr) => { ($borrows:expr) => {
@ -464,6 +467,7 @@ impl<'a> Context<'a> {
op: *op, op: *op,
closure_layout: *closure_layout, closure_layout: *closure_layout,
function_owns_closure_data: true, function_owns_closure_data: true,
specialization_id: *specialization_id,
} }
} else { } else {
call_type call_type

View file

@ -1146,6 +1146,8 @@ pub enum CallType<'a> {
op: LowLevel, op: LowLevel,
/// the layout of the closure argument, if any /// the layout of the closure argument, if any
closure_layout: Layout<'a>, closure_layout: Layout<'a>,
/// specialization id of the function argument
specialization_id: CallSpecId,
/// does the function need to own the closure data /// does the function need to own the closure data
function_owns_closure_data: bool, function_owns_closure_data: bool,
}, },
@ -2707,11 +2709,12 @@ macro_rules! match_on_closure_argument {
$env, $env,
lambda_set, lambda_set,
$closure_data_symbol, $closure_data_symbol,
|top_level_function, closure_data, function_layout| self::Call { |top_level_function, closure_data, function_layout, specialization_id| self::Call {
call_type: CallType::HigherOrderLowLevel { call_type: CallType::HigherOrderLowLevel {
op: $op, op: $op,
closure_layout: function_layout, closure_layout: function_layout,
function_owns_closure_data: false specialization_id,
function_owns_closure_data: false,
}, },
arguments: arena.alloc([$($x,)* top_level_function, closure_data]), arguments: arena.alloc([$($x,)* top_level_function, closure_data]),
}, },
@ -7696,7 +7699,7 @@ fn lowlevel_match_on_lambda_set<'a, ToLowLevelCall>(
hole: &'a Stmt<'a>, hole: &'a Stmt<'a>,
) -> Stmt<'a> ) -> Stmt<'a>
where where
ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy, ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>, CallSpecId) -> Call<'a> + Copy,
{ {
match lambda_set.runtime_representation() { match lambda_set.runtime_representation() {
Layout::Union(_) => { Layout::Union(_) => {
@ -7733,7 +7736,13 @@ where
Layout::Struct(_) => { Layout::Struct(_) => {
let function_symbol = lambda_set.set[0].0; let function_symbol = lambda_set.set[0].0;
let call = to_lowlevel_call(function_symbol, closure_data_symbol, function_layout); let call_spec_id = env.next_call_specialization_id();
let call = to_lowlevel_call(
function_symbol,
closure_data_symbol,
function_layout,
call_spec_id,
);
build_call(env, call, assigned, return_layout, env.arena.alloc(hole)) build_call(env, call, assigned, return_layout, env.arena.alloc(hole))
} }
@ -7787,7 +7796,7 @@ fn lowlevel_union_lambda_set_to_switch<'a, ToLowLevelCall>(
hole: &'a Stmt<'a>, hole: &'a Stmt<'a>,
) -> Stmt<'a> ) -> Stmt<'a>
where where
ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy, ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>, CallSpecId) -> Call<'a> + Copy,
{ {
debug_assert!(!lambda_set.is_empty()); debug_assert!(!lambda_set.is_empty());
@ -7800,7 +7809,13 @@ where
let hole = Stmt::Jump(join_point_id, env.arena.alloc([assigned])); let hole = Stmt::Jump(join_point_id, env.arena.alloc([assigned]));
let call = to_lowlevel_call(*function_symbol, closure_data_symbol, function_layout); let call_spec_id = env.next_call_specialization_id();
let call = to_lowlevel_call(
*function_symbol,
closure_data_symbol,
function_layout,
call_spec_id,
);
let stmt = build_call(env, call, assigned, return_layout, env.arena.alloc(hole)); let stmt = build_call(env, call, assigned, return_layout, env.arena.alloc(hole));
branches.push((i as u64, BranchInfo::None, stmt)); branches.push((i as u64, BranchInfo::None, stmt));
@ -8206,7 +8221,7 @@ fn lowlevel_enum_lambda_set_to_switch<'a, ToLowLevelCall>(
hole: &'a Stmt<'a>, hole: &'a Stmt<'a>,
) -> Stmt<'a> ) -> Stmt<'a>
where where
ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy, ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>, CallSpecId) -> Call<'a> + Copy,
{ {
debug_assert!(!lambda_set.is_empty()); debug_assert!(!lambda_set.is_empty());
@ -8219,7 +8234,13 @@ where
let hole = Stmt::Jump(join_point_id, env.arena.alloc([result_symbol])); let hole = Stmt::Jump(join_point_id, env.arena.alloc([result_symbol]));
let call = to_lowlevel_call(*function_symbol, closure_data_symbol, function_layout); let call_spec_id = env.next_call_specialization_id();
let call = to_lowlevel_call(
*function_symbol,
closure_data_symbol,
function_layout,
call_spec_id,
);
let stmt = build_call( let stmt = build_call(
env, env,
call, call,