mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 19:19:53 +00:00
Address #466?
Do not restore pc when returning from top most fiber frame. Also add JANET_DEBUG config define for various debugging related configurations. In fiber.c, when debug is enabled we reallocate the entire stack everytime we push a frame to help uncover use after free errors.
This commit is contained in:
parent
58374623b7
commit
5377e10532
@ -57,6 +57,7 @@
|
|||||||
/* #define JANET_NO_UMASK */
|
/* #define JANET_NO_UMASK */
|
||||||
|
|
||||||
/* Other settings */
|
/* Other settings */
|
||||||
|
/* #define JANET_DEBUG */
|
||||||
/* #define JANET_PRF */
|
/* #define JANET_PRF */
|
||||||
/* #define JANET_NO_UTC_MKTIME */
|
/* #define JANET_NO_UTC_MKTIME */
|
||||||
/* #define JANET_OUT_OF_MEMORY do { printf("janet out of memory\n"); exit(1); } while (0) */
|
/* #define JANET_OUT_OF_MEMORY do { printf("janet out of memory\n"); exit(1); } while (0) */
|
||||||
|
@ -85,6 +85,22 @@ JanetFiber *janet_fiber(JanetFunction *callee, int32_t capacity, int32_t argc, c
|
|||||||
return janet_fiber_reset(fiber_alloc(capacity), callee, argc, argv);
|
return janet_fiber_reset(fiber_alloc(capacity), callee, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef JANET_DEBUG
|
||||||
|
/* Test for memory issues by reallocating fiber every time we push a stack frame */
|
||||||
|
static void janet_fiber_refresh_memory(JanetFiber *fiber) {
|
||||||
|
int32_t n = fiber->capacity;
|
||||||
|
if (n) {
|
||||||
|
Janet *newData = malloc(sizeof(Janet) * n);
|
||||||
|
if (NULL == newData) {
|
||||||
|
JANET_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
memcpy(newData, fiber->data, fiber->capacity * sizeof(Janet));
|
||||||
|
free(fiber->data);
|
||||||
|
fiber->data = newData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Ensure that the fiber has enough extra capacity */
|
/* Ensure that the fiber has enough extra capacity */
|
||||||
void janet_fiber_setcapacity(JanetFiber *fiber, int32_t n) {
|
void janet_fiber_setcapacity(JanetFiber *fiber, int32_t n) {
|
||||||
Janet *newData = realloc(fiber->data, sizeof(Janet) * n);
|
Janet *newData = realloc(fiber->data, sizeof(Janet) * n);
|
||||||
@ -173,6 +189,10 @@ int janet_fiber_funcframe(JanetFiber *fiber, JanetFunction *func) {
|
|||||||
|
|
||||||
if (fiber->capacity < nextstacktop) {
|
if (fiber->capacity < nextstacktop) {
|
||||||
janet_fiber_setcapacity(fiber, 2 * nextstacktop);
|
janet_fiber_setcapacity(fiber, 2 * nextstacktop);
|
||||||
|
#ifdef JANET_DEBUG
|
||||||
|
} else {
|
||||||
|
janet_fiber_refresh_memory(fiber);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nil unset stack arguments (Needed for gc correctness) */
|
/* Nil unset stack arguments (Needed for gc correctness) */
|
||||||
@ -305,6 +325,10 @@ int janet_fiber_funcframe_tail(JanetFiber *fiber, JanetFunction *func) {
|
|||||||
|
|
||||||
if (fiber->capacity < nextstacktop) {
|
if (fiber->capacity < nextstacktop) {
|
||||||
janet_fiber_setcapacity(fiber, 2 * nextstacktop);
|
janet_fiber_setcapacity(fiber, 2 * nextstacktop);
|
||||||
|
#ifdef JANET_DEBUG
|
||||||
|
} else {
|
||||||
|
janet_fiber_refresh_memory(fiber);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Janet *stack = fiber->data + fiber->frame;
|
Janet *stack = fiber->data + fiber->frame;
|
||||||
@ -367,6 +391,10 @@ void janet_fiber_cframe(JanetFiber *fiber, JanetCFunction cfun) {
|
|||||||
|
|
||||||
if (fiber->capacity < nextstacktop) {
|
if (fiber->capacity < nextstacktop) {
|
||||||
janet_fiber_setcapacity(fiber, 2 * nextstacktop);
|
janet_fiber_setcapacity(fiber, 2 * nextstacktop);
|
||||||
|
#ifdef JANET_DEBUG
|
||||||
|
} else {
|
||||||
|
janet_fiber_refresh_memory(fiber);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the next frame */
|
/* Set the next frame */
|
||||||
|
@ -95,6 +95,10 @@ JANET_THREAD_LOCAL jmp_buf *janet_vm_jmp_buf = NULL;
|
|||||||
vm_commit(); \
|
vm_commit(); \
|
||||||
return (sig); \
|
return (sig); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#define vm_return_no_restore(sig, val) do { \
|
||||||
|
janet_vm_return_reg[0] = (val); \
|
||||||
|
return (sig); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* Next instruction variations */
|
/* Next instruction variations */
|
||||||
#define maybe_collect() do {\
|
#define maybe_collect() do {\
|
||||||
@ -623,7 +627,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
|||||||
Janet retval = stack[D];
|
Janet retval = stack[D];
|
||||||
int entrance_frame = janet_stack_frame(stack)->flags & JANET_STACKFRAME_ENTRANCE;
|
int entrance_frame = janet_stack_frame(stack)->flags & JANET_STACKFRAME_ENTRANCE;
|
||||||
janet_fiber_popframe(fiber);
|
janet_fiber_popframe(fiber);
|
||||||
if (entrance_frame) vm_return(JANET_SIGNAL_OK, retval);
|
if (entrance_frame) vm_return_no_restore(JANET_SIGNAL_OK, retval);
|
||||||
vm_restore();
|
vm_restore();
|
||||||
stack[A] = retval;
|
stack[A] = retval;
|
||||||
vm_checkgc_pcnext();
|
vm_checkgc_pcnext();
|
||||||
@ -633,7 +637,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
|||||||
Janet retval = janet_wrap_nil();
|
Janet retval = janet_wrap_nil();
|
||||||
int entrance_frame = janet_stack_frame(stack)->flags & JANET_STACKFRAME_ENTRANCE;
|
int entrance_frame = janet_stack_frame(stack)->flags & JANET_STACKFRAME_ENTRANCE;
|
||||||
janet_fiber_popframe(fiber);
|
janet_fiber_popframe(fiber);
|
||||||
if (entrance_frame) vm_return(JANET_SIGNAL_OK, retval);
|
if (entrance_frame) vm_return_no_restore(JANET_SIGNAL_OK, retval);
|
||||||
vm_restore();
|
vm_restore();
|
||||||
stack[A] = retval;
|
stack[A] = retval;
|
||||||
vm_checkgc_pcnext();
|
vm_checkgc_pcnext();
|
||||||
@ -1011,8 +1015,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
|||||||
retreg = call_nonfn(fiber, callee);
|
retreg = call_nonfn(fiber, callee);
|
||||||
}
|
}
|
||||||
janet_fiber_popframe(fiber);
|
janet_fiber_popframe(fiber);
|
||||||
if (entrance_frame)
|
if (entrance_frame) {
|
||||||
vm_return(JANET_SIGNAL_OK, retreg);
|
vm_return_no_restore(JANET_SIGNAL_OK, retreg);
|
||||||
|
}
|
||||||
vm_restore();
|
vm_restore();
|
||||||
stack[A] = retreg;
|
stack[A] = retreg;
|
||||||
vm_checkgc_pcnext();
|
vm_checkgc_pcnext();
|
||||||
|
Loading…
Reference in New Issue
Block a user