-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mir: separate index/bound checks from array access (#1076)
## Summary * code generators don't decide index and bound check placement -- the AST -> MIR translation does * data-flow analysis considers index and bound errors, fixing destructors not being run when the only possibly raised exception is an `IndexDefect` * bound checks are performed for `toOpenArray` calls when using the JS backend * MIR semantics: allow mutations of projection from aliases created with `Bind` ## Details ### Translation changes A statement like `arr[i] = (inc i; 1)` was previously translated to: ``` def _1 = i bind_mut _1 = arr[_1] inc(name i) _2 = 1 ``` It is now translated to: ``` def _1 = i chckIndex(arg arr, arg _1) inc(name i) arr[_1] = 1 ``` Similarily, `call(toOpenArray(a, lo, hi))` is now translated to: ``` chckBounds(arg a, arg lo, arg hi) def _1 = toOpenArray(arg a, arg lo, arg hi) call(arg _1) ``` ### Consequences * `mnkPathArray` never has side-effects now * `mnkToSlice` never has side-effects now * exceptional control-flow arising from index and bound checks encoded in the MIR, making it accessible for data-flow analysis * decision making regarding the initial placement of index and bound checks happens in a single place instead of in each code generator * code generators no longer need to query the local `optBoundChecks` option This is progress towards: * an optimization pass that eliminates redundant index and bound checks * making all lvalue expressions free of side-effects * all possible exceptional control-flow being encoded in the MIR * restoring local `.push`/`.pop` support for all checks ### Implementation details * index and bound checks are represented in the MIR via the new internal `mChckIndex` and `mChckBounds` magics * `isPure` and `isStable` analysis is simplified, now that `mnkPathArray` is free of side-effects * the operand in the array slot of an `nkBracketExpr` may be either an rvalue, lvalue, or literal. The new `mirgen.capture` procedure implements the logic for correctly capturing the operand * `jsgen` now implements code generation for bound checks **Changes to the VM:** * the `opcIndexCheck` opcode is introduced; it implements the index check (`mChckIndex`) * the index check logic is removed from all handle-computation-only operation; the access checks of memory load/store operations ensures that memory safety is not compromised. Operations that write directly to a memory location (`opcWrStrIdx` and `opcWrArr`) still need to perform the index check ### MIR semantics For for both efficiency and implementation simplicity, aliases created through the `Bind` statement support indirect mutations (e.g., `x.a = 1`), but not direct assignments or being passed to a mutable by-name parameter. Without this adjustment, `mirgen.capture` would need to know whether a projection (e.g., `x[1]` or `x.a`) of the alias is used for mutation. --------- Co-authored-by: Saem Ghani <saemghani+github@gmail.com>
- Loading branch information
Showing
17 changed files
with
374 additions
and
187 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.