mirror of
https://github.com/janet-lang/janet
synced 2024-11-18 22:54:49 +00:00
Add some more fiber functions.
Add fiber.current and fiber.lineage
This commit is contained in:
parent
584c75b3f6
commit
ee01547b3a
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user