Skip to content

Commit 26765ad

Browse files
committed
Refactoring: Moving nodes for obtaining double and int from an object to separate classes.
1 parent 2bb3dab commit 26765ad

File tree

5 files changed

+199
-119
lines changed

5 files changed

+199
-119
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_math.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,7 +1323,7 @@ def test_erf(self):
13231323
(-26.8, -1.0), (-27.0, -1.0), (-27.2, -1.0), (-27.4, -1.0), (-27.6, -1.0)
13241324
]
13251325
self.executeFnTest(erfValues, math.erf, 'math.erf')
1326-
1326+
13271327
def test_erfc(self):
13281328
values = [(0.0, 1.0), (-0.0, 1.0), (INF, 0.0), (NINF, 2.0), (NAN, NAN),
13291329
# tiny values
@@ -1345,7 +1345,6 @@ def test_erfc(self):
13451345
(27.4, 0.0), (27.6, 0.0), (-26.2, 2.0), (-26.4, 2.0), (-26.6, 2.0),
13461346
(-26.8, 2.0), (-27.0, 2.0), (-27.2, 2.0), (-27.4, 2.0), (-27.6, 2.0)
13471347
]
1348-
13491348
self.executeFnTest(values, math.erfc, 'math.erfc')
13501349

13511350
def test_gamma(self):
@@ -1365,7 +1364,6 @@ def test_gamma(self):
13651364
self.assertRaises(OverflowError, math.gamma, 2000)
13661365
self.assertRaises(OverflowError, math.gamma, 1.7e308)
13671366

1368-
13691367
values = [
13701368
# special values
13711369
(INF, INF), (NAN, NAN),
@@ -1426,7 +1424,6 @@ def test_lgamma(self):
14261424
self.assertRaises(OverflowError, math.lgamma, 2.55998332785164e305)
14271425
self.assertRaises(OverflowError, math.lgamma, 1.7e308)
14281426

1429-
14301427
values = [(INF, INF), (-INF, INF), (NAN, NAN),
14311428
# small positive integers give factorials
14321429
(1, 0.0), (2, 0.0),
@@ -1504,7 +1501,6 @@ def test_lgamma(self):
15041501
(-2.457024738, 3.346471988407984e-10)
15051502
]
15061503
self.executeFnTest(values, math.lgamma, 'math.lgamma')
1507-
15081504

15091505
def testFsum(self):
15101506
# math.fsum relies on exact rounding for correct operation.

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@
121121
import com.oracle.graal.python.nodes.object.GetClassNode;
122122
import com.oracle.graal.python.nodes.subscript.GetItemNode;
123123
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
124+
import com.oracle.graal.python.nodes.util.GetIntNode;
124125
import com.oracle.graal.python.runtime.PythonContext;
125126
import com.oracle.graal.python.runtime.PythonCore;
126127
import com.oracle.graal.python.runtime.PythonOptions;
@@ -236,7 +237,7 @@ public String doPI(PInt x) {
236237

237238
@Specialization
238239
public String doO(Object x,
239-
@Cached("create()") MathModuleBuiltins.ConvertToIntNode toIntNode,
240+
@Cached("create()") GetIntNode toIntNode,
240241
@Cached("create()") BinNode recursiveNode) {
241242
Object value = toIntNode.execute(x);
242243
return recursiveNode.executeObject(value);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MathModuleBuiltins.java

Lines changed: 23 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
5353
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
5454
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
55+
import com.oracle.graal.python.nodes.util.*;
5556
import com.oracle.graal.python.runtime.exception.PException;
5657
import com.oracle.graal.python.runtime.exception.PythonErrorType;
5758
import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError;
@@ -86,97 +87,6 @@ public MathModuleBuiltins() {
8687
builtinConstants.put("nan", Double.NaN);
8788
}
8889

89-
@TypeSystemReference(PythonArithmeticTypes.class)
90-
@ImportStatic(MathGuards.class)
91-
static abstract class ConvertToFloatNode extends PBaseNode {
92-
93-
@Child private LookupAndCallUnaryNode callFloatNode;
94-
95-
abstract double execute(Object x);
96-
97-
public static ConvertToFloatNode create() {
98-
return MathModuleBuiltinsFactory.ConvertToFloatNodeGen.create();
99-
}
100-
101-
@Specialization
102-
public double toDouble(long x) {
103-
return x;
104-
}
105-
106-
@Specialization
107-
public double toDouble(PInt x) {
108-
return x.doubleValue();
109-
}
110-
111-
@Specialization
112-
public double toDouble(double x) {
113-
return x;
114-
}
115-
116-
@Specialization(guards = "!isNumber(x)")
117-
public double toDouble(Object x) {
118-
if (callFloatNode == null) {
119-
CompilerDirectives.transferToInterpreterAndInvalidate();
120-
callFloatNode = insert(LookupAndCallUnaryNode.create(SpecialMethodNames.__FLOAT__));
121-
}
122-
Object result = callFloatNode.executeObject(x);
123-
if (result == PNone.NO_VALUE) {
124-
throw raise(TypeError, "must be real number, not %p", x);
125-
}
126-
if (result instanceof PFloat) {
127-
return ((PFloat) result).getValue();
128-
}
129-
if (result instanceof Float || result instanceof Double) {
130-
return (double) result;
131-
}
132-
throw raise(TypeError, "%p.__float__ returned non-float (type %p)", x, result);
133-
}
134-
}
135-
136-
@TypeSystemReference(PythonArithmeticTypes.class)
137-
@ImportStatic(MathGuards.class)
138-
static abstract class ConvertToIntNode extends PBaseNode {
139-
140-
@Child private LookupAndCallUnaryNode callIndexNode;
141-
142-
abstract Object execute(Object x);
143-
144-
public static ConvertToIntNode create() {
145-
return MathModuleBuiltinsFactory.ConvertToIntNodeGen.create();
146-
}
147-
148-
@Specialization
149-
public long toInt(long x) {
150-
return x;
151-
}
152-
153-
@Specialization
154-
public PInt toInt(PInt x) {
155-
return x;
156-
}
157-
158-
@Specialization
159-
public long toInt(double x) {
160-
throw raise(TypeError, "'float' object cannot be interpreted as an integer");
161-
}
162-
163-
@Specialization(guards = "!isNumber(x)")
164-
public Object toInt(Object x) {
165-
if (callIndexNode == null) {
166-
CompilerDirectives.transferToInterpreterAndInvalidate();
167-
callIndexNode = insert(LookupAndCallUnaryNode.create(SpecialMethodNames.__INDEX__));
168-
}
169-
Object result = callIndexNode.executeObject(x);
170-
if (result == PNone.NONE) {
171-
throw raise(TypeError, "'%p' object cannot be interpreted as an integer", x);
172-
}
173-
if (!PGuards.isInteger(result) && !PGuards.isPInt(result) && !(result instanceof Boolean)) {
174-
throw raise(TypeError, " __index__ returned non-int (type %p)", result);
175-
}
176-
return result;
177-
}
178-
}
179-
18090
public abstract static class MathUnaryBuiltinNode extends PythonUnaryBuiltinNode {
18191

18292
public void checkMathRangeError(boolean con) {
@@ -219,7 +129,7 @@ public double doPI(PInt value) {
219129

220130
@Specialization(guards = "!isNumber(value)")
221131
public double doGeneral(Object value,
222-
@Cached("create()") ConvertToFloatNode convertToFloat) {
132+
@Cached("create()") GetDoubleNode convertToFloat) {
223133
return count(convertToFloat.execute(value));
224134
}
225135
}
@@ -353,7 +263,7 @@ public Object ceil(PInt value,
353263

354264
@Specialization(guards = {"!isNumber(value)"})
355265
public Object ceil(Object value,
356-
@Cached("create()") ConvertToFloatNode convertToFloat,
266+
@Cached("create()") GetDoubleNode convertToFloat,
357267
@Cached("create(__CEIL__)") LookupAndCallUnaryNode dispatchCeil) {
358268
Object result = dispatchCeil.executeObject(value);
359269
if (result == PNone.NO_VALUE) {
@@ -835,7 +745,7 @@ public PTuple frexpPI(PInt value) {
835745

836746
@Specialization(guards = "!isNumber(value)")
837747
public PTuple frexpO(Object value,
838-
@Cached("create()") ConvertToFloatNode convertToFloat) {
748+
@Cached("create()") GetDoubleNode convertToFloat) {
839749
return frexpD(convertToFloat.execute(value));
840750
}
841751
}
@@ -862,7 +772,7 @@ public boolean isNan(double value) {
862772

863773
@Specialization(guards = "!isNumber(value)")
864774
public boolean isinf(Object value,
865-
@Cached("create()") ConvertToFloatNode convertToFloat) {
775+
@Cached("create()") GetDoubleNode convertToFloat) {
866776
return isNan(convertToFloat.execute(value));
867777
}
868778
}
@@ -1052,7 +962,7 @@ public PTuple frexpPI(PInt value) {
1052962

1053963
@Specialization(guards = "!isNumber(value)")
1054964
public PTuple frexpO(Object value,
1055-
@Cached("create()") ConvertToFloatNode convertToFloatNode) {
965+
@Cached("create()") GetDoubleNode convertToFloatNode) {
1056966
return modfD(convertToFloatNode.execute(value));
1057967
}
1058968
}
@@ -1077,7 +987,7 @@ public abstract static class FsumNode extends PythonUnaryBuiltinNode {
1077987
public double doIt(Object iterable,
1078988
@Cached("create()") GetIteratorNode getIterator,
1079989
@Cached("create(__NEXT__)") LookupAndCallUnaryNode next,
1080-
@Cached("create()") ConvertToFloatNode toFloat,
990+
@Cached("create()") GetDoubleNode toFloat,
1081991
@Cached("createBinaryProfile()") ConditionProfile stopProfile) {
1082992
Object iterator = getIterator.executeWith(iterable);
1083993
double x, y, t, hi, lo = 0, yr, inf_sum = 0, special_sum = 0, sum;
@@ -1238,8 +1148,8 @@ int gcd(PInt x, double y) {
12381148

12391149
@Specialization(guards = "!isNumber(x) || !isNumber(y)")
12401150
Object gcd(Object x, Object y,
1241-
@Cached("create()") ConvertToIntNode xConvert,
1242-
@Cached("create()") ConvertToIntNode yConvert,
1151+
@Cached("create()") GetIntNode xConvert,
1152+
@Cached("create()") GetIntNode yConvert,
12431153
@Cached("create()") GcdNode recursiveNode) {
12441154
Object xValue = xConvert.execute(x);
12451155
Object yValue = yConvert.execute(y);
@@ -1434,7 +1344,7 @@ public boolean isfinite(double value) {
14341344

14351345
@Specialization(guards = "!isNumber(value)")
14361346
public boolean isinf(Object value,
1437-
@Cached("create()") ConvertToFloatNode convertToFloat) {
1347+
@Cached("create()") GetDoubleNode convertToFloat) {
14381348
return isfinite(convertToFloat.execute(value));
14391349
}
14401350
}
@@ -1462,7 +1372,7 @@ public boolean isinf(double value) {
14621372

14631373
@Specialization(guards = "!isNumber(value)")
14641374
public boolean isinf(Object value,
1465-
@Cached("create()") ConvertToFloatNode convertToFloat) {
1375+
@Cached("create()") GetDoubleNode convertToFloat) {
14661376
return isinf(convertToFloat.execute(value));
14671377
}
14681378
}
@@ -1473,22 +1383,22 @@ public boolean isinf(Object value,
14731383
@GenerateNodeFactory
14741384
public abstract static class LogNode extends PythonBinaryBuiltinNode {
14751385

1476-
@Child private ConvertToFloatNode valueConvertNode;
1477-
@Child private ConvertToFloatNode baseConvertNode;
1386+
@Child private GetDoubleNode valueConvertNode;
1387+
@Child private GetDoubleNode baseConvertNode;
14781388
@Child private LogNode recLogNode;
14791389

1480-
private ConvertToFloatNode getValueConvertNode() {
1390+
private GetDoubleNode getValueConvertNode() {
14811391
if (valueConvertNode == null) {
14821392
CompilerDirectives.transferToInterpreterAndInvalidate();
1483-
valueConvertNode = insert(ConvertToFloatNode.create());
1393+
valueConvertNode = insert(GetDoubleNode.create());
14841394
}
14851395
return valueConvertNode;
14861396
}
14871397

1488-
private ConvertToFloatNode getBaseConvertNode() {
1398+
private GetDoubleNode getBaseConvertNode() {
14891399
if (baseConvertNode == null) {
14901400
CompilerDirectives.transferToInterpreterAndInvalidate();
1491-
baseConvertNode = insert(ConvertToFloatNode.create());
1401+
baseConvertNode = insert(GetDoubleNode.create());
14921402
}
14931403
return baseConvertNode;
14941404
}
@@ -1895,8 +1805,8 @@ public abstract static class PowNode extends PythonBinaryBuiltinNode {
18951805

18961806
@Specialization(guards = {"!isNumber(left)||!isNumber(right)"})
18971807
double pow(Object left, Object right,
1898-
@Cached("create()") ConvertToFloatNode convertLeftFloat,
1899-
@Cached("create()") ConvertToFloatNode convertRightFloat) {
1808+
@Cached("create()") GetDoubleNode convertLeftFloat,
1809+
@Cached("create()") GetDoubleNode convertRightFloat) {
19001810
return pow(convertLeftFloat.execute(left), convertRightFloat.execute(right));
19011811
}
19021812
}
@@ -1969,8 +1879,8 @@ public abstract static class Atan2Node extends PythonBinaryBuiltinNode {
19691879

19701880
@Specialization(guards = "!isNumber(left) || !isNumber(right)")
19711881
double atan2(Object left, Object right,
1972-
@Cached("create()") ConvertToFloatNode convertLeftFloat,
1973-
@Cached("create()") ConvertToFloatNode convertRightFloat) {
1882+
@Cached("create()") GetDoubleNode convertLeftFloat,
1883+
@Cached("create()") GetDoubleNode convertRightFloat) {
19741884
return atan2DD(convertLeftFloat.execute(left), convertRightFloat.execute(right));
19751885
}
19761886
}
@@ -2057,8 +1967,8 @@ public double hypotPIL(PInt x, long y) {
20571967

20581968
@Specialization(guards = "!isNumber(objectX) || !isNumber(objectY)")
20591969
public double hypotOO(Object objectX, Object objectY,
2060-
@Cached("create()") ConvertToFloatNode xConvertNode,
2061-
@Cached("create()") ConvertToFloatNode yConvertNode) {
1970+
@Cached("create()") GetDoubleNode xConvertNode,
1971+
@Cached("create()") GetDoubleNode yConvertNode) {
20621972
return hypotDD(xConvertNode.execute(objectX), yConvertNode.execute(objectY));
20631973
}
20641974
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (c) 2017, 2018, Oracle and/or its affiliates.
3+
* Copyright (c) 2014, Regents of the University of California
4+
*
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without modification, are
8+
* permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice, this list of
11+
* conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
13+
* conditions and the following disclaimer in the documentation and/or other materials provided
14+
* with the distribution.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
17+
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19+
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21+
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
24+
* OF THE POSSIBILITY OF SUCH DAMAGE.
25+
*/
26+
package com.oracle.graal.python.nodes.util;
27+
28+
import com.oracle.graal.python.builtins.modules.MathGuards;
29+
import com.oracle.graal.python.builtins.objects.PNone;
30+
import com.oracle.graal.python.builtins.objects.floats.PFloat;
31+
import com.oracle.graal.python.builtins.objects.ints.PInt;
32+
import com.oracle.graal.python.nodes.PBaseNode;
33+
import com.oracle.graal.python.nodes.SpecialMethodNames;
34+
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
35+
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
36+
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
37+
import com.oracle.truffle.api.CompilerDirectives;
38+
import com.oracle.truffle.api.dsl.ImportStatic;
39+
import com.oracle.truffle.api.dsl.Specialization;
40+
import com.oracle.truffle.api.dsl.TypeSystemReference;
41+
import com.oracle.truffle.api.nodes.Node;
42+
43+
@TypeSystemReference(PythonArithmeticTypes.class)
44+
@ImportStatic(MathGuards.class)
45+
public abstract class GetDoubleNode extends PBaseNode {
46+
47+
@Node.Child private LookupAndCallUnaryNode callFloatNode;
48+
49+
abstract public double execute(Object x);
50+
51+
public static GetDoubleNode create() {
52+
return GetDoubleNodeGen.create();
53+
}
54+
55+
@Specialization
56+
public double toDouble(long x) {
57+
return x;
58+
}
59+
60+
@Specialization
61+
public double toDouble(PInt x) {
62+
return x.doubleValue();
63+
}
64+
65+
@Specialization
66+
public double toDouble(double x) {
67+
return x;
68+
}
69+
70+
@Specialization(guards = "!isNumber(x)")
71+
public double toDouble(Object x) {
72+
if (callFloatNode == null) {
73+
CompilerDirectives.transferToInterpreterAndInvalidate();
74+
callFloatNode = insert(LookupAndCallUnaryNode.create(SpecialMethodNames.__FLOAT__));
75+
}
76+
Object result = callFloatNode.executeObject(x);
77+
if (result == PNone.NO_VALUE) {
78+
throw raise(TypeError, "must be real number, not %p", x);
79+
}
80+
if (result instanceof PFloat) {
81+
return ((PFloat) result).getValue();
82+
}
83+
if (result instanceof Float || result instanceof Double) {
84+
return (double) result;
85+
}
86+
throw raise(TypeError, "%p.__float__ returned non-float (type %p)", x, result);
87+
}
88+
}

0 commit comments

Comments
 (0)