Skip to content

Commit 445a977

Browse files
committed
Compiler: preserve bit representation of NaN
1 parent bfd4988 commit 445a977

File tree

6 files changed

+48
-10
lines changed

6 files changed

+48
-10
lines changed

compiler/lib/generate.ml

+16-4
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,6 @@ let source_location ctx position pc =
386386

387387
(****)
388388

389-
let float_const f = J.ENum (J.Num.of_float (Int64.float_of_bits f))
390-
391389
let s_var name = J.EVar (J.ident (Utf8_string.of_string_exn name))
392390

393391
let runtime_fun ctx name =
@@ -398,6 +396,20 @@ let runtime_fun ctx name =
398396
J.dot (J.EVar (J.V runtime)) name
399397
| None -> s_var name
400398

399+
let float_const ctx bits =
400+
let f = Int64.float_of_bits bits in
401+
match Float.classify_float f with
402+
| FP_nan ->
403+
let targetint x = J.ENum (J.Num.of_string_unsafe (Targetint.to_string_16 x)) in
404+
let p = Share.get_prim (runtime_fun ctx) "jsoo_float_of_bits" ctx.Ctx.share in
405+
let lo = targetint (Targetint.of_int32_truncate (Int64.to_int32 bits))
406+
and hi =
407+
targetint
408+
(Targetint.of_int32_truncate (Int64.to_int32 (Int64.shift_right bits 32)))
409+
in
410+
J.call p [ lo; hi ] J.N
411+
| FP_zero | FP_normal | FP_subnormal | FP_infinite -> J.ENum (J.Num.of_float f)
412+
401413
let str_js_byte s =
402414
let b = Buffer.create (String.length s) in
403415
String.iter s ~f:(function
@@ -468,11 +480,11 @@ let rec constant_rec ~ctx x level instrs =
468480
match s with
469481
| Byte x -> Share.get_byte_string str_js_byte x ctx.Ctx.share, instrs
470482
| Utf (Utf8 x) -> Share.get_utf_string str_js_utf8 x ctx.Ctx.share, instrs)
471-
| Float f -> float_const f, instrs
483+
| Float f -> float_const ctx f, instrs
472484
| Float_array a ->
473485
( Mlvalue.Array.make
474486
~tag:Obj.double_array_tag
475-
~args:(Array.to_list (Array.map a ~f:(fun x -> J.Element (float_const x))))
487+
~args:(Array.to_list (Array.map a ~f:(fun x -> J.Element (float_const ctx x))))
476488
, instrs )
477489
| Int64 i ->
478490
let p =

compiler/lib/targetint.ml

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ let max_int () =
4141

4242
let to_string x = Int32.to_string x
4343

44+
let to_string_16 (x : t) = Printf.sprintf "0x%lx" x
45+
4446
let to_float x = Int32.to_float x
4547

4648
let to_int32 x = x

compiler/lib/targetint.mli

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ val is_zero : t -> bool
1010

1111
val to_string : t -> string
1212

13+
val to_string_16 : t -> string
14+
1315
val to_int_exn : t -> int
1416

1517
val to_float : t -> float

compiler/tests-compiler/variable_declaration_output.ml

+18-4
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,17 @@ let%expect_test _ =
5555
//end
5656
var bx = [254, 1., 2., 3., 4.];
5757
//end
58-
var cx = [254, NaN, NaN, Infinity, - Infinity, 0., - 0.];
58+
var cx = [254,
59+
runtime.jsoo_float_of_bits(0x0, 0xfff80000),
60+
runtime.jsoo_float_of_bits(0x0, 0xfff80000),
61+
Infinity,
62+
- Infinity,
63+
0.,
64+
- 0.];
5965
//end
6066
var symbol_op = [0, symbol_bind, symbol_map, symbol];
61-
//end |}]
67+
//end
68+
|}]
6269

6370
let%expect_test _ =
6471
let program =
@@ -98,10 +105,17 @@ let%expect_test _ =
98105
//end
99106
var bx = [254, 1., 2., 3., 4.];
100107
//end
101-
var cx = [254, NaN, NaN, Infinity, - Infinity, 0., - 0.];
108+
var cx = [254,
109+
runtime.jsoo_float_of_bits(0x0, 0xfff80000),
110+
runtime.jsoo_float_of_bits(0x0, 0xfff80000),
111+
Infinity,
112+
- Infinity,
113+
0.,
114+
- 0.];
102115
//end
103116
var symbol_op = [0, symbol_bind, symbol_map, symbol];
104-
//end |}]
117+
//end
118+
|}]
105119

106120
let%expect_test _ =
107121
let compile ~enable s =

compiler/tests-full/stdlib.cma.expected.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -888,7 +888,7 @@
888888
lnot,
889889
Infinity,
890890
-Infinity,
891-
NaN,
891+
runtime.jsoo_float_of_bits(0x1, 0x7ff80000),
892892
1.7976931348623157e+308,
893893
2.2250738585072014e-308,
894894
2.220446049250313e-16,
@@ -9008,7 +9008,7 @@
90089008
infinity,
90099009
neg_infinity,
90109010
nan,
9011-
NaN,
9011+
runtime.jsoo_float_of_bits(0x1, 0x7ff00000),
90129012
nan,
90139013
3.141592653589793,
90149014
max_float,

runtime/js/ieee_754.js

+8
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ function caml_int64_float_of_bits(x) {
113113
return jsoo_dataview.getFloat64(0, true);
114114
}
115115

116+
//Provides: jsoo_float_of_bits const
117+
//Requires: jsoo_dataview
118+
function jsoo_float_of_bits(l, h) {
119+
jsoo_dataview.setUint32(0, l, true);
120+
jsoo_dataview.setUint32(4, h, true);
121+
return jsoo_dataview.getFloat64(0, true);
122+
}
123+
116124
//Provides: caml_nextafter_float const
117125
//Requires: caml_int64_float_of_bits, caml_int64_bits_of_float, caml_int64_add, caml_int64_sub,caml_int64_of_int32
118126
function caml_nextafter_float(x, y) {

0 commit comments

Comments
 (0)