From 1dc9aadf3fab9d0970576dfe4ff46d7017fa19ab Mon Sep 17 00:00:00 2001 From: Tacodiva <27910867+Tacodiva@users.noreply.github.com> Date: Tue, 25 Jun 2024 18:25:47 +1000 Subject: [PATCH] Fix issue when setting variables to InputType.ANY and add test --- src/compiler/iroptimizer.js | 18 +++++++----------- test/fixtures/tw-type-assertions.sb3 | Bin 4947 -> 5400 bytes ...procedure-return-recursion.sb3.tw-snapshot | 8 ++++---- ...procedure-return-recursion.sb3.tw-snapshot | 8 ++++---- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/compiler/iroptimizer.js b/src/compiler/iroptimizer.js index c161f3c8..15424a72 100644 --- a/src/compiler/iroptimizer.js +++ b/src/compiler/iroptimizer.js @@ -17,8 +17,6 @@ class TypeState { constructor () { /** @type {Object.}*/ this.variables = {}; - /** @type {InputType | 0} */ - this.defaultType = 0; } /** @@ -33,7 +31,6 @@ class TypeState { } } this.variables = {}; - this.defaultType = InputType.ANY; return modified; } @@ -46,7 +43,6 @@ class TypeState { for (const varId in this.variables) { clone.variables[varId] = this.variables[varId]; } - clone.defaultType = this.defaultType; return clone; } @@ -84,8 +80,8 @@ class TypeState { */ or (other) { return this.mutate(other, varId => { - const thisType = this.variables[varId] ?? this.defaultType; - const otherType = other.variables[varId] ?? other.defaultType; + const thisType = this.variables[varId] ?? InputType.ANY; + const otherType = other.variables[varId] ?? InputType.ANY; return thisType | otherType; }); } @@ -96,9 +92,9 @@ class TypeState { */ after (other) { return this.mutate(other, varId => { - const otherType = other.variables[varId] ?? other.defaultType; + const otherType = other.variables[varId]; if (otherType !== 0) return otherType; - return this.variables[varId] ?? this.defaultType; + return this.variables[varId] ?? InputType.ANY; }); } @@ -108,7 +104,7 @@ class TypeState { * @returns {boolean} */ setVariableType (variable, type) { - if (this.getVariableType(variable) === type) return false; + if (this.variables[variable.id] === type) return false; this.variables[variable.id] = type; return true; } @@ -119,7 +115,7 @@ class TypeState { * @returns {InputType} */ getVariableType (variable) { - return this.variables[variable.id] ?? (this.defaultType === 0 ? InputType.ANY : this.defaultType); + return this.variables[variable.id] ?? InputType.ANY; } } @@ -528,7 +524,7 @@ class IROptimizer { state = state.clone(); } - modified = modified || this.analyzeInputs(inputs, state); + modified = this.analyzeInputs(inputs, state) || modified; switch (stackBlock.opcode) { case StackOpcode.VAR_SET: diff --git a/test/fixtures/tw-type-assertions.sb3 b/test/fixtures/tw-type-assertions.sb3 index 406d204a94e856ea9271bda0bad10ec6eda0c911..29392ebe18ebd7d02e3b51aef8f8101cb342b93e 100644 GIT binary patch delta 4206 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 F004rQF>?R_ 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 ee666ba3..b7824ee7 100644 --- a/test/snapshot/__snapshots__/tw-procedure-return-recursion.sb3.tw-snapshot +++ b/test/snapshot/__snapshots__/tw-procedure-return-recursion.sb3.tw-snapshot @@ -10,17 +10,17 @@ 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; b2.value = thread.procedures["Wwarp recursion should not yield %s"](8); -if ((b1.value === 0)) { +if (compareEqual(b1.value, 0)) { yield* executeInCompatibilityLayer({"MESSAGE":"pass warp recursion does not yield",}, b0, false, false, "ar", null); } 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"); @@ -68,7 +68,7 @@ return function* genXYZ_recursing_yields_bet (p0) { if ((("" + p0).toLowerCase() === "initial".toLowerCase())) { b0.value = 0; b1.value = ((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 1)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 1)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 2)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 2)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 3)) || 0) + (+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 3)) || 0)) || 0)) || 0)) || 0)) || 0)); -if ((b0.value === 3)) { +if (((+b0.value || 0) === 3)) { yield* executeInCompatibilityLayer({"MESSAGE":"pass recursing between calls yields final",}, b2, false, false, "aK", null); } else { yield* executeInCompatibilityLayer({"MESSAGE":"fail recursing between calls yields final",}, b2, false, false, "aL", null); 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 ee666ba3..b7824ee7 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,17 +10,17 @@ 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; b2.value = thread.procedures["Wwarp recursion should not yield %s"](8); -if ((b1.value === 0)) { +if (compareEqual(b1.value, 0)) { yield* executeInCompatibilityLayer({"MESSAGE":"pass warp recursion does not yield",}, b0, false, false, "ar", null); } 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"); @@ -68,7 +68,7 @@ return function* genXYZ_recursing_yields_bet (p0) { if ((("" + p0).toLowerCase() === "initial".toLowerCase())) { b0.value = 0; b1.value = ((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 1)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 1)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 2)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 2)) || 0) + (((+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 3)) || 0) + (+(yield* yieldThenCallGenerator(thread.procedures["Zrecursing yields between each %s"], 3)) || 0)) || 0)) || 0)) || 0)) || 0)); -if ((b0.value === 3)) { +if (((+b0.value || 0) === 3)) { yield* executeInCompatibilityLayer({"MESSAGE":"pass recursing between calls yields final",}, b2, false, false, "aK", null); } else { yield* executeInCompatibilityLayer({"MESSAGE":"fail recursing between calls yields final",}, b2, false, false, "aL", null);