mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-10 00:08:23 +03:00
Add global variables
PUSHGLOBALPAGE and SH_GLOBALREF instructions.
This commit is contained in:
@@ -270,11 +270,11 @@ static bool read_tag(struct ain_reader *r, struct ain *ain)
|
||||
int32_t count = read_int32(r);
|
||||
ain->functions = read_functions(r, count, ain);
|
||||
} else if (TAG_EQ("GLOB")) {
|
||||
int32_t count = read_int32(r);
|
||||
ain->globals = read_globals(r, count, ain);
|
||||
ain->nr_globals = read_int32(r);
|
||||
ain->globals = read_globals(r, ain->nr_globals, ain);
|
||||
} else if (TAG_EQ("GSET")) {
|
||||
int32_t count = read_int32(r);
|
||||
ain->global_initvals = read_initvals(r, count);
|
||||
ain->nr_initvals = read_int32(r);
|
||||
ain->global_initvals = read_initvals(r, ain->nr_initvals);
|
||||
} else if (TAG_EQ("STRT")) {
|
||||
int32_t count = read_int32(r);
|
||||
ain->structures = read_structures(r, count);
|
||||
|
||||
@@ -160,7 +160,9 @@ struct ain {
|
||||
size_t code_size;
|
||||
struct ain_function *functions;
|
||||
struct ain_global *globals;
|
||||
int32_t nr_globals;
|
||||
struct ain_initval *global_initvals;
|
||||
int32_t nr_initvals;
|
||||
struct ain_struct *structures;
|
||||
struct string **messages;
|
||||
int32_t main;
|
||||
|
||||
@@ -162,6 +162,16 @@ static enum ain_data_type local_type(int varno)
|
||||
return f->vars[varno].data_type;
|
||||
}
|
||||
|
||||
static int32_t global_get(int varno)
|
||||
{
|
||||
return heap[0].page[varno].i;
|
||||
}
|
||||
|
||||
static enum ain_data_type global_type(int varno)
|
||||
{
|
||||
return ain->globals[varno].data_type;
|
||||
}
|
||||
|
||||
// Read the opcode at ADDR.
|
||||
static int16_t get_opcode(size_t addr)
|
||||
{
|
||||
@@ -370,6 +380,9 @@ static void execute_instruction(int16_t opcode)
|
||||
stack_push(b);
|
||||
stack_push(c);
|
||||
break;
|
||||
case PUSHGLOBALPAGE:
|
||||
stack_push(0);
|
||||
break;
|
||||
case PUSHLOCALPAGE:
|
||||
stack_push(call_stack[call_stack_ptr-1].page_slot);
|
||||
break;
|
||||
@@ -377,6 +390,17 @@ static void execute_instruction(int16_t opcode)
|
||||
val = stack_pop();
|
||||
stack_pop_ref()[0] = val;
|
||||
break;
|
||||
case SH_GLOBALREF: // VARNO
|
||||
index = get_argument(0);
|
||||
stack_push(global_get(index));
|
||||
switch (global_type(index)) {
|
||||
case AIN_STRING:
|
||||
heap_ref(global_get(index));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SH_LOCALREF: // VARNO
|
||||
index = get_argument(0);
|
||||
stack_push(local_get(index));
|
||||
@@ -615,6 +639,32 @@ void vm_execute(struct ain *program)
|
||||
|
||||
ain = program;
|
||||
|
||||
// Initialize globals
|
||||
heap[0].page = xmalloc(sizeof(union vm_value) * ain->nr_globals);
|
||||
for (int i = 0; i < ain->nr_globals; i++) {
|
||||
switch (ain->globals[i].data_type) {
|
||||
case AIN_STRING:
|
||||
heap[0].page[i].i = heap_alloc_slot(VM_STRING);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < ain->nr_initvals; i++) {
|
||||
int32_t index;
|
||||
struct ain_initval *v = &ain->global_initvals[i];
|
||||
switch (v->data_type) {
|
||||
case AIN_STRING:
|
||||
index = heap_alloc_slot(VM_STRING);
|
||||
heap[0].page[v->global_index].i = index;
|
||||
heap[index].s = make_string(v->string_value, strlen(v->string_value));
|
||||
break;
|
||||
default:
|
||||
heap[0].page[v->global_index].i = v->int_value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Jump to main. We set up a stack frame so that when main returns,
|
||||
// the first instruction past the end of the code section is executed.
|
||||
// (When we read the AIN file, CALLSYS 0x0 was placed there.)
|
||||
|
||||
Reference in New Issue
Block a user