summaryrefslogtreecommitdiffstats
path: root/vm.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2025-02-07 19:16:43 -0800
committerKaz Kylheku <kaz@kylheku.com>2025-02-07 19:16:43 -0800
commit08aa8ffdfb59fd9bdec686d416357958167dad8f (patch)
treef1793c8c82b95efa3f327d3e9bb68d0c843b01dc /vm.c
parent91d261ac1fdad312cf9040b31daa04bf00aab376 (diff)
downloadtxr-08aa8ffdfb59fd9bdec686d416357958167dad8f.tar.gz
txr-08aa8ffdfb59fd9bdec686d416357958167dad8f.tar.bz2
txr-08aa8ffdfb59fd9bdec686d416357958167dad8f.zip
vm: missed cases of signal check in backwards branch
Only the JMP instruction is checking for a backwards branch and calling sig_check_fast() so that a loop can be interrupted by Ctrl-C. The compiler can optimize that so that a backwards jump is performed by an instruction in the IF family. * vm.c (vm_if, vm_ifq, vm_ifql): Check for a backwards branch and call sig_check_fast. Also, eliminate the redundant call to vm_insn_bigop, which is just a masking macro. The ip variable is already the result of vm_insn_bigop.
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/vm.c b/vm.c
index c8d0e6fa..63a8d1a7 100644
--- a/vm.c
+++ b/vm.c
@@ -733,8 +733,11 @@ NOINLINE static void vm_if(struct vm *vm, vm_word_t insn)
vm_word_t arg = vm->code[vm->ip++];
val test = vm_get(vm->dspl, vm_arg_operand_lo(arg));
- if (!test)
- vm->ip = vm_insn_bigop(ip);
+ if (!test) {
+ if (ip < vm->ip)
+ sig_check_fast();
+ vm->ip = ip;
+ }
}
NOINLINE static void vm_ifq(struct vm *vm, vm_word_t insn)
@@ -744,8 +747,11 @@ NOINLINE static void vm_ifq(struct vm *vm, vm_word_t insn)
val a = vm_get(vm->dspl, vm_arg_operand_lo(arg));
val b = vm_get(vm->dspl, vm_arg_operand_hi(arg));
- if (a != b)
- vm->ip = vm_insn_bigop(ip);
+ if (a != b) {
+ if (ip < vm->ip)
+ sig_check_fast();
+ vm->ip = ip;
+ }
}
NOINLINE static void vm_ifql(struct vm *vm, vm_word_t insn)
@@ -755,8 +761,11 @@ NOINLINE static void vm_ifql(struct vm *vm, vm_word_t insn)
val a = vm_get(vm->dspl, vm_arg_operand_lo(arg));
val b = vm_get(vm->dspl, vm_arg_operand_hi(arg));
- if (!eql(a, b))
- vm->ip = vm_insn_bigop(ip);
+ if (!eql(a, b)) {
+ if (ip < vm->ip)
+ sig_check_fast();
+ vm->ip = ip;
+ }
}
NOINLINE static void vm_swtch(struct vm *vm, vm_word_t insn)