Skip to content

Commit

Permalink
save system
Browse files Browse the repository at this point in the history
  • Loading branch information
ShawSumma committed May 15, 2024
1 parent 3ad40b1 commit ca67450
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 65 deletions.
13 changes: 1 addition & 12 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,6 @@
"files.associations": {
"*.inc": "c",
"*.c": "c",
"*.h": "c",
"compare": "c",
"cstdint": "c",
"*.tcc": "c",
"optional": "c",
"system_error": "c",
"array": "c",
"functional": "c",
"tuple": "c",
"type_traits": "c",
"utility": "c",
"cstddef": "c"
"*.h": "c"
}
}
25 changes: 18 additions & 7 deletions vm/lua/repl.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,13 +236,17 @@ void vm_lang_lua_repl(vm_config_t *config, vm_table_t *std, vm_blocks_t *blocks)
.std = std,
};

vm_save_t save = vm_save_value((vm_std_value_t) {.tag = VM_TAG_TAB, .value.table = std});
std = vm_load_value(save).value.table;
// FILE *f = fopen("out.bin", "wb");
// if (f != NULL) {
// fwrite(save.buf, 1, save.len, f);
// fclose(f);
// }
{
FILE *f = fopen("out.bin", "rb");
if (f != NULL) {
vm_save_t save = vm_save_load(f);
fclose(f);
vm_std_value_t val = vm_load_value(save);
if (val.tag == VM_TAG_TAB) {
std = val.value.table;
}
}
}

// #if defined(EMSCRIPTEN)
// setvbuf(stdin, NULL, _IONBF, 0);
Expand Down Expand Up @@ -306,5 +310,12 @@ void vm_lang_lua_repl(vm_config_t *config, vm_table_t *std, vm_blocks_t *blocks)

printf("took: %.3fms\n", diff);
}

vm_save_t save = vm_save_value((vm_std_value_t) {.tag = VM_TAG_TAB, .value.table = std});
FILE *f = fopen("out.bin", "wb");
if (f != NULL) {
fwrite(save.buf, 1, save.len, f);
fclose(f);
}
}
}
142 changes: 136 additions & 6 deletions vm/save/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@
struct vm_save_read_t;
typedef struct vm_save_read_t vm_save_read_t;

struct vm_save_value_t;
typedef struct vm_save_value_t vm_save_value_t;

struct vm_save_value_t {
size_t start;
vm_std_value_t value;
};

struct vm_save_read_t {
struct {
size_t len;
vm_std_value_t *ptr;
vm_save_value_t *ptr;
size_t alloc;
} values;

Expand Down Expand Up @@ -61,16 +69,138 @@ vm_std_value_t vm_load_value(vm_save_t arg) {
.buf.len = arg.len,
.buf.bytes = arg.buf,
.buf.read = 0,
.values.len = 0,
.values.ptr = NULL,
.values.alloc = 0,
};
while (!vm_save_read_is_done(&read)) {
vm_tag_t type = (vm_tag_t) vm_save_read_byte(&read);
vm_value_t val;
switch (type) {
size_t start = read.buf.read;
vm_tag_t tag = (vm_tag_t) vm_save_read_byte(&read);
vm_value_t value;
switch (tag) {
case VM_TAG_UNK: {
break;
}
case VM_TAG_NIL: {
value.all = NULL;
break;
}
case VM_TAG_BOOL: {
value.b = vm_save_read_byte(&read) != 0;
break;
}
case VM_TAG_I8: {
value.i8 = (int8_t) vm_save_read_sleb(&read);
break;
}
case VM_TAG_I16: {
value.i16 = (int16_t) vm_save_read_sleb(&read);
break;
}
case VM_TAG_FUN:
case VM_TAG_I32: {
value.i32 = (int32_t) vm_save_read_sleb(&read);
break;
}
case VM_TAG_I64: {
value.i64 = (int64_t) vm_save_read_sleb(&read);
break;
}
case VM_TAG_F32: {
uint32_t n = (uint32_t) vm_save_read_uleb(&read);
value.f32 = *(float *)&n;
break;
}
case VM_TAG_F64: {
uint64_t n = vm_save_read_uleb(&read);
value.f64 = *(double *)&n;
break;
}
case VM_TAG_ERROR:
case VM_TAG_STR: {
uint64_t len = vm_save_read_uleb(&read);
char *buf = vm_malloc(sizeof(char) * len);
for (size_t i = 0; i < len; i++) {
buf[i] = vm_save_read_byte(&read);
}
value.str = buf;
break;
}
case VM_TAG_FFI: {
value.all = (void *) (size_t) vm_save_read_uleb(&read);
break;
}
case VM_TAG_CLOSURE: {
uint64_t len = vm_save_read_uleb(&read);
vm_std_value_t *closure = vm_malloc(sizeof(vm_std_value_t) * (len + 1));
closure[0] = (vm_std_value_t) {
.tag = VM_TAG_I32,
.value.i32 = (int32_t) (uint32_t) len,
};
closure += 1;
for (size_t i = 0; i < len; i++) {
vm_save_read_uleb(&read);
}
value.closure = closure;
}
case VM_TAG_TAB: {
uint64_t real = vm_save_read_uleb(&read);
vm_table_t *table = vm_table_new();
for (size_t i = 0; i < real; i++) {
vm_save_read_uleb(&read);
vm_save_read_uleb(&read);
}
value.table = table;
break;
}
default: {
fprintf(stderr, "unhandled object #%zu at [%zu]: type %zu\n", read.values.len, start, (size_t) tag);
goto error;
}
}
if (read.values.len + 1 >= read.values.alloc) {
read.values.alloc = (read.values.len + 1) * 2;
read.values.ptr = vm_realloc(read.values.ptr, sizeof(vm_save_value_t) * read.values.alloc);
}
read.values.ptr[read.values.len++] = (vm_save_value_t) {
.start = start,
.value = (vm_std_value_t) {
.tag = tag,
.value = value,
},
};
}
for (size_t i = 0; i < read.values.len; i++) {
vm_save_value_t save = read.values.ptr[i];
vm_value_t value = save.value.value;
read.buf.read = save.start;
vm_tag_t tag = (vm_tag_t) vm_save_read_byte(&read);
switch (tag) {
case VM_TAG_CLOSURE: {
uint64_t len = vm_save_read_uleb(&read);
vm_std_value_t *closure = value.closure;
for (uint64_t i = 0; i < len; i++) {
size_t value_index = vm_save_read_uleb(&read);
closure[i] = read.values.ptr[value_index].value;
}
break;
}
case VM_TAG_TAB: {
uint64_t real = vm_save_read_uleb(&read);
vm_table_t *table = value.table;
for (size_t i = 0; i < real; i++) {
size_t key_index = vm_save_read_uleb(&read);
size_t value_index = vm_save_read_uleb(&read);
VM_TABLE_SET_VALUE(table, read.values.ptr[key_index].value, read.values.ptr[value_index].value);
}
break;
}
default: {
fprintf("unhandled object %zu at %zu\n", read.values.len, read.buf.read);
break;
}
}
}
return read.values.ptr[0];
return read.values.ptr[0].value;
error:;
return (vm_std_value_t) {.tag = VM_TAG_NIL};
}
3 changes: 2 additions & 1 deletion vm/save/save.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ struct vm_save_t {
uint8_t *buf;
};

vm_save_t vm_save_value(vm_std_value_t arg);
vm_save_t vm_save_load(FILE *file);
vm_std_value_t vm_load_value(vm_save_t arg);
vm_save_t vm_save_value(vm_std_value_t arg);

#endif
Loading

0 comments on commit ca67450

Please sign in to comment.