diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-06-15 17:00:26 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-06-15 17:13:04 -0700 |
commit | d292196ff5ab9f103364e05c42a1edc03dc1b5ab (patch) | |
tree | 2e80472fd9d248f3631903aaf2282f7e0831a075 /apps | |
parent | 5a6d2d0db7ccc1d6b09ce898e3b57f62a5b1b787 (diff) | |
download | mu-d292196ff5ab9f103364e05c42a1edc03dc1b5ab.tar.gz |
6529 - don't let `addr`s escape functions
I've gone back and forth on this. I initially disallowed this, then allowed it because I forgot why I disallowed it. The reason to disallow it: if you return an `addr` to a variable allocated on the stack, the space might be reused for a different type, which violates type-safety. And once you can reinterpret bits of one type as another you lose memory-safety as well. This has some interesting implications for Mu programs; certain kinds of helper functions become impossible to write. Now I find myself relying a lot more on scopes (and editor folding support) for abstracting details. And they won't help manage duplication. We'll see how this goes. While I'm being draconian about `addr`s on the stack, I'm still abusing `addr`s on the heap, with the expectation that future checks on reclamation will protect me. The boon and bane of stack space is that it's constantly reclaimed.
Diffstat (limited to 'apps')
-rw-r--r-- | apps/browse.mu | 40 | ||||
-rw-r--r-- | apps/mu.subx | 3 |
2 files changed, 24 insertions, 19 deletions
diff --git a/apps/browse.mu b/apps/browse.mu index 10dd65b1..4a7ab2c1 100644 --- a/apps/browse.mu +++ b/apps/browse.mu @@ -6,9 +6,27 @@ # # Press 'q' to quit. All other keys scroll down. -fn main args: (addr array (addr array byte)) -> exit-status/ebx: int { - var filename/eax: (addr array byte) <- first-arg args - var file/esi: (addr buffered-file) <- load-file filename +fn main args-on-stack: (addr array (addr array byte)) -> exit-status/ebx: int { + # var file/esi: (addr buffered-file) = open args-on-stack[1] for reading {{{ + var file/esi: (addr buffered-file) <- copy 0 + { + var file-handle: (handle buffered-file) + { + var address-of-file-handle/esi: (addr handle buffered-file) <- address file-handle + # var filename/ecx: (addr array byte) = args-on-stack[1] {{{ + var filename/ecx: (addr array byte) <- copy 0 + { + var args/eax: (addr array (addr array byte)) <- copy args-on-stack + var tmp/eax: (addr addr array byte) <- index args, 1 + filename <- copy *tmp + } + # }}} + open filename, 0, address-of-file-handle + } + var tmp/eax: (addr buffered-file) <- lookup file-handle + file <- copy tmp + } + # }}} enable-screen-grid-mode var nrows/eax: int <- copy 0 var ncols/ecx: int <- copy 0 @@ -154,22 +172,6 @@ fn clear toprow: int, leftcol: int, botrow: int, rightcol: int { } } -fn first-arg args-on-stack: (addr array (addr array byte)) -> out/eax: (addr array byte) { - var args/eax: (addr array (addr array byte)) <- copy args-on-stack - var result/eax: (addr addr array byte) <- index args, 1 - out <- copy *result -} - -fn load-file filename: (addr array byte) -> out/esi: (addr buffered-file) { - var result: (handle buffered-file) - { - var tmp1/eax: (addr handle buffered-file) <- address result - open filename, 0, tmp1 - } - var tmp2/eax: (addr buffered-file) <- lookup result - out <- copy tmp2 -} - fn dump in: (addr buffered-file) { var c/eax: byte <- read-byte-buffered in compare c, 0xffffffff # EOF marker diff --git a/apps/mu.subx b/apps/mu.subx index 70ad482d..cd08466e 100644 --- a/apps/mu.subx +++ b/apps/mu.subx @@ -4638,6 +4638,9 @@ $parse-mu:error2: # ✓ fn foo x: int { # ✓ fn foo x: int { # ✓ fn foo x: int -> y/eax: int { +# TODO: +# disallow outputs of type `(... addr ...)` +# disallow inputs of type `(... addr ... addr ...)` populate-mu-function-header: # first-line: (addr stream byte), out: (addr function), vars: (addr stack live-var), err: (addr buffered-file), ed: (addr exit-descriptor) # pseudocode: # var name: slice |