Add global variables

PUSHGLOBALPAGE and SH_GLOBALREF instructions.
This commit is contained in:
Nunuhara Cabbage
2019-10-13 20:00:11 -07:00
parent 8a40058c81
commit b7bdd17a50
3 changed files with 56 additions and 4 deletions
+4 -4
View File
@@ -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);
+2
View File
@@ -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;
+50
View File
@@ -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.)