mirror of
https://github.com/wren-lang/wren.git
synced 2026-01-10 21:58:48 +01:00
Reset API stack a fiber is aborted from wrenCall().
This commit is contained in:
@ -400,6 +400,7 @@ static void runtimeError(WrenVM* vm)
|
||||
// If we got here, nothing caught the error, so show the stack trace.
|
||||
wrenDebugPrintStackTrace(vm);
|
||||
vm->fiber = NULL;
|
||||
vm->apiStack = NULL;
|
||||
}
|
||||
|
||||
// Aborts the current fiber with an appropriate method not found error for a
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "handle.h"
|
||||
#include "lists.h"
|
||||
#include "new_vm.h"
|
||||
#include "reset_stack_after_call_abort.h"
|
||||
#include "reset_stack_after_foreign_construct.h"
|
||||
#include "slots.h"
|
||||
|
||||
@ -87,8 +88,15 @@ static WrenForeignClassMethods bindForeignClass(
|
||||
}
|
||||
|
||||
static void afterLoad(WrenVM* vm) {
|
||||
if (strstr(testName, "/call.wren") != NULL) callRunTests(vm);
|
||||
if (strstr(testName, "/reset_stack_after_foreign_construct.wren") != NULL)
|
||||
if (strstr(testName, "/call.wren") != NULL)
|
||||
{
|
||||
callRunTests(vm);
|
||||
}
|
||||
else if (strstr(testName, "/reset_stack_after_call_abort.wren") != NULL)
|
||||
{
|
||||
resetStackAfterCallAbortRunTests(vm);
|
||||
}
|
||||
else if (strstr(testName, "/reset_stack_after_foreign_construct.wren") != NULL)
|
||||
{
|
||||
resetStackAfterForeignConstructRunTests(vm);
|
||||
}
|
||||
|
||||
28
test/api/reset_stack_after_call_abort.c
Normal file
28
test/api/reset_stack_after_call_abort.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wren.h"
|
||||
|
||||
void resetStackAfterCallAbortRunTests(WrenVM* vm)
|
||||
{
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenGetVariable(vm, "main", "Test", 0);
|
||||
WrenHandle* testClass = wrenGetSlotHandle(vm, 0);
|
||||
|
||||
WrenHandle* abortFiber = wrenMakeCallHandle(vm, "abortFiber()");
|
||||
WrenHandle* afterConstruct = wrenMakeCallHandle(vm, "afterAbort(_,_)");
|
||||
|
||||
wrenEnsureSlots(vm, 1);
|
||||
wrenSetSlotHandle(vm, 0, testClass);
|
||||
wrenCall(vm, abortFiber);
|
||||
|
||||
wrenEnsureSlots(vm, 3);
|
||||
wrenSetSlotHandle(vm, 0, testClass);
|
||||
wrenSetSlotDouble(vm, 1, 1.0);
|
||||
wrenSetSlotDouble(vm, 2, 2.0);
|
||||
wrenCall(vm, afterConstruct);
|
||||
|
||||
wrenReleaseHandle(vm, testClass);
|
||||
wrenReleaseHandle(vm, abortFiber);
|
||||
wrenReleaseHandle(vm, afterConstruct);
|
||||
}
|
||||
3
test/api/reset_stack_after_call_abort.h
Normal file
3
test/api/reset_stack_after_call_abort.h
Normal file
@ -0,0 +1,3 @@
|
||||
#include "wren.h"
|
||||
|
||||
void resetStackAfterCallAbortRunTests(WrenVM* vm);
|
||||
14
test/api/reset_stack_after_call_abort.wren
Normal file
14
test/api/reset_stack_after_call_abort.wren
Normal file
@ -0,0 +1,14 @@
|
||||
// Regression test.
|
||||
//
|
||||
// If you invoked some code with wrenCall() and that code aborted the current
|
||||
// fiber, it did not reset the API stack. If you tried to immediately reuse the
|
||||
// API stack by calling wrenCall(), it would be in a broken state.
|
||||
class Test {
|
||||
static abortFiber() {
|
||||
Fiber.abort("Abort!") // expect handled runtime error: Abort!
|
||||
}
|
||||
|
||||
static afterAbort(a, b) {
|
||||
System.print(a + b) // expect: 3
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "foreign_class.h"
|
||||
#include "wren.h"
|
||||
|
||||
static void counterAllocate(WrenVM* vm)
|
||||
{
|
||||
|
||||
@ -18,7 +18,7 @@ TEST_APP = join(WREN_DIR, 'build', 'debug', 'test', 'wrend')
|
||||
EXPECT_PATTERN = re.compile(r'// expect: ?(.*)')
|
||||
EXPECT_ERROR_PATTERN = re.compile(r'// expect error(?! line)')
|
||||
EXPECT_ERROR_LINE_PATTERN = re.compile(r'// expect error line (\d+)')
|
||||
EXPECT_RUNTIME_ERROR_PATTERN = re.compile(r'// expect runtime error: (.+)')
|
||||
EXPECT_RUNTIME_ERROR_PATTERN = re.compile(r'// expect (handled )?runtime error: (.+)')
|
||||
ERROR_PATTERN = re.compile(r'\[.* line (\d+)\] Error')
|
||||
STACK_TRACE_PATTERN = re.compile(r'\[main line (\d+)\] in')
|
||||
STDIN_PATTERN = re.compile(r'// stdin: (.*)')
|
||||
@ -77,9 +77,10 @@ class Test:
|
||||
match = EXPECT_RUNTIME_ERROR_PATTERN.search(line)
|
||||
if match:
|
||||
self.runtime_error_line = line_num
|
||||
self.runtime_error_message = match.group(1)
|
||||
# If we expect a runtime error, it should exit with EX_SOFTWARE.
|
||||
self.exit_code = 70
|
||||
self.runtime_error_message = match.group(2)
|
||||
# If the runtime error isn't handled, it should exit with EX_SOFTWARE.
|
||||
if match.group(1) != "handled ":
|
||||
self.exit_code = 70
|
||||
expectations += 1
|
||||
|
||||
match = STDIN_PATTERN.search(line)
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
29D025E41C19CD1000A3BB28 /* os.c in Sources */ = {isa = PBXBuildFile; fileRef = 29D025E01C19CD1000A3BB28 /* os.c */; };
|
||||
29D025E51C19CD1000A3BB28 /* os.wren.inc in Sources */ = {isa = PBXBuildFile; fileRef = 29D025E21C19CD1000A3BB28 /* os.wren.inc */; };
|
||||
29D025E61C19CD1000A3BB28 /* os.wren.inc in Sources */ = {isa = PBXBuildFile; fileRef = 29D025E21C19CD1000A3BB28 /* os.wren.inc */; };
|
||||
29D880661DC8ECF600025364 /* reset_stack_after_call_abort.c in Sources */ = {isa = PBXBuildFile; fileRef = 29D880641DC8ECF600025364 /* reset_stack_after_call_abort.c */; };
|
||||
29DC149F1BBA2FCC008A8274 /* vm.c in Sources */ = {isa = PBXBuildFile; fileRef = 29C8A9311AB71FFF00DEC81D /* vm.c */; };
|
||||
29DC14A01BBA2FD6008A8274 /* timer.c in Sources */ = {isa = PBXBuildFile; fileRef = 2901D7621B74F4050083A2C8 /* timer.c */; };
|
||||
29DC14A11BBA2FEC008A8274 /* scheduler.c in Sources */ = {isa = PBXBuildFile; fileRef = 291647C21BA5EA45006142EE /* scheduler.c */; };
|
||||
@ -151,6 +152,8 @@
|
||||
29D025E01C19CD1000A3BB28 /* os.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = os.c; path = ../../src/module/os.c; sourceTree = "<group>"; };
|
||||
29D025E11C19CD1000A3BB28 /* os.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = os.h; path = ../../src/module/os.h; sourceTree = "<group>"; };
|
||||
29D025E21C19CD1000A3BB28 /* os.wren.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = os.wren.inc; path = ../../src/module/os.wren.inc; sourceTree = "<group>"; };
|
||||
29D880641DC8ECF600025364 /* reset_stack_after_call_abort.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = reset_stack_after_call_abort.c; path = ../../test/api/reset_stack_after_call_abort.c; sourceTree = "<group>"; };
|
||||
29D880651DC8ECF600025364 /* reset_stack_after_call_abort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = reset_stack_after_call_abort.h; path = ../../test/api/reset_stack_after_call_abort.h; sourceTree = "<group>"; };
|
||||
29F384111BD19706002F84E0 /* io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = io.h; path = ../../src/module/io.h; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@ -294,6 +297,8 @@
|
||||
29932D531C210F8D00099DEE /* lists.h */,
|
||||
29C946961C88F14F00B4A4F3 /* new_vm.c */,
|
||||
29C946971C88F14F00B4A4F3 /* new_vm.h */,
|
||||
29D880641DC8ECF600025364 /* reset_stack_after_call_abort.c */,
|
||||
29D880651DC8ECF600025364 /* reset_stack_after_call_abort.h */,
|
||||
29C80D581D73332A00493837 /* reset_stack_after_foreign_construct.c */,
|
||||
29C80D591D73332A00493837 /* reset_stack_after_foreign_construct.h */,
|
||||
29D009AA1B7E39A8000CE58C /* slots.c */,
|
||||
@ -415,6 +420,7 @@
|
||||
29DC14A11BBA2FEC008A8274 /* scheduler.c in Sources */,
|
||||
29A427391BDBE435001E6E22 /* wren_opt_random.c in Sources */,
|
||||
293B255A1CEFD8C7005D9537 /* repl.wren.inc in Sources */,
|
||||
29D880661DC8ECF600025364 /* reset_stack_after_call_abort.c in Sources */,
|
||||
29932D511C20D8C900099DEE /* benchmark.c in Sources */,
|
||||
29DC14A01BBA2FD6008A8274 /* timer.c in Sources */,
|
||||
29DC149F1BBA2FCC008A8274 /* vm.c in Sources */,
|
||||
|
||||
Reference in New Issue
Block a user