harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

commit c086f8d7c7c76db1b55649e6ca5a506e32333e39
parent f6369572ec56f72d8449306face08cbb216e8740
Author: Pierre Curto <pierre.curto@gmail.com>
Date:   Wed, 23 Nov 2022 20:26:09 +0100

initialize memory with expandable array in alloc

Fixes: https://todo.sr.ht/~sircmpwn/hare/534

Signed-off-by: Pierre Curto <pierre.curto@gmail.com>

Diffstat:
Msrc/gen.c | 25+++++++++++++++++++++++--
Mtests/17-alloc.ha | 9+++++++++
2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -1859,16 +1859,37 @@ gen_const_array_at(struct gen_context *ctx, size_t n = 0; const struct type *atype = type_dealias(expr->result); + size_t msize = atype->array.members->size; struct gen_value item = mkgtemp(ctx, atype->array.members, "item.%d"); for (const struct array_constant *ac = aexpr; ac; ac = ac->next) { - struct qbe_value offs = constl(n * atype->array.members->size); + struct qbe_value offs = constl(n * msize); struct qbe_value ptr = mklval(ctx, &item); pushi(ctx->current, &ptr, Q_ADD, &base, &offs, NULL); gen_expr_at(ctx, ac->value, item); ++n; } - assert(n == atype->array.length); + if (!atype->array.expandable || n == 0) { + return; + } + assert(out.type); + const struct type_array arr = type_dealias(out.type)->array; + if (arr.length <= n) { + return; + } + + // last copied element + struct qbe_value lsize = constl((n - 1) * msize); + struct qbe_value last = mkqtmp(ctx, ctx->arch.ptr, ".%d"); + pushi(ctx->current, &last, Q_ADD, &base, &lsize, NULL); + // start from the elements already copied + struct qbe_value nsize = constl(n * msize); + struct qbe_value next = mkqtmp(ctx, ctx->arch.ptr, ".%d"); + pushi(ctx->current, &next, Q_ADD, &base, &nsize, NULL); + + struct qbe_value rtmemcpy = mkrtfunc(ctx, "rt.memcpy"); + struct qbe_value qlen = constl((arr.length - n) * msize); + pushi(ctx->current, NULL, Q_CALL, &rtmemcpy, &next, &last, &qlen, NULL); } static void diff --git a/tests/17-alloc.ha b/tests/17-alloc.ha @@ -62,6 +62,15 @@ fn array() void = { free(aa); let aa: nullable *aarray = alloc([0...]: aarray); free(aa); + + let x: *[24]int = alloc([1, 2...]); + + assert(len(x) == 24); + assert(x[0] == 1); + for (let i = 1z; i < len(x); i += 1) { + assert(x[i] == 2); + }; + free(x); }; fn slice() void = {