@@ -49,6 +49,8 @@ struct l2_vm_value { | |||
union { | |||
l2_word ns_parent; | |||
l2_word cont_call; | |||
l2_word buf_length; | |||
l2_word arr_length; | |||
} extra; | |||
// Byte 4: 1 byte, 3 bytes padding | |||
@@ -58,7 +60,7 @@ struct l2_vm_value { | |||
union { | |||
l2_word atom; | |||
double real; | |||
struct l2_vm_buffer *buffer; | |||
char *buffer; | |||
struct l2_vm_array *array; | |||
struct l2_vm_namespace *ns; | |||
struct { | |||
@@ -73,13 +75,7 @@ struct l2_vm_value { | |||
#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 { | |||
size_t len; | |||
size_t size; | |||
l2_word data[]; | |||
}; |
@@ -24,18 +24,13 @@ static void print_val(struct l2_vm *vm, struct l2_io_writer *out, struct l2_vm_v | |||
case L2_VAL_TYPE_BUFFER: | |||
if (val->buffer != NULL) { | |||
out->write(out, val->buffer->data, val->buffer->len); | |||
out->write(out, val->buffer, val->extra.buf_length); | |||
} | |||
break; | |||
case L2_VAL_TYPE_ARRAY: | |||
if (val->array == NULL) { | |||
out->write(out, "[]", 2); | |||
break; | |||
} | |||
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) { | |||
out->write(out, " ", 1); | |||
} | |||
@@ -200,11 +195,11 @@ l2_word l2_builtin_eq(struct l2_vm *vm, l2_word argc, l2_word *argv) { | |||
return vm->kfalse; | |||
} | |||
if (a->buffer->len != b->buffer->len) { | |||
if (a->extra.buf_length != b->extra.buf_length) { | |||
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; | |||
} | |||
} else { | |||
@@ -288,15 +283,11 @@ l2_word l2_builtin_len(struct l2_vm *vm, l2_word argc, l2_word *argv) { | |||
break; | |||
case L2_VAL_TYPE_BUFFER: | |||
if (val->buffer) { | |||
ret->real = val->buffer->len; | |||
} | |||
ret->real = val->extra.buf_length; | |||
break; | |||
case L2_VAL_TYPE_ARRAY: | |||
if (val->array) { | |||
ret->real = val->array->len; | |||
} | |||
ret->real = val->extra.arr_length; | |||
break; | |||
case L2_VAL_TYPE_NAMESPACE: |
@@ -58,8 +58,8 @@ void l2_vm_print_val(struct l2_vm_value *val) { | |||
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]); | |||
} | |||
} | |||
@@ -72,9 +72,9 @@ void l2_vm_print_val(struct l2_vm_value *val) { | |||
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; |
@@ -61,7 +61,7 @@ static void gc_mark_array(struct l2_vm *vm, struct l2_vm_value *val) { | |||
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]); | |||
} | |||
} | |||
@@ -360,8 +360,8 @@ static void call_func( | |||
vm->values[arr_id].flags = L2_VAL_TYPE_ARRAY; | |||
vm->values[arr_id].array = malloc( | |||
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; | |||
arr->len = argc; | |||
arr->size = argc; | |||
for (l2_word i = 0; i < argc; ++i) { | |||
@@ -564,11 +564,9 @@ void l2_vm_step(struct l2_vm *vm) { | |||
l2_word length = read(vm); \ | |||
l2_word offset = read(vm); \ | |||
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->sptr += 1; | |||
case L2_OP_ALLOC_BUFFER_STATIC_U4: { X(read_u4le); } break; | |||
@@ -580,13 +578,13 @@ void l2_vm_step(struct l2_vm *vm) { | |||
l2_word arr_id = alloc_val(vm); \ | |||
struct l2_vm_value *arr = &vm->values[arr_id]; \ | |||
arr->flags = L2_VAL_TYPE_ARRAY; \ | |||
arr->extra.arr_length = count; \ | |||
if (count == 0) { \ | |||
arr->array = NULL; \ | |||
vm->stack[vm->sptr++] = arr_id; \ | |||
break; \ | |||
} \ | |||
arr->array = malloc(sizeof(struct l2_vm_array) + count * sizeof(l2_word)); \ | |||
arr->array->len = count; \ | |||
arr->array->size = count; \ | |||
for (l2_word i = 0; i < count; ++i) { \ | |||
arr->array->data[count - 1 - i] = vm->stack[--vm->sptr]; \ |