From 2244b26773ca958613873b33dc23681775d9f963 Mon Sep 17 00:00:00 2001 From: Thomas Weber Date: Wed, 24 Sep 2025 16:48:01 -0500 Subject: [PATCH] Discard old state after calling yielding procedure --- src/compiler/iroptimizer.js | 12 ++++++ ...analyze-yields-due-to-direct-recursion.sb3 | Bin 0 -> 3330 bytes ...tate-accounts-for-yields-in-procedures.sb3 | Bin 0 -> 3243 bytes ...ds-due-to-direct-recursion.sb3.tw-snapshot | 39 ++++++++++++++++++ ...s-for-yields-in-procedures.sb3.tw-snapshot | 38 +++++++++++++++++ ...procedure-return-recursion.sb3.tw-snapshot | 4 +- ...ds-due-to-direct-recursion.sb3.tw-snapshot | 39 ++++++++++++++++++ ...s-for-yields-in-procedures.sb3.tw-snapshot | 38 +++++++++++++++++ ...procedure-return-recursion.sb3.tw-snapshot | 4 +- 9 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 test/fixtures/execute/tw-analyze-yields-due-to-direct-recursion.sb3 create mode 100644 test/fixtures/execute/tw-exit-state-accounts-for-yields-in-procedures.sb3 create mode 100644 test/snapshot/__snapshots__/tw-analyze-yields-due-to-direct-recursion.sb3.tw-snapshot create mode 100644 test/snapshot/__snapshots__/tw-exit-state-accounts-for-yields-in-procedures.sb3.tw-snapshot create mode 100644 test/snapshot/__snapshots__/warp-timer/tw-analyze-yields-due-to-direct-recursion.sb3.tw-snapshot create mode 100644 test/snapshot/__snapshots__/warp-timer/tw-exit-state-accounts-for-yields-in-procedures.sb3.tw-snapshot diff --git a/src/compiler/iroptimizer.js b/src/compiler/iroptimizer.js index 416f1c3e06..ae7d98e495 100644 --- a/src/compiler/iroptimizer.js +++ b/src/compiler/iroptimizer.js @@ -99,6 +99,14 @@ class TypeState { }); } + /** + * @param {TypeState} other + * @returns {boolean} + */ + overwrite (other) { + return this.mutate(other, varId => other.variables[varId] ?? InputType.ANY); + } + /** * @param {*} variable A variable codegen object. * @param {InputType} type The type to set this variable to @@ -490,6 +498,8 @@ class IROptimizer { if (!script || !script.cachedAnalysisEndState) { modified = state.clear() || modified; + } else if (script.yields) { + modified = state.overwrite(script.cachedAnalysisEndState) || modified; } else { modified = state.after(script.cachedAnalysisEndState) || modified; } @@ -578,6 +588,8 @@ class IROptimizer { if (!script || !script.cachedAnalysisEndState) { modified = state.clear() || modified; + } else if (script.yields) { + modified = state.overwrite(script.cachedAnalysisEndState) || modified; } else { modified = state.after(script.cachedAnalysisEndState) || modified; } diff --git a/test/fixtures/execute/tw-analyze-yields-due-to-direct-recursion.sb3 b/test/fixtures/execute/tw-analyze-yields-due-to-direct-recursion.sb3 new file mode 100644 index 0000000000000000000000000000000000000000..136864b417e341ade429b75c618475aca7379c65 GIT binary patch literal 3330 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 XAi>lCc<~bept-p77oFvw5eM)O$|&Lp literal 0 HcmV?d00001 diff --git a/test/fixtures/execute/tw-exit-state-accounts-for-yields-in-procedures.sb3 b/test/fixtures/execute/tw-exit-state-accounts-for-yields-in-procedures.sb3 new file mode 100644 index 0000000000000000000000000000000000000000..6d194449637014725c30803b67f292eeb3ef212b GIT binary patch literal 3243 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 literal 0 HcmV?d00001 diff --git a/test/snapshot/__snapshots__/tw-analyze-yields-due-to-direct-recursion.sb3.tw-snapshot b/test/snapshot/__snapshots__/tw-analyze-yields-due-to-direct-recursion.sb3.tw-snapshot new file mode 100644 index 0000000000..c19e45f704 --- /dev/null +++ b/test/snapshot/__snapshots__/tw-analyze-yields-due-to-direct-recursion.sb3.tw-snapshot @@ -0,0 +1,39 @@ +// TW Snapshot +// Input SHA-256: 848a4efc16b174b53f0a4b581e6b6d1091ae9eaa916e040c963e360ce3883509 + +// Sprite1 script +(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage(); +const b0 = runtime.getOpcodeFunction("looks_say"); +const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"]; +const b2 = stage.variables["FpLI$ida6)qR,q~y`1|*"]; +return function* genXYZ () { +yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, "j", null); +b1.value = (1 + 2); +yield* thread.procedures["Znon-warp recursion %s"](2); +if ((("" + listGet(b2.value, b1.value)).toLowerCase() === "the only thing".toLowerCase())) { +yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "t", null); +} +yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, "s", null); +retire(); return; +}; }) + +// Sprite1 Znon-warp recursion %s +(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage(); +return function* genXYZ_non_warp_recursion_ (p0) { +if (compareGreaterThan(p0, 0)) { +yield; +yield* thread.procedures["Znon-warp recursion %s"](((+p0 || 0) - 1)); +} +return ""; +}; }) + +// Sprite1 script +(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage(); +const b0 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"]; +return function* genXYZ () { +for (var a0 = 1; a0 >= 0.5; a0--) { +yield; +} +b0.value = "random"; +retire(); return; +}; }) diff --git a/test/snapshot/__snapshots__/tw-exit-state-accounts-for-yields-in-procedures.sb3.tw-snapshot b/test/snapshot/__snapshots__/tw-exit-state-accounts-for-yields-in-procedures.sb3.tw-snapshot new file mode 100644 index 0000000000..c8bf63116b --- /dev/null +++ b/test/snapshot/__snapshots__/tw-exit-state-accounts-for-yields-in-procedures.sb3.tw-snapshot @@ -0,0 +1,38 @@ +// TW Snapshot +// Input SHA-256: 4715c75fe8effcdcdea3ad810949e33a7b6beb3fbd253c1edc2ed4f2bd093df3 + +// Sprite1 script +(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage(); +const b0 = runtime.getOpcodeFunction("looks_say"); +const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"]; +const b2 = stage.variables["FpLI$ida6)qR,q~y`1|*"]; +return function* genXYZ () { +yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, "e", null); +b1.value = (1 + 2); +yield* thread.procedures["Zsomething that yields"](); +if ((("" + listGet(b2.value, b1.value)).toLowerCase() === "the only thing".toLowerCase())) { +yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "o", null); +} +yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, "n", null); +retire(); return; +}; }) + +// Sprite1 Zsomething that yields +(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage(); +return function* genXYZ_something_that_yield () { +for (var a0 = 2; a0 >= 0.5; a0--) { +yield; +} +return ""; +}; }) + +// Sprite1 script +(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage(); +const b0 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"]; +return function* genXYZ () { +for (var a0 = 1; a0 >= 0.5; a0--) { +yield; +} +b0.value = "random"; +retire(); return; +}; }) diff --git a/test/snapshot/__snapshots__/tw-procedure-return-recursion.sb3.tw-snapshot b/test/snapshot/__snapshots__/tw-procedure-return-recursion.sb3.tw-snapshot index 6b2bc2a9f6..c242a148a3 100644 --- a/test/snapshot/__snapshots__/tw-procedure-return-recursion.sb3.tw-snapshot +++ b/test/snapshot/__snapshots__/tw-procedure-return-recursion.sb3.tw-snapshot @@ -10,7 +10,7 @@ return function* genXYZ () { yield* executeInCompatibilityLayer({"MESSAGE":"plan 18",}, b0, false, false, "G", null); b1.value = 0; b2.value = (yield* thread.procedures["Znon warp recursion should yield %s"](8)); -if ((b1.value === 4)) { +if (((+b1.value || 0) === 4)) { yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp recursion yields",}, b0, false, false, "ao", null); } b1.value = 0; @@ -20,7 +20,7 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass warp recursion does not yiel } b1.value = 0; b2.value = (yield* thread.procedures["Zfib %s"](7)); -if ((b1.value === 20)) { +if (((+b1.value || 0) === 20)) { yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp fib yielded",}, b0, false, false, "au", null); } yield* thread.procedures["Zrecursing yields between each %s"]("initial"); diff --git a/test/snapshot/__snapshots__/warp-timer/tw-analyze-yields-due-to-direct-recursion.sb3.tw-snapshot b/test/snapshot/__snapshots__/warp-timer/tw-analyze-yields-due-to-direct-recursion.sb3.tw-snapshot new file mode 100644 index 0000000000..c19e45f704 --- /dev/null +++ b/test/snapshot/__snapshots__/warp-timer/tw-analyze-yields-due-to-direct-recursion.sb3.tw-snapshot @@ -0,0 +1,39 @@ +// TW Snapshot +// Input SHA-256: 848a4efc16b174b53f0a4b581e6b6d1091ae9eaa916e040c963e360ce3883509 + +// Sprite1 script +(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage(); +const b0 = runtime.getOpcodeFunction("looks_say"); +const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"]; +const b2 = stage.variables["FpLI$ida6)qR,q~y`1|*"]; +return function* genXYZ () { +yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, "j", null); +b1.value = (1 + 2); +yield* thread.procedures["Znon-warp recursion %s"](2); +if ((("" + listGet(b2.value, b1.value)).toLowerCase() === "the only thing".toLowerCase())) { +yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "t", null); +} +yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, "s", null); +retire(); return; +}; }) + +// Sprite1 Znon-warp recursion %s +(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage(); +return function* genXYZ_non_warp_recursion_ (p0) { +if (compareGreaterThan(p0, 0)) { +yield; +yield* thread.procedures["Znon-warp recursion %s"](((+p0 || 0) - 1)); +} +return ""; +}; }) + +// Sprite1 script +(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage(); +const b0 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"]; +return function* genXYZ () { +for (var a0 = 1; a0 >= 0.5; a0--) { +yield; +} +b0.value = "random"; +retire(); return; +}; }) diff --git a/test/snapshot/__snapshots__/warp-timer/tw-exit-state-accounts-for-yields-in-procedures.sb3.tw-snapshot b/test/snapshot/__snapshots__/warp-timer/tw-exit-state-accounts-for-yields-in-procedures.sb3.tw-snapshot new file mode 100644 index 0000000000..c8bf63116b --- /dev/null +++ b/test/snapshot/__snapshots__/warp-timer/tw-exit-state-accounts-for-yields-in-procedures.sb3.tw-snapshot @@ -0,0 +1,38 @@ +// TW Snapshot +// Input SHA-256: 4715c75fe8effcdcdea3ad810949e33a7b6beb3fbd253c1edc2ed4f2bd093df3 + +// Sprite1 script +(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage(); +const b0 = runtime.getOpcodeFunction("looks_say"); +const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"]; +const b2 = stage.variables["FpLI$ida6)qR,q~y`1|*"]; +return function* genXYZ () { +yield* executeInCompatibilityLayer({"MESSAGE":"plan 1",}, b0, false, false, "e", null); +b1.value = (1 + 2); +yield* thread.procedures["Zsomething that yields"](); +if ((("" + listGet(b2.value, b1.value)).toLowerCase() === "the only thing".toLowerCase())) { +yield* executeInCompatibilityLayer({"MESSAGE":"pass",}, b0, false, false, "o", null); +} +yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, "n", null); +retire(); return; +}; }) + +// Sprite1 Zsomething that yields +(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage(); +return function* genXYZ_something_that_yield () { +for (var a0 = 2; a0 >= 0.5; a0--) { +yield; +} +return ""; +}; }) + +// Sprite1 script +(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage(); +const b0 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"]; +return function* genXYZ () { +for (var a0 = 1; a0 >= 0.5; a0--) { +yield; +} +b0.value = "random"; +retire(); return; +}; }) diff --git a/test/snapshot/__snapshots__/warp-timer/tw-procedure-return-recursion.sb3.tw-snapshot b/test/snapshot/__snapshots__/warp-timer/tw-procedure-return-recursion.sb3.tw-snapshot index 6b2bc2a9f6..c242a148a3 100644 --- a/test/snapshot/__snapshots__/warp-timer/tw-procedure-return-recursion.sb3.tw-snapshot +++ b/test/snapshot/__snapshots__/warp-timer/tw-procedure-return-recursion.sb3.tw-snapshot @@ -10,7 +10,7 @@ return function* genXYZ () { yield* executeInCompatibilityLayer({"MESSAGE":"plan 18",}, b0, false, false, "G", null); b1.value = 0; b2.value = (yield* thread.procedures["Znon warp recursion should yield %s"](8)); -if ((b1.value === 4)) { +if (((+b1.value || 0) === 4)) { yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp recursion yields",}, b0, false, false, "ao", null); } b1.value = 0; @@ -20,7 +20,7 @@ yield* executeInCompatibilityLayer({"MESSAGE":"pass warp recursion does not yiel } b1.value = 0; b2.value = (yield* thread.procedures["Zfib %s"](7)); -if ((b1.value === 20)) { +if (((+b1.value || 0) === 20)) { yield* executeInCompatibilityLayer({"MESSAGE":"pass non warp fib yielded",}, b0, false, false, "au", null); } yield* thread.procedures["Zrecursing yields between each %s"]("initial");