nga-c: add guard() to most of the instructions (ref #96)

FossilOrigin-Name: 298bd790ad29f3fb8866e146c3e63d1c6e59b1beb3f89fbf66fe73837dc9427f
This commit is contained in:
crc 2023-03-29 13:27:55 +00:00
parent 0b6f4769e2
commit 52c850571d

View file

@ -219,10 +219,12 @@ void inst_iq(NgaState *); void inst_ii(NgaState *);
void guard(NgaState *vm, int n, int m, int diff) {
if (vm->cpu[vm->active].sp < n) {
printf("E: Data Stack Underflow");
vm->cpu[vm->active].sp = 0;
return;
}
if (((vm->cpu[vm->active].sp + m) - n) > (STACK_DEPTH - 1)) {
printf("E: Data Stack Overflow");
vm->cpu[vm->active].sp = 0;
return;
}
@ -1111,25 +1113,30 @@ void prepare_vm(NgaState *vm) {
}
void inst_no(NgaState *vm) {
guard(vm, 0, 0, 0);
}
void inst_li(NgaState *vm) {
guard(vm, 0, 1, 0);
vm->cpu[vm->active].sp++;
vm->cpu[vm->active].ip++;
TOS = vm->memory[vm->cpu[vm->active].ip];
}
void inst_du(NgaState *vm) {
guard(vm, 1, 2, 0);
vm->cpu[vm->active].sp++;
vm->cpu[vm->active].data[vm->cpu[vm->active].sp] = NOS;
}
void inst_dr(NgaState *vm) {
guard(vm, 1, 0, 0);
vm->cpu[vm->active].data[vm->cpu[vm->active].sp] = 0;
vm->cpu[vm->active].sp--;
}
void inst_sw(NgaState *vm) {
guard(vm, 2, 2, 0);
CELL a;
a = TOS;
TOS = NOS;
@ -1137,23 +1144,27 @@ void inst_sw(NgaState *vm) {
}
void inst_pu(NgaState *vm) {
guard(vm, 1, 0, 1);
vm->cpu[vm->active].rp++;
TORS = TOS;
inst_dr(vm);
}
void inst_po(NgaState *vm) {
guard(vm, 0, 1, -1);
vm->cpu[vm->active].sp++;
TOS = TORS;
vm->cpu[vm->active].rp--;
}
void inst_ju(NgaState *vm) {
guard(vm, 1, 0, 0);
vm->cpu[vm->active].ip = TOS - 1;
inst_dr(vm);
}
void inst_ca(NgaState *vm) {
guard(vm, 1, 0, 1);
vm->cpu[vm->active].rp++;
TORS = vm->cpu[vm->active].ip;
vm->cpu[vm->active].ip = TOS - 1;
@ -1161,6 +1172,7 @@ void inst_ca(NgaState *vm) {
}
void inst_cc(NgaState *vm) {
guard(vm, 2, 0, 1);
CELL a, b;
a = TOS; inst_dr(vm); /* Target */
b = TOS; inst_dr(vm); /* Flag */
@ -1172,11 +1184,13 @@ void inst_cc(NgaState *vm) {
}
void inst_re(NgaState *vm) {
guard(vm, 0, 0, -1);
vm->cpu[vm->active].ip = TORS;
vm->cpu[vm->active].rp--;
}
void inst_eq(NgaState *vm) {
guard(vm, 2, 1, 0);
if (vm->cpu[vm->active].u != 0) {
NOS = ((unsigned)NOS == (unsigned)TOS) ? -1 : 0;
vm->cpu[vm->active].u = 0;
@ -1187,6 +1201,7 @@ void inst_eq(NgaState *vm) {
}
void inst_ne(NgaState *vm) {
guard(vm, 2, 1, 0);
if (vm->cpu[vm->active].u != 0) {
NOS = ((unsigned)NOS != (unsigned)TOS) ? -1 : 0;
vm->cpu[vm->active].u = 0;
@ -1197,6 +1212,7 @@ void inst_ne(NgaState *vm) {
}
void inst_lt(NgaState *vm) {
guard(vm, 2, 1, 0);
if (vm->cpu[vm->active].u != 0) {
NOS = ((unsigned)NOS < (unsigned)TOS) ? -1 : 0;
vm->cpu[vm->active].u = 0;
@ -1207,6 +1223,7 @@ void inst_lt(NgaState *vm) {
}
void inst_gt(NgaState *vm) {
guard(vm, 2, 1, 0);
if (vm->cpu[vm->active].u != 0) {
NOS = ((unsigned)NOS > (unsigned)TOS) ? -1 : 0;
vm->cpu[vm->active].u = 0;
@ -1217,6 +1234,7 @@ void inst_gt(NgaState *vm) {
}
void inst_fe(NgaState *vm) {
guard(vm, 1, 1, 0);
switch (TOS) {
case -1: TOS = vm->cpu[vm->active].sp - 1; break;
case -2: TOS = vm->cpu[vm->active].rp; break;
@ -1228,12 +1246,14 @@ void inst_fe(NgaState *vm) {
}
void inst_st(NgaState *vm) {
guard(vm, 2, 0, 0);
vm->memory[TOS] = NOS;
inst_dr(vm);
inst_dr(vm);
}
void inst_ad(NgaState *vm) {
guard(vm, 2, 1, 0);
if (vm->cpu[vm->active].u != 0) {
NOS = (unsigned)NOS + (unsigned)TOS;
vm->cpu[vm->active].u = 0;
@ -1244,6 +1264,7 @@ void inst_ad(NgaState *vm) {
}
void inst_su(NgaState *vm) {
guard(vm, 2, 1, 0);
if (vm->cpu[vm->active].u != 0) {
NOS = (unsigned)NOS - (unsigned)TOS;
vm->cpu[vm->active].u = 0;
@ -1254,6 +1275,7 @@ void inst_su(NgaState *vm) {
}
void inst_mu(NgaState *vm) {
guard(vm, 2, 1, 0);
if (vm->cpu[vm->active].u != 0) {
NOS = (unsigned)NOS * (unsigned)TOS;
vm->cpu[vm->active].u = 0;
@ -1264,6 +1286,7 @@ void inst_mu(NgaState *vm) {
}
void inst_di(NgaState *vm) {
guard(vm, 2, 2, 0);
CELL a, b;
a = TOS;
b = NOS;
@ -1278,21 +1301,25 @@ void inst_di(NgaState *vm) {
}
void inst_an(NgaState *vm) {
guard(vm, 2, 1, 0);
NOS = TOS & NOS;
inst_dr(vm);
}
void inst_or(NgaState *vm) {
guard(vm, 2, 1, 0);
NOS = TOS | NOS;
inst_dr(vm);
}
void inst_xo(NgaState *vm) {
guard(vm, 2, 1, 0);
NOS = TOS ^ NOS;
inst_dr(vm);
}
void inst_sh(NgaState *vm) {
guard(vm, 2, 1, 0);
CELL y = TOS;
CELL x = NOS;
if (TOS < 0)
@ -1325,10 +1352,12 @@ void inst_ha(NgaState *vm) {
}
void inst_ie(NgaState *vm) {
guard(vm, 1, 1, 0);
stack_push(vm, vm->devices);
}
void inst_iq(NgaState *vm) {
guard(vm, 1, 1, 0);
vm->IO_queryHandlers[stack_pop(vm)](vm);
}