Merge pull request #172 from kichikuou/RSMv9

resume: Support RSM v9 format
This commit is contained in:
Nunuhara Cabbage
2024-08-05 21:33:52 -07:00
committed by GitHub
3 changed files with 78 additions and 22 deletions
+11 -5
View File
@@ -66,11 +66,17 @@ struct page {
int index;
enum ain_data_type a_type;
};
// array-specific metadata
struct {
int struct_type;
int rank;
} array;
union {
// local-specific metadata
struct {
int struct_ptr;
} local;
// array-specific metadata
struct {
int struct_type;
int rank;
} array;
};
int nr_vars;
union vm_value values[];
};
+63 -16
View File
@@ -154,10 +154,11 @@ static cJSON *vm_image_to_json(const char *key)
return image;
}
static struct rsave_heap_frame *frame_page_to_rsave(struct page *page, int ref)
static struct rsave_heap_frame *frame_page_to_rsave(struct page *page, int slot)
{
struct rsave_heap_frame *o = xcalloc(1, sizeof(struct rsave_heap_frame) + page->nr_vars * sizeof(int32_t));
o->ref = ref;
o->ref = heap[slot].ref;
o->seq = heap[slot].seq;
struct ain_variable *vars;
if (page->type == GLOBAL_PAGE) {
o->tag = RSAVE_GLOBALS;
@@ -170,6 +171,7 @@ static struct rsave_heap_frame *frame_page_to_rsave(struct page *page, int ref)
o->func.name = strdup(f->name);
assert(page->nr_vars == f->nr_vars);
vars = f->vars;
o->struct_ptr = page->local.struct_ptr;
}
o->nr_types = page->nr_vars;
o->types = xcalloc(o->nr_types, sizeof(int32_t));
@@ -181,11 +183,12 @@ static struct rsave_heap_frame *frame_page_to_rsave(struct page *page, int ref)
return o;
}
static struct rsave_heap_struct *struct_page_to_rsave(struct page *page, int ref)
static struct rsave_heap_struct *struct_page_to_rsave(struct page *page, int slot)
{
struct rsave_heap_struct *o = xcalloc(1, sizeof(struct rsave_heap_struct) + page->nr_vars * sizeof(int32_t));
o->tag = RSAVE_STRUCT;
o->ref = ref;
o->ref = heap[slot].ref;
o->seq = heap[slot].seq;
struct ain_struct *s = &ain->structures[page->index];
o->ctor.name = strdup(s->constructor >= 0 ? ain->functions[s->constructor].name : "");
o->dtor.name = strdup(s->destructor >= 0 ? ain->functions[s->destructor].name : "");
@@ -201,11 +204,12 @@ static struct rsave_heap_struct *struct_page_to_rsave(struct page *page, int ref
return o;
}
static struct rsave_heap_array *array_page_to_rsave(struct page *page, int ref)
static struct rsave_heap_array *array_page_to_rsave(struct page *page, int slot)
{
struct rsave_heap_array *o = xcalloc(1, sizeof(struct rsave_heap_array) + page->nr_vars * sizeof(int32_t));
o->tag = RSAVE_ARRAY;
o->ref = ref;
o->ref = heap[slot].ref;
o->seq = heap[slot].seq;
o->rank_minus_1 = page->array.rank - 1;
o->data_type = page->index;
if (page->array.struct_type >= 0)
@@ -220,6 +224,18 @@ static struct rsave_heap_array *array_page_to_rsave(struct page *page, int ref)
return o;
}
static struct rsave_heap_delegate *delegate_page_to_rsave(struct page *page, int slot)
{
struct rsave_heap_delegate *o = xcalloc(1, sizeof(struct rsave_heap_delegate) + page->nr_vars * sizeof(int32_t));
o->tag = RSAVE_DELEGATE;
o->ref = heap[slot].ref;
o->seq = heap[slot].seq;
o->nr_slots = page->nr_vars;
for (int i = 0; i < o->nr_slots; i++)
o->slots[i] = page->values[i].i;
return o;
}
static void *heap_item_to_rsave(int i)
{
if (!heap[i].ref)
@@ -229,6 +245,7 @@ static void *heap_item_to_rsave(int i)
struct rsave_heap_string *s = xmalloc(sizeof(struct rsave_heap_string) + len);
s->tag = RSAVE_STRING;
s->ref = heap[i].ref;
s->seq = heap[i].seq;
s->uk = 0;
s->len = len;
memcpy(s->text, heap[i].s->text, len);
@@ -240,6 +257,7 @@ static void *heap_item_to_rsave(int i)
struct rsave_heap_array *o = xcalloc(1, sizeof(struct rsave_heap_array));
o->tag = RSAVE_ARRAY;
o->ref = heap[i].ref;
o->seq = heap[i].seq;
o->rank_minus_1 = -1;
// FIXME: System40.exe populates them but we don't have the type
@@ -255,11 +273,13 @@ static void *heap_item_to_rsave(int i)
switch (page->type) {
case GLOBAL_PAGE:
case LOCAL_PAGE:
return frame_page_to_rsave(page, heap[i].ref);
return frame_page_to_rsave(page, i);
case STRUCT_PAGE:
return struct_page_to_rsave(page, heap[i].ref);
return struct_page_to_rsave(page, i);
case ARRAY_PAGE:
return array_page_to_rsave(page, heap[i].ref);
return array_page_to_rsave(page, i);
case DELEGATE_PAGE:
return delegate_page_to_rsave(page, i);
default:
ERROR("unsupported type %d", page->type);
}
@@ -334,9 +354,13 @@ static void save_func_names_to_rsave(struct rsave *rs)
static struct rsave *make_rsave(const char *key)
{
struct rsave *save = xcalloc(1, sizeof(struct rsave));
// FIXME: This is not always correct. RSM version cannot be determined from
// the ain version alone.
save->version = ain->version <= 4 ? 6 : 7;
if (ain->nr_delegates > 0) {
save->version = 9;
} else {
// FIXME: This is not always correct. Pastel Chime Continue is AIN v4
// but uses RSM v7.
save->version = ain->version <= 4 ? 6 : 7;
}
save->key = strdup(key);
return save;
}
@@ -344,6 +368,7 @@ static struct rsave *make_rsave(const char *key)
static struct rsave *vm_image_to_rsave(const char *key)
{
struct rsave *save = make_rsave(key);
save->next_seq = heap_next_seq;
save_heap_to_rsave(save);
save_call_stack_to_rsave(save);
save_stack_to_rsave(save);
@@ -480,6 +505,7 @@ static void delete_heap(void)
break;
}
heap[i].ref = 0;
heap[i].seq = 0;
}
heap_free_ptr = 0;
@@ -566,6 +592,7 @@ static void load_rsave_frame(int slot, struct rsave_heap_frame *f)
page = alloc_page(LOCAL_PAGE, func, f->nr_slots);
nr_vars = ain->functions[func].nr_vars;
vars = ain->functions[func].vars;
page->local.struct_ptr = f->struct_ptr;
}
// type check
@@ -586,6 +613,7 @@ static void load_rsave_frame(int slot, struct rsave_heap_frame *f)
}
alloc_heap_slot(slot);
heap[slot].ref = f->ref;
heap[slot].seq = f->seq;
heap[slot].type = VM_PAGE;
heap[slot].page = page;
}
@@ -594,6 +622,7 @@ static void load_rsave_string(int slot, struct rsave_heap_string *s)
{
alloc_heap_slot(slot);
heap[slot].ref = s->ref;
heap[slot].seq = s->seq;
heap[slot].type = VM_STRING;
heap[slot].s = make_string(s->text, s->len - 1);
}
@@ -603,6 +632,7 @@ static void load_rsave_array(int slot, struct rsave_heap_array *a)
if (a->rank_minus_1 < 0) {
alloc_heap_slot(slot);
heap[slot].ref = a->ref;
heap[slot].seq = a->seq;
heap[slot].type = VM_PAGE;
heap[slot].page = NULL;
return;
@@ -615,6 +645,7 @@ static void load_rsave_array(int slot, struct rsave_heap_array *a)
alloc_heap_slot(slot);
heap[slot].ref = a->ref;
heap[slot].seq = a->seq;
heap[slot].type = VM_PAGE;
heap[slot].page = page;
}
@@ -645,6 +676,20 @@ static void load_rsave_struct(int slot, struct rsave_heap_struct *s)
alloc_heap_slot(slot);
heap[slot].ref = s->ref;
heap[slot].seq = s->seq;
heap[slot].type = VM_PAGE;
heap[slot].page = page;
}
static void load_rsave_delegate(int slot, struct rsave_heap_delegate *d)
{
struct page *page = alloc_page(DELEGATE_PAGE, 0, d->nr_slots);
for (int i = 0; i < d->nr_slots; i++)
page->values[i].i = d->slots[i];
alloc_heap_slot(slot);
heap[slot].ref = d->ref;
heap[slot].seq = d->seq;
heap[slot].type = VM_PAGE;
heap[slot].page = page;
}
@@ -657,13 +702,15 @@ static void load_rsave_heap(struct rsave *save)
enum rsave_heap_tag *tag = save->heap[slot];
switch (*tag) {
case RSAVE_GLOBALS:
case RSAVE_LOCALS: load_rsave_frame(slot, save->heap[slot]); break;
case RSAVE_STRING: load_rsave_string(slot, save->heap[slot]); break;
case RSAVE_ARRAY: load_rsave_array(slot, save->heap[slot]); break;
case RSAVE_STRUCT: load_rsave_struct(slot, save->heap[slot]); break;
case RSAVE_LOCALS: load_rsave_frame(slot, save->heap[slot]); break;
case RSAVE_STRING: load_rsave_string(slot, save->heap[slot]); break;
case RSAVE_ARRAY: load_rsave_array(slot, save->heap[slot]); break;
case RSAVE_STRUCT: load_rsave_struct(slot, save->heap[slot]); break;
case RSAVE_DELEGATE: load_rsave_delegate(slot, save->heap[slot]); break;
case RSAVE_NULL: break;
}
}
heap_next_seq = save->next_seq;
}
static void load_json_call_stack(cJSON *json)
+4 -1
View File
@@ -334,6 +334,7 @@ static int _function_call(int fno, int return_address)
struct ain_function *f = &ain->functions[fno];
int slot = heap_alloc_slot(VM_PAGE);
heap_set_page(slot, alloc_page(LOCAL_PAGE, fno, f->nr_vars));
heap[slot].page->local.struct_ptr = -1;
call_stack[call_stack_ptr++] = (struct function_call) {
.fno = fno,
@@ -376,7 +377,9 @@ static void function_call(int fno, int return_address)
static void method_call(int fno, int return_address)
{
function_call(fno, return_address);
call_stack[call_stack_ptr-1].struct_page = stack_pop().i;
int struct_page = stack_pop().i;
call_stack[call_stack_ptr-1].struct_page = struct_page;
heap[call_stack[call_stack_ptr-1].page_slot].page->local.struct_ptr = struct_page;
}
static void vm_execute(void);