hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit ebb371e6409074aa037052c83c93ccc110232f28
parent 2a10eb194237b03e83ab9bdda579c20e814156cb
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 12 Feb 2021 14:11:14 -0500

all: improve slice allocation usage

Diffstat:
Mfmt/fmt.ha | 2+-
Mrt/ensure.ha | 12+++++++++---
Mrt/malloc.ha | 9+++++----
Mstrings/tokenize.ha | 2+-
4 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/fmt/fmt.ha b/fmt/fmt.ha @@ -207,7 +207,7 @@ fn format( }; fn scan_uint(iter: *strings::iterator) uint = { - let num = alloc([]u8, [], 1); // TODO: alloc slice w/o cap + let num = alloc([]u8, []); defer free(num); for (true) { let r = match (strings::next(iter)) { diff --git a/rt/ensure.ha b/rt/ensure.ha @@ -5,10 +5,16 @@ export type slice = struct { }; export fn ensure(s: *slice, membsz: size, length: size) void = { - // TODO: make sure length * membsz < SIZE_MAX - for (s.capacity < length) { - s.capacity *= 2; + let cap = s.capacity; + for (cap < length) { + assert(cap >= s.capacity, "slice out of memory (overflow)"); + if (cap == 0) { + cap = length; + } else { + cap *= 2; + }; }; + s.capacity = cap; let data = realloc(s.data, s.capacity * membsz); assert(data != null); s.data = data; diff --git a/rt/malloc.ha b/rt/malloc.ha @@ -47,8 +47,8 @@ fn size2bin(s: size) size = { // Allocates n bytes of memory and returns a pointer to them, or null if there // is insufficient memory. export fn malloc(n: size) nullable *void = { - assert(n > 0); - return if (n > bin2size(len(bins) - 1)) malloc_large(n) + return if (n == 0) null + else if (n > bin2size(len(bins) - 1)) malloc_large(n) else malloc_small(n); }; @@ -135,8 +135,9 @@ fn free_small(p: *void, s: size) void = { // in-place. Returns null if there is insufficient memory to support the // request. export fn realloc(_p: nullable *void, n: size) nullable *void = { - assert(n > 0); - if (_p == null) { + if (n == 0) { + return null; + } else if (_p == null) { return malloc(n); }; diff --git a/strings/tokenize.ha b/strings/tokenize.ha @@ -54,7 +54,7 @@ export fn remaining_tokens(s: *tokenizer) str = { // borrowed from 'in', and needn't be freed - but should be [strings::dup_all]'d // if they should outlive 'in'. export fn splitN(in: str, delim: str, n: size) []str = { - let toks = alloc([]str, [], 8); // TODO: Drop explicit capacity + let toks = alloc([]str, []); let tok = tokenize(in, delim); for (let i = 0z; i < n - 1z; i += 1) { match (next_token(&tok)) {