Skip to content

Commit 42ff464

Browse files
committed
Optimize float formatting fast paths and validate scalar/SIMD output
1 parent c13739d commit 42ff464

24 files changed

Lines changed: 12115 additions & 7713 deletions

‎NOTICE‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ the following terms:
9595
* xjb-as: https://github.com/JairusSW/xjb-as
9696

9797
The ECMAScript-compatible f64/f32 -> string (dtoa/ftoa) implementation in
98-
std/assembly/util/xjb.ts is vendored from xjb-as.
98+
std/assembly/util/dtoa.ts is vendored from xjb-as.
9999

100100
Copyright (c) Jairus Tanaka
101101
Apache License, Version 2.0 (https://opensource.org/licenses/Apache-2.0)

‎package.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,10 @@
7979
"build": "node scripts/build",
8080
"watch": "node scripts/build --watch",
8181
"coverage": "npx c8 -- npm test",
82-
"test": "npm run test:parser && npm run test:compiler -- --parallel && npm run test:browser && npm run test:asconfig && npm run test:transform && npm run test:cli",
82+
"test": "npm run test:parser && npm run test:compiler -- --parallel && npm run test:dtoa && npm run test:browser && npm run test:asconfig && npm run test:transform && npm run test:cli",
8383
"test:parser": "node --enable-source-maps tests/parser",
8484
"test:compiler": "node --enable-source-maps --no-warnings tests/compiler",
85+
"test:dtoa": "node tests/dtoa",
8586
"test:browser": "node --enable-source-maps tests/browser",
8687
"test:asconfig": "cd tests/asconfig && npm run test",
8788
"test:transform": "npm run test:transform:esm && npm run test:transform:cjs",

‎std/assembly/util/dtoa.ts‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,20 @@ export function dtoa_buffered(buffer: usize, value: f64): u32 {
983983
store<u16>(buf, CharCode.MINUS);
984984
buf += 2;
985985
}
986+
let q = binExp - FLOAT_EXP_OFFSET;
987+
if (q >= -FLOAT_SIGNIFICAND_SIZE && q < 24) {
988+
let c = binSig | FLOAT_HIDDEN_BIT;
989+
let intValue: u64 = 0;
990+
if (q < 0) {
991+
let shift = -q;
992+
let mask = ((<u64>1) << shift) - 1;
993+
if ((c & mask) == 0) intValue = c >> shift;
994+
} else {
995+
intValue = c << q;
996+
if (intValue > 16777216) intValue = 0;
997+
}
998+
if (intValue != 0) return finishInteger(writeUInt16(buf, intValue), dotZero);
999+
}
9861000
toDecimalFloat(binSig | FLOAT_HIDDEN_BIT, binExp, binSig != 0);
9871001
}
9881002

‎std/assembly/util/number.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,11 @@ export function itoa64(value: i64, radix: i32): String {
413413
@lazy @inline const dtoa_buf = memory.data(128);
414414

415415
export function dtoa<T extends number>(value: T): String {
416+
if (value == 0) return "0.0";
417+
if (!isFinite(value)) {
418+
if (isNaN(value)) return "NaN";
419+
return select<String>("-Infinity", "Infinity", value < 0);
420+
}
416421
let len: u32;
417422
if (isFloat<T>() && sizeof<T>() == 4) {
418423
// @ts-ignore: type

‎tests/compiler/issues/2873.debug.wat‎

Lines changed: 1109 additions & 566 deletions
Large diffs are not rendered by default.

‎tests/compiler/issues/2873.release.wat‎

Lines changed: 836 additions & 399 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)