Skip to content

Modernize runtime #1937

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
* Lib: make the Wasm version of Json.output work with native ints and JavaScript objects (#1872)
* Compiler: static evaluation of more primitives (#1912)
* Compiler: faster compilation by stopping sooner when optimizations become unproductive (#1939)
* Runtime: use Dataview to convert between floats and bit representation

## Bug fixes
* Compiler: fix stack overflow issues with double translation (#1869)
Expand Down
4 changes: 4 additions & 0 deletions ECMASCRIPT.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ Features are grouped by ECMAScript version.

- [Compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap#browser_compatibility)

### DataView

- [Compatibility](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView#browser_compatibility)

## ECMAScript 2016

### async function
Expand Down
1 change: 1 addition & 0 deletions compiler/lib/reserved.ml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ let provided =
; "require" (* only available in node *)
; "Symbol"
; "ArrayBuffer"
; "DataView"
; "Float32Array"
; "Float64Array"
; "Int16Array"
Expand Down
3 changes: 3 additions & 0 deletions compiler/tests-check-prim/main.4.14.output
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ caml_gr_text_size
caml_gr_wait_event
caml_gr_window_id

From +hash.js:
caml_hash_mix_int64

From +ints.js:
caml_div
caml_mod
Expand Down
3 changes: 3 additions & 0 deletions compiler/tests-check-prim/main.5.2.output
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ caml_gr_text_size
caml_gr_wait_event
caml_gr_window_id

From +hash.js:
caml_hash_mix_int64

From +ints.js:
caml_div
caml_mod
Expand Down
3 changes: 3 additions & 0 deletions compiler/tests-check-prim/main.5.3.output
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ caml_gr_text_size
caml_gr_wait_event
caml_gr_window_id

From +hash.js:
caml_hash_mix_int64

From +ints.js:
caml_div
caml_mod
Expand Down
3 changes: 3 additions & 0 deletions compiler/tests-check-prim/unix-Unix.4.14.output
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ caml_gr_text_size
caml_gr_wait_event
caml_gr_window_id

From +hash.js:
caml_hash_mix_int64

From +ints.js:
caml_div
caml_mod
Expand Down
3 changes: 3 additions & 0 deletions compiler/tests-check-prim/unix-Unix.5.2.output
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,9 @@ caml_gr_text_size
caml_gr_wait_event
caml_gr_window_id

From +hash.js:
caml_hash_mix_int64

From +ints.js:
caml_div
caml_mod
Expand Down
3 changes: 3 additions & 0 deletions compiler/tests-check-prim/unix-Unix.5.3.output
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ caml_gr_text_size
caml_gr_wait_event
caml_gr_window_id

From +hash.js:
caml_hash_mix_int64

From +ints.js:
caml_div
caml_mod
Expand Down
3 changes: 3 additions & 0 deletions compiler/tests-check-prim/unix-Win32.4.14.output
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ caml_gr_text_size
caml_gr_wait_event
caml_gr_window_id

From +hash.js:
caml_hash_mix_int64

From +ints.js:
caml_div
caml_mod
Expand Down
3 changes: 3 additions & 0 deletions compiler/tests-check-prim/unix-Win32.5.2.output
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ caml_gr_text_size
caml_gr_wait_event
caml_gr_window_id

From +hash.js:
caml_hash_mix_int64

From +ints.js:
caml_div
caml_mod
Expand Down
3 changes: 3 additions & 0 deletions compiler/tests-check-prim/unix-Win32.5.3.output
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ caml_gr_text_size
caml_gr_wait_event
caml_gr_window_id

From +hash.js:
caml_hash_mix_int64

From +ints.js:
caml_div
caml_mod
Expand Down
23 changes: 20 additions & 3 deletions runtime/js/hash.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,26 @@ function caml_hash_mix_final(h) {
}

//Provides: caml_hash_mix_float
//Requires: caml_int64_bits_of_float, caml_hash_mix_int64
function caml_hash_mix_float(h, v0) {
return caml_hash_mix_int64(h, caml_int64_bits_of_float(v0));
//Requires: caml_int64_bits_of_float
//Requires: caml_hash_mix_int
//Requires: caml_int64_lo32, caml_int64_hi32
function caml_hash_mix_float(hash, v0) {
var i64 = caml_int64_bits_of_float(v0);
var l = caml_int64_lo32(i64);
var h = caml_int64_hi32(i64);
/* Normalize NaNs */
if ((h & 0x7ff00000) === 0x7ff00000 && (l | (h & 0xfffff)) !== 0) {
h = 0x7ff00000;
l = 0x00000001;
} else if (h === (0x80000000 | 0) && l === 0) {
/* Normalize -0 into +0 */
// This code path is not used by caml_hash because 0 and -0 look
// like integers
h = 0;
}
hash = caml_hash_mix_int(hash, l);
hash = caml_hash_mix_int(hash, h);
return hash;
}
//Provides: caml_hash_mix_int64
//Requires: caml_hash_mix_int
Expand Down
107 changes: 24 additions & 83 deletions runtime/js/ieee_754.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,74 +17,27 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

//Provides: jsoo_floor_log2
var log2_ok = Math.log2 && Math.log2(1.1235582092889474e307) === 1020;
function jsoo_floor_log2(x) {
if (log2_ok) return Math.floor(Math.log2(x));
var i = 0;
if (x === 0) return Number.NEGATIVE_INFINITY;
if (x >= 1) {
while (x >= 2) {
x /= 2;
i++;
}
} else {
while (x < 1) {
x *= 2;
i--;
}
}
return i;
}
//Provides: jsoo_dataview
var jsoo_dataview = new DataView(new ArrayBuffer(8));

//Provides: caml_int64_bits_of_float const
//Requires: jsoo_floor_log2, caml_int64_create_lo_mi_hi
//Requires: caml_int64_create_lo_mi_hi
//Requires: jsoo_dataview
function caml_int64_bits_of_float(x) {
if (!Number.isFinite(x)) {
if (Number.isNaN(x)) return caml_int64_create_lo_mi_hi(1, 0, 0x7ff0);
if (x > 0) return caml_int64_create_lo_mi_hi(0, 0, 0x7ff0);
else return caml_int64_create_lo_mi_hi(0, 0, 0xfff0);
}
var sign =
x === 0 && 1 / x === Number.NEGATIVE_INFINITY
? 0x8000
: x >= 0
? 0
: 0x8000;
if (sign) x = -x;
// Int64.bits_of_float 1.1235582092889474E+307 = 0x7fb0000000000000L
// using Math.LOG2E*Math.log(x) in place of Math.log2 result in precision lost
var exp = jsoo_floor_log2(x) + 1023;
if (exp <= 0) {
exp = 0;
x /= Math.pow(2, -1026);
} else {
x /= Math.pow(2, exp - 1027);
if (x < 16) {
x *= 2;
exp -= 1;
}
if (exp === 0) {
x /= 2;
}
}
var k = Math.pow(2, 24);
var r3 = x | 0;
x = (x - r3) * k;
var r2 = x | 0;
x = (x - r2) * k;
var r1 = x | 0;
r3 = (r3 & 0xf) | sign | (exp << 4);
jsoo_dataview.setFloat64(0, x, true);
var lo32 = jsoo_dataview.getUint32(0, true);
var hi32 = jsoo_dataview.getUint32(4, true);
var r1 = lo32 & 0xffffff;
var r2 = (lo32 >>> 24) | ((hi32 << 8) & 0xffffff);
var r3 = (hi32 >>> 16) & 0xffff;
return caml_int64_create_lo_mi_hi(r1, r2, r3);
}

//Provides: caml_int32_bits_of_float const
//Requires: jsoo_floor_log2
//Requires: jsoo_dataview
function caml_int32_bits_of_float(x) {
var float32a = new Float32Array(1);
float32a[0] = x;
var int32a = new Int32Array(float32a.buffer);
return int32a[0] | 0;
jsoo_dataview.setFloat32(0, x, true);
return jsoo_dataview.getUint32(0, true) | 0;
}

//FP literals can be written using the hexadecimal
Expand Down Expand Up @@ -150,24 +103,14 @@ function caml_hexstring_of_float(x, prec, style) {
}

//Provides: caml_int64_float_of_bits const
//Requires: jsoo_dataview
function caml_int64_float_of_bits(x) {
var lo = x.lo;
var mi = x.mi;
var hi = x.hi;
var exp = (hi & 0x7fff) >> 4;
if (exp === 2047) {
if ((lo | mi | (hi & 0xf)) === 0)
return hi & 0x8000 ? Number.NEGATIVE_INFINITY : Number.POSITIVE_INFINITY;
else return Number.NaN;
}
var k = Math.pow(2, -24);
var res = (lo * k + mi) * k + (hi & 0xf);
if (exp > 0) {
res += 16;
res *= Math.pow(2, exp - 1027);
} else res *= Math.pow(2, -1026);
if (hi & 0x8000) res = -res;
return res;
jsoo_dataview.setUint32(0, lo | (mi << 24), true);
jsoo_dataview.setUint32(4, (mi >>> 8) | (hi << 16), true);
return jsoo_dataview.getFloat64(0, true);
}

//Provides: caml_nextafter_float const
Expand All @@ -192,11 +135,10 @@ function caml_trunc_float(x) {
}

//Provides: caml_int32_float_of_bits const
//Requires: jsoo_dataview
function caml_int32_float_of_bits(x) {
var int32a = new Int32Array(1);
int32a[0] = x;
var float32a = new Float32Array(int32a.buffer);
return float32a[0];
jsoo_dataview.setUint32(0, x, true);
return jsoo_dataview.getFloat32(0, true);
}

//Provides: caml_classify_float const
Expand Down Expand Up @@ -244,12 +186,11 @@ function caml_ldexp_float(x, exp) {
return x;
}
//Provides: caml_frexp_float const
//Requires: jsoo_floor_log2
function caml_frexp_float(x) {
if (x === 0 || !Number.isFinite(x)) return [0, x, 0];
var neg = x < 0;
if (neg) x = -x;
var exp = Math.max(-1023, jsoo_floor_log2(x) + 1);
var exp = Math.max(-1023, Math.floor(Math.log2(x)) + 1);
x *= Math.pow(2, -exp);
while (x < 0.5) {
x *= 2;
Expand Down Expand Up @@ -482,7 +423,7 @@ function caml_fma_float(x, y, z) {
}

//Provides: caml_format_float const
//Requires: caml_parse_format, caml_finish_formatting
//Requires: caml_str_repeat, caml_parse_format, caml_finish_formatting
function caml_format_float(fmt, x) {
function toFixed(x, dp) {
if (Math.abs(x) < 1.0) {
Expand All @@ -492,9 +433,9 @@ function caml_format_float(fmt, x) {
if (e > 20) {
e -= 20;
x /= Math.pow(10, e);
x += new Array(e + 1).join("0");
x += caml_str_repeat(e, "0");
if (dp > 0) {
x = x + "." + new Array(dp + 1).join("0");
x = x + "." + caml_str_repeat(dp, "0");
}
return x;
} else return x.toFixed(dp);
Expand Down
19 changes: 1 addition & 18 deletions runtime/js/mlBytes.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,7 @@

//Provides: caml_str_repeat
function caml_str_repeat(n, s) {
if (n === 0) return "";
if (s.repeat) {
return s.repeat(n);
} // ECMAscript 6 and Firefox 24+
var r = "",
l = 0;
for (;;) {
if (n & 1) r += s;
n >>= 1;
if (n === 0) return r;
s += s;
l++;
if (l === 9) {
s.slice(0, 1); // flatten the string
// then, the flattening of the whole string will be faster,
// as it will be composed of larger pieces
}
}
return s.repeat(n);
}

//Provides: caml_subarray_to_jsbytes
Expand Down
Loading