// SPDX-License-Identifier: MIT // Copyright (c) 2023 John Watts and the LuminaSensum contributors #include "list.h" #include "object.h" #include "vm.h" #include <stddef.h> static struct object_class object_list_class; struct object_list { int length; Object elems[]; }; Object object_list_create(VmState state, int length) { size_t elem_size = sizeof(Object) * length; size_t size = sizeof(struct object_list) + elem_size; Object obj = object_create(state, &object_list_class, size); struct object_list *list = (struct object_list *)object_priv( state, obj, &object_list_class); list->length = length; for (int i = 0; i < length; ++i) list->elems[i] = object_none(); return obj; } static void object_list_cleanup(VmState state, Object obj) { struct object_list *list = (struct object_list *)object_priv( state, obj, &object_list_class); for (int i = 0; i < list->length; ++i) object_drop(state, &(list->elems[i])); } int object_list_length(VmState state, Object obj) { struct object_list *list = (struct object_list *)object_priv( state, obj, &object_list_class); return list->length; } void object_list_set(VmState state, Object obj, int index, Object new) { struct object_list *list = (struct object_list *)object_priv( state, obj, &object_list_class); vm_abort_if(state, index < 0, "object_list_get: index too small"); vm_abort_if(state, index >= list->length, "object_list_get: index too large"); object_drop(state, &(list->elems[index])); list->elems[index] = new; } Object object_list_get(VmState state, Object obj, int index) { struct object_list *list = (struct object_list *)object_priv( state, obj, &object_list_class); vm_abort_if(state, index < 0, "object_list_get: index too small"); vm_abort_if(state, index >= list->length, "object_list_get: index too large"); Object new = list->elems[index]; object_hold(state, new); return new; } static struct object_call object_list_calls[] = {{.name = NULL, /* end */}}; static struct object_class object_list_class = { .cleanup = object_list_cleanup, .calls = &object_list_calls[0], };