From a022591091dd387f1bdd88fd140d6d865c76bfb6 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Thu, 15 May 2025 13:50:10 +0800 Subject: [PATCH 1/4] fix: avoid powi opt in js engine only when exponent <= 2 --- src/util/math.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/util/math.ts b/src/util/math.ts index 25759f35d1..ee00da221b 100644 --- a/src/util/math.ts +++ b/src/util/math.ts @@ -11,15 +11,11 @@ export function isPowerOf2(x: i32): bool { export function accuratePow64(x: f64, y: f64): f64 { if (!ASC_TARGET) { // ASC_TARGET == JS // Engines like V8, WebKit and SpiderMonkey uses powi fast path if exponent is integer - // This speculative optimization leads to loose precisions like 10 ** 208 != 1e208 - // or/and 10 ** -5 != 1e-5 anymore. For avoid this behaviour we are forcing exponent + // This speculative optimization leads to loose precisions like 10 ** -5 != 1e-5 anymore. + // For avoid this behaviour we are forcing exponent // to fractional form and compensate this afterwards. - if (isFinite(y) && Math.abs(y) >= 2 && Math.trunc(y) == y) { - if (y < 0) { - return Math.pow(x, y + 0.5) / Math.pow(x, 0.5); - } else { - return Math.pow(x, y - 0.5) * Math.pow(x, 0.5); - } + if (isFinite(y) && y <= -2 && Math.trunc(y) == y) { + return Math.pow(x, y + 0.5) / Math.pow(x, 0.5); } } return Math.pow(x, y); From e80108170f8d9e5d88fed37f82485ae17cb12f72 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Wed, 28 May 2025 10:10:57 +0800 Subject: [PATCH 2/4] wip --- package-lock.json | 12 ++++++++++++ package.json | 1 + src/glue/js/float.d.ts | 1 + src/glue/js/float.js | 4 ++++ src/util/math.ts | 10 ++++------ 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index cc1ddb0d78..d34606ae3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "license": "Apache-2.0", "dependencies": { + "as-float": "^1.0.0", "binaryen": "116.0.0-nightly.20240114", "long": "^5.2.4" }, @@ -953,6 +954,12 @@ "node": ">=8" } }, + "node_modules/as-float": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/as-float/-/as-float-1.0.0.tgz", + "integrity": "sha512-zJqF6tGqxqVQdQBSJbl2ft3/HhwCrWFY1YCA+WQF69Pqb9+WNtbH4ZU9VrQ3biYS69MgUjKU6XK3boboR9l3hA==", + "license": "MIT" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3054,6 +3061,11 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "as-float": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/as-float/-/as-float-1.0.0.tgz", + "integrity": "sha512-zJqF6tGqxqVQdQBSJbl2ft3/HhwCrWFY1YCA+WQF69Pqb9+WNtbH4ZU9VrQ3biYS69MgUjKU6XK3boboR9l3hA==" + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", diff --git a/package.json b/package.json index 2b10b739a3..1431e54b61 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ }, "engineStrict": true, "dependencies": { + "as-float": "^1.0.0", "binaryen": "116.0.0-nightly.20240114", "long": "^5.2.4" }, diff --git a/src/glue/js/float.d.ts b/src/glue/js/float.d.ts index 8694f03b52..0e24039b14 100644 --- a/src/glue/js/float.d.ts +++ b/src/glue/js/float.d.ts @@ -7,3 +7,4 @@ declare function f32_as_i32(value: f32): i32; declare function i32_as_f32(value: i32): f32; declare function f64_as_i64(value: f64): i64; declare function i64_as_f64(value: i64): f64; +declare function f64_pow(value: f64, exponent: f64): f64; \ No newline at end of file diff --git a/src/glue/js/float.js b/src/glue/js/float.js index 090af6cf96..6b68fdfef1 100644 --- a/src/glue/js/float.js +++ b/src/glue/js/float.js @@ -3,6 +3,8 @@ * @license Apache-2.0 */ +import { f64_pow } from "as-float"; + /* eslint-disable no-undef */ const F64 = new Float64Array(1); @@ -29,3 +31,5 @@ globalThis.i64_as_f64 = function i64_as_f64(value) { I32[1] = i64_high(value); return F64[0]; }; + +globalThis.f64_pow = f64_pow; diff --git a/src/util/math.ts b/src/util/math.ts index ee00da221b..56655e921c 100644 --- a/src/util/math.ts +++ b/src/util/math.ts @@ -11,12 +11,10 @@ export function isPowerOf2(x: i32): bool { export function accuratePow64(x: f64, y: f64): f64 { if (!ASC_TARGET) { // ASC_TARGET == JS // Engines like V8, WebKit and SpiderMonkey uses powi fast path if exponent is integer - // This speculative optimization leads to loose precisions like 10 ** -5 != 1e-5 anymore. - // For avoid this behaviour we are forcing exponent - // to fractional form and compensate this afterwards. - if (isFinite(y) && y <= -2 && Math.trunc(y) == y) { - return Math.pow(x, y + 0.5) / Math.pow(x, 0.5); - } + // This speculative optimization leads to loose precisions like 10 ** -5 != 1e-5 anymore + // and introduces inconsistencies between different engines and versions + // For avoid this behavior we using bootstrap f64_pow function. + return f64_pow(x, y); } return Math.pow(x, y); } From 280e2b9a75676a4b036936f016b685be4afd09b7 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Wed, 28 May 2025 11:27:08 +0800 Subject: [PATCH 3/4] put as-float to devdeps --- package-lock.json | 6 ++++-- package.json | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d34606ae3a..db1bad2df6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "0.0.0", "license": "Apache-2.0", "dependencies": { - "as-float": "^1.0.0", "binaryen": "116.0.0-nightly.20240114", "long": "^5.2.4" }, @@ -21,6 +20,7 @@ "@types/node": "^18.19.75", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", + "as-float": "^1.0.0", "diff": "^7.0.0", "esbuild": "^0.25.0", "eslint": "^8.57.1", @@ -958,6 +958,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/as-float/-/as-float-1.0.0.tgz", "integrity": "sha512-zJqF6tGqxqVQdQBSJbl2ft3/HhwCrWFY1YCA+WQF69Pqb9+WNtbH4ZU9VrQ3biYS69MgUjKU6XK3boboR9l3hA==", + "dev": true, "license": "MIT" }, "node_modules/balanced-match": { @@ -3064,7 +3065,8 @@ "as-float": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/as-float/-/as-float-1.0.0.tgz", - "integrity": "sha512-zJqF6tGqxqVQdQBSJbl2ft3/HhwCrWFY1YCA+WQF69Pqb9+WNtbH4ZU9VrQ3biYS69MgUjKU6XK3boboR9l3hA==" + "integrity": "sha512-zJqF6tGqxqVQdQBSJbl2ft3/HhwCrWFY1YCA+WQF69Pqb9+WNtbH4ZU9VrQ3biYS69MgUjKU6XK3boboR9l3hA==", + "dev": true }, "balanced-match": { "version": "1.0.2", diff --git a/package.json b/package.json index 1431e54b61..43f15ecda8 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,6 @@ }, "engineStrict": true, "dependencies": { - "as-float": "^1.0.0", "binaryen": "116.0.0-nightly.20240114", "long": "^5.2.4" }, @@ -33,6 +32,7 @@ "@types/node": "^18.19.75", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", + "as-float": "^1.0.0", "diff": "^7.0.0", "esbuild": "^0.25.0", "eslint": "^8.57.1", From b1fc6da6f0e7e7d982ee72416bf4e52d4ff018d9 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Thu, 29 May 2025 06:19:34 +0800 Subject: [PATCH 4/4] bump to as-float@1.0.1 --- package-lock.json | 14 +++++++------- package.json | 2 +- src/glue/js/float.d.ts | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index db1bad2df6..e2bceb3ad0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,7 @@ "@types/node": "^18.19.75", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", - "as-float": "^1.0.0", + "as-float": "^1.0.1", "diff": "^7.0.0", "esbuild": "^0.25.0", "eslint": "^8.57.1", @@ -955,9 +955,9 @@ } }, "node_modules/as-float": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/as-float/-/as-float-1.0.0.tgz", - "integrity": "sha512-zJqF6tGqxqVQdQBSJbl2ft3/HhwCrWFY1YCA+WQF69Pqb9+WNtbH4ZU9VrQ3biYS69MgUjKU6XK3boboR9l3hA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/as-float/-/as-float-1.0.1.tgz", + "integrity": "sha512-TsN1UpoFdtzuKXqqpdnGbFuMYnK/eqMEjd2xVvACG29H/v4KLx+UD+tHRz9v6zO+Ge/AR/uskSruBIPZrchhHw==", "dev": true, "license": "MIT" }, @@ -3063,9 +3063,9 @@ "dev": true }, "as-float": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/as-float/-/as-float-1.0.0.tgz", - "integrity": "sha512-zJqF6tGqxqVQdQBSJbl2ft3/HhwCrWFY1YCA+WQF69Pqb9+WNtbH4ZU9VrQ3biYS69MgUjKU6XK3boboR9l3hA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/as-float/-/as-float-1.0.1.tgz", + "integrity": "sha512-TsN1UpoFdtzuKXqqpdnGbFuMYnK/eqMEjd2xVvACG29H/v4KLx+UD+tHRz9v6zO+Ge/AR/uskSruBIPZrchhHw==", "dev": true }, "balanced-match": { diff --git a/package.json b/package.json index 43f15ecda8..cf320be2a8 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "@types/node": "^18.19.75", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", - "as-float": "^1.0.0", + "as-float": "^1.0.1", "diff": "^7.0.0", "esbuild": "^0.25.0", "eslint": "^8.57.1", diff --git a/src/glue/js/float.d.ts b/src/glue/js/float.d.ts index 0e24039b14..b116ad846c 100644 --- a/src/glue/js/float.d.ts +++ b/src/glue/js/float.d.ts @@ -7,4 +7,4 @@ declare function f32_as_i32(value: f32): i32; declare function i32_as_f32(value: i32): f32; declare function f64_as_i64(value: f64): i64; declare function i64_as_f64(value: i64): f64; -declare function f64_pow(value: f64, exponent: f64): f64; \ No newline at end of file +declare function f64_pow(value: f64, exponent: f64): f64;