Skip to content

Commit 7fefa6f

Browse files
committed
Check for either input never being numbers first in OP_EQUALS
Fixes TurboWarp#311
1 parent 0e5043d commit 7fefa6f

File tree

8 files changed

+206
-130
lines changed

8 files changed

+206
-130
lines changed

src/compiler/jsgen.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ class JSGenerator {
297297
const left = node.left;
298298
const right = node.right;
299299

300+
// When either operand is known to never be a number, only use string comparison to avoid all number parsing.
301+
if (!left.isSometimesType(InputType.NUMBER_INTERPRETABLE) || !right.isSometimesType(InputType.NUMBER_INTERPRETABLE)) {
302+
return `(${this.descendInput(left.toType(InputType.STRING))}.toLowerCase() === ${this.descendInput(right.toType(InputType.STRING))}.toLowerCase())`;
303+
}
300304
// When both operands are known to be numbers, we can use ===
301305
if (left.isAlwaysType(InputType.NUMBER_INTERPRETABLE) && right.isAlwaysType(InputType.NUMBER_INTERPRETABLE)) {
302306
return `(${this.descendInput(left.toType(InputType.NUMBER))} === ${this.descendInput(right.toType(InputType.NUMBER))})`;
@@ -305,10 +309,6 @@ class JSGenerator {
305309
if (isSafeInputForEqualsOptimization(left, right) || isSafeInputForEqualsOptimization(right, left)) {
306310
return `(${this.descendInput(left.toType(InputType.NUMBER))} === ${this.descendInput(right.toType(InputType.NUMBER))})`;
307311
}
308-
// When either operand is known to never be a number, only use string comparison to avoid all number parsing.
309-
if (!left.isSometimesType(InputType.NUMBER_INTERPRETABLE) || !right.isSometimesType(InputType.NUMBER_INTERPRETABLE)) {
310-
return `(${this.descendInput(left.toType(InputType.STRING))}.toLowerCase() === ${this.descendInput(right.toType(InputType.STRING))}.toLowerCase())`;
311-
}
312312
// No compile-time optimizations possible - use fallback method.
313313
return `compareEqual(${this.descendInput(left)}, ${this.descendInput(right)})`;
314314
}
3.23 KB
Binary file not shown.

test/snapshot/__snapshots__/tw-comparison-matrix-inline.sb3.tw-snapshot

Lines changed: 60 additions & 60 deletions
Large diffs are not rendered by default.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// TW Snapshot
2+
// Input SHA-256: 70cf221f35f1459c3b81ece31ed7b377098ff26eeafb66eba3788dd82c90bdd5
3+
4+
// Sprite1 script
5+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
6+
const b0 = stage.variables["{vwNMZe-LO,q/k3(A,.`"];
7+
const b1 = stage.variables["DKX$)W98mALB-eeMoj(d"];
8+
return function* genXYZ () {
9+
runtime.ext_scratch3_looks._say("plan 8", target);
10+
if (!("true".toLowerCase() === "1".toLowerCase())) {
11+
runtime.ext_scratch3_looks._say("pass", target);
12+
}
13+
if (!("1".toLowerCase() === "true".toLowerCase())) {
14+
runtime.ext_scratch3_looks._say("pass", target);
15+
}
16+
if (((+(2 === 2)) === 1)) {
17+
runtime.ext_scratch3_looks._say("pass", target);
18+
}
19+
if ((1 === (+(2 === 2)))) {
20+
runtime.ext_scratch3_looks._say("pass", target);
21+
}
22+
b0.value = (2 === 2);
23+
b1.value = ("tr" + "ue");
24+
if (!(toNotNaN(+b1.value) === 1)) {
25+
runtime.ext_scratch3_looks._say("pass", target);
26+
}
27+
if (!(1 === toNotNaN(+b1.value))) {
28+
runtime.ext_scratch3_looks._say("pass", target);
29+
}
30+
if (((+b0.value) === 1)) {
31+
runtime.ext_scratch3_looks._say("pass", target);
32+
}
33+
if ((1 === (+b0.value))) {
34+
runtime.ext_scratch3_looks._say("pass", target);
35+
}
36+
runtime.ext_scratch3_looks._say("end", target);
37+
retire(); return;
38+
}; })

test/snapshot/__snapshots__/tw-unsafe-equals.sb3.tw-snapshot

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ runtime.ext_scratch3_looks._say("pass 14", target);
5757
}
5858
yield;
5959
}
60-
if ((0 === 1)) {
60+
if (("".toLowerCase() === "1".toLowerCase())) {
6161
runtime.ext_scratch3_looks._say("fail", target);
6262
}
63-
if ((1 === 0)) {
63+
if (("1".toLowerCase() === "".toLowerCase())) {
6464
runtime.ext_scratch3_looks._say("fail", target);
6565
}
66-
if ((0 === 1)) {
66+
if ((" ".toLowerCase() === "1".toLowerCase())) {
6767
runtime.ext_scratch3_looks._say("fail", target);
6868
}
6969
if ((" ".toLowerCase() === "0".toLowerCase())) {

test/snapshot/__snapshots__/warp-timer/tw-comparison-matrix-inline.sb3.tw-snapshot

Lines changed: 60 additions & 60 deletions
Large diffs are not rendered by default.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// TW Snapshot
2+
// Input SHA-256: 70cf221f35f1459c3b81ece31ed7b377098ff26eeafb66eba3788dd82c90bdd5
3+
4+
// Sprite1 script
5+
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
6+
const b0 = stage.variables["{vwNMZe-LO,q/k3(A,.`"];
7+
const b1 = stage.variables["DKX$)W98mALB-eeMoj(d"];
8+
return function* genXYZ () {
9+
runtime.ext_scratch3_looks._say("plan 8", target);
10+
if (!("true".toLowerCase() === "1".toLowerCase())) {
11+
runtime.ext_scratch3_looks._say("pass", target);
12+
}
13+
if (!("1".toLowerCase() === "true".toLowerCase())) {
14+
runtime.ext_scratch3_looks._say("pass", target);
15+
}
16+
if (((+(2 === 2)) === 1)) {
17+
runtime.ext_scratch3_looks._say("pass", target);
18+
}
19+
if ((1 === (+(2 === 2)))) {
20+
runtime.ext_scratch3_looks._say("pass", target);
21+
}
22+
b0.value = (2 === 2);
23+
b1.value = ("tr" + "ue");
24+
if (!(toNotNaN(+b1.value) === 1)) {
25+
runtime.ext_scratch3_looks._say("pass", target);
26+
}
27+
if (!(1 === toNotNaN(+b1.value))) {
28+
runtime.ext_scratch3_looks._say("pass", target);
29+
}
30+
if (((+b0.value) === 1)) {
31+
runtime.ext_scratch3_looks._say("pass", target);
32+
}
33+
if ((1 === (+b0.value))) {
34+
runtime.ext_scratch3_looks._say("pass", target);
35+
}
36+
runtime.ext_scratch3_looks._say("end", target);
37+
retire(); return;
38+
}; })

test/snapshot/__snapshots__/warp-timer/tw-unsafe-equals.sb3.tw-snapshot

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ runtime.ext_scratch3_looks._say("pass 14", target);
5757
}
5858
yield;
5959
}
60-
if ((0 === 1)) {
60+
if (("".toLowerCase() === "1".toLowerCase())) {
6161
runtime.ext_scratch3_looks._say("fail", target);
6262
}
63-
if ((1 === 0)) {
63+
if (("1".toLowerCase() === "".toLowerCase())) {
6464
runtime.ext_scratch3_looks._say("fail", target);
6565
}
66-
if ((0 === 1)) {
66+
if ((" ".toLowerCase() === "1".toLowerCase())) {
6767
runtime.ext_scratch3_looks._say("fail", target);
6868
}
6969
if ((" ".toLowerCase() === "0".toLowerCase())) {

0 commit comments

Comments
 (0)