diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2025-02-07 19:16:43 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2025-02-07 19:16:43 -0800 |
commit | 08aa8ffdfb59fd9bdec686d416357958167dad8f (patch) | |
tree | f1793c8c82b95efa3f327d3e9bb68d0c843b01dc /vm.c | |
parent | 91d261ac1fdad312cf9040b31daa04bf00aab376 (diff) | |
download | txr-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.c | 21 |
1 files changed, 15 insertions, 6 deletions
@@ -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) |