Don't allow calling the root fiber.
The VM used to not detect this case. It meant you could get into a situation where another fiber's caller had completed. Then, when it tried to resume that fiber, the VM would crash because there was nothing to resume to. This is part of thinking through all the cases around re-entrancy. Added some notes for that too.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wren.h"
|
||||
#include "vm.h"
|
||||
|
||||
void callWrenCallRootRunTests(WrenVM* vm)
|
||||
{
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenGetVariable(vm, "./test/api/call_wren_call_root", "Test", 0);
|
||||
WrenHandle* testClass = wrenGetSlotHandle(vm, 0);
|
||||
|
||||
WrenHandle* run = wrenMakeCallHandle(vm, "run()");
|
||||
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenSetSlotHandle(vm, 0, testClass);
|
||||
WrenInterpretResult result = wrenCall(vm, run);
|
||||
if (result == WREN_RESULT_RUNTIME_ERROR)
|
||||
{
|
||||
setExitCode(70);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Missing runtime error.\n");
|
||||
}
|
||||
|
||||
wrenReleaseHandle(vm, testClass);
|
||||
wrenReleaseHandle(vm, run);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#include "wren.h"
|
||||
|
||||
void callWrenCallRootRunTests(WrenVM* vm);
|
||||
@@ -0,0 +1,12 @@
|
||||
class Test {
|
||||
static run() {
|
||||
var root = Fiber.current
|
||||
System.print("begin root") // expect: begin root
|
||||
|
||||
Fiber.new {
|
||||
System.print("in new fiber") // expect: in new fiber
|
||||
root.call() // expect runtime error: Cannot call root fiber.
|
||||
System.print("called root")
|
||||
}.transfer()
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "benchmark.h"
|
||||
#include "call.h"
|
||||
#include "call_wren_call_root.h"
|
||||
#include "error.h"
|
||||
#include "get_variable.h"
|
||||
#include "foreign_class.h"
|
||||
@@ -101,6 +102,10 @@ static void afterLoad(WrenVM* vm)
|
||||
{
|
||||
callRunTests(vm);
|
||||
}
|
||||
else if (strstr(testName, "/call_wren_call_root.wren") != NULL)
|
||||
{
|
||||
callWrenCallRootRunTests(vm);
|
||||
}
|
||||
else if (strstr(testName, "/reset_stack_after_call_abort.wren") != NULL)
|
||||
{
|
||||
resetStackAfterCallAbortRunTests(vm);
|
||||
@@ -122,5 +127,5 @@ int main(int argc, const char* argv[])
|
||||
testName = argv[1];
|
||||
setTestCallbacks(bindForeignMethod, bindForeignClass, afterLoad);
|
||||
runFile(testName);
|
||||
return 0;
|
||||
return getExitCode();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
var root = Fiber.current
|
||||
System.print("begin root") // expect: begin root
|
||||
|
||||
Fiber.new {
|
||||
System.print("in new fiber") // expect: in new fiber
|
||||
root.call() // expect runtime error: Cannot call root fiber.
|
||||
System.print("called root")
|
||||
}.transfer()
|
||||
Reference in New Issue
Block a user