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 406d204a..29392ebe 100644 Binary files a/test/fixtures/tw-type-assertions.sb3 and b/test/fixtures/tw-type-assertions.sb3 differ 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);