mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 07:33:01 +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:
		| @@ -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(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose