From 08aa8ffdfb59fd9bdec686d416357958167dad8f Mon Sep 17 00:00:00 2001
From: Kaz Kylheku <kaz@kylheku.com>
Date: Fri, 7 Feb 2025 19:16:43 -0800
Subject: 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.
---
 vm.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

(limited to 'vm.c')

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)
-- 
cgit v1.2.3