mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
store the layout of a function passed to a lowlevel
This commit is contained in:
parent
27a6a179da
commit
357f93a2ee
6 changed files with 72 additions and 33 deletions
|
@ -882,9 +882,10 @@ pub fn build_exp_call<'a, 'ctx, 'env>(
|
||||||
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
|
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
|
||||||
}
|
}
|
||||||
|
|
||||||
CallType::LowLevel { op } => {
|
CallType::LowLevel {
|
||||||
run_low_level(env, layout_ids, scope, parent, layout, *op, arguments)
|
op,
|
||||||
}
|
opt_closure_layout,
|
||||||
|
} => run_low_level(env, layout_ids, scope, parent, layout, *op, arguments),
|
||||||
|
|
||||||
CallType::Foreign {
|
CallType::Foreign {
|
||||||
foreign_symbol,
|
foreign_symbol,
|
||||||
|
|
|
@ -211,9 +211,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CallType::LowLevel { op: lowlevel } => {
|
CallType::LowLevel {
|
||||||
self.build_run_low_level(sym, lowlevel, arguments, layout)
|
op: lowlevel,
|
||||||
}
|
opt_closure_layout: _,
|
||||||
|
} => self.build_run_low_level(sym, lowlevel, arguments, layout),
|
||||||
x => Err(format!("the call type, {:?}, is not yet implemented", x)),
|
x => Err(format!("the call type, {:?}, is not yet implemented", x)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -407,7 +407,10 @@ impl<'a> BorrowInfState<'a> {
|
||||||
self.own_args(arguments);
|
self.own_args(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
LowLevel { op } => {
|
LowLevel {
|
||||||
|
op,
|
||||||
|
opt_closure_layout: _,
|
||||||
|
} => {
|
||||||
// very unsure what demand RunLowLevel should place upon its arguments
|
// very unsure what demand RunLowLevel should place upon its arguments
|
||||||
self.own_var(z);
|
self.own_var(z);
|
||||||
|
|
||||||
|
|
|
@ -1405,7 +1405,10 @@ fn compile_test_help<'a>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let test = Expr::Call(crate::ir::Call {
|
let test = Expr::Call(crate::ir::Call {
|
||||||
call_type: crate::ir::CallType::LowLevel { op: LowLevel::Eq },
|
call_type: crate::ir::CallType::LowLevel {
|
||||||
|
op: LowLevel::Eq,
|
||||||
|
opt_closure_layout: None,
|
||||||
|
},
|
||||||
arguments: arena.alloc([lhs, rhs]),
|
arguments: arena.alloc([lhs, rhs]),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -442,7 +442,10 @@ impl<'a> Context<'a> {
|
||||||
use crate::ir::CallType::*;
|
use crate::ir::CallType::*;
|
||||||
|
|
||||||
match &call_type {
|
match &call_type {
|
||||||
LowLevel { op } => {
|
LowLevel {
|
||||||
|
op,
|
||||||
|
opt_closure_layout: _,
|
||||||
|
} => {
|
||||||
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op);
|
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op);
|
||||||
let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars);
|
let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars);
|
||||||
|
|
||||||
|
@ -762,7 +765,10 @@ impl<'a> Context<'a> {
|
||||||
|
|
||||||
use crate::ir::CallType;
|
use crate::ir::CallType;
|
||||||
let stmt = match &call.call_type {
|
let stmt = match &call.call_type {
|
||||||
CallType::LowLevel { op } => {
|
CallType::LowLevel {
|
||||||
|
op,
|
||||||
|
opt_closure_layout: _,
|
||||||
|
} => {
|
||||||
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op);
|
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op);
|
||||||
self.add_dec_after_lowlevel(call.arguments, ps, cont, &invoke_live_vars)
|
self.add_dec_after_lowlevel(call.arguments, ps, cont, &invoke_live_vars)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1040,7 +1040,10 @@ impl<'a> Call<'a> {
|
||||||
.text("CallByPointer ")
|
.text("CallByPointer ")
|
||||||
.append(alloc.intersperse(it, " "))
|
.append(alloc.intersperse(it, " "))
|
||||||
}
|
}
|
||||||
LowLevel { op: lowlevel } => {
|
LowLevel {
|
||||||
|
op: lowlevel,
|
||||||
|
opt_closure_layout: _,
|
||||||
|
} => {
|
||||||
let it = arguments.iter().map(|s| symbol_to_doc(alloc, *s));
|
let it = arguments.iter().map(|s| symbol_to_doc(alloc, *s));
|
||||||
|
|
||||||
alloc
|
alloc
|
||||||
|
@ -1082,6 +1085,8 @@ pub enum CallType<'a> {
|
||||||
},
|
},
|
||||||
LowLevel {
|
LowLevel {
|
||||||
op: LowLevel,
|
op: LowLevel,
|
||||||
|
/// the layout of the closure argument, if any
|
||||||
|
opt_closure_layout: Option<Layout<'a>>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2671,8 +2676,8 @@ macro_rules! match_on_closure_argument {
|
||||||
$env,
|
$env,
|
||||||
lambda_set,
|
lambda_set,
|
||||||
$closure_data_symbol,
|
$closure_data_symbol,
|
||||||
|top_level_function, closure_data| self::Call {
|
|top_level_function, closure_data, function_layout| self::Call {
|
||||||
call_type: CallType::LowLevel { op: $op },
|
call_type: CallType::LowLevel { op: $op, opt_closure_layout: Some(function_layout) },
|
||||||
arguments: arena.alloc([$($x,)* top_level_function, closure_data]),
|
arguments: arena.alloc([$($x,)* top_level_function, closure_data]),
|
||||||
},
|
},
|
||||||
arena.alloc(top_level).full(),
|
arena.alloc(top_level).full(),
|
||||||
|
@ -4357,7 +4362,10 @@ pub fn with_hole<'a>(
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let call = self::Call {
|
let call = self::Call {
|
||||||
call_type: CallType::LowLevel { op },
|
call_type: CallType::LowLevel {
|
||||||
|
op,
|
||||||
|
opt_closure_layout: None,
|
||||||
|
},
|
||||||
arguments: arg_symbols,
|
arguments: arg_symbols,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4577,6 +4585,7 @@ pub fn from_can<'a>(
|
||||||
|
|
||||||
let call_type = CallType::LowLevel {
|
let call_type = CallType::LowLevel {
|
||||||
op: LowLevel::ExpectTrue,
|
op: LowLevel::ExpectTrue,
|
||||||
|
opt_closure_layout: None,
|
||||||
};
|
};
|
||||||
let arguments = env.arena.alloc([cond_symbol]);
|
let arguments = env.arena.alloc([cond_symbol]);
|
||||||
let call = self::Call {
|
let call = self::Call {
|
||||||
|
@ -7634,18 +7643,18 @@ pub fn num_argument_to_int_or_float(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use the lambda set to figure out how to make a lowlevel call
|
/// Use the lambda set to figure out how to make a lowlevel call
|
||||||
fn lowlevel_match_on_lambda_set<'a, F>(
|
fn lowlevel_match_on_lambda_set<'a, ToLowLevelCall>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
lambda_set: LambdaSet<'a>,
|
lambda_set: LambdaSet<'a>,
|
||||||
closure_data_symbol: Symbol,
|
closure_data_symbol: Symbol,
|
||||||
to_lowlevel_call: F,
|
to_lowlevel_call: ToLowLevelCall,
|
||||||
function_layout: Layout<'a>,
|
function_layout: Layout<'a>,
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
assigned: Symbol,
|
assigned: Symbol,
|
||||||
hole: &'a Stmt<'a>,
|
hole: &'a Stmt<'a>,
|
||||||
) -> Stmt<'a>
|
) -> Stmt<'a>
|
||||||
where
|
where
|
||||||
F: Fn(Symbol, Symbol) -> Call<'a> + Copy,
|
ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy,
|
||||||
{
|
{
|
||||||
match lambda_set.runtime_representation() {
|
match lambda_set.runtime_representation() {
|
||||||
Layout::Union(_) => {
|
Layout::Union(_) => {
|
||||||
|
@ -7687,7 +7696,11 @@ where
|
||||||
// build the call
|
// build the call
|
||||||
let stmt = Stmt::Let(
|
let stmt = Stmt::Let(
|
||||||
assigned,
|
assigned,
|
||||||
Expr::Call(to_lowlevel_call(bound, closure_data_symbol)),
|
Expr::Call(to_lowlevel_call(
|
||||||
|
bound,
|
||||||
|
closure_data_symbol,
|
||||||
|
function_layout,
|
||||||
|
)),
|
||||||
return_layout,
|
return_layout,
|
||||||
env.arena.alloc(hole),
|
env.arena.alloc(hole),
|
||||||
);
|
);
|
||||||
|
@ -7736,20 +7749,20 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lowlevel_union_lambda_set_to_switch<'a, F>(
|
fn lowlevel_union_lambda_set_to_switch<'a, ToLowLevelCall>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
lambda_set: &'a [(Symbol, &'a [Layout<'a>])],
|
lambda_set: &'a [(Symbol, &'a [Layout<'a>])],
|
||||||
closure_tag_id_symbol: Symbol,
|
closure_tag_id_symbol: Symbol,
|
||||||
closure_tag_id_layout: Layout<'a>,
|
closure_tag_id_layout: Layout<'a>,
|
||||||
closure_data_symbol: Symbol,
|
closure_data_symbol: Symbol,
|
||||||
to_lowlevel_call: F,
|
to_lowlevel_call: ToLowLevelCall,
|
||||||
function_layout: Layout<'a>,
|
function_layout: Layout<'a>,
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
assigned: Symbol,
|
assigned: Symbol,
|
||||||
hole: &'a Stmt<'a>,
|
hole: &'a Stmt<'a>,
|
||||||
) -> Stmt<'a>
|
) -> Stmt<'a>
|
||||||
where
|
where
|
||||||
F: Fn(Symbol, Symbol) -> Call<'a> + Copy,
|
ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy,
|
||||||
{
|
{
|
||||||
debug_assert!(!lambda_set.is_empty());
|
debug_assert!(!lambda_set.is_empty());
|
||||||
|
|
||||||
|
@ -7767,7 +7780,11 @@ where
|
||||||
// build the call
|
// build the call
|
||||||
let stmt = Stmt::Let(
|
let stmt = Stmt::Let(
|
||||||
assigned,
|
assigned,
|
||||||
Expr::Call(to_lowlevel_call(bound, closure_data_symbol)),
|
Expr::Call(to_lowlevel_call(
|
||||||
|
bound,
|
||||||
|
closure_data_symbol,
|
||||||
|
function_layout,
|
||||||
|
)),
|
||||||
return_layout,
|
return_layout,
|
||||||
env.arena.alloc(hole),
|
env.arena.alloc(hole),
|
||||||
);
|
);
|
||||||
|
@ -7810,18 +7827,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lowlevel_union_lambda_set_branch<'a, F>(
|
fn lowlevel_union_lambda_set_branch<'a, ToLowLevelCall>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
join_point_id: JoinPointId,
|
join_point_id: JoinPointId,
|
||||||
function_symbol: Symbol,
|
function_symbol: Symbol,
|
||||||
closure_data_symbol: Symbol,
|
closure_data_symbol: Symbol,
|
||||||
closure_data_layout: Layout<'a>,
|
closure_data_layout: Layout<'a>,
|
||||||
function_layout: Layout<'a>,
|
function_layout: Layout<'a>,
|
||||||
to_lowlevel_call: F,
|
to_lowlevel_call: ToLowLevelCall,
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
) -> Stmt<'a>
|
) -> Stmt<'a>
|
||||||
where
|
where
|
||||||
F: Fn(Symbol, Symbol) -> Call<'a> + Copy,
|
ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy,
|
||||||
{
|
{
|
||||||
let assigned = env.unique_symbol();
|
let assigned = env.unique_symbol();
|
||||||
|
|
||||||
|
@ -7832,7 +7849,11 @@ where
|
||||||
// build the call
|
// build the call
|
||||||
let stmt = Stmt::Let(
|
let stmt = Stmt::Let(
|
||||||
assigned,
|
assigned,
|
||||||
Expr::Call(to_lowlevel_call(bound, closure_data_symbol)),
|
Expr::Call(to_lowlevel_call(
|
||||||
|
bound,
|
||||||
|
closure_data_symbol,
|
||||||
|
function_layout,
|
||||||
|
)),
|
||||||
return_layout,
|
return_layout,
|
||||||
env.arena.alloc(hole),
|
env.arena.alloc(hole),
|
||||||
);
|
);
|
||||||
|
@ -8225,20 +8246,20 @@ fn enum_lambda_set_branch_help<'a>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lowlevel_enum_lambda_set_to_switch<'a, F>(
|
fn lowlevel_enum_lambda_set_to_switch<'a, ToLowLevelCall>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
lambda_set: &'a [(Symbol, &'a [Layout<'a>])],
|
lambda_set: &'a [(Symbol, &'a [Layout<'a>])],
|
||||||
closure_tag_id_symbol: Symbol,
|
closure_tag_id_symbol: Symbol,
|
||||||
closure_tag_id_layout: Layout<'a>,
|
closure_tag_id_layout: Layout<'a>,
|
||||||
closure_data_symbol: Symbol,
|
closure_data_symbol: Symbol,
|
||||||
to_lowlevel_call: F,
|
to_lowlevel_call: ToLowLevelCall,
|
||||||
function_layout: Layout<'a>,
|
function_layout: Layout<'a>,
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
assigned: Symbol,
|
assigned: Symbol,
|
||||||
hole: &'a Stmt<'a>,
|
hole: &'a Stmt<'a>,
|
||||||
) -> Stmt<'a>
|
) -> Stmt<'a>
|
||||||
where
|
where
|
||||||
F: Fn(Symbol, Symbol) -> Call<'a> + Copy,
|
ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy,
|
||||||
{
|
{
|
||||||
debug_assert!(!lambda_set.is_empty());
|
debug_assert!(!lambda_set.is_empty());
|
||||||
|
|
||||||
|
@ -8290,18 +8311,18 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lowlevel_enum_lambda_set_branch<'a, F>(
|
fn lowlevel_enum_lambda_set_branch<'a, ToLowLevelCall>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
join_point_id: JoinPointId,
|
join_point_id: JoinPointId,
|
||||||
function_symbol: Symbol,
|
function_symbol: Symbol,
|
||||||
closure_data_symbol: Symbol,
|
closure_data_symbol: Symbol,
|
||||||
closure_data_layout: Layout<'a>,
|
closure_data_layout: Layout<'a>,
|
||||||
to_lowlevel_call: F,
|
to_lowlevel_call: ToLowLevelCall,
|
||||||
function_layout: Layout<'a>,
|
function_layout: Layout<'a>,
|
||||||
return_layout: Layout<'a>,
|
return_layout: Layout<'a>,
|
||||||
) -> Stmt<'a>
|
) -> Stmt<'a>
|
||||||
where
|
where
|
||||||
F: Fn(Symbol, Symbol) -> Call<'a> + Copy,
|
ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy,
|
||||||
{
|
{
|
||||||
let result_symbol = env.unique_symbol();
|
let result_symbol = env.unique_symbol();
|
||||||
|
|
||||||
|
@ -8312,7 +8333,11 @@ where
|
||||||
// build the call
|
// build the call
|
||||||
let stmt = Stmt::Let(
|
let stmt = Stmt::Let(
|
||||||
result_symbol,
|
result_symbol,
|
||||||
Expr::Call(to_lowlevel_call(bound, closure_data_symbol)),
|
Expr::Call(to_lowlevel_call(
|
||||||
|
bound,
|
||||||
|
closure_data_symbol,
|
||||||
|
function_layout,
|
||||||
|
)),
|
||||||
return_layout,
|
return_layout,
|
||||||
env.arena.alloc(hole),
|
env.arena.alloc(hole),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue