1
0
forked from Mirror/wren

Catch errors in the first try()

This commit is contained in:
Andew Jones
2017-03-30 21:57:29 -04:00
parent 8d313be3ce
commit 7d631276cb
3 changed files with 48 additions and 9 deletions

View File

@ -82,6 +82,12 @@ DEF_PRIMITIVE(fiber_abort)
static bool runFiber(WrenVM* vm, ObjFiber* fiber, Value* args, bool isCall,
bool hasValue, const char* verb)
{
if (!IS_NULL(fiber->error))
{
RETURN_ERROR_FMT("Cannot $ an aborted fiber.", verb);
}
if (isCall)
{
if (fiber->caller != NULL) RETURN_ERROR("Fiber has already been called.");
@ -95,11 +101,6 @@ static bool runFiber(WrenVM* vm, ObjFiber* fiber, Value* args, bool isCall,
RETURN_ERROR_FMT("Cannot $ a finished fiber.", verb);
}
if (!IS_NULL(fiber->error))
{
RETURN_ERROR_FMT("Cannot $ an aborted fiber.", verb);
}
// When the calling fiber resumes, we'll store the result of the call in its
// stack. If the call has two arguments (the fiber and the value), we only
// need one slot for the result, so discard the other slot now.

View File

@ -384,12 +384,19 @@ static void runtimeError(WrenVM* vm)
{
ASSERT(!IS_NULL(vm->fiber->error), "Should only call this after an error.");
// Unhook the caller since we will never resume and return to it.
ObjFiber* caller = vm->fiber->caller;
vm->fiber->caller = NULL;
ObjFiber* current = vm->fiber;
while (current->caller != NULL) {
if (current->callerIsTrying) {
break;
}
ObjFiber* temp = current;
current = temp->caller;
temp->caller = NULL;
}
ObjFiber* caller = current->caller;
// If the caller ran this fiber using "try", give it the error.
if (vm->fiber->callerIsTrying)
if (current->callerIsTrying)
{
// Make the caller's try method return the error message.
caller->stackTop[-1] = vm->fiber->error;

View File

@ -8,3 +8,34 @@ System.print(fiber.try())
// expect: before
// expect: Bool does not implement 'unknownMethod'.
System.print("after try") // expect: after try
var fiber2 = Fiber.new {
var fiberInner = Fiber.new {
System.print("before")
true.unknownMethod
System.print("after")
}
fiberInner.call()
}
System.print(fiber2.try())
// expect: before
// expect: Bool does not implement 'unknownMethod'.
System.print("after try") // expect: after try
var fiber3 = Fiber.new {
var fiberInner = Fiber.new {
var fiberInnerInner = Fiber.new {
System.print("before")
true.unknownMethod
System.print("after")
}
fiberInnerInner.call()
}
fiberInner.call()
}
System.print(fiber3.try())
// expect: before
// expect: Bool does not implement 'unknownMethod'.
System.print("after try") // expect: after try