mirror of
				https://github.com/janet-lang/janet
				synced 2025-10-31 15:43:01 +00:00 
			
		
		
		
	Add some more fiber functions.
Add fiber.current and fiber.lineage
This commit is contained in:
		| @@ -904,7 +904,7 @@ onvalue." | ||||
|       (res) | ||||
|       (do | ||||
|        (:= good false) | ||||
|        (onerr "compile" (get res :error))))) :de)) | ||||
|        (onerr "compile" (get res :error))))) :dey)) | ||||
|   (def res (fiber.resume f)) | ||||
|   (if good | ||||
|    (cond | ||||
|   | ||||
| @@ -268,11 +268,11 @@ static int cfun_new(DstArgs args) { | ||||
|         const uint8_t *flags; | ||||
|         int32_t len, i; | ||||
|         dst_arg_bytes(flags, len, args, 1); | ||||
|         fiber->flags |= DST_FIBER_MASK_ERROR; | ||||
|         fiber->flags |= DST_FIBER_MASK_ERROR | DST_FIBER_MASK_YIELD; | ||||
|         for (i = 0; i < len; i++) { | ||||
|             switch (flags[i]) { | ||||
|                 default: | ||||
|                     return dst_throw(args, "invalid flag, expected d or e"); | ||||
|                     return dst_throw(args, "invalid flag, expected d, e, or y"); | ||||
|                 case ':': | ||||
|                     break; | ||||
|                 case 'd': | ||||
| @@ -281,6 +281,9 @@ static int cfun_new(DstArgs args) { | ||||
|                 case 'e': | ||||
|                     fiber->flags &= ~DST_FIBER_MASK_ERROR; | ||||
|                     break; | ||||
|                 case 'y': | ||||
|                     fiber->flags &= ~DST_FIBER_MASK_YIELD; | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| @@ -367,10 +370,31 @@ static int cfun_stack(DstArgs args) { | ||||
|     return dst_return(args, dst_wrap_array(array)); | ||||
| } | ||||
|  | ||||
| static int cfun_current(DstArgs args) { | ||||
|     dst_fixarity(args, 0); | ||||
|     return dst_return(args, dst_wrap_fiber(dst_vm_fiber)); | ||||
| } | ||||
|  | ||||
| static int cfun_lineage(DstArgs args) { | ||||
|     DstFiber *fiber; | ||||
|     DstArray *array; | ||||
|     dst_fixarity(args, 1); | ||||
|     dst_check(args, 0, DST_FIBER); | ||||
|     fiber = dst_unwrap_fiber(args.v[0]); | ||||
|     array = dst_array(0); | ||||
|     while (fiber) { | ||||
|         dst_array_push(array, dst_wrap_fiber(fiber)); | ||||
|         fiber = fiber->child; | ||||
|     } | ||||
|     return dst_return(args, dst_wrap_array(array)); | ||||
| } | ||||
|  | ||||
| static const DstReg cfuns[] = { | ||||
|     {"fiber.new", cfun_new}, | ||||
|     {"fiber.status", cfun_status}, | ||||
|     {"fiber.stack", cfun_stack}, | ||||
|     {"fiber.current", cfun_current}, | ||||
|     {"fiber.lineage", cfun_lineage}, | ||||
|     {NULL, NULL} | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -25,6 +25,8 @@ | ||||
|  | ||||
| #include <dst/dst.h> | ||||
|  | ||||
| extern DST_THREAD_LOCAL DstFiber *dst_vm_fiber; | ||||
|  | ||||
| #define dst_stack_frame(s) ((DstStackFrame *)((s) - DST_FRAME_SIZE)) | ||||
| #define dst_fiber_frame(f) dst_stack_frame((f)->data + (f)->frame) | ||||
| DstFiber *dst_fiber_reset(DstFiber *fiber, DstFunction *callee); | ||||
|   | ||||
| @@ -29,6 +29,7 @@ | ||||
|  | ||||
| /* VM state */ | ||||
| DST_THREAD_LOCAL int dst_vm_stackn = 0; | ||||
| DST_THREAD_LOCAL DstFiber *dst_vm_fiber = NULL; | ||||
|  | ||||
| /* Maybe collect garbage */ | ||||
| #define dst_maybe_collect() do {\ | ||||
| @@ -37,6 +38,9 @@ DST_THREAD_LOCAL int dst_vm_stackn = 0; | ||||
| /* Start running the VM from where it left off. */ | ||||
| Dst dst_run(DstFiber *fiber) { | ||||
|  | ||||
|     /* Save old fiber to reset */ | ||||
|     DstFiber *old_vm_fiber = dst_vm_fiber; | ||||
|  | ||||
|     /* VM state */ | ||||
|     register Dst *stack; | ||||
|     register uint32_t *pc; | ||||
| @@ -53,13 +57,14 @@ Dst dst_run(DstFiber *fiber) { | ||||
|     } | ||||
|     dst_vm_stackn++; | ||||
|  | ||||
|     /* Reset fiber state */ | ||||
|     /* Setup fiber state */ | ||||
|     dst_vm_fiber = fiber; | ||||
|     dst_gcroot(dst_wrap_fiber(fiber)); | ||||
|     if (fiber->flags & DST_FIBER_FLAG_NEW) { | ||||
|         dst_fiber_funcframe(fiber, fiber->root); | ||||
|         fiber->flags &= ~DST_FIBER_FLAG_NEW; | ||||
|     } | ||||
|     fiber->status = DST_FIBER_ALIVE; | ||||
|     dst_gcroot(dst_wrap_fiber(fiber)); | ||||
|     stack = fiber->data + fiber->frame; | ||||
|     pc = dst_stack_frame(stack)->pc; | ||||
|     func = dst_stack_frame(stack)->func; | ||||
| @@ -202,7 +207,7 @@ static void *op_lookup[255] = { | ||||
|         vm_next();\ | ||||
|     } | ||||
|  | ||||
|     /* Main interpreter loop. Sematically is a switch on | ||||
|     /* Main interpreter loop. Semantically is a switch on | ||||
|      * (*pc & 0xFF) inside of an infinte loop. */ | ||||
|     VM_START(); | ||||
|  | ||||
| @@ -739,6 +744,7 @@ static void *op_lookup[255] = { | ||||
|         } | ||||
|         fiber->child = nextfiber; | ||||
|         retreg = dst_run(nextfiber); | ||||
|         dst_vm_fiber = fiber; | ||||
|         switch (nextfiber->status) { | ||||
|             case DST_FIBER_DEBUG: | ||||
|                 if (nextfiber->flags & DST_FIBER_MASK_DEBUG) goto vm_debug; | ||||
| @@ -748,6 +754,13 @@ static void *op_lookup[255] = { | ||||
|                 if (nextfiber->flags & DST_FIBER_MASK_ERROR) goto vm_error; | ||||
|                 fiber->child = NULL; | ||||
|                 break; | ||||
|             case DST_FIBER_PENDING: | ||||
|                 if (nextfiber->flags & DST_FIBER_MASK_YIELD) { | ||||
|                     fiber->status = DST_FIBER_PENDING; | ||||
|                     goto vm_exit; | ||||
|                 } | ||||
|                 fiber->child = NULL; | ||||
|                 break; | ||||
|             default: | ||||
|                 fiber->child = NULL; | ||||
|                 break; | ||||
| @@ -853,6 +866,7 @@ static void *op_lookup[255] = { | ||||
|         dst_stack_frame(stack)->pc = pc; | ||||
|         dst_vm_stackn--; | ||||
|         dst_gcunroot(dst_wrap_fiber(fiber)); | ||||
|         dst_vm_fiber = old_vm_fiber; | ||||
|         return retreg; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -344,6 +344,7 @@ struct DstArgs { | ||||
| /* Fiber signal masks. Should not overlap any fiber flags. */ | ||||
| #define DST_FIBER_MASK_ERROR 1 | ||||
| #define DST_FIBER_MASK_DEBUG 2 | ||||
| #define DST_FIBER_MASK_YIELD 4 | ||||
|  | ||||
| /* A lightweight green thread in dst. Does not correspond to | ||||
|  * operating system threads. */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Calvin Rose
					Calvin Rose