forked from Mirror/wren
Handle errors with fiber usage.
This commit is contained in:
@ -196,11 +196,18 @@ DEF_NATIVE(fiber_create)
|
||||
RETURN_VAL(OBJ_VAL(newFiber));
|
||||
}
|
||||
|
||||
DEF_NATIVE(fiber_isDone)
|
||||
{
|
||||
ObjFiber* runFiber = AS_FIBER(args[0]);
|
||||
RETURN_BOOL(runFiber->numFrames == 0);
|
||||
}
|
||||
|
||||
DEF_NATIVE(fiber_run)
|
||||
{
|
||||
// TODO: Error if the fiber is already complete.
|
||||
ObjFiber* runFiber = AS_FIBER(args[0]);
|
||||
|
||||
if (runFiber->numFrames == 0) RETURN_ERROR("Cannot run a finished fiber.");
|
||||
|
||||
// Remember who ran it.
|
||||
runFiber->caller = fiber;
|
||||
|
||||
@ -215,9 +222,10 @@ DEF_NATIVE(fiber_run)
|
||||
|
||||
DEF_NATIVE(fiber_run1)
|
||||
{
|
||||
// TODO: Error if the fiber is already complete.
|
||||
ObjFiber* runFiber = AS_FIBER(args[0]);
|
||||
|
||||
if (runFiber->numFrames == 0) RETURN_ERROR("Cannot run a finished fiber.");
|
||||
|
||||
// Remember who ran it.
|
||||
runFiber->caller = fiber;
|
||||
|
||||
@ -239,7 +247,7 @@ DEF_NATIVE(fiber_run1)
|
||||
|
||||
DEF_NATIVE(fiber_yield)
|
||||
{
|
||||
// TODO: Handle caller being null.
|
||||
if (fiber->caller == NULL) RETURN_ERROR("No fiber to yield to.");
|
||||
|
||||
// Make the caller's run method return null.
|
||||
fiber->caller->stack[fiber->caller->stackSize - 1] = NULL_VAL;
|
||||
@ -251,7 +259,7 @@ DEF_NATIVE(fiber_yield)
|
||||
|
||||
DEF_NATIVE(fiber_yield1)
|
||||
{
|
||||
// TODO: Handle caller being null.
|
||||
if (fiber->caller == NULL) RETURN_ERROR("No fiber to yield to.");
|
||||
|
||||
// Make the caller's run method return the argument passed to yield.
|
||||
fiber->caller->stack[fiber->caller->stackSize - 1] = args[1];
|
||||
@ -698,6 +706,7 @@ void wrenInitializeCore(WrenVM* vm)
|
||||
NATIVE(vm->fiberClass->metaclass, "create ", fiber_create);
|
||||
NATIVE(vm->fiberClass->metaclass, "yield", fiber_yield);
|
||||
NATIVE(vm->fiberClass->metaclass, "yield ", fiber_yield1);
|
||||
NATIVE(vm->fiberClass, "isDone", fiber_isDone);
|
||||
NATIVE(vm->fiberClass, "run", fiber_run);
|
||||
NATIVE(vm->fiberClass, "run ", fiber_run1);
|
||||
// TODO: Primitives for switching to a fiber without setting the caller.
|
||||
|
||||
11
test/fiber/is_done.wren
Normal file
11
test/fiber/is_done.wren
Normal file
@ -0,0 +1,11 @@
|
||||
var fiber = Fiber.create(fn {
|
||||
IO.print("1")
|
||||
Fiber.yield
|
||||
IO.print("2")
|
||||
})
|
||||
|
||||
IO.print(fiber.isDone) // expect: false
|
||||
fiber.run // expect: 1
|
||||
IO.print(fiber.isDone) // expect: false
|
||||
fiber.run // expect: 2
|
||||
IO.print(fiber.isDone) // expect: true
|
||||
6
test/fiber/run_when_done.wren
Normal file
6
test/fiber/run_when_done.wren
Normal file
@ -0,0 +1,6 @@
|
||||
var fiber = Fiber.create(fn {
|
||||
IO.print("run")
|
||||
})
|
||||
|
||||
fiber.run // expect: run
|
||||
fiber.run // expect runtime error: Cannot run a finished fiber.
|
||||
6
test/fiber/run_with_value_when_done.wren
Normal file
6
test/fiber/run_with_value_when_done.wren
Normal file
@ -0,0 +1,6 @@
|
||||
var fiber = Fiber.create(fn {
|
||||
IO.print("run")
|
||||
})
|
||||
|
||||
fiber.run(1) // expect: run
|
||||
fiber.run(2) // expect runtime error: Cannot run a finished fiber.
|
||||
1
test/fiber/yield_from_main.wren
Normal file
1
test/fiber/yield_from_main.wren
Normal file
@ -0,0 +1 @@
|
||||
Fiber.yield // expect runtime error: No fiber to yield to.
|
||||
1
test/fiber/yield_with_value_from_main.wren
Normal file
1
test/fiber/yield_with_value_from_main.wren
Normal file
@ -0,0 +1 @@
|
||||
Fiber.yield(1) // expect runtime error: No fiber to yield to.
|
||||
Reference in New Issue
Block a user