diff options
| author | 2026-02-15 23:17:53 -0600 | |
|---|---|---|
| committer | 2026-02-16 09:02:07 -0600 | |
| commit | 0299620a2d7b8e9d833a2c7ac5dc4135c9302f69 (patch) | |
| tree | ec985f4a3ab82655a1be748decf5a997b30f7b6d | |
| parent | Expose module/add-syspath and update CHANGELOG.md (diff) | |
Code defensively with regard to stack resizes from custom get and put
for abstract types.
Abstract types whose get/put/length/etc. implementations allocated fiber
slots could break the VM by invalidating the stack pointer in the
interpreter. This is admittedly a bit unusual but is something most
users would probably expect to work. Debugging this would be a real pain.
| -rw-r--r-- | src/core/value.c | 4 | ||||
| -rw-r--r-- | src/core/vm.c | 73 |
2 files changed, 59 insertions, 18 deletions
diff --git a/src/core/value.c b/src/core/value.c index ae407f7c..2a0c4fe0 100644 --- a/src/core/value.c +++ b/src/core/value.c @@ -495,7 +495,7 @@ Janet janet_in(Janet ds, Janet key) { if (!(type->get)(janet_unwrap_abstract(ds), key, &value)) janet_panicf("key %v not found in %v ", key, ds); } else { - janet_panicf("no getter for %v ", ds); + janet_panicf("no getter for %v", ds); } break; } @@ -622,7 +622,7 @@ Janet janet_getindex(Janet ds, int32_t index) { if (!(type->get)(janet_unwrap_abstract(ds), janet_wrap_integer(index), &value)) value = janet_wrap_nil(); } else { - janet_panicf("no getter for %v ", ds); + janet_panicf("no getter for %v", ds); } break; } diff --git a/src/core/vm.c b/src/core/vm.c index 0d19aea7..02ee3d10 100644 --- a/src/core/vm.c +++ b/src/core/vm.c @@ -129,7 +129,9 @@ if (!janet_checktype(op1, JANET_NUMBER)) {\ vm_commit();\ Janet _argv[2] = { op1, janet_wrap_number(CS) };\ - stack[A] = janet_mcall(#op, 2, _argv);\ + Janet a = janet_mcall(#op, 2, _argv);\ + stack = fiber->data + fiber->frame;\ + stack[A] = a;\ vm_checkgc_pcnext();\ } else {\ double x1 = janet_unwrap_number(op1);\ @@ -143,7 +145,9 @@ if (!janet_checktype(op1, JANET_NUMBER)) {\ vm_commit();\ Janet _argv[2] = { op1, janet_wrap_number(CS) };\ - stack[A] = janet_mcall(#op, 2, _argv);\ + Janet a = janet_mcall(#op, 2, _argv);\ + stack = fiber->data + fiber->frame;\ + stack[A] = a;\ vm_checkgc_pcnext();\ } else {\ double y1 = janet_unwrap_number(op1);\ @@ -166,7 +170,9 @@ vm_pcnext();\ } else {\ vm_commit();\ - stack[A] = janet_binop_call(#op, "r" #op, op1, op2);\ + Janet a = janet_binop_call(#op, "r" #op, op1, op2);\ + stack = fiber->data + fiber->frame;\ + stack[A] = a;\ vm_checkgc_pcnext();\ }\ } @@ -186,7 +192,9 @@ vm_pcnext();\ } else {\ vm_commit();\ - stack[A] = janet_binop_call(#op, "r" #op, op1, op2);\ + Janet a = janet_binop_call(#op, "r" #op, op1, op2);\ + stack = fiber->data + fiber->frame;\ + stack[A] = a;\ vm_checkgc_pcnext();\ }\ } @@ -203,7 +211,9 @@ vm_pcnext();\ } else {\ vm_commit();\ - stack[A] = janet_wrap_boolean(janet_compare(op1, op2) op 0);\ + Janet a = janet_wrap_boolean(janet_compare(op1, op2) op 0);\ + stack = fiber->data + fiber->frame;\ + stack[A] = a;\ vm_checkgc_pcnext();\ }\ } @@ -217,7 +227,9 @@ vm_pcnext();\ } else {\ vm_commit();\ - stack[A] = janet_wrap_boolean(janet_compare(op1, janet_wrap_integer(CS)) op 0);\ + Janet a = janet_wrap_boolean(janet_compare(op1, janet_wrap_integer(CS)) op 0);\ + stack = fiber->data + fiber->frame;\ + stack[A] = a;\ vm_checkgc_pcnext();\ }\ } @@ -710,7 +722,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) { vm_pcnext(); } else { vm_commit(); - stack[A] = janet_binop_call("div", "rdiv", op1, op2); + Janet a = janet_binop_call("div", "rdiv", op1, op2); + stack = fiber->data + fiber->frame; + stack[A] = a; vm_checkgc_pcnext(); } } @@ -730,7 +744,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) { vm_pcnext(); } else { vm_commit(); - stack[A] = janet_binop_call("mod", "rmod", op1, op2); + Janet a = janet_binop_call("mod", "rmod", op1, op2); + stack = fiber->data + fiber->frame; + stack[A] = a; vm_checkgc_pcnext(); } } @@ -745,7 +761,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) { vm_pcnext(); } else { vm_commit(); - stack[A] = janet_binop_call("%", "r%", op1, op2); + Janet a = janet_binop_call("%", "r%", op1, op2); + stack = fiber->data + fiber->frame; + stack[A] = a; vm_checkgc_pcnext(); } } @@ -766,7 +784,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) { vm_pcnext(); } else { vm_commit(); - stack[A] = janet_unary_call("~", op); + Janet a = janet_unary_call("~", op); + stack = fiber->data + fiber->frame; + stack[A] = a; vm_checkgc_pcnext(); } } @@ -872,8 +892,11 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) { stack[A] = janet_wrap_boolean(!janet_checktype(stack[B], JANET_NUMBER) || (janet_unwrap_number(stack[B]) != (double) CS)); vm_pcnext(); - VM_OP(JOP_COMPARE) - stack[A] = janet_wrap_integer(janet_compare(stack[B], stack[C])); + VM_OP(JOP_COMPARE) { + Janet a = janet_wrap_integer(janet_compare(stack[B], stack[C])); + stack = fiber->data + fiber->frame; + stack[A] = a; + } vm_pcnext(); VM_OP(JOP_NEXT) @@ -1157,6 +1180,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) { vm_commit(); fiber->flags |= JANET_FIBER_RESUME_NO_USEVAL; janet_put(stack[A], stack[B], stack[C]); + stack = fiber->data + fiber->frame; fiber->flags &= ~JANET_FIBER_RESUME_NO_USEVAL; vm_checkgc_pcnext(); @@ -1164,27 +1188,44 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) { vm_commit(); fiber->flags |= JANET_FIBER_RESUME_NO_USEVAL; janet_putindex(stack[A], C, stack[B]); + stack = fiber->data + fiber->frame; fiber->flags &= ~JANET_FIBER_RESUME_NO_USEVAL; vm_checkgc_pcnext(); VM_OP(JOP_IN) vm_commit(); - stack[A] = janet_in(stack[B], stack[C]); + { + Janet a = janet_in(stack[B], stack[C]); + stack = fiber->data + fiber->frame; + stack[A] = a; + } vm_pcnext(); VM_OP(JOP_GET) vm_commit(); - stack[A] = janet_get(stack[B], stack[C]); + { + Janet a = janet_get(stack[B], stack[C]); + stack = fiber->data + fiber->frame; + stack[A] = a; + } vm_pcnext(); VM_OP(JOP_GET_INDEX) vm_commit(); - stack[A] = janet_getindex(stack[B], C); + { + Janet a = janet_getindex(stack[B], C); + stack = fiber->data + fiber->frame; + stack[A] = a; + } vm_pcnext(); VM_OP(JOP_LENGTH) vm_commit(); - stack[A] = janet_lengthv(stack[E]); + { + Janet a = janet_lengthv(stack[E]); + stack = fiber->data + fiber->frame; + stack[A] = a; + } vm_pcnext(); VM_OP(JOP_MAKE_ARRAY) { |
