Skip to content

Commit c043cdc

Browse files
authored
fix Number.MAX_SAFE_INTEGER, MIN_SAFE_INTEGER, MIN_VALUE, MAX_VALUE emitting wrong Lua (#1698)
All four constants evaluated to Infinity or -Infinity in Lua. Additionally, MIN_SAFE_INTEGER and MIN_VALUE emitted identical code, as did MAX_SAFE_INTEGER and MAX_VALUE. The existing test did not catch this because it only checked Lua-side results with comparisons that the wrong values accidentally satisfied.
1 parent 84ef0b2 commit c043cdc

File tree

2 files changed

+58
-21
lines changed

2 files changed

+58
-21
lines changed

src/transformation/builtins/number.ts

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,31 +77,62 @@ export function transformNumberProperty(
7777
node
7878
);
7979
case "MIN_VALUE":
80+
// 2 ^ -1074 = 5e-324 (smallest positive double)
8081
return lua.createBinaryExpression(
81-
lua.createNumericLiteral(-2),
82-
lua.createNumericLiteral(1074),
82+
lua.createNumericLiteral(2),
83+
lua.createNumericLiteral(-1074),
8384
lua.SyntaxKind.PowerOperator,
8485
node
8586
);
8687
case "MIN_SAFE_INTEGER":
87-
return lua.createBinaryExpression(
88-
lua.createNumericLiteral(-2),
89-
lua.createNumericLiteral(1074),
90-
lua.SyntaxKind.PowerOperator,
88+
// -(2 ^ 53 - 1) = -9007199254740991
89+
return lua.createUnaryExpression(
90+
lua.createParenthesizedExpression(
91+
lua.createBinaryExpression(
92+
lua.createBinaryExpression(
93+
lua.createNumericLiteral(2),
94+
lua.createNumericLiteral(53),
95+
lua.SyntaxKind.PowerOperator
96+
),
97+
lua.createNumericLiteral(1),
98+
lua.SyntaxKind.SubtractionOperator
99+
)
100+
),
101+
lua.SyntaxKind.NegationOperator,
91102
node
92103
);
93104
case "MAX_SAFE_INTEGER":
105+
// 2 ^ 53 - 1 = 9007199254740991
94106
return lua.createBinaryExpression(
95-
lua.createNumericLiteral(2),
96-
lua.createNumericLiteral(1024),
97-
lua.SyntaxKind.PowerOperator,
107+
lua.createBinaryExpression(
108+
lua.createNumericLiteral(2),
109+
lua.createNumericLiteral(53),
110+
lua.SyntaxKind.PowerOperator
111+
),
112+
lua.createNumericLiteral(1),
113+
lua.SyntaxKind.SubtractionOperator,
98114
node
99115
);
100116
case "MAX_VALUE":
117+
// (2 - 2 ^ -52) * 2 ^ 1023 = 1.7976931348623157e+308
101118
return lua.createBinaryExpression(
102-
lua.createNumericLiteral(2),
103-
lua.createNumericLiteral(1024),
104-
lua.SyntaxKind.PowerOperator,
119+
lua.createParenthesizedExpression(
120+
lua.createBinaryExpression(
121+
lua.createNumericLiteral(2),
122+
lua.createBinaryExpression(
123+
lua.createNumericLiteral(2),
124+
lua.createNumericLiteral(-52),
125+
lua.SyntaxKind.PowerOperator
126+
),
127+
lua.SyntaxKind.SubtractionOperator
128+
)
129+
),
130+
lua.createBinaryExpression(
131+
lua.createNumericLiteral(2),
132+
lua.createNumericLiteral(1023),
133+
lua.SyntaxKind.PowerOperator
134+
),
135+
lua.SyntaxKind.MultiplicationOperator,
105136
node
106137
);
107138

test/unit/builtins/numbers.spec.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -212,17 +212,23 @@ test.each(["42", "undefined"])("prototype call on nullable number (%p)", value =
212212
});
213213

214214
test.each([
215-
"Number.NEGATIVE_INFINITY <= Number.MIN_VALUE",
216-
"Number.MIN_VALUE <= Number.MIN_SAFE_INTEGER",
217-
218-
"Number.MAX_SAFE_INTEGER <= Number.MAX_VALUE",
219-
"Number.MAX_VALUE <= Number.POSITIVE_INFINITY",
215+
// Full ordering: NEG_INF < MIN_SAFE < 0 < MIN_VALUE < EPSILON < MAX_SAFE < MAX_VALUE < POS_INF
216+
"Number.NEGATIVE_INFINITY < Number.MIN_SAFE_INTEGER",
220217
"Number.MIN_SAFE_INTEGER < 0",
221-
222-
"0 < Number.EPSILON",
218+
"0 < Number.MIN_VALUE",
219+
"Number.MIN_VALUE < Number.EPSILON",
223220
"Number.EPSILON < Number.MAX_SAFE_INTEGER",
224-
])("Numer constants have correct relative sizes (%p)", comparison => {
225-
util.testExpression(comparison).expectToEqual(true);
221+
"Number.MAX_SAFE_INTEGER < Number.MAX_VALUE",
222+
"Number.MAX_VALUE < Number.POSITIVE_INFINITY",
223+
224+
// Verify specific values
225+
"Number.MIN_VALUE > 0",
226+
"Number.MIN_SAFE_INTEGER === -(2**53 - 1)",
227+
"Number.MAX_SAFE_INTEGER === 2**53 - 1",
228+
"Number.MAX_SAFE_INTEGER + 1 !== Number.MAX_SAFE_INTEGER",
229+
"Number.MIN_SAFE_INTEGER - 1 !== Number.MIN_SAFE_INTEGER",
230+
])("Number constants have correct relative sizes (%p)", comparison => {
231+
util.testExpression(comparison).expectToMatchJsResult();
226232
});
227233

228234
// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1629

0 commit comments

Comments
 (0)