This commit is contained in:
Folkert 2021-10-17 20:45:49 +02:00
parent 434ccbbf68
commit a4f7ddb1f5
6 changed files with 3 additions and 1061 deletions

View file

@ -463,7 +463,7 @@ impl<'a> Context<'a> {
&*self.arena.alloc(Stmt::Let(z, v, l, b))
}
NewHigherOrderLowLevel {
HigherOrderLowLevel {
op,
closure_env_layout,
specialization_id,
@ -620,222 +620,6 @@ impl<'a> Context<'a> {
}
}
HigherOrderLowLevel {
op,
closure_env_layout,
specialization_id,
arg_layouts,
ret_layout,
..
} => {
macro_rules! create_call {
($borrows:expr) => {
Expr::Call(crate::ir::Call {
call_type: if let Some(OWNED) = $borrows.map(|p| p.borrow) {
HigherOrderLowLevel {
op: *op,
closure_env_layout: *closure_env_layout,
function_owns_closure_data: true,
specialization_id: *specialization_id,
arg_layouts,
ret_layout: *ret_layout,
}
} else {
call_type
},
arguments,
})
};
}
macro_rules! decref_if_owned {
($borrows:expr, $argument:expr, $stmt:expr) => {
if !$borrows {
self.arena.alloc(Stmt::Refcounting(
ModifyRc::DecRef($argument),
self.arena.alloc($stmt),
))
} else {
$stmt
}
};
}
const FUNCTION: bool = BORROWED;
const CLOSURE_DATA: bool = BORROWED;
let function_layout = ProcLayout {
arguments: arg_layouts,
result: *ret_layout,
};
match op {
roc_module::low_level::LowLevel::ListMap
| roc_module::low_level::LowLevel::ListKeepIf
| roc_module::low_level::LowLevel::ListKeepOks
| roc_module::low_level::LowLevel::ListKeepErrs => {
match self.param_map.get_symbol(arguments[1], function_layout) {
Some(function_ps) => {
let borrows = [function_ps[0].borrow, FUNCTION, CLOSURE_DATA];
let b = self.add_dec_after_lowlevel(
arguments,
&borrows,
b,
b_live_vars,
);
// if the list is owned, then all elements have been consumed, but not the list itself
let b = decref_if_owned!(function_ps[0].borrow, arguments[0], b);
let v = create_call!(function_ps.get(1));
&*self.arena.alloc(Stmt::Let(z, v, l, b))
}
None => unreachable!(),
}
}
roc_module::low_level::LowLevel::ListMapWithIndex => {
match self.param_map.get_symbol(arguments[1], function_layout) {
Some(function_ps) => {
let borrows = [function_ps[1].borrow, FUNCTION, CLOSURE_DATA];
let b = self.add_dec_after_lowlevel(
arguments,
&borrows,
b,
b_live_vars,
);
let b = decref_if_owned!(function_ps[1].borrow, arguments[0], b);
let v = create_call!(function_ps.get(2));
&*self.arena.alloc(Stmt::Let(z, v, l, b))
}
None => unreachable!(),
}
}
roc_module::low_level::LowLevel::ListMap2 => {
match self.param_map.get_symbol(arguments[2], function_layout) {
Some(function_ps) => {
let borrows = [
function_ps[0].borrow,
function_ps[1].borrow,
FUNCTION,
CLOSURE_DATA,
];
let b = self.add_dec_after_lowlevel(
arguments,
&borrows,
b,
b_live_vars,
);
let b = decref_if_owned!(function_ps[0].borrow, arguments[0], b);
let b = decref_if_owned!(function_ps[1].borrow, arguments[1], b);
let v = create_call!(function_ps.get(2));
&*self.arena.alloc(Stmt::Let(z, v, l, b))
}
None => unreachable!(),
}
}
roc_module::low_level::LowLevel::ListMap3 => {
match self.param_map.get_symbol(arguments[3], function_layout) {
Some(function_ps) => {
let borrows = [
function_ps[0].borrow,
function_ps[1].borrow,
function_ps[2].borrow,
FUNCTION,
CLOSURE_DATA,
];
let b = self.add_dec_after_lowlevel(
arguments,
&borrows,
b,
b_live_vars,
);
let b = decref_if_owned!(function_ps[0].borrow, arguments[0], b);
let b = decref_if_owned!(function_ps[1].borrow, arguments[1], b);
let b = decref_if_owned!(function_ps[2].borrow, arguments[2], b);
let v = create_call!(function_ps.get(3));
&*self.arena.alloc(Stmt::Let(z, v, l, b))
}
None => unreachable!(),
}
}
roc_module::low_level::LowLevel::ListSortWith => {
match self.param_map.get_symbol(arguments[1], function_layout) {
Some(function_ps) => {
let borrows = [OWNED, FUNCTION, CLOSURE_DATA];
let b = self.add_dec_after_lowlevel(
arguments,
&borrows,
b,
b_live_vars,
);
let v = create_call!(function_ps.get(2));
&*self.arena.alloc(Stmt::Let(z, v, l, b))
}
None => unreachable!(),
}
}
roc_module::low_level::LowLevel::ListWalk
| roc_module::low_level::LowLevel::ListWalkUntil
| roc_module::low_level::LowLevel::ListWalkBackwards
| roc_module::low_level::LowLevel::DictWalk => {
match self.param_map.get_symbol(arguments[2], function_layout) {
Some(function_ps) => {
// borrow data structure based on first argument of the folded function
// borrow the default based on second argument of the folded function
let borrows = [
function_ps[1].borrow,
function_ps[0].borrow,
FUNCTION,
CLOSURE_DATA,
];
let b = self.add_dec_after_lowlevel(
arguments,
&borrows,
b,
b_live_vars,
);
let b = decref_if_owned!(function_ps[1].borrow, arguments[0], b);
let v = create_call!(function_ps.get(2));
&*self.arena.alloc(Stmt::Let(z, v, l, b))
}
None => unreachable!(),
}
}
_ => {
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op);
let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars);
let v = Expr::Call(crate::ir::Call {
call_type,
arguments,
});
&*self.arena.alloc(Stmt::Let(z, v, l, b))
}
}
}
Foreign { .. } => {
let ps = crate::borrow::foreign_borrow_signature(self.arena, arguments.len());
let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars);