@@ -262,14 +262,32 @@ function makeInlineCalculation(expression, value, tempVar) {
262
262
263
263
// XXX Make all i64 parts signed
264
264
265
+ function castToBigInt ( x ) {
266
+ // Micro-size-optimization: if x is an integer literal, then we can append
267
+ // the suffix 'n' instead of casting to BigInt(), to get smaller code size.
268
+ var n = Number ( x ) ;
269
+ if ( Number . isInteger ( n ) && isFinite ( n ) ) {
270
+ // NOTE: BigInt(316059037807746200000) != 316059037807746200000n
271
+ // i.e. constructing numbers with BigInt()s is subject to rounding, if
272
+ // the input value cannot be exactly represented as a 64-bit double.
273
+ // Currently the test suite depends on this rounding behavior, so only
274
+ // apply this literal optimization to safe integers for now.
275
+ if ( Math . abs ( n ) < Number . MAX_SAFE_INTEGER ) {
276
+ return `${ x } n` ;
277
+ }
278
+ }
279
+ return `BigInt(${ x } )` ;
280
+ }
281
+
282
+
265
283
// Splits a number (an integer in a double, possibly > 32 bits) into an i64
266
284
// value, represented by a low and high i32 pair.
267
285
// Will suffer from rounding and truncation.
268
286
function splitI64 ( value ) {
269
287
if ( WASM_BIGINT ) {
270
288
// Nothing to do: just make sure it is a BigInt (as it must be of that
271
289
// type, to be sent into wasm).
272
- return `BigInt( ${ value } )` ;
290
+ return castToBigInt ( value ) ;
273
291
}
274
292
275
293
// general idea:
@@ -474,7 +492,7 @@ function makeSetValueImpl(ptr, pos, value, type) {
474
492
475
493
const slab = getHeapForType ( type ) ;
476
494
if ( slab == 'HEAPU64' || slab == 'HEAP64' ) {
477
- value = `BigInt( ${ value } )` ;
495
+ value = castToBigInt ( value ) ;
478
496
}
479
497
return `${ slab } [${ getHeapOffset ( offset , type ) } ] = ${ value } ` ;
480
498
}
@@ -595,7 +613,7 @@ function getHeapForType(type) {
595
613
596
614
export function makeReturn64 ( value ) {
597
615
if ( WASM_BIGINT ) {
598
- return `BigInt( ${ value } )` ;
616
+ return castToBigInt ( value ) ;
599
617
}
600
618
const pair = splitI64 ( value ) ;
601
619
// `return (a, b, c)` in JavaScript will execute `a`, and `b` and return the final
@@ -1000,7 +1018,7 @@ function from64Expr(x) {
1000
1018
// Converts a value to BigInt if building for wasm64, with both 64-bit pointers
1001
1019
// and 64-bit memory. Used for indices into the memory tables, for example.
1002
1020
function toIndexType ( x ) {
1003
- if ( MEMORY64 == 1 ) return `BigInt( ${ x } )` ;
1021
+ if ( MEMORY64 == 1 ) return castToBigInt ( x ) ;
1004
1022
return x ;
1005
1023
}
1006
1024
@@ -1010,7 +1028,7 @@ function toIndexType(x) {
1010
1028
// this conversion before passing them).
1011
1029
function to64 ( x ) {
1012
1030
if ( ! MEMORY64 ) return x ;
1013
- return `BigInt( ${ x } )` ;
1031
+ return castToBigInt ( x ) ;
1014
1032
}
1015
1033
1016
1034
function asyncIf ( condition ) {
0 commit comments