This commit is contained in:
Folkert 2022-05-06 10:26:44 +02:00
parent 032104e02b
commit 8f5956fdfe
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C

View file

@ -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
} }
} }
} }