mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-30 02:48:14 +03:00
Merge pull request #172 from kichikuou/RSMv9
resume: Support RSM v9 format
This commit is contained in:
+11
-5
@@ -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
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user