Add globals to the VM:
var vm_global_names: [64][]const u8 = undefined;
var vm_global_values: [64]i64 = undefined;
var vm_global_count: usize = 0;
fn vm_get_global(name: []const u8) i64 {
for (0..vm_global_count) |i| {
if (streq(vm_global_names[i], name)) {
return vm_global_values[i];
}
}
return 0;
}
fn vm_set_global(name: []const u8, val: i64) void {
for (0..vm_global_count) |i| {
if (streq(vm_global_names[i], name)) {
vm_global_values[i] = val;
return;
}
}
vm_global_names[vm_global_count] = name;
vm_global_values[vm_global_count] = val;
vm_global_count += 1;
}
Add instruction handling in vm_exec_line:
if (starts_with(line, "global.get $")) {
vm_push(vm_get_global(parse_name(line, 0)));
return;
}
if (starts_with(line, "global.set $")) {
vm_set_global(parse_name(line, 0), vm_pop());
return;
}
And in vm_scan_functions (or a new vm_scan_globals), parse (global $name ...) declarations:
if (starts_with(line, "(global $")) {
vm_set_global(parse_name(line, 0), 0);
}
Critically, globals are NOT saved/restored in the VM's function call handler. The call handler saves vm_local_names/vm_local_values/vm_local_count only. Globals persist.
Reset in vm_run_wat:
vm_global_count = 0;