AsyncEmbeddedScript2 use tail recursion for stack management

This commit is contained in:
2023-08-19 14:18:16 -06:00
parent 636f332bc5
commit 4478327fa8

View File

@@ -167,10 +167,7 @@ class AsyncEmbeddedScript2 {
public var running(default, null):Bool = false; public var running(default, null):Bool = false;
public var unwindStack(default, default):Bool = false; private function runInstruction(instructionPointer:Int, withBreakPoints = true):Void {
public var alwaysUnwindStack(default, default):Bool = false;
private function runInstruction(instructionPointer:Int, withBreakPoints = true) {
running = true; running = true;
var skipping = false; var skipping = false;
if (skipTarget != null) { if (skipTarget != null) {
@@ -190,21 +187,19 @@ class AsyncEmbeddedScript2 {
onBreak(this, false, () -> runInstruction(instructionPointer, false)); onBreak(this, false, () -> runInstruction(instructionPointer, false));
} }
} }
var tryCallNextWithTailRecursion = false;
var nextCalledWithTailRecursion = false;
var continuation = if (instructionPointer < instructions.length - 1) { var continuation = if (instructionPointer < instructions.length - 1) {
() -> { () -> {
// runInstruction may be called externally to skip through the script. // runInstruction may be called externally to skip through the script.
// When this happens, make sure other scheduled continuations are canceled // When this happens, make sure other scheduled continuations are canceled
// by verifying that lastInstructionPointer hasn't changed // by verifying that lastInstructionPointer hasn't changed
if (lastInstructionPointer == instructionPointer) { if (lastInstructionPointer == instructionPointer) {
if (unwindStack || alwaysUnwindStack) { tryCallNextWithTailRecursion = true;
haxe.Timer.delay(()->{runInstruction(instructionPointer + 1, withBreakPoints);}, 0); haxe.Timer.delay(()->{
if (!alwaysUnwindStack) if (!nextCalledWithTailRecursion)
unwindStack = false;
return;
}
else {
runInstruction(instructionPointer + 1, withBreakPoints); runInstruction(instructionPointer + 1, withBreakPoints);
} }, 0);
} }
}; };
} else { } else {
@@ -215,6 +210,11 @@ class AsyncEmbeddedScript2 {
} else { } else {
instructions[instructionPointer](this, skipping, continuation); instructions[instructionPointer](this, skipping, continuation);
} }
if (tryCallNextWithTailRecursion) {
nextCalledWithTailRecursion = true;
runInstruction(instructionPointer + 1, withBreakPoints);
}
} }
public function run(withBreakPoints = true) { public function run(withBreakPoints = true) {