diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-02-26 18:07:52 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-02-26 18:07:52 -0800 |
commit | aed2929055ee8de978da739fbeaec7112418fc1d (patch) | |
tree | 6fa1b5eab4e214fa8254a81761fc837a37a4412f | |
parent | 5e1f318d5097dbe5443ffad3e258e950a062a5fe (diff) | |
download | mu-aed2929055ee8de978da739fbeaec7112418fc1d.tar.gz |
2716 - more holes in immutability checks
We're still not done. Layer 60 doesn't yet handle variables in surrounding spaces. There's probably other issues..
-rw-r--r-- | 060immutable.cc | 103 | ||||
-rw-r--r-- | 078table.mu | 6 | ||||
-rw-r--r-- | edit/004-programming-environment.mu | 6 | ||||
-rw-r--r-- | edit/005-sandbox.mu | 2 |
4 files changed, 104 insertions, 13 deletions
diff --git a/060immutable.cc b/060immutable.cc index 532746a5..b715bec2 100644 --- a/060immutable.cc +++ b/060immutable.cc @@ -60,7 +60,7 @@ recipe foo x:address:shared:number [ load-ingredients *x <- copy 34 ] -+error: foo: cannot modify ingredient x in instruction '*x <- copy 34' because it's not also a product of foo ++error: foo: cannot modify x in instruction '*x <- copy 34' because it's not also a product of foo :(scenario cannot_take_address_inside_immutable_ingredients) % Hide_errors = true; @@ -112,6 +112,87 @@ recipe foo p:address:shared:point [ ] +error: foo: cannot modify q after instruction 'x:address:number <- get-address *q, x:offset' because that would modify ingredient p which is not also a product of foo +:(scenario can_modify_copies_of_mutable_ingredients) +recipe main [ + local-scope + p:address:shared:point <- new point:type + foo p +] +recipe foo p:address:shared:point -> p:address:shared:point [ + local-scope + load-ingredients + q:address:shared:point <- copy p + x:address:number <- get-address *q, x:offset +] +$error: 0 + +:(scenario cannot_modify_address_inside_immutable_ingredients) +% Hide_errors = true; +container foo [ + x:address:shared:array:number # contains an address +] +recipe main [ + # don't run anything +] +recipe foo a:address:shared:foo [ + local-scope + load-ingredients + x:address:shared:array:number <- get *a, x:offset # just a regular get of the container + y:address:number <- index-address *x, 0 # but then index-address on the result + *y <- copy 34 +] ++error: foo: cannot modify x after instruction 'y:address:number <- index-address *x, 0' because that would modify ingredient a which is not also a product of foo + +:(scenario cannot_modify_address_inside_immutable_ingredients_2) +container foo [ + x:address:shared:array:number # contains an address +] +recipe main [ + # don't run anything +] +recipe foo a:address:shared:foo [ + local-scope + load-ingredients + b:foo <- merge 0 # completely unrelated to 'a' + x:address:shared:array:number <- get b, x:offset # just a regular get of the container + y:address:number <- index-address *x, 0 # but then index-address on the result + *y <- copy 34 +] +$error: 0 + +:(scenario cannot_modify_address_inside_immutable_ingredients_3) +% Hide_errors = true; +container foo [ + x:number +] +recipe main [ + # don't run anything +] +recipe foo a:address:shared:array:address:number [ + local-scope + load-ingredients + x:address:number <- index *a, 0 # just a regular index of the array + *x <- copy 34 # but then modify the result +] +# +error: foo: cannot modify x in instruction '*x <- copy 34' because that would modify ingredient a which is not also a product of foo ++error: foo: cannot modify x in instruction '*x <- copy 34' because it's not also a product of foo + +:(scenario cannot_modify_address_inside_immutable_ingredients_4) +container foo [ + x:address:shared:array:number # contains an address +] +recipe main [ + # don't run anything +] +recipe foo a:address:shared:array:address:number [ + local-scope + load-ingredients + b:address:shared:array:address:number <- new {(address number): type}, 3 # completely unrelated to 'a' + x:address:number <- index *b, 0 # just a regular index of the array + *x <- copy 34 # but then modify the result +] +$error: 0 + :(scenario can_traverse_immutable_ingredients) container test-list [ next:address:shared:test-list @@ -182,10 +263,20 @@ void update_aliases(const instruction& inst, set<string>& current_ingredient_and set<long long int> current_ingredient_indices = ingredient_indices(inst, current_ingredient_and_aliases); if (!contains_key(Recipe, inst.operation)) { // primitive recipe - if (inst.operation == COPY) { - for (set<long long int>::iterator p = current_ingredient_indices.begin(); p != current_ingredient_indices.end(); ++p) { - current_ingredient_and_aliases.insert(inst.products.at(*p).name); - } + switch (inst.operation) { + case COPY: + for (set<long long int>::iterator p = current_ingredient_indices.begin(); p != current_ingredient_indices.end(); ++p) + current_ingredient_and_aliases.insert(inst.products.at(*p).name); + break; + case GET: + case INDEX: + // current_ingredient_indices can only have 0 or one value + if (!current_ingredient_indices.empty()) { + if (is_mu_address(inst.products.at(0))) + current_ingredient_and_aliases.insert(inst.products.at(0).name); + } + break; + default: break; } } else { @@ -245,7 +336,7 @@ void check_immutable_ingredient_in_instruction(const instruction& inst, const se for (long long int i = 0; i < SIZE(inst.products); ++i) { if (has_property(inst.products.at(i), "lookup") && current_ingredient_and_aliases.find(inst.products.at(i).name) != current_ingredient_and_aliases.end()) { - raise << maybe(caller.name) << "cannot modify ingredient " << inst.products.at(i).name << " in instruction '" << to_string(inst) << "' because it's not also a product of " << caller.name << '\n' << end(); + raise << maybe(caller.name) << "cannot modify " << inst.products.at(i).name << " in instruction '" << to_string(inst) << "' because it's not also a product of " << caller.name << '\n' << end(); return; } } diff --git a/078table.mu b/078table.mu index 09613a15..a58b210b 100644 --- a/078table.mu +++ b/078table.mu @@ -55,8 +55,8 @@ recipe index table:address:shared:table:_key:_value, key:_key -> result:_value [ capacity:number <- get *table, capacity:offset _, hash <- divide-with-remainder hash, capacity table-data:address:shared:array:table_row:_key:_value <- get *table, data:offset - x:address:table_row:_key:_value <- index-address *table-data, hash - occupied?:boolean <- get *x, occupied?:offset + x:table_row:_key:_value <- index *table-data, hash + occupied?:boolean <- get x, occupied?:offset assert occupied?, [can't handle missing elements yet] - result <- get *x, value:offset + result <- get x, value:offset ] diff --git a/edit/004-programming-environment.mu b/edit/004-programming-environment.mu index c712c09b..75d14245 100644 --- a/edit/004-programming-environment.mu +++ b/edit/004-programming-environment.mu @@ -372,7 +372,7 @@ def] ] ] -recipe render-all screen:address:shared:screen, env:address:shared:programming-environment-data -> screen:address:shared:screen [ +recipe render-all screen:address:shared:screen, env:address:shared:programming-environment-data -> screen:address:shared:screen, env:address:shared:programming-environment-data [ local-scope load-ingredients trace 10, [app], [render all] @@ -405,7 +405,7 @@ recipe render-all screen:address:shared:screen, env:address:shared:programming-e show-screen screen ] -recipe render-recipes screen:address:shared:screen, env:address:shared:programming-environment-data -> screen:address:shared:screen [ +recipe render-recipes screen:address:shared:screen, env:address:shared:programming-environment-data -> screen:address:shared:screen, env:address:shared:programming-environment-data [ local-scope load-ingredients trace 11, [app], [render recipes] @@ -424,7 +424,7 @@ recipe render-recipes screen:address:shared:screen, env:address:shared:programmi ] # replaced in a later layer -recipe render-sandbox-side screen:address:shared:screen, env:address:shared:programming-environment-data -> screen:address:shared:screen [ +recipe render-sandbox-side screen:address:shared:screen, env:address:shared:programming-environment-data -> screen:address:shared:screen, env:address:shared:programming-environment-data [ local-scope load-ingredients current-sandbox:address:shared:editor-data <- get *env, current-sandbox:offset diff --git a/edit/005-sandbox.mu b/edit/005-sandbox.mu index 48935761..4f96e55e 100644 --- a/edit/005-sandbox.mu +++ b/edit/005-sandbox.mu @@ -237,7 +237,7 @@ recipe save-sandboxes env:address:shared:programming-environment-data [ } ] -recipe! render-sandbox-side screen:address:shared:screen, env:address:shared:programming-environment-data -> screen:address:shared:screen [ +recipe! render-sandbox-side screen:address:shared:screen, env:address:shared:programming-environment-data -> screen:address:shared:screen, env:address:shared:programming-environment-data [ local-scope load-ingredients trace 11, [app], [render sandbox side] |