mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
refactor
This commit is contained in:
parent
032104e02b
commit
8f5956fdfe
1 changed files with 94 additions and 106 deletions
|
@ -569,54 +569,6 @@ impl<'a> Context<'a> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! handle_ownership_post {
|
|
||||||
($ownership:expr, $argument:expr, $stmt:expr) => {
|
|
||||||
match $ownership {
|
|
||||||
DataOwnedFunctionOwns | DataBorrowedFunctionOwns => {
|
|
||||||
// elements have been consumed, must still consume the list itself
|
|
||||||
let rest = self.arena.alloc($stmt);
|
|
||||||
let rc = Stmt::Refcounting(ModifyRc::DecRef($argument), rest);
|
|
||||||
|
|
||||||
&*self.arena.alloc(rc)
|
|
||||||
}
|
|
||||||
DataOwnedFunctionBorrows => {
|
|
||||||
// must consume list and elements
|
|
||||||
let rest = self.arena.alloc($stmt);
|
|
||||||
let rc = Stmt::Refcounting(ModifyRc::Dec($argument), rest);
|
|
||||||
|
|
||||||
&*self.arena.alloc(rc)
|
|
||||||
}
|
|
||||||
DataBorrowedFunctionBorrows => {
|
|
||||||
// list borrows, function borrows, so there is nothing to do
|
|
||||||
$stmt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! handle_ownership_pre {
|
|
||||||
($ownership:expr, $argument:expr, $stmt:expr) => {
|
|
||||||
match $ownership {
|
|
||||||
DataBorrowedFunctionOwns => {
|
|
||||||
// the data is borrowed;
|
|
||||||
// increment it to own the values so the function can use them
|
|
||||||
let rest = self.arena.alloc($stmt);
|
|
||||||
let rc = Stmt::Refcounting(ModifyRc::Inc($argument, 1), rest);
|
|
||||||
|
|
||||||
self.arena.alloc(rc)
|
|
||||||
}
|
|
||||||
DataOwnedFunctionOwns | DataOwnedFunctionBorrows => {
|
|
||||||
// we actually own the data; nothing to do
|
|
||||||
$stmt
|
|
||||||
}
|
|
||||||
DataBorrowedFunctionBorrows => {
|
|
||||||
// list borrows, function borrows, so there is nothing to do
|
|
||||||
$stmt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const FUNCTION: bool = BORROWED;
|
const FUNCTION: bool = BORROWED;
|
||||||
const CLOSURE_DATA: bool = BORROWED;
|
const CLOSURE_DATA: bool = BORROWED;
|
||||||
|
|
||||||
|
@ -633,6 +585,66 @@ impl<'a> Context<'a> {
|
||||||
None => unreachable!(),
|
None => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
macro_rules! handle_ownerships_post {
|
||||||
|
($stmt:expr, $args:expr) => {{
|
||||||
|
let mut stmt = $stmt;
|
||||||
|
|
||||||
|
for (argument, function_ps) in $args.iter().copied() {
|
||||||
|
let ownership = DataFunction::new(&self.vars, argument, function_ps);
|
||||||
|
|
||||||
|
match ownership {
|
||||||
|
DataOwnedFunctionOwns | DataBorrowedFunctionOwns => {
|
||||||
|
// elements have been consumed, must still consume the list itself
|
||||||
|
let rest = self.arena.alloc($stmt);
|
||||||
|
let rc = Stmt::Refcounting(ModifyRc::DecRef(argument), rest);
|
||||||
|
|
||||||
|
stmt = self.arena.alloc(rc);
|
||||||
|
}
|
||||||
|
DataOwnedFunctionBorrows => {
|
||||||
|
// must consume list and elements
|
||||||
|
let rest = self.arena.alloc($stmt);
|
||||||
|
let rc = Stmt::Refcounting(ModifyRc::Dec(argument), rest);
|
||||||
|
|
||||||
|
stmt = self.arena.alloc(rc);
|
||||||
|
}
|
||||||
|
DataBorrowedFunctionBorrows => {
|
||||||
|
// list borrows, function borrows, so there is nothing to do
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! handle_ownerships_pre {
|
||||||
|
($stmt:expr, $args:expr) => {{
|
||||||
|
let mut stmt = self.arena.alloc($stmt);
|
||||||
|
|
||||||
|
for (argument, function_ps) in $args.iter().copied() {
|
||||||
|
let ownership = DataFunction::new(&self.vars, argument, function_ps);
|
||||||
|
|
||||||
|
match ownership {
|
||||||
|
DataBorrowedFunctionOwns => {
|
||||||
|
// the data is borrowed;
|
||||||
|
// increment it to own the values so the function can use them
|
||||||
|
let rc = Stmt::Refcounting(ModifyRc::Inc(argument, 1), stmt);
|
||||||
|
|
||||||
|
stmt = self.arena.alloc(rc);
|
||||||
|
}
|
||||||
|
DataOwnedFunctionOwns | DataOwnedFunctionBorrows => {
|
||||||
|
// we actually own the data; nothing to do
|
||||||
|
}
|
||||||
|
DataBorrowedFunctionBorrows => {
|
||||||
|
// list borrows, function borrows, so there is nothing to do
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
let borrows = [FUNCTION, CLOSURE_DATA];
|
let borrows = [FUNCTION, CLOSURE_DATA];
|
||||||
let after_arguments = &arguments[op.function_index()..];
|
let after_arguments = &arguments[op.function_index()..];
|
||||||
|
|
||||||
|
@ -644,86 +656,68 @@ impl<'a> Context<'a> {
|
||||||
| ListAny { xs }
|
| ListAny { xs }
|
||||||
| ListAll { xs }
|
| ListAll { xs }
|
||||||
| ListFindUnsafe { xs } => {
|
| ListFindUnsafe { xs } => {
|
||||||
let ownership1 = DataFunction::new(&self.vars, xs, function_ps[0]);
|
let ownerships = [(xs, function_ps[0])];
|
||||||
|
|
||||||
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
||||||
|
|
||||||
let b = handle_ownership_post!(ownership1, xs, b);
|
let b = handle_ownerships_post!(b, ownerships);
|
||||||
|
|
||||||
let v = create_call!(function_ps.get(1));
|
let v = create_call!(function_ps.get(1));
|
||||||
|
|
||||||
let b = &*self.arena.alloc(Stmt::Let(z, v, l, b));
|
handle_ownerships_pre!(Stmt::Let(z, v, l, b), ownerships)
|
||||||
|
|
||||||
handle_ownership_pre!(ownership1, xs, b)
|
|
||||||
}
|
}
|
||||||
ListMap2 { xs, ys } => {
|
ListMap2 { xs, ys } => {
|
||||||
let ownership1 = DataFunction::new(&self.vars, xs, function_ps[0]);
|
let ownerships = [(xs, function_ps[0]), (ys, function_ps[1])];
|
||||||
let ownership2 = DataFunction::new(&self.vars, ys, function_ps[1]);
|
|
||||||
|
|
||||||
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
||||||
|
|
||||||
let b = handle_ownership_post!(ownership1, xs, b);
|
let b = handle_ownerships_post!(b, ownerships);
|
||||||
let b = handle_ownership_post!(ownership2, ys, b);
|
|
||||||
|
|
||||||
let v = create_call!(function_ps.get(2));
|
let v = create_call!(function_ps.get(2));
|
||||||
|
|
||||||
let b = &*self.arena.alloc(Stmt::Let(z, v, l, b));
|
handle_ownerships_pre!(Stmt::Let(z, v, l, b), ownerships)
|
||||||
|
|
||||||
let b = handle_ownership_pre!(ownership1, xs, b);
|
|
||||||
handle_ownership_pre!(ownership2, ys, b)
|
|
||||||
}
|
}
|
||||||
ListMap3 { xs, ys, zs } => {
|
ListMap3 { xs, ys, zs } => {
|
||||||
let ownership1 = DataFunction::new(&self.vars, xs, function_ps[0]);
|
let ownerships = [
|
||||||
let ownership2 = DataFunction::new(&self.vars, ys, function_ps[1]);
|
(xs, function_ps[0]),
|
||||||
let ownership3 = DataFunction::new(&self.vars, zs, function_ps[2]);
|
(ys, function_ps[1]),
|
||||||
|
(zs, function_ps[2]),
|
||||||
|
];
|
||||||
|
|
||||||
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
||||||
|
|
||||||
let b = handle_ownership_post!(ownership1, xs, b);
|
let b = handle_ownerships_post!(b, ownerships);
|
||||||
let b = handle_ownership_post!(ownership2, ys, b);
|
|
||||||
let b = handle_ownership_post!(ownership3, zs, b);
|
|
||||||
|
|
||||||
let v = create_call!(function_ps.get(3));
|
let v = create_call!(function_ps.get(3));
|
||||||
|
|
||||||
let b = &*self.arena.alloc(Stmt::Let(z, v, l, b));
|
handle_ownerships_pre!(Stmt::Let(z, v, l, b), ownerships)
|
||||||
|
|
||||||
let b = handle_ownership_pre!(ownership1, xs, b);
|
|
||||||
let b = handle_ownership_pre!(ownership2, ys, b);
|
|
||||||
handle_ownership_pre!(ownership3, zs, b)
|
|
||||||
}
|
}
|
||||||
ListMap4 { xs, ys, zs, ws } => {
|
ListMap4 { xs, ys, zs, ws } => {
|
||||||
let ownership1 = DataFunction::new(&self.vars, xs, function_ps[0]);
|
let ownerships = [
|
||||||
let ownership2 = DataFunction::new(&self.vars, ys, function_ps[1]);
|
(xs, function_ps[0]),
|
||||||
let ownership3 = DataFunction::new(&self.vars, zs, function_ps[2]);
|
(ys, function_ps[1]),
|
||||||
let ownership4 = DataFunction::new(&self.vars, ws, function_ps[3]);
|
(zs, function_ps[2]),
|
||||||
|
(ws, function_ps[3]),
|
||||||
|
];
|
||||||
|
|
||||||
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
||||||
|
|
||||||
let b = handle_ownership_post!(ownership1, xs, b);
|
let b = handle_ownerships_post!(b, ownerships);
|
||||||
let b = handle_ownership_post!(ownership2, ys, b);
|
|
||||||
let b = handle_ownership_post!(ownership3, zs, b);
|
|
||||||
let b = handle_ownership_post!(ownership4, ws, b);
|
|
||||||
|
|
||||||
let v = create_call!(function_ps.get(3));
|
let v = create_call!(function_ps.get(3));
|
||||||
|
|
||||||
let b = &*self.arena.alloc(Stmt::Let(z, v, l, b));
|
handle_ownerships_pre!(Stmt::Let(z, v, l, b), ownerships)
|
||||||
|
|
||||||
let b = handle_ownership_pre!(ownership1, xs, b);
|
|
||||||
let b = handle_ownership_pre!(ownership2, ys, b);
|
|
||||||
handle_ownership_pre!(ownership3, zs, b)
|
|
||||||
}
|
}
|
||||||
ListMapWithIndex { xs } => {
|
ListMapWithIndex { xs } => {
|
||||||
let ownership1 = DataFunction::new(&self.vars, xs, function_ps[1]);
|
let ownerships = [(xs, function_ps[0])];
|
||||||
|
|
||||||
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
||||||
|
|
||||||
let b = handle_ownership_post!(ownership1, xs, b);
|
let b = handle_ownerships_post!(b, ownerships);
|
||||||
|
|
||||||
let v = create_call!(function_ps.get(2));
|
let v = create_call!(function_ps.get(2));
|
||||||
|
|
||||||
let b = &*self.arena.alloc(Stmt::Let(z, v, l, b));
|
handle_ownerships_pre!(Stmt::Let(z, v, l, b), ownerships)
|
||||||
|
|
||||||
handle_ownership_pre!(ownership1, xs, b)
|
|
||||||
}
|
}
|
||||||
ListSortWith { xs } => {
|
ListSortWith { xs } => {
|
||||||
// NOTE: we may apply the function to the same argument multiple times.
|
// NOTE: we may apply the function to the same argument multiple times.
|
||||||
|
@ -731,40 +725,34 @@ impl<'a> Context<'a> {
|
||||||
// enforced at the moment
|
// enforced at the moment
|
||||||
//
|
//
|
||||||
// we also don't check that both arguments have the same ownership characteristics
|
// we also don't check that both arguments have the same ownership characteristics
|
||||||
let ownership1 = DataFunction::new(&self.vars, xs, function_ps[0]);
|
let ownerships = [(xs, function_ps[0])];
|
||||||
|
|
||||||
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
||||||
|
|
||||||
let b = handle_ownership_post!(ownership1, xs, b);
|
let b = handle_ownerships_post!(b, ownerships);
|
||||||
|
|
||||||
let v = create_call!(function_ps.get(2));
|
let v = create_call!(function_ps.get(2));
|
||||||
|
|
||||||
let b = &*self.arena.alloc(Stmt::Let(z, v, l, b));
|
handle_ownerships_pre!(Stmt::Let(z, v, l, b), ownerships)
|
||||||
|
|
||||||
handle_ownership_pre!(ownership1, xs, b)
|
|
||||||
}
|
}
|
||||||
ListWalk { xs, state }
|
ListWalk { xs, state }
|
||||||
| ListWalkUntil { xs, state }
|
| ListWalkUntil { xs, state }
|
||||||
| ListWalkBackwards { xs, state }
|
| ListWalkBackwards { xs, state }
|
||||||
| DictWalk { xs, state } => {
|
| DictWalk { xs, state } => {
|
||||||
// borrow data structure based on second argument of the folded function
|
let ownerships = [
|
||||||
let ownership1 = DataFunction::new(&self.vars, xs, function_ps[1]);
|
// borrow data structure based on second argument of the folded function
|
||||||
|
(xs, function_ps[1]),
|
||||||
|
];
|
||||||
// borrow the default based on first argument of the folded function
|
// borrow the default based on first argument of the folded function
|
||||||
// let ownership2 = DataFunction::new(&self.vars, state, function_ps[0]);
|
// (state, function_ps[0])
|
||||||
|
|
||||||
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
let b = self.add_dec_after_lowlevel(after_arguments, &borrows, b, b_live_vars);
|
||||||
|
|
||||||
let b = handle_ownership_post!(ownership1, xs, b);
|
let b = handle_ownerships_post!(b, ownerships);
|
||||||
// let b = handle_ownership_post!(ownership2, state, b);
|
|
||||||
|
|
||||||
let v = create_call!(function_ps.get(2));
|
let v = create_call!(function_ps.get(2));
|
||||||
|
|
||||||
let b = &*self.arena.alloc(Stmt::Let(z, v, l, b));
|
handle_ownerships_pre!(Stmt::Let(z, v, l, b), ownerships)
|
||||||
|
|
||||||
let b = handle_ownership_pre!(ownership1, xs, b);
|
|
||||||
// handle_ownership_pre!(ownership2, state, b)
|
|
||||||
b
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue