summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2024-10-18 15:27:33 +0200
committerGitHub <noreply@github.com>2024-10-18 15:27:33 +0200
commit4b18a9b7897efbe5cee0b1c5eb3ba2c327ef3579 (patch)
tree04e1270662f04680f0584713aeff8b04d882e3a4
parentaa189522c26ba7d7bc34aca07351f7f359e89423 (diff)
parente5fe6b1b822bddeac7e6a6657e6c4885aef2f2d0 (diff)
Merge pull request #213 from jow-/improve-vector-macros
utils: improve vector macros
-rw-r--r--chunk.c45
-rw-r--r--compiler.c86
-rw-r--r--include/ucode/util.h198
-rw-r--r--lexer.c6
-rw-r--r--lib/ubus.c4
-rw-r--r--source.c10
-rw-r--r--types.c36
-rw-r--r--vm.c53
8 files changed, 230 insertions, 208 deletions
diff --git a/chunk.c b/chunk.c
index 5dbd1a1..63a7064 100644
--- a/chunk.c
+++ b/chunk.c
@@ -67,9 +67,7 @@ uc_chunk_add(uc_chunk_t *chunk, uint8_t byte, size_t offset)
uc_offsetinfo_t *offsets = &chunk->debuginfo.offsets;
size_t i;
- uc_vector_grow(chunk);
-
- chunk->entries[chunk->count] = byte;
+ uc_vector_push(chunk, byte);
/* offset info is encoded in bytes, for each byte, the first three bits
* specify the number of source text bytes to advance since the last entry
@@ -81,13 +79,11 @@ uc_chunk_add(uc_chunk_t *chunk, uint8_t byte, size_t offset)
* instructions each */
for (i = offset; i > OFFSETINFO_MAX_BYTES; i -= OFFSETINFO_MAX_BYTES) {
/* advance by 7 bytes */
- uc_vector_grow(offsets);
- offsets->entries[offsets->count++] = OFFSETINFO_ENCODE(OFFSETINFO_MAX_BYTES, 0);
+ uc_vector_push(offsets, OFFSETINFO_ENCODE(OFFSETINFO_MAX_BYTES, 0));
}
/* advance by `i` bytes, count one instruction */
- uc_vector_grow(offsets);
- offsets->entries[offsets->count++] = OFFSETINFO_ENCODE(i, 1);
+ uc_vector_push(offsets, OFFSETINFO_ENCODE(i, 1));
}
/* update instruction count at current offset entry */
@@ -97,18 +93,18 @@ uc_chunk_add(uc_chunk_t *chunk, uint8_t byte, size_t offset)
* emit another offset entry with the initial three bits set to zero */
if (OFFSETINFO_NUM_INSNS(offsets->entries[offsets->count - 1]) >= OFFSETINFO_MAX_INSNS) {
/* advance by 0 bytes, count one instruction */
- uc_vector_grow(offsets);
- offsets->entries[offsets->count++] = OFFSETINFO_ENCODE(0, 1);
+ uc_vector_push(offsets, OFFSETINFO_ENCODE(0, 1));
}
else {
- offsets->entries[offsets->count - 1] = OFFSETINFO_ENCODE(
- OFFSETINFO_NUM_BYTES(offsets->entries[offsets->count - 1]),
- OFFSETINFO_NUM_INSNS(offsets->entries[offsets->count - 1]) + 1
- );
+ uint8_t *prev = uc_vector_last(offsets);
+
+ *prev = OFFSETINFO_ENCODE(
+ OFFSETINFO_NUM_BYTES(*prev),
+ OFFSETINFO_NUM_INSNS(*prev) + 1);
}
}
- return chunk->count++;
+ return chunk->count - 1;
}
void
@@ -124,10 +120,9 @@ uc_chunk_pop(uc_chunk_t *chunk)
n_insns = OFFSETINFO_NUM_INSNS(offsets->entries[offsets->count - 1]);
if (n_insns > 0) {
- offsets->entries[offsets->count - 1] = OFFSETINFO_ENCODE(
- OFFSETINFO_NUM_BYTES(offsets->entries[offsets->count - 1]),
- n_insns - 1
- );
+ uint8_t *prev = uc_vector_last(offsets);
+
+ *prev = OFFSETINFO_ENCODE(OFFSETINFO_NUM_BYTES(*prev), n_insns - 1);
}
else {
offsets->count--;
@@ -162,14 +157,12 @@ uc_chunk_debug_add_variable(uc_chunk_t *chunk, size_t from, size_t to, size_t sl
if (upval)
slot += (size_t)-1 / 2;
- uc_vector_grow(variables);
-
- variables->entries[variables->count].nameidx = uc_vallist_add(varnames, name);
- variables->entries[variables->count].slot = slot;
- variables->entries[variables->count].from = from;
- variables->entries[variables->count].to = to;
-
- variables->count++;
+ uc_vector_push(variables, {
+ .nameidx = uc_vallist_add(varnames, name),
+ .slot = slot,
+ .from = from,
+ .to = to
+ });
}
uc_value_t *
diff --git a/compiler.c b/compiler.c
index b64537a..6e417d2 100644
--- a/compiler.c
+++ b/compiler.c
@@ -823,14 +823,13 @@ uc_compiler_declare_local(uc_compiler_t *compiler, uc_value_t *name, bool consta
}
}
- uc_vector_grow(locals);
-
- locals->entries[locals->count].name = ucv_get(name);
- locals->entries[locals->count].depth = -1;
- locals->entries[locals->count].captured = false;
- locals->entries[locals->count].from = chunk->count;
- locals->entries[locals->count].constant = constant;
- locals->count++;
+ uc_vector_push(locals, {
+ .name = ucv_get(name),
+ .depth = -1,
+ .captured = false,
+ .from = chunk->count,
+ .constant = constant
+ });
return -1;
}
@@ -896,16 +895,16 @@ uc_compiler_add_upval(uc_compiler_t *compiler, size_t idx, bool local, uc_value_
return -1;
}
- uc_vector_grow(upvals);
-
- upvals->entries[upvals->count].local = local;
- upvals->entries[upvals->count].index = idx;
- upvals->entries[upvals->count].name = ucv_get(name);
- upvals->entries[upvals->count].constant = constant;
+ uc_vector_push(upvals, {
+ .local = local,
+ .index = idx,
+ .name = ucv_get(name),
+ .constant = constant
+ });
function->nupvals++;
- return upvals->count++;
+ return upvals->count - 1;
}
static ssize_t
@@ -1618,10 +1617,8 @@ uc_compiler_compile_call(uc_compiler_t *compiler)
if (!uc_compiler_parse_check(compiler, TK_RPAREN)) {
do {
/* if this is a spread arg, remember the argument index */
- if (uc_compiler_parse_match(compiler, TK_ELLIP)) {
- uc_vector_grow(&spreads);
- spreads.entries[spreads.count++] = nargs;
- }
+ if (uc_compiler_parse_match(compiler, TK_ELLIP))
+ uc_vector_push(&spreads, nargs);
/* compile argument expression */
uc_compiler_parse_precedence(compiler, P_ASSIGN);
@@ -2175,14 +2172,14 @@ uc_compiler_declare_internal(uc_compiler_t *compiler, size_t srcpos, const char
uc_chunk_t *chunk = uc_compiler_current_chunk(compiler);
uc_locals_t *locals = &compiler->locals;
- uc_vector_grow(locals);
+ uc_vector_push(locals, {
+ .name = ucv_string_new(name),
+ .depth = compiler->scope_depth,
+ .captured = false,
+ .from = chunk->count
+ });
- locals->entries[locals->count].name = ucv_string_new(name);
- locals->entries[locals->count].depth = compiler->scope_depth;
- locals->entries[locals->count].captured = false;
- locals->entries[locals->count].from = chunk->count;
-
- return locals->count++;
+ return locals->count - 1;
}
static void
@@ -2292,8 +2289,7 @@ uc_compiler_compile_if(uc_compiler_t *compiler)
/* we just compiled an elsif block */
if (!expect_endif && type == TK_ELIF) {
/* emit jump to skip to the end */
- uc_vector_grow(&elifs);
- elifs.entries[elifs.count++] = uc_compiler_emit_jmp(compiler, 0);
+ uc_vector_push(&elifs, uc_compiler_emit_jmp(compiler, 0));
/* point previous conditional jump to beginning of branch */
uc_compiler_set_jmpaddr(compiler, jmpz_off, chunk->count);
@@ -2310,8 +2306,7 @@ uc_compiler_compile_if(uc_compiler_t *compiler)
}
else if (!expect_endif && type == TK_ELSE) {
/* emit jump to skip to the end */
- uc_vector_grow(&elifs);
- elifs.entries[elifs.count++] = uc_compiler_emit_jmp(compiler, 0);
+ uc_vector_push(&elifs, uc_compiler_emit_jmp(compiler, 0));
/* point previous conditional jump to beginning of branch */
uc_compiler_set_jmpaddr(compiler, jmpz_off, chunk->count);
@@ -2746,13 +2741,9 @@ uc_compiler_compile_switch(uc_compiler_t *compiler)
* For the `default` case, beginning and end offsets of the
* condition expression are equal.
*/
- uc_vector_grow(&cases);
+ uc_vector_extend(&cases, 3);
cases.entries[cases.count++] = (locals->count - 1) - value_slot;
-
- uc_vector_grow(&cases);
cases.entries[cases.count++] = chunk->count;
-
- uc_vector_grow(&cases);
cases.entries[cases.count++] = chunk->count;
}
@@ -2770,13 +2761,9 @@ uc_compiler_compile_switch(uc_compiler_t *compiler)
* 2) beginning of condition expression
* 3) end of condition expression
*/
- uc_vector_grow(&cases);
+ uc_vector_extend(&cases, 3);
cases.entries[cases.count++] = (locals->count - 1) - value_slot;
-
- uc_vector_grow(&cases);
cases.entries[cases.count++] = skip_jmp + 5;
-
- uc_vector_grow(&cases);
cases.entries[cases.count++] = uc_compiler_emit_jmp(compiler, 0);
/* patch jump skipping over the case value */
@@ -2911,13 +2898,12 @@ uc_compiler_compile_try(uc_compiler_t *compiler)
/* Catch block ---------------------------------------------------------- */
if (try_to > try_from) {
- uc_vector_grow(ranges);
-
- ranges->entries[ranges->count].from = try_from;
- ranges->entries[ranges->count].to = try_to;
- ranges->entries[ranges->count].target = chunk->count;
- ranges->entries[ranges->count].slot = ehvar_slot;
- ranges->count++;
+ uc_vector_push(ranges, {
+ .from = try_from,
+ .to = try_to,
+ .target = chunk->count,
+ .slot = ehvar_slot
+ });
}
uc_compiler_enter_scope(compiler);
@@ -2983,10 +2969,8 @@ uc_compiler_compile_control(uc_compiler_t *compiler)
uc_compiler_emit_insn(compiler, 0,
locals->entries[i - 1].captured ? I_CUPV : I_POP);
- uc_vector_grow(p);
-
- p->entries[p->count++] =
- uc_compiler_emit_jmp_dest(compiler, pos, chunk->count + type);
+ uc_vector_push(p,
+ uc_compiler_emit_jmp_dest(compiler, pos, chunk->count + type));
uc_compiler_parse_consume(compiler, TK_SCOL);
}
diff --git a/include/ucode/util.h b/include/ucode/util.h
index a3692d5..cc92e33 100644
--- a/include/ucode/util.h
+++ b/include/ucode/util.h
@@ -30,6 +30,14 @@
#define __hidden __attribute__((visibility("hidden")))
#endif
+#ifndef localfunc
+# if defined(__GNUC__) || defined(__clang__)
+# define localfunc static __attribute__((noinline,unused))
+# else
+# define localfunc static inline
+# endif
+#endif
+
/* alignment & array size */
@@ -42,69 +50,6 @@
#endif
-/* vector macros */
-
-#define UC_VECTOR_CHUNK_SIZE 8
-
-#define uc_declare_vector(name, type) \
- typedef struct { \
- size_t count; \
- type *entries; \
- } name
-
-#define uc_vector_grow(vec) \
- do { \
- if (((vec)->count % UC_VECTOR_CHUNK_SIZE) == 0) { \
- (vec)->entries = xrealloc((vec)->entries, sizeof((vec)->entries[0]) * ((vec)->count + UC_VECTOR_CHUNK_SIZE)); \
- memset(&(vec)->entries[(vec)->count], 0, sizeof((vec)->entries[0]) * UC_VECTOR_CHUNK_SIZE); \
- } \
- } while(0)
-
-#define uc_vector_clear(vec) \
- do { \
- free((vec)->entries); \
- (vec)->entries = NULL; \
- (vec)->count = 0; \
- } while(0)
-
-#define uc_vector_first(vec) \
- (&((vec)->entries[0]))
-
-#define uc_vector_last(vec) \
- (&((vec)->entries[(vec)->count - 1]))
-
-#define uc_vector_push(vec, val) do { \
- uc_vector_grow(vec); \
- (vec)->entries[(vec)->count++] = (val); \
-} while(0)
-
-
-/* linked lists */
-
-typedef struct uc_list {
- struct uc_list *prev;
- struct uc_list *next;
-} uc_list_t;
-
-static inline void uc_list_insert(uc_list_t *list, uc_list_t *item)
-{
- list->next->prev = item;
- item->next = list->next;
- item->prev = list;
- list->next = item;
-}
-
-static inline void uc_list_remove(uc_list_t *item)
-{
- item->next->prev = item->prev;
- item->prev->next = item->next;
- item->prev = item->next = item;
-}
-
-#define uc_list_foreach(item, list) \
- for (uc_list_t *item = (list)->next; item != (list); item = item->next)
-
-
/* "failsafe" utility functions */
static inline void *xcalloc(size_t size, size_t nmemb) {
@@ -195,4 +140,131 @@ static inline struct printbuf *xprintbuf_new(void) {
return pb;
}
+
+/* linked lists */
+
+typedef struct uc_list {
+ struct uc_list *prev;
+ struct uc_list *next;
+} uc_list_t;
+
+static inline void uc_list_insert(uc_list_t *list, uc_list_t *item)
+{
+ list->next->prev = item;
+ item->next = list->next;
+ item->prev = list;
+ list->next = item;
+}
+
+static inline void uc_list_remove(uc_list_t *item)
+{
+ item->next->prev = item->prev;
+ item->prev->next = item->next;
+ item->prev = item->next = item;
+}
+
+#define uc_list_foreach(item, list) \
+ for (uc_list_t *item = (list)->next; item != (list); item = item->next)
+
+
+/* vector macros */
+
+#define UC_VECTOR_INIT_SIZE 8
+
+#define uc_declare_vector(name, type) \
+ typedef struct { \
+ size_t count; \
+ type *entries; \
+ } name
+
+localfunc size_t
+uc_vector_capacity(size_t init, size_t count)
+{
+ if (count == 0)
+ return init;
+
+ size_t capacity = init;
+
+ while (capacity <= count)
+ capacity += (capacity >> 1);
+
+ return capacity;
+}
+
+localfunc void
+uc_vector_reduce_(char **base, size_t itemsize, size_t count, size_t remove)
+{
+ if (*base == NULL)
+ return;
+
+ if (remove > count)
+ remove = count;
+
+ size_t next_capacity = uc_vector_capacity(UC_VECTOR_INIT_SIZE, count - remove);
+
+ if (uc_vector_capacity(next_capacity, count) != next_capacity)
+ *base = (__typeof__(*base))xrealloc(*base, itemsize * next_capacity);
+}
+
+localfunc void *
+uc_vector_extend_(char **base, size_t itemsize, size_t count, size_t add)
+{
+ size_t curr_capacity = uc_vector_capacity(UC_VECTOR_INIT_SIZE, count);
+
+ if (*base == NULL || count + add >= curr_capacity) {
+ size_t next_capacity = uc_vector_capacity(curr_capacity, count + add);
+
+ *base = (__typeof__(*base))xrealloc(*base, itemsize * next_capacity);
+
+ memset(*base + itemsize * count, 0,
+ itemsize * (next_capacity - count));
+ }
+
+ return *base + itemsize * count;
+}
+
+#define uc_vector_reduce(vec, remove) \
+ uc_vector_reduce_((char **)&(vec)->entries, sizeof((vec)->entries[0]), (vec)->count, (remove))
+
+#define uc_vector_extend(vec, add) \
+ (__typeof__((vec)->entries + 0)) uc_vector_extend_( \
+ (char **)&(vec)->entries, \
+ sizeof((vec)->entries[0]), \
+ (vec)->count, (add))
+
+#define uc_vector_grow(vec) \
+ uc_vector_extend_((char **)&(vec)->entries, sizeof((vec)->entries[0]), (vec)->count, 1)
+
+#define uc_vector_clear(vec) \
+ do { \
+ free((vec)->entries); \
+ (vec)->entries = NULL; \
+ (vec)->count = 0; \
+ } while(0)
+
+#define uc_vector_first(vec) \
+ (&((vec)->entries[0]))
+
+#define uc_vector_last(vec) \
+ ((vec)->count ? &((vec)->entries[(vec)->count - 1]) : NULL)
+
+#define uc_vector_push(vec, ...) ({ \
+ *uc_vector_extend((vec), 1) = ((__typeof__((vec)->entries[0]))__VA_ARGS__); \
+ &(vec)->entries[(vec)->count++]; \
+})
+
+#define uc_vector_pop(vec) \
+ ((vec)->count ? &(vec)->entries[--(vec)->count] : NULL)
+
+#define uc_vector_foreach(vec, iter) \
+ for (__typeof__((vec)->entries + 0) iter = (vec)->entries; \
+ iter < (vec)->entries + (vec)->count; \
+ iter++)
+
+#define uc_vector_foreach_reverse(vec, iter) \
+ for (__typeof__((vec)->entries + 0) iter = (vec)->count \
+ ? (vec)->entries + (vec)->count - 1 : NULL; \
+ iter != NULL && iter >= (vec)->entries; \
+ iter--)
+
#endif /* UCODE_UTIL_H */
diff --git a/lexer.c b/lexer.c
index 52945dc..875e5dd 100644
--- a/lexer.c
+++ b/lexer.c
@@ -153,11 +153,13 @@ emit_op(uc_lexer_t *lex, ssize_t pos, int type, uc_value_t *uv)
static uc_token_t *
emit_buffer(uc_lexer_t *lex, ssize_t pos, int type, const char *strip_trailing_chars) {
uc_token_t *rv = NULL;
+ char *p;
if (lex->buffer.count) {
if (strip_trailing_chars)
- while (lex->buffer.count > 0 && strchr(strip_trailing_chars, *uc_vector_last(&lex->buffer)))
- lex->buffer.count--;
+ for (p = uc_vector_last(&lex->buffer);
+ p && strchr(strip_trailing_chars, *p);
+ lex->buffer.count--, p = uc_vector_last(&lex->buffer));
rv = emit_op(lex, pos, type, ucv_string_new_length(uc_vector_first(&lex->buffer), lex->buffer.count));
diff --git a/lib/ubus.c b/lib/ubus.c
index 36a5674..40711d1 100644
--- a/lib/ubus.c
+++ b/lib/ubus.c
@@ -724,6 +724,7 @@ uc_ubus_defer(uc_vm_t *vm, size_t nargs)
uc_ubus_deferred_t *defer;
uc_ubus_connection_t *c;
enum ubus_msg_status rv;
+ uc_callframe_t *frame;
uint32_t id;
conn_get(vm, &c);
@@ -762,7 +763,8 @@ uc_ubus_defer(uc_vm_t *vm, size_t nargs)
uloop_timeout_set(&defer->timeout, c->timeout * 1000);
res = uc_resource_new(defer_type, defer);
- conn = uc_vector_last(&vm->callframes)->ctx;
+ frame = uc_vector_last(&vm->callframes);
+ conn = frame ? frame->ctx : NULL;
defer->registry_index = request_reg_add(vm, ucv_get(res), ucv_get(replycb), ucv_get(conn));
diff --git a/source.c b/source.c
index 39295f6..e23c24d 100644
--- a/source.c
+++ b/source.c
@@ -157,10 +157,7 @@ uc_source_type_test(uc_source_t *source)
void
uc_source_line_next(uc_source_t *source)
{
- uc_lineinfo_t *lines = &source->lineinfo;
-
- uc_vector_grow(lines);
- lines->entries[lines->count++] = 0x80;
+ uc_vector_push(&source->lineinfo, 0x80);
}
void
@@ -183,11 +180,8 @@ uc_source_line_update(uc_source_t *source, size_t off)
while (off > 0) {
n = (off > 0x7f) ? 0x7f : off;
- uc_vector_grow(lines);
- entry = uc_vector_last(lines);
- entry[1] = n;
+ uc_vector_push(lines, n);
off -= n;
- lines->count++;
}
}
}
diff --git a/types.c b/types.c
index c4bc456..9751e24 100644
--- a/types.c
+++ b/types.c
@@ -705,17 +705,13 @@ ucv_array_new_length(uc_vm_t *vm, size_t length)
{
uc_array_t *array;
- /* XXX */
- length = 0;
-
- array = xalloc(sizeof(*array) + length * sizeof(array->entries[0]));
+ array = xalloc(sizeof(*array));
array->header.type = UC_ARRAY;
array->header.refcount = 1;
- if (length > 0)
- array->count = length;
-
- uc_vector_grow(array);
+ /* preallocate memory */
+ if (length)
+ uc_vector_extend(array, length);
if (vm) {
ucv_ref(&vm->values, &array->ref);
@@ -779,10 +775,9 @@ ucv_array_unshift(uc_value_t *uv, uc_value_t *item)
if (ucv_type(uv) != UC_ARRAY)
return NULL;
- array->count++;
- uc_vector_grow(array);
+ uc_vector_extend(array, 1);
- for (i = array->count; i > 1; i--)
+ for (i = ++array->count; i > 1; i--)
array->entries[i - 1] = array->entries[i - 2];
array->entries[0] = item;
@@ -826,10 +821,9 @@ ucv_array_delete(uc_value_t *uv, size_t offset, size_t count)
&array->entries[offset + count],
(array->count - (offset + count)) * sizeof(array->entries[0]));
+ uc_vector_reduce(array, count);
array->count -= count;
- uc_vector_grow(array);
-
return true;
}
@@ -837,24 +831,13 @@ bool
ucv_array_set(uc_value_t *uv, size_t index, uc_value_t *item)
{
uc_array_t *array = (uc_array_t *)uv;
- size_t old_count, new_count;
if (ucv_type(uv) != UC_ARRAY)
return false;
if (index >= array->count) {
- old_count = array->count;
- new_count = (index + 1) & ~(UC_VECTOR_CHUNK_SIZE - 1);
-
- if (new_count > old_count) {
- array->count = new_count;
- uc_vector_grow(array);
- }
-
+ uc_vector_extend(array, index + 1 - array->count);
array->count = index + 1;
-
- while (old_count < array->count)
- array->entries[old_count++] = NULL;
}
else {
ucv_put(array->entries[index]);
@@ -1151,8 +1134,7 @@ ucv_resource_type_add(uc_vm_t *vm, const char *name, uc_value_t *proto, void (*f
type->proto = proto;
type->free = freefn;
- uc_vector_grow(&vm->restypes);
- vm->restypes.entries[vm->restypes.count++] = type;
+ uc_vector_push(&vm->restypes, type);
return type;
}
diff --git a/vm.c b/vm.c
index b492236..3dd054b 100644
--- a/vm.c
+++ b/vm.c
@@ -431,11 +431,7 @@ uc_vm_resolve_upval(uc_vm_t *vm, uc_value_t *value)
void
uc_vm_stack_push(uc_vm_t *vm, uc_value_t *value)
{
- uc_vector_grow(&vm->stack);
-
- ucv_put(vm->stack.entries[vm->stack.count]);
- vm->stack.entries[vm->stack.count] = uc_vm_resolve_upval(vm, value);
- vm->stack.count++;
+ uc_vector_push(&vm->stack, value);
if (vm->trace) {
fprintf(stderr, " [+%zd] %s\n",
@@ -488,14 +484,13 @@ uc_vm_call_native(uc_vm_t *vm, uc_value_t *ctx, uc_cfunction_t *fptr, bool mcall
uc_callframe_t *frame;
/* add new callframe */
- uc_vector_grow(&vm->callframes);
-
- frame = &vm->callframes.entries[vm->callframes.count++];
- frame->stackframe = vm->stack.count - nargs - 1;
- frame->cfunction = fptr;
- frame->closure = NULL;
- frame->ctx = ctx;
- frame->mcall = mcall;
+ frame = uc_vector_push(&vm->callframes, {
+ .stackframe = vm->stack.count - nargs - 1,
+ .cfunction = fptr,
+ .closure = NULL,
+ .ctx = ctx,
+ .mcall = mcall
+ });
if (vm->trace)
uc_vm_frame_dump(vm, frame);
@@ -641,16 +636,15 @@ uc_vm_call_function(uc_vm_t *vm, uc_value_t *ctx, uc_value_t *fno, bool mcall, s
}
}
- uc_vector_grow(&vm->callframes);
-
- frame = &vm->callframes.entries[vm->callframes.count++];
- frame->stackframe = stackoff;
- frame->cfunction = NULL;
- frame->closure = closure;
- frame->ctx = ctx;
- frame->ip = function->chunk.entries;
- frame->mcall = mcall;
- frame->strict = function->strict;
+ frame = uc_vector_push(&vm->callframes, {
+ .stackframe = stackoff,
+ .cfunction = NULL,
+ .closure = closure,
+ .ctx = ctx,
+ .ip = function->chunk.entries,
+ .mcall = mcall,
+ .strict = function->strict
+ });
if (vm->trace)
uc_vm_frame_dump(vm, frame);
@@ -3033,13 +3027,12 @@ uc_vm_execute(uc_vm_t *vm, uc_program_t *program, uc_value_t **retval)
uc_stringbuf_t *buf;
uc_value_t *val;
- uc_vector_grow(&vm->callframes);
-
- frame = &vm->callframes.entries[vm->callframes.count++];
- frame->closure = closure;
- frame->stackframe = 0;
- frame->ip = uc_vm_frame_chunk(frame)->entries;
- frame->strict = fn->strict;
+ frame = uc_vector_push(&vm->callframes, {
+ .closure = closure,
+ .stackframe = 0,
+ .ip = closure->function->chunk.entries,
+ .strict = fn->strict
+ });
if (vm->trace) {
buf = xprintbuf_new();