diff options
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/rt.zc | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/src/runtime/rt.zc b/src/runtime/rt.zc index ee3594d..a54d88c 100644 --- a/src/runtime/rt.zc +++ b/src/runtime/rt.zc @@ -760,7 +760,10 @@ word .u new_t(int n, int t) { if (dbg & 1) note_alloc(p, alloc_line); return p; } -// allocate n words without a type stamp; the caller owns the fresh object. +// new(n) allocates n zeroed words without a type stamp. new(T) and new(T, n) allocate +// a fresh heap object of type T (n of them for the second form) and stamp T in its +// header; the compiler rewrites those forms to new_t or new_k. the caller owns it, +// and the analyzer frees it when its owner's block ends. word .u new(int n) { return new_t(n, 0); } // the compiler works out the size class of a constant-size new at compile // time (k is the class of n + HDR words), so a repeated allocation of the same @@ -1380,3 +1383,28 @@ char* .u readfile(char* path) { syscall(SYS_CLOSE, fd, 0, 0); return buf; } +// reads a file's bytes into an owned block, one byte to a word after a length word: +// [n, b0, b1, ...]. unlike readfile, a 0 byte in the file is kept. returns null if +// opening fails. +word.u readbytes(char* path) { + int fd; word buf; int n = 0, got, cap; word nb; + fd = syscall(SYS_OPEN, path, 0, 0); + if (fd < 0) return 0; + cap = 256; + buf = new(cap); + while (1) { + if (n + 130 >= cap) { + nb = new(cap + cap); + copy_w(nb, buf, n + 1); + free(buf); + buf = nb; + cap = cap + cap; + } + got = syscall(SYS_READ, fd, buf + 1 + n, 128); + if (got <= 0) break; + n = n + got; + } + buf[0] = n; + syscall(SYS_CLOSE, fd, 0, 0); + return buf; +} |
