AsyncEmbeddedScript2 use tail recursion for stack management
This commit is contained in:
@@ -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) {
|
||||||
|
Reference in New Issue
Block a user