mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 07:33:01 +00:00 
			
		
		
		
	Enable debug opcode in vm and debug state for fibers.
This commit is contained in:
		| @@ -86,6 +86,7 @@ static const DstInstructionDef dst_ops[] = { | ||||
|     {"call", DOP_CALL}, | ||||
|     {"clo", DOP_CLOSURE}, | ||||
|     {"cmp", DOP_COMPARE}, | ||||
|     {"debug", DOP_DEBUG}, | ||||
|     {"div", DOP_DIVIDE}, | ||||
|     {"divim", DOP_DIVIDE_IMMEDIATE}, | ||||
|     {"divi", DOP_DIVIDE_INTEGER}, | ||||
|   | ||||
| @@ -85,7 +85,8 @@ enum DstInstructionType dst_instructions[DOP_INSTRUCTION_COUNT] = { | ||||
|     DIT_SSS, /* DOP_PUT, */ | ||||
|     DIT_SSU, /* DOP_GET_INDEX, */ | ||||
|     DIT_SSU, /* DOP_PUT_INDEX, */ | ||||
|     DIT_SS /* DOP_LENGTH */ | ||||
|     DIT_SS, /* DOP_LENGTH */ | ||||
|     DIT_0 /* DOP_DEBUG */ | ||||
| }; | ||||
|  | ||||
| /* Verify some bytecode */ | ||||
|   | ||||
| @@ -192,6 +192,9 @@ int dst_core_fiber_status(DstArgs args) { | ||||
|         case DST_FIBER_ERROR: | ||||
|             status = ":error"; | ||||
|             break; | ||||
|         case DST_FIBER_DEBUG: | ||||
|             status = ":debug"; | ||||
|             break; | ||||
|     } | ||||
|     return dst_return(args, dst_csymbolv(status)); | ||||
| } | ||||
|   | ||||
| @@ -38,6 +38,7 @@ DstFiber *dst_fiber(int32_t capacity) { | ||||
|     } | ||||
|     fiber->parent = NULL; | ||||
|     fiber->maxstack = DST_STACK_MAX; | ||||
|     fiber->flags = DST_FIBER_MASK_DEBUG; | ||||
|     return dst_fiber_reset(fiber); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -30,19 +30,16 @@ DstFiber *dst_vm_fiber = NULL; | ||||
| int dst_vm_stackn = 0; | ||||
|  | ||||
| /* Helper to ensure proper fiber is activated after returning */ | ||||
| static int dst_update_fiber() { | ||||
| static int dst_update_fiber(uint32_t mask) { | ||||
|     if (dst_vm_fiber->frame == 0) { | ||||
|         dst_vm_fiber->status = DST_FIBER_DEAD; | ||||
|     } | ||||
|     while (dst_vm_fiber->status == DST_FIBER_DEAD || | ||||
|             dst_vm_fiber->status == DST_FIBER_ERROR) { | ||||
|             dst_vm_fiber->status == DST_FIBER_ERROR || | ||||
|             dst_vm_fiber->status == DST_FIBER_DEBUG || | ||||
|             dst_vm_fiber->flags & mask) { | ||||
|         if (NULL != dst_vm_fiber->parent) { | ||||
|             dst_vm_fiber = dst_vm_fiber->parent; | ||||
|             if (dst_vm_fiber->status == DST_FIBER_ALIVE) { | ||||
|                 /* If the parent thread is still alive, | ||||
|                    we are inside a cfunction */ | ||||
|                 return 1; | ||||
|             } | ||||
|         } else { | ||||
|             /* The root thread has terminated */ | ||||
|             return 1; | ||||
| @@ -139,6 +136,7 @@ static void *op_lookup[255] = { | ||||
|     &&label_DOP_GET_INDEX, | ||||
|     &&label_DOP_PUT_INDEX, | ||||
|     &&label_DOP_LENGTH, | ||||
|     &&label_DOP_DEBUG, | ||||
|     &&label_unknown_op | ||||
| }; | ||||
| #else | ||||
| @@ -204,16 +202,13 @@ static void *op_lookup[255] = { | ||||
|  | ||||
|     vm_init_fiber_state(); | ||||
|  | ||||
|     /* Main interpreter loop. It is large, but it is | ||||
|      * is maintainable. Adding new opcodes is mostly just adding newcases | ||||
|      * to this loop, adding the opcode to opcodes.h, and adding it to the assembler. | ||||
|      * Some opcodes, especially ones that do arithmetic, are almost entirely | ||||
|      * templated by the above macros. */ | ||||
|     /* Main interpreter loop. Sematically is a switch on | ||||
|      * (*pc & 0xFF) inside of an infinte loop. */ | ||||
|     VM_START(); | ||||
|  | ||||
|     VM_DEFAULT(); | ||||
|     retreg = dst_wrap_string(dst_formatc("unknown opcode %d", *pc & 0xFF)); | ||||
|     goto vm_error; | ||||
|     VM_OP(DOP_DEBUG) | ||||
|     goto vm_debug; | ||||
|  | ||||
|     VM_OP(DOP_NOOP) | ||||
|     pc++; | ||||
| @@ -707,60 +702,78 @@ static void *op_lookup[255] = { | ||||
|     vm_return_cfunc: | ||||
|     { | ||||
|         dst_fiber_popframe(dst_vm_fiber); | ||||
|         if (dst_update_fiber()) { | ||||
|             *returnreg = retreg; | ||||
|             dst_vm_stackn--; | ||||
|             return 0; | ||||
|         } | ||||
|         if (dst_update_fiber(DST_FIBER_MASK_RETURN)) goto vm_exit_value; | ||||
|         stack = dst_vm_fiber->data + dst_vm_fiber->frame; | ||||
|         stack[oparg(1, 0xFF)] = retreg; | ||||
|         pc++; | ||||
|         vm_checkgc_next(); | ||||
|     } | ||||
|  | ||||
|     /* Return from a cfunction that is in tail position (pop 2 stack frames) */ | ||||
|     vm_return_cfunc_tail: | ||||
|     { | ||||
|         dst_fiber_popframe(dst_vm_fiber); | ||||
|         if (dst_update_fiber()) { | ||||
|             *returnreg = retreg; | ||||
|             dst_vm_stackn--; | ||||
|             return 0; | ||||
|         } | ||||
|         /* Fall through to normal return */ | ||||
|         if (dst_update_fiber(DST_FIBER_MASK_RETURN)) goto vm_exit_value; | ||||
|         goto vm_return; | ||||
|     } | ||||
|  | ||||
|     /* Handle returning from stack frame. Expect return value in retreg */ | ||||
|     vm_return: | ||||
|     { | ||||
|         dst_fiber_popframe(dst_vm_fiber); | ||||
|         if (dst_update_fiber()) { | ||||
|             *returnreg = retreg; | ||||
|             dst_vm_stackn--; | ||||
|             return 0; | ||||
|         } | ||||
|         stack = dst_vm_fiber->data + dst_vm_fiber->frame; | ||||
|         func = dst_stack_frame(stack)->func; | ||||
|         pc = dst_stack_frame(stack)->pc; | ||||
|         stack[oparg(1, 0xFF)] = retreg; | ||||
|         pc++; | ||||
|         vm_checkgc_next(); | ||||
|         if (dst_update_fiber(DST_FIBER_MASK_RETURN)) goto vm_exit_value; | ||||
|         goto vm_reset; | ||||
|     } | ||||
|  | ||||
|     /* Handle errors from c functions and vm opcodes */ | ||||
|     vm_error: | ||||
|     { | ||||
|         dst_vm_fiber->status = DST_FIBER_ERROR; | ||||
|         if (dst_update_fiber()) { | ||||
|             *returnreg = retreg; | ||||
|             dst_vm_stackn--; | ||||
|             return 1; | ||||
|         } | ||||
|         if (dst_update_fiber(DST_FIBER_MASK_ERROR)) goto vm_exit_error; | ||||
|         goto vm_reset; | ||||
|     } | ||||
|  | ||||
|     /* Handle debugger interrupts */ | ||||
|     vm_debug: | ||||
|     { | ||||
|         dst_vm_fiber->status = DST_FIBER_DEBUG; | ||||
|         if (dst_update_fiber(DST_FIBER_MASK_DEBUG)) goto vm_exit_debug; | ||||
|         goto vm_reset; | ||||
|     } | ||||
|  | ||||
|     /* Reset state of machine */ | ||||
|     vm_reset: | ||||
|     { | ||||
|         stack = dst_vm_fiber->data + dst_vm_fiber->frame; | ||||
|         func = dst_stack_frame(stack)->func; | ||||
|         pc = dst_stack_frame(stack)->pc; | ||||
|         stack[oparg(1, 0xFF)] = retreg; | ||||
|         pc++; | ||||
|         vm_checkgc_next(); | ||||
|     }    | ||||
|  | ||||
|     /* Exit loop with return value */ | ||||
|     vm_exit_value: | ||||
|     { | ||||
|         *returnreg = retreg; | ||||
|         dst_vm_stackn--; | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     /* Exit loop with error value */ | ||||
|     vm_exit_error: | ||||
|     { | ||||
|         *returnreg = retreg; | ||||
|         dst_vm_stackn--; | ||||
|         return 1; | ||||
|     } | ||||
|  | ||||
|     /* Exit loop with debug */ | ||||
|     vm_exit_debug: | ||||
|     { | ||||
|         *returnreg = dst_wrap_nil(); | ||||
|         dst_vm_stackn--; | ||||
|         return 2; | ||||
|     } | ||||
|      | ||||
|     VM_END() | ||||
|   | ||||
| @@ -118,6 +118,7 @@ enum DstOpCode { | ||||
|     DOP_GET_INDEX, | ||||
|     DOP_PUT_INDEX, | ||||
|     DOP_LENGTH, | ||||
|     DOP_DEBUG, | ||||
|     DOP_INSTRUCTION_COUNT | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -305,6 +305,11 @@ struct DstArgs { | ||||
|     Dst *ret; | ||||
| }; | ||||
|  | ||||
| /* Fiber signal masks */ | ||||
| #define DST_FIBER_MASK_RETURN 1 | ||||
| #define DST_FIBER_MASK_ERROR 2 | ||||
| #define DST_FIBER_MASK_DEBUG 4 | ||||
|  | ||||
| /* A lightweight green thread in dst. Does not correspond to | ||||
|  * operating system threads. */ | ||||
| struct DstFiber { | ||||
| @@ -315,12 +320,14 @@ struct DstFiber { | ||||
|     int32_t stacktop; /* Top of stack. Where values are pushed and popped from. */ | ||||
|     int32_t capacity; | ||||
|     int32_t maxstack; /* Arbitrary defined limit for stack overflow */ | ||||
|     uint32_t flags; /* Various flags */ | ||||
|     enum { | ||||
|         DST_FIBER_PENDING, | ||||
|         DST_FIBER_NEW, | ||||
|         DST_FIBER_ALIVE, | ||||
|         DST_FIBER_DEAD, | ||||
|         DST_FIBER_ERROR | ||||
|         DST_FIBER_ERROR, | ||||
|         DST_FIBER_DEBUG | ||||
|     } status; | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose