forked from Mirror/wren
Catch errors in the first try()
This commit is contained in:
@ -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.
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user