Skip to content

Commit c15df0c

Browse files
authored
improve bigint literal comparison (#7029)
1 parent ded2d06 commit c15df0c

File tree

3 files changed

+53
-44
lines changed

3 files changed

+53
-44
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,13 @@
1313
# 12.0.0-alpha.4 (Unreleased)
1414

1515
#### :bug: Bug fix
16+
1617
- Fix tuple coercion. https://github.com/rescript-lang/rescript-compiler/pull/7024
1718

19+
#### :nail_care: Polish
20+
21+
- Improve bigint literal comparison. https://github.com/rescript-lang/rescript-compiler/pull/7029
22+
1823
# 12.0.0-alpha.3
1924

2025
#### :bug: Bug fix

jscomp/core/js_exp_make.ml

+34-12
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* but WITHOUT ANY WARRANTY; without even the implied warranty of
1818
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1919
* GNU Lesser General Public License for more details.
20-
*
20+
*
2121
* You should have received a copy of the GNU Lesser General Public License
2222
* along with this program; if not, write to the Free Software
2323
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
@@ -29,7 +29,7 @@ type t = J.expression
2929
(*
3030
[remove_pure_sub_exp x]
3131
Remove pure part of the expression (minor optimization)
32-
and keep the non-pure part while preserve the semantics
32+
and keep the non-pure part while preserve the semantics
3333
(modulo return value)
3434
It will return None if [x] is pure
3535
*)
@@ -86,8 +86,8 @@ let runtime_var_dot ?comment (x : string) (e1 : string) : J.expression =
8686
let ml_var_dot ?comment ?(dynamic_import = false) (id : Ident.t) e : J.expression =
8787
{ expression_desc = Var (Qualified ({ id; kind = Ml; dynamic_import }, Some e)); comment }
8888

89-
(**
90-
module as a value
89+
(**
90+
module as a value
9191
{[
9292
var http = require("http")
9393
]}
@@ -182,7 +182,7 @@ let instanceof ?comment (e0 : t) (e1: t) : t =
182182
let is_array (e0 : t) : t =
183183
let f = str "Array.isArray" ~delim:DNoQuotes in
184184
{ expression_desc = Call (f, [e0], Js_call_info.ml_full_call); comment=None }
185-
185+
186186
let new_ ?comment e0 args : t =
187187
{ expression_desc = New (e0, Some args); comment }
188188

@@ -455,7 +455,7 @@ let assign_by_exp (e : t) index value : t =
455455
| Array _
456456
(*
457457
Temporary block -- address not held
458-
Optimize cases like this which is really
458+
Optimize cases like this which is really
459459
rare {[
460460
(ref x) := 3
461461
]}
@@ -474,7 +474,7 @@ let record_assign (e : t) (pos : int32) (name : string) (value : t) =
474474
| Array _
475475
(*
476476
Temporary block -- address not held
477-
Optimize cases like this which is really
477+
Optimize cases like this which is really
478478
rare {[
479479
(ref x) := 3
480480
]}
@@ -492,7 +492,7 @@ let extension_assign (e : t) (pos : int32) name (value : t) =
492492
| Array _
493493
(*
494494
Temporary block -- address not held
495-
Optimize cases like this which is really
495+
Optimize cases like this which is really
496496
rare {[
497497
(ref x) := 3
498498
]}
@@ -809,7 +809,7 @@ let tag_type = function
809809
| Ast_untagged_variants.String s -> str s ~delim:DStarJ
810810
| Int i -> small_int i
811811
| Float f -> float f
812-
| BigInt i ->
812+
| BigInt i ->
813813
let sign, i = Bigint_utils.parse_bigint i in
814814
bigint sign i
815815
| Bool b -> bool b
@@ -841,7 +841,7 @@ let rec emit_check (check : t Ast_untagged_variants.DynamicChecks.t) = match che
841841
| IsInstanceOf (Array, x) -> is_array (emit_check x)
842842
| IsInstanceOf (instance, x) ->
843843
let instance_name = Ast_untagged_variants.Instance.to_string instance in
844-
instanceof (emit_check x) (str instance_name ~delim:DNoQuotes)
844+
instanceof (emit_check x) (str instance_name ~delim:DNoQuotes)
845845
| Not x -> not (emit_check x)
846846
| Expr x -> x
847847

@@ -1266,14 +1266,36 @@ let rec int32_band ?comment (e1 : J.expression) (e2 : J.expression) :
12661266
let bigint_op ?comment op (e1: t) (e2: t) = bin ?comment op e1 e2
12671267

12681268
let bigint_comp (cmp : Lam_compat.comparison) ?comment (e0: t) (e1: t) =
1269-
bin ?comment (Lam_compile_util.jsop_of_comp cmp) e0 e1
1269+
let normalize s =
1270+
let len = String.length s in
1271+
let buf = Buffer.create len in
1272+
let trim = ref false in
1273+
s |> String.iteri (fun i c -> (
1274+
match (c, i, !trim) with
1275+
| ('0', 0, _) -> trim := true
1276+
| ('0', _, true) -> ()
1277+
| ('_', _, _) -> ()
1278+
| _ -> (
1279+
trim := false;
1280+
Buffer.add_char buf c
1281+
)
1282+
));
1283+
buf |> Buffer.to_bytes |> Bytes.to_string
1284+
in
1285+
match (cmp, e0.expression_desc, e1.expression_desc) with
1286+
| Ceq, Number (BigInt { positive = p1; value = v1 }), Number (BigInt { positive = p2; value = v2 }) ->
1287+
bool (p1 = p2 && String.equal (normalize v1) (normalize v2))
1288+
| Cneq, Number (BigInt { positive = p1; value = v1 }), Number (BigInt { positive = p2; value = v2 }) ->
1289+
not (bool (p1 = p2 && String.equal (normalize v1) (normalize v2)))
1290+
| _ ->
1291+
bin ?comment (Lam_compile_util.jsop_of_comp cmp) e0 e1
12701292

12711293
let bigint_div ~checked ?comment (e0: t) (e1: t) =
12721294
if checked then
12731295
runtime_call Js_runtime_modules.bigint "div" [e0; e1]
12741296
else
12751297
bigint_op ?comment Div e0 e1
1276-
1298+
12771299
let bigint_mod ~checked ?comment (e0: t) (e1: t) =
12781300
if checked then
12791301
runtime_call Js_runtime_modules.bigint "mod_" [e0; e1]

jscomp/test/bigint_test.js

+14-32
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)