Repository navigation
Commit 77309cb
Compile integer operations with an identity operand to the operand
Integer `x + 0`, `0 + x`, `x - 0`, `x * 1`, `1 * x` and `x / 1` compile
to `x`. A ReScript `int` value is a 32-bit integer in JavaScript, so the
`| 0` truncation (or `<< 0` for `* 1`) that these operations emitted
leaves the value unchanged. The JavaScript expression builders in
`Js_exp_make` (`int32_add`, `int32_minus`, `int32_mul`, `int32_div`)
return the other operand when one operand is the literal identity. The
dropped operand is a literal, so evaluation of the kept operand is
unchanged.
Example (rescript):
let addZero = (x: int) => x + 0
let subZero = (x: int) => x - 0
let mulOne = (x: int) => x * 1
let divOne = (x: int) => x / 1
Before (js):
function addZero(x) {
return x + 0 | 0;
}
function subZero(x) {
return x - 0 | 0;
}
function mulOne(x) {
return (x << 0);
}
function divOne(x) {
return x / 1 | 0;
}
After (js):
function addZero(x) {
return x;
}
function subZero(x) {
return x;
}
function mulOne(x) {
return x;
}
function divOne(x) {
return x;
}
Source: `bsc Example.res` (CommonJS, to stdout) with bsc built from
aa2078e (Before) and from this commit (After); function bodies shown, the
module header and exports are identical.
Changelog entry: - Compile integer `x + 0`, `0 + x`, `x - 0`, `x * 1`,
`1 * x` and `x / 1` to `x`. #8871
Review: Can an `int` operand hold a value outside the 32-bit range? Every
int the compiler computes is already truncated: compiling `-x`,
`Int.fromFloat(f)` and `Int.shiftRightUnsigned(x, y)` with this commit
gives `-x | 0`, `f | 0` and `(x >>> y) | 0`. A value outside the range
reaches an `int` only through an external or `%raw` typed `int`; for
those the result changes, for example `Number.MAX_SAFE_INTEGER + 0` gave
-1 and gives 9007199254740991. The compiler already relies on the same
assumption: `Plsrint` by the literal 0 compiles to the operand
(compiler/core/lam_compile_primitive.ml, `[e1; 0] -> e1`), dropping
`(x >>> 0) | 0`.
Review: Does `x / 1` still check for division by zero? The divisor is the
literal 1, so no check applies; the existing rule for a nonzero literal
divisor already skipped the runtime `div` call.
Area: codegen tests
Changelog: polish
Output: changed integer `+ 0`, `0 +`, `- 0`, `* 1`, `1 *`, `/ 1` on a
non-literal operand, now the bare operand; in tests/tests/src one existing
snapshot changes (gpr_3609_test.mjs, `0 + state._0 | 0` -> `state._0`)
and in the gentype example Docstrings.res.js six `+ 0` functions
drop the addition (`a + 0 | 0` -> `a`),
and the stdlib build (make lib) emits no changed JS
Formats: none
Tests: +tests/tests/src/int_identity_ops_test.res
+tests/tests/src/int_identity_ops_test.mjs
~tests/tests/src/gpr_3609_test.mjs
~tests/gentype_tests/typescript-react-example/src/Docstrings.res.js
Ran: make test on bc2e0e1 + this stack (exit 0: 318 ounit tests OK,
tests/tests mocha 606 passing including Int_identity_ops_test, stdlib
mocha 744 passing); make checkformat (exit 0); yarn
changelog:check (passes); make
test-gentype, test-analysis, test-tools (exit 0); make test-rewatch
fails locally on a temp-directory symlink (Path is a directory:
rescript-gentype-root-*-link), with no generated JS change
Depends: #8870 (stacked)
PR: #8871
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>1 parent 22cdcc4 commit 77309cb
6 files changed
Lines changed: 124 additions & 10 deletions
File tree
- changes
- compiler/core
- tests
- gentype_tests/typescript-react-example/src
- tests/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1595 | 1595 | | |
1596 | 1596 | | |
1597 | 1597 | | |
1598 | | - | |
| 1598 | + | |
| 1599 | + | |
| 1600 | + | |
| 1601 | + | |
| 1602 | + | |
| 1603 | + | |
| 1604 | + | |
1599 | 1605 | | |
1600 | | - | |
1601 | | - | |
| 1606 | + | |
| 1607 | + | |
| 1608 | + | |
| 1609 | + | |
1602 | 1610 | | |
1603 | 1611 | | |
1604 | 1612 | | |
| |||
1610 | 1618 | | |
1611 | 1619 | | |
1612 | 1620 | | |
| 1621 | + | |
1613 | 1622 | | |
1614 | 1623 | | |
1615 | 1624 | | |
| |||
1654 | 1663 | | |
1655 | 1664 | | |
1656 | 1665 | | |
| 1666 | + | |
| 1667 | + | |
| 1668 | + | |
1657 | 1669 | | |
1658 | 1670 | | |
1659 | 1671 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
0 commit comments