1
0
mirror of https://github.com/janet-lang/janet synced 2025-06-15 21:14:12 +00:00

Add some more fiber functions.

Add fiber.current and fiber.lineage
This commit is contained in:
Calvin Rose 2018-05-10 20:25:49 -04:00
parent 584c75b3f6
commit ee01547b3a
5 changed files with 47 additions and 6 deletions

View File

@ -904,7 +904,7 @@ onvalue."
(res) (res)
(do (do
(:= good false) (:= good false)
(onerr "compile" (get res :error))))) :de)) (onerr "compile" (get res :error))))) :dey))
(def res (fiber.resume f)) (def res (fiber.resume f))
(if good (if good
(cond (cond

View File

@ -268,11 +268,11 @@ static int cfun_new(DstArgs args) {
const uint8_t *flags; const uint8_t *flags;
int32_t len, i; int32_t len, i;
dst_arg_bytes(flags, len, args, 1); 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++) { for (i = 0; i < len; i++) {
switch (flags[i]) { switch (flags[i]) {
default: default:
return dst_throw(args, "invalid flag, expected d or e"); return dst_throw(args, "invalid flag, expected d, e, or y");
case ':': case ':':
break; break;
case 'd': case 'd':
@ -281,6 +281,9 @@ static int cfun_new(DstArgs args) {
case 'e': case 'e':
fiber->flags &= ~DST_FIBER_MASK_ERROR; fiber->flags &= ~DST_FIBER_MASK_ERROR;
break; 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)); 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[] = { static const DstReg cfuns[] = {
{"fiber.new", cfun_new}, {"fiber.new", cfun_new},
{"fiber.status", cfun_status}, {"fiber.status", cfun_status},
{"fiber.stack", cfun_stack}, {"fiber.stack", cfun_stack},
{"fiber.current", cfun_current},
{"fiber.lineage", cfun_lineage},
{NULL, NULL} {NULL, NULL}
}; };

View File

@ -25,6 +25,8 @@
#include <dst/dst.h> #include <dst/dst.h>
extern DST_THREAD_LOCAL DstFiber *dst_vm_fiber;
#define dst_stack_frame(s) ((DstStackFrame *)((s) - DST_FRAME_SIZE)) #define dst_stack_frame(s) ((DstStackFrame *)((s) - DST_FRAME_SIZE))
#define dst_fiber_frame(f) dst_stack_frame((f)->data + (f)->frame) #define dst_fiber_frame(f) dst_stack_frame((f)->data + (f)->frame)
DstFiber *dst_fiber_reset(DstFiber *fiber, DstFunction *callee); DstFiber *dst_fiber_reset(DstFiber *fiber, DstFunction *callee);

View File

@ -29,6 +29,7 @@
/* VM state */ /* VM state */
DST_THREAD_LOCAL int dst_vm_stackn = 0; DST_THREAD_LOCAL int dst_vm_stackn = 0;
DST_THREAD_LOCAL DstFiber *dst_vm_fiber = NULL;
/* Maybe collect garbage */ /* Maybe collect garbage */
#define dst_maybe_collect() do {\ #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. */ /* Start running the VM from where it left off. */
Dst dst_run(DstFiber *fiber) { Dst dst_run(DstFiber *fiber) {
/* Save old fiber to reset */
DstFiber *old_vm_fiber = dst_vm_fiber;
/* VM state */ /* VM state */
register Dst *stack; register Dst *stack;
register uint32_t *pc; register uint32_t *pc;
@ -53,13 +57,14 @@ Dst dst_run(DstFiber *fiber) {
} }
dst_vm_stackn++; 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) { if (fiber->flags & DST_FIBER_FLAG_NEW) {
dst_fiber_funcframe(fiber, fiber->root); dst_fiber_funcframe(fiber, fiber->root);
fiber->flags &= ~DST_FIBER_FLAG_NEW; fiber->flags &= ~DST_FIBER_FLAG_NEW;
} }
fiber->status = DST_FIBER_ALIVE; fiber->status = DST_FIBER_ALIVE;
dst_gcroot(dst_wrap_fiber(fiber));
stack = fiber->data + fiber->frame; stack = fiber->data + fiber->frame;
pc = dst_stack_frame(stack)->pc; pc = dst_stack_frame(stack)->pc;
func = dst_stack_frame(stack)->func; func = dst_stack_frame(stack)->func;
@ -202,7 +207,7 @@ static void *op_lookup[255] = {
vm_next();\ 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. */ * (*pc & 0xFF) inside of an infinte loop. */
VM_START(); VM_START();
@ -739,6 +744,7 @@ static void *op_lookup[255] = {
} }
fiber->child = nextfiber; fiber->child = nextfiber;
retreg = dst_run(nextfiber); retreg = dst_run(nextfiber);
dst_vm_fiber = fiber;
switch (nextfiber->status) { switch (nextfiber->status) {
case DST_FIBER_DEBUG: case DST_FIBER_DEBUG:
if (nextfiber->flags & DST_FIBER_MASK_DEBUG) goto vm_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; if (nextfiber->flags & DST_FIBER_MASK_ERROR) goto vm_error;
fiber->child = NULL; fiber->child = NULL;
break; 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: default:
fiber->child = NULL; fiber->child = NULL;
break; break;
@ -853,6 +866,7 @@ static void *op_lookup[255] = {
dst_stack_frame(stack)->pc = pc; dst_stack_frame(stack)->pc = pc;
dst_vm_stackn--; dst_vm_stackn--;
dst_gcunroot(dst_wrap_fiber(fiber)); dst_gcunroot(dst_wrap_fiber(fiber));
dst_vm_fiber = old_vm_fiber;
return retreg; return retreg;
} }

View File

@ -344,6 +344,7 @@ struct DstArgs {
/* Fiber signal masks. Should not overlap any fiber flags. */ /* Fiber signal masks. Should not overlap any fiber flags. */
#define DST_FIBER_MASK_ERROR 1 #define DST_FIBER_MASK_ERROR 1
#define DST_FIBER_MASK_DEBUG 2 #define DST_FIBER_MASK_DEBUG 2
#define DST_FIBER_MASK_YIELD 4
/* A lightweight green thread in dst. Does not correspond to /* A lightweight green thread in dst. Does not correspond to
* operating system threads. */ * operating system threads. */