Skip to content

Commit 44a11ce

Browse files
committed
[GR-53531] Implementation of Math.sumPrecise proposal.
PullRequest: js/3333
2 parents aef918c + 2131acd commit 44a11ce

File tree

5 files changed

+780
-3
lines changed

5 files changed

+780
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ See [release calendar](https://www.graalvm.org/release-calendar/) for release da
88
## Version 24.2.0
99
* Updated Node.js to version 20.15.1.
1010
* Implemented the [`Error.isError`](https://github.com/tc39/proposal-is-error) proposal. It is available in ECMAScript staging mode (`--js.ecmascript-version=staging`).
11+
* Implemented the [`Math.sumPrecise`](https://github.com/tc39/proposal-math-sum) proposal. It is available in ECMAScript staging mode (`--js.ecmascript-version=staging`).
1112
* Implemented the [`Promise.try`](https://github.com/tc39/proposal-promise-try) proposal. It is available in ECMAScript staging mode (`--js.ecmascript-version=staging`).
1213
* Implemented the [`Atomics.pause`](https://github.com/tc39/proposal-atomics-microwait) proposal. It is available in ECMAScript staging mode (`--js.ecmascript-version=staging`).
1314
* Implemented the [Uint8Array to/from base64 and hex](https://github.com/tc39/proposal-arraybuffer-base64) proposal. It is available in ECMAScript staging mode (`--js.ecmascript-version=staging`).

graal-js/src/com.oracle.truffle.js.test.external/src/com/oracle/truffle/js/test/external/test262/Test262Runnable.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ public class Test262Runnable extends TestRunnable {
142142
"Intl.RelativeTimeFormat",
143143
"Intl.Segmenter",
144144
"Map",
145+
"Math.sumPrecise",
145146
"Object.fromEntries",
146147
"Object.hasOwn",
147148
"Object.is",
@@ -280,7 +281,6 @@ public class Test262Runnable extends TestRunnable {
280281
private static final Set<String> UNSUPPORTED_FEATURES = featureSet(new String[]{
281282
"Intl.DurationFormat",
282283
"IsHTMLDDA",
283-
"Math.sumPrecise",
284284
"explicit-resource-management",
285285
"tail-call-optimization",
286286
});
@@ -291,6 +291,7 @@ public class Test262Runnable extends TestRunnable {
291291
"FinalizationRegistry.prototype.cleanupSome",
292292
"Float16Array",
293293
"Intl.Locale-info",
294+
"Math.sumPrecise",
294295
"RegExp.escape",
295296
"ShadowRealm",
296297
"decorators",

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/builtins/math/MathBuiltins.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ public enum Math implements BuiltinEnum<Math> {
9999
atanh(1),
100100
fround(1),
101101

102-
f16round(1);
102+
f16round(1),
103+
sumPrecise(1);
103104

104105
private final int length;
105106

@@ -117,7 +118,7 @@ public int getECMAScriptVersion() {
117118
if (EnumSet.range(imul, fround).contains(this)) {
118119
return 6;
119120
}
120-
if (f16round == this) {
121+
if (EnumSet.range(f16round, sumPrecise).contains(this)) {
121122
return JSConfig.StagingECMAScriptVersion;
122123
}
123124
return BuiltinEnum.super.getECMAScriptVersion();
@@ -199,6 +200,8 @@ protected Object createNode(JSContext context, JSBuiltin builtin, boolean constr
199200
return FroundNodeGen.create(context, builtin, args().fixedArgs(1).createArgumentNodes(context));
200201
case f16round:
201202
return F16roundNodeGen.create(context, builtin, args().fixedArgs(1).createArgumentNodes(context));
203+
case sumPrecise:
204+
return SumPreciseNodeGen.create(context, builtin, args().fixedArgs(1).createArgumentNodes(context));
202205
default:
203206
return null;
204207
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright (c) 2024, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.truffle.js.builtins.math;
42+
43+
import com.oracle.truffle.api.dsl.Cached;
44+
import com.oracle.truffle.api.dsl.Specialization;
45+
import com.oracle.truffle.api.exception.AbstractTruffleException;
46+
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
47+
import com.oracle.truffle.js.nodes.access.GetIteratorNode;
48+
import com.oracle.truffle.js.nodes.access.IteratorCloseNode;
49+
import com.oracle.truffle.js.nodes.access.IteratorStepNode;
50+
import com.oracle.truffle.js.nodes.access.IteratorValueNode;
51+
import com.oracle.truffle.js.nodes.access.RequireObjectCoercibleNode;
52+
import com.oracle.truffle.js.nodes.cast.IsNumberNode;
53+
import com.oracle.truffle.js.nodes.cast.JSNumberToDoubleNode;
54+
import com.oracle.truffle.js.nodes.function.JSBuiltin;
55+
import com.oracle.truffle.js.runtime.Errors;
56+
import com.oracle.truffle.js.runtime.JSContext;
57+
import com.oracle.truffle.js.runtime.JSRuntime;
58+
import com.oracle.truffle.js.runtime.external.XSum.SmallAccumulator;
59+
import com.oracle.truffle.js.runtime.objects.IteratorRecord;
60+
61+
public abstract class SumPreciseNode extends MathOperation {
62+
63+
public SumPreciseNode(JSContext context, JSBuiltin builtin) {
64+
super(context, builtin);
65+
}
66+
67+
@Specialization
68+
protected double sumPrecise(Object items,
69+
@Cached RequireObjectCoercibleNode requireObjectCoercible,
70+
@Cached(inline = true) GetIteratorNode getIteratorNode,
71+
@Cached IteratorStepNode iteratorStepNode,
72+
@Cached IteratorValueNode iteratorValueNode,
73+
@Cached("create(getContext())") IteratorCloseNode iteratorCloseNode,
74+
@Cached IsNumberNode isNumberNode,
75+
@Cached JSNumberToDoubleNode toDoubleNode,
76+
@Cached InlinedBranchProfile errorBranch) {
77+
requireObjectCoercible.executeVoid(items);
78+
IteratorRecord iter = getIteratorNode.execute(this, items);
79+
80+
boolean negativeZero = true;
81+
SmallAccumulator acc = new SmallAccumulator();
82+
try {
83+
while (true) {
84+
Object next = iteratorStepNode.execute(iter);
85+
if (next == Boolean.FALSE) {
86+
break;
87+
}
88+
Object nextValue = iteratorValueNode.execute(next);
89+
if (isNumberNode.execute(this, nextValue)) {
90+
double doubleValue = toDoubleNode.execute(this, nextValue);
91+
if (!JSRuntime.isNegativeZero(doubleValue)) {
92+
negativeZero = false;
93+
acc.add(doubleValue);
94+
}
95+
} else {
96+
errorBranch.enter(this);
97+
throw Errors.createTypeErrorNotANumber(nextValue);
98+
}
99+
}
100+
return negativeZero ? -0d : acc.round();
101+
} catch (AbstractTruffleException ex) {
102+
errorBranch.enter(this);
103+
iteratorCloseNode.executeAbrupt(iter.getIterator());
104+
throw ex;
105+
}
106+
}
107+
108+
}

0 commit comments

Comments
 (0)