mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
revise RC for function pointers
This commit is contained in:
parent
a1731518ad
commit
9d3db2f507
2 changed files with 64 additions and 41 deletions
|
@ -261,6 +261,16 @@ impl<'a> BorrowInfState<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn own_arg(&mut self, x: Symbol) {
|
||||
self.own_var(x);
|
||||
}
|
||||
|
||||
fn own_args(&mut self, xs: &[Symbol]) {
|
||||
for x in xs.iter() {
|
||||
self.own_arg(*x);
|
||||
}
|
||||
}
|
||||
|
||||
/// For each xs[i], if xs[i] is owned, then mark ps[i] as owned.
|
||||
/// We use this action to preserve tail calls. That is, if we have
|
||||
/// a tail call `f xs`, if the i-th parameter is borrowed, but `xs[i]` is owned
|
||||
|
@ -308,31 +318,33 @@ impl<'a> BorrowInfState<'a> {
|
|||
} = e;
|
||||
|
||||
match call_type {
|
||||
ByName {
|
||||
name, arg_layouts, ..
|
||||
}
|
||||
| ByPointer {
|
||||
name, arg_layouts, ..
|
||||
} => {
|
||||
ByName { name, .. } => {
|
||||
// get the borrow signature of the applied function
|
||||
let ps = match self.param_map.get_symbol(*name) {
|
||||
Some(slice) => slice,
|
||||
None => Vec::from_iter_in(
|
||||
arg_layouts.iter().cloned().map(|layout| Param {
|
||||
symbol: Symbol::UNDERSCORE,
|
||||
borrow: false,
|
||||
layout,
|
||||
}),
|
||||
self.arena,
|
||||
)
|
||||
.into_bump_slice(),
|
||||
};
|
||||
match self.param_map.get_symbol(*name) {
|
||||
Some(ps) => {
|
||||
// the return value will be owned
|
||||
self.own_var(z);
|
||||
|
||||
// if the function exects an owned argument (ps), the argument must be owned (args)
|
||||
self.own_args_using_params(arguments, ps);
|
||||
}
|
||||
None => {
|
||||
// this is really an indirect call, but the function was bound to a symbol
|
||||
// the return value will be owned
|
||||
self.own_var(z);
|
||||
|
||||
// if the function exects an owned argument (ps), the argument must be owned (args)
|
||||
self.own_args(arguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ByPointer { .. } => {
|
||||
// the return value will be owned
|
||||
self.own_var(z);
|
||||
|
||||
// if the function exects an owned argument (ps), the argument must be owned (args)
|
||||
self.own_args_using_params(arguments, ps);
|
||||
self.own_args(arguments);
|
||||
}
|
||||
|
||||
LowLevel { op } => {
|
||||
|
|
|
@ -466,35 +466,46 @@ impl<'a> Context<'a> {
|
|||
&*self.arena.alloc(Stmt::Let(z, v, l, b))
|
||||
}
|
||||
|
||||
ByName {
|
||||
name, arg_layouts, ..
|
||||
}
|
||||
| ByPointer {
|
||||
name, arg_layouts, ..
|
||||
} => {
|
||||
ByName { name, .. } => {
|
||||
// get the borrow signature
|
||||
let ps = match self.param_map.get_symbol(*name) {
|
||||
Some(slice) => slice,
|
||||
None => Vec::from_iter_in(
|
||||
arg_layouts.iter().cloned().map(|layout| Param {
|
||||
symbol: Symbol::UNDERSCORE,
|
||||
borrow: false,
|
||||
layout,
|
||||
}),
|
||||
self.arena,
|
||||
)
|
||||
.into_bump_slice(),
|
||||
};
|
||||
match self.param_map.get_symbol(*name) {
|
||||
Some(ps) => {
|
||||
let v = Expr::Call(crate::ir::Call {
|
||||
call_type,
|
||||
arguments,
|
||||
});
|
||||
|
||||
let b = self.add_dec_after_application(arguments, ps, b, b_live_vars);
|
||||
let b = self.arena.alloc(Stmt::Let(z, v, l, b));
|
||||
|
||||
self.add_inc_before(arguments, ps, b, b_live_vars)
|
||||
}
|
||||
None => {
|
||||
// an indirect call that was bound to a name
|
||||
let v = Expr::Call(crate::ir::Call {
|
||||
call_type,
|
||||
arguments,
|
||||
});
|
||||
|
||||
self.add_inc_before_consume_all(
|
||||
arguments,
|
||||
self.arena.alloc(Stmt::Let(z, v, l, b)),
|
||||
b_live_vars,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
ByPointer { .. } => {
|
||||
let v = Expr::Call(crate::ir::Call {
|
||||
call_type,
|
||||
arguments,
|
||||
});
|
||||
|
||||
let b = self.add_dec_after_application(arguments, ps, b, b_live_vars);
|
||||
let b = self.arena.alloc(Stmt::Let(z, v, l, b));
|
||||
|
||||
self.add_inc_before(arguments, ps, b, b_live_vars)
|
||||
self.add_inc_before_consume_all(
|
||||
arguments,
|
||||
self.arena.alloc(Stmt::Let(z, v, l, b)),
|
||||
b_live_vars,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue