2767 - reclaim refcounts for local variables
This uncovered a second bug (besides 2766) -- I was manually doing the work of 'new-fake-console' inside 'assume-console' but forgetting to increment a refcount.
This commit is contained in:
parent
194c4ed71d
commit
d8f2d0b130
34
043space.cc
34
043space.cc
|
@ -211,6 +211,14 @@ def foo [
|
|||
# both calls to foo should have received the same default-space
|
||||
+mem: storing 1 in location 3
|
||||
|
||||
:(scenario local_scope_frees_up_allocations)
|
||||
def main [
|
||||
local-scope
|
||||
x:address:shared:array:character <- new [abc]
|
||||
]
|
||||
+mem: clearing x:address:shared:array:character
|
||||
|
||||
//: todo: do this in a transform, rather than magically in the reply instruction
|
||||
:(after "Falling Through End Of Recipe")
|
||||
try_reclaim_locals();
|
||||
:(after "Starting Reply")
|
||||
|
@ -231,10 +239,36 @@ void try_reclaim_locals() {
|
|||
if (exiting_recipe.steps.empty()) return;
|
||||
const instruction& inst = exiting_recipe.steps.at(0);
|
||||
if (inst.old_name != "local-scope") return;
|
||||
// reclaim any local variables unless they're being returned
|
||||
vector<double> zero;
|
||||
zero.push_back(0);
|
||||
for (long long int i = /*leave default space for last*/1; i < SIZE(exiting_recipe.steps); ++i) {
|
||||
const instruction& inst = exiting_recipe.steps.at(i);
|
||||
for (long long int i = 0; i < SIZE(inst.products); ++i) {
|
||||
if (!is_mu_address(inst.products.at(i))) continue;
|
||||
// local variables only
|
||||
if (has_property(inst.products.at(i), "space")) continue;
|
||||
if (has_property(inst.products.at(i), "lookup")) continue;
|
||||
if (escaping(inst.products.at(i))) continue;
|
||||
trace(9999, "mem") << "clearing " << inst.products.at(i).original_string << end();
|
||||
write_memory(inst.products.at(i), zero);
|
||||
}
|
||||
}
|
||||
abandon(current_call().default_space,
|
||||
/*refcount*/1 + /*array length*/1 + /*number-of-locals*/Name[r][""]);
|
||||
}
|
||||
|
||||
// is this reagent one of the values returned by the current (reply) instruction?
|
||||
bool escaping(const reagent& r) {
|
||||
// nothing escapes when you fall through past end of recipe
|
||||
if (current_step_index() >= SIZE(Current_routine->steps())) return false;
|
||||
for (long long i = 0; i < SIZE(current_instruction().ingredients); ++i) {
|
||||
if (r == current_instruction().ingredients.at(i))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void rewrite_default_space_instruction(instruction& curr) {
|
||||
if (!curr.ingredients.empty())
|
||||
raise << to_string(curr) << " can't take any ingredients\n" << end();
|
||||
|
|
|
@ -119,6 +119,8 @@ case ASSUME_CONSOLE: {
|
|||
long long int console_address = get_or_insert(Memory, CONSOLE);
|
||||
trace(9999, "mem") << "storing console data in " << console_address+2 << end();
|
||||
put(Memory, console_address+/*skip refcount*/1+/*offset of 'data' in container 'events'*/1, event_data_address);
|
||||
// increment refcount for event data
|
||||
put(Memory, event_data_address, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user