Browse Source

store array/buffer length in the l2_vm_value itself

master
Martin Dørum 3 years ago
parent
commit
dd620958b7
4 changed files with 20 additions and 35 deletions
  1. 3
    7
      include/lang2/vm/vm.h
  2. 6
    15
      lib/vm/builtins.c
  3. 5
    5
      lib/vm/print.c
  4. 6
    8
      lib/vm/vm.c

+ 3
- 7
include/lang2/vm/vm.h View File

union { union {
l2_word ns_parent; l2_word ns_parent;
l2_word cont_call; l2_word cont_call;
l2_word buf_length;
l2_word arr_length;
} extra; } extra;


// Byte 4: 1 byte, 3 bytes padding // Byte 4: 1 byte, 3 bytes padding
union { union {
l2_word atom; l2_word atom;
double real; double real;
struct l2_vm_buffer *buffer;
char *buffer;
struct l2_vm_array *array; struct l2_vm_array *array;
struct l2_vm_namespace *ns; struct l2_vm_namespace *ns;
struct { struct {


#define l2_vm_value_type(val) ((enum l2_value_type)((val)->flags & 0x0f)) #define l2_vm_value_type(val) ((enum l2_value_type)((val)->flags & 0x0f))


struct l2_vm_buffer {
size_t len;
char data[];
};

struct l2_vm_array { struct l2_vm_array {
size_t len;
size_t size; size_t size;
l2_word data[]; l2_word data[];
}; };

+ 6
- 15
lib/vm/builtins.c View File



case L2_VAL_TYPE_BUFFER: case L2_VAL_TYPE_BUFFER:
if (val->buffer != NULL) { if (val->buffer != NULL) {
out->write(out, val->buffer->data, val->buffer->len);
out->write(out, val->buffer, val->extra.buf_length);
} }
break; break;


case L2_VAL_TYPE_ARRAY: case L2_VAL_TYPE_ARRAY:
if (val->array == NULL) {
out->write(out, "[]", 2);
break;
}

out->write(out, "[", 1); out->write(out, "[", 1);
for (size_t i = 0; i < val->array->len; ++i) {
for (size_t i = 0; i < val->extra.arr_length; ++i) {
if (i != 0) { if (i != 0) {
out->write(out, " ", 1); out->write(out, " ", 1);
} }
return vm->kfalse; return vm->kfalse;
} }


if (a->buffer->len != b->buffer->len) {
if (a->extra.buf_length != b->extra.buf_length) {
return vm->kfalse; return vm->kfalse;
} }


if (memcmp(a->buffer->data, b->buffer->data, a->buffer->len) != 0) {
if (memcmp(a->buffer, b->buffer, a->extra.buf_length) != 0) {
return vm->kfalse; return vm->kfalse;
} }
} else { } else {
break; break;


case L2_VAL_TYPE_BUFFER: case L2_VAL_TYPE_BUFFER:
if (val->buffer) {
ret->real = val->buffer->len;
}
ret->real = val->extra.buf_length;
break; break;


case L2_VAL_TYPE_ARRAY: case L2_VAL_TYPE_ARRAY:
if (val->array) {
ret->real = val->array->len;
}
ret->real = val->extra.arr_length;
break; break;


case L2_VAL_TYPE_NAMESPACE: case L2_VAL_TYPE_NAMESPACE:

+ 5
- 5
lib/vm/print.c View File

return; return;
} }


printf("ARRAY, len %zu\n", val->array->len);
for (size_t i = 0; i < val->array->len; ++i) {
printf("ARRAY, len %u\n", val->extra.arr_length);
for (size_t i = 0; i < val->extra.arr_length; ++i) {
printf(" %zu: %u\n", i, val->array->data[i]); printf(" %zu: %u\n", i, val->array->data[i]);
} }
} }
return; return;
} }


printf("BUFFER, len %zu\n", val->buffer->len);
for (size_t i = 0; i < val->buffer->len; ++i) {
printf(" %zu: %c\n", i, val->buffer->data[i]);
printf("BUFFER, len %u\n", val->extra.buf_length);
for (size_t i = 0; i < val->extra.buf_length; ++i) {
printf(" %zu: %c\n", i, val->buffer[i]);
} }
} }
break; break;

+ 6
- 8
lib/vm/vm.c View File

return; return;
} }


for (size_t i = 0; i < val->array->len; ++i) {
for (size_t i = 0; i < val->extra.arr_length; ++i) {
gc_mark(vm, val->array->data[i]); gc_mark(vm, val->array->data[i]);
} }
} }
vm->values[arr_id].flags = L2_VAL_TYPE_ARRAY; vm->values[arr_id].flags = L2_VAL_TYPE_ARRAY;
vm->values[arr_id].array = malloc( vm->values[arr_id].array = malloc(
sizeof(struct l2_vm_array) + sizeof(l2_word) * argc); sizeof(struct l2_vm_array) + sizeof(l2_word) * argc);
vm->values[arr_id].extra.arr_length = argc;
struct l2_vm_array *arr = vm->values[arr_id].array; struct l2_vm_array *arr = vm->values[arr_id].array;
arr->len = argc;
arr->size = argc; arr->size = argc;


for (l2_word i = 0; i < argc; ++i) { for (l2_word i = 0; i < argc; ++i) {
l2_word length = read(vm); \ l2_word length = read(vm); \
l2_word offset = read(vm); \ l2_word offset = read(vm); \
vm->values[word].flags = L2_VAL_TYPE_BUFFER; \ vm->values[word].flags = L2_VAL_TYPE_BUFFER; \
vm->values[word].buffer = malloc(sizeof(struct l2_vm_buffer) + length); \
vm->values[word].buffer->len = length; \
memcpy( \
(unsigned char *)vm->values[word].buffer + sizeof(struct l2_vm_buffer), \
vm->ops + offset, length); \
vm->values[word].buffer = length > 0 ? malloc(length) : NULL; \
vm->values[word].extra.buf_length = length; \
memcpy(vm->values[word].buffer, vm->ops + offset, length); \
vm->stack[vm->sptr] = word; \ vm->stack[vm->sptr] = word; \
vm->sptr += 1; vm->sptr += 1;
case L2_OP_ALLOC_BUFFER_STATIC_U4: { X(read_u4le); } break; case L2_OP_ALLOC_BUFFER_STATIC_U4: { X(read_u4le); } break;
l2_word arr_id = alloc_val(vm); \ l2_word arr_id = alloc_val(vm); \
struct l2_vm_value *arr = &vm->values[arr_id]; \ struct l2_vm_value *arr = &vm->values[arr_id]; \
arr->flags = L2_VAL_TYPE_ARRAY; \ arr->flags = L2_VAL_TYPE_ARRAY; \
arr->extra.arr_length = count; \
if (count == 0) { \ if (count == 0) { \
arr->array = NULL; \ arr->array = NULL; \
vm->stack[vm->sptr++] = arr_id; \ vm->stack[vm->sptr++] = arr_id; \
break; \ break; \
} \ } \
arr->array = malloc(sizeof(struct l2_vm_array) + count * sizeof(l2_word)); \ arr->array = malloc(sizeof(struct l2_vm_array) + count * sizeof(l2_word)); \
arr->array->len = count; \
arr->array->size = count; \ arr->array->size = count; \
for (l2_word i = 0; i < count; ++i) { \ for (l2_word i = 0; i < count; ++i) { \
arr->array->data[count - 1 - i] = vm->stack[--vm->sptr]; \ arr->array->data[count - 1 - i] = vm->stack[--vm->sptr]; \

Loading…
Cancel
Save