Skip to content

Commit d859056

Browse files
committed
[GR-8766] add ducktype test nodes
PullRequest: graalpython-open/27
2 parents 763bc1c + 45f4ede commit d859056

File tree

9 files changed

+547
-40
lines changed

9 files changed

+547
-40
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/NodeFactory.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@
5151
import com.oracle.graal.python.nodes.control.LoopNode;
5252
import com.oracle.graal.python.nodes.control.ReturnNode;
5353
import com.oracle.graal.python.nodes.control.WhileNode;
54+
import com.oracle.graal.python.nodes.datamodel.IsCallableNode;
55+
import com.oracle.graal.python.nodes.datamodel.IsContextManagerNode;
56+
import com.oracle.graal.python.nodes.datamodel.IsIterableNode;
57+
import com.oracle.graal.python.nodes.datamodel.IsMappingNode;
58+
import com.oracle.graal.python.nodes.datamodel.IsSequenceNode;
59+
import com.oracle.graal.python.nodes.datamodel.PDataModelEmulationNode;
5460
import com.oracle.graal.python.nodes.expression.AndNode;
5561
import com.oracle.graal.python.nodes.expression.BinaryArithmetic;
5662
import com.oracle.graal.python.nodes.expression.BinaryComparisonNode;
@@ -508,4 +514,24 @@ public PNode createSetAttribute(PNode object, String key, PNode rhs) {
508514
public PNode createDestructuringAssignment(PNode rhs, List<ReadNode> slots, int starredIndex, PNode[] assignments) {
509515
return DestructuringAssignmentNode.create(rhs, slots, starredIndex, assignments);
510516
}
517+
518+
public PDataModelEmulationNode createIsMapping() {
519+
return IsMappingNode.create();
520+
}
521+
522+
public PDataModelEmulationNode createIsSequence() {
523+
return IsSequenceNode.create();
524+
}
525+
526+
public PDataModelEmulationNode createIsContextManager() {
527+
return IsContextManagerNode.create();
528+
}
529+
530+
public PDataModelEmulationNode createIsCallable() {
531+
return IsCallableNode.create();
532+
}
533+
534+
public PDataModelEmulationNode createIsIterable() {
535+
return IsIterableNode.create();
536+
}
511537
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates.
3+
*
4+
* The Universal Permissive License (UPL), Version 1.0
5+
*
6+
* Subject to the condition set forth below, permission is hereby granted to any
7+
* person obtaining a copy of this software, associated documentation and/or data
8+
* (collectively the "Software"), free of charge and under any and all copyright
9+
* rights in the Software, and any and all patent rights owned or freely
10+
* licensable by each licensor hereunder covering either (i) the unmodified
11+
* Software as contributed to or provided by such licensor, or (ii) the Larger
12+
* Works (as defined below), to deal in both
13+
*
14+
* (a) the Software, and
15+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
16+
* one is included with the Software (each a "Larger Work" to which the
17+
* Software is contributed by such licensors),
18+
*
19+
* without restriction, including without limitation the rights to copy, create
20+
* derivative works of, display, perform, and distribute the Software and make,
21+
* use, sell, offer for sale, import, export, have made, and have sold the
22+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
23+
* either these or other terms.
24+
*
25+
* This license is subject to the following condition:
26+
*
27+
* The above copyright notice and either this complete permission notice or at a
28+
* minimum a reference to the UPL must be included in all copies or substantial
29+
* portions of the Software.
30+
*
31+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37+
* SOFTWARE.
38+
*/
39+
package com.oracle.graal.python.nodes.attributes;
40+
41+
import com.oracle.graal.python.builtins.objects.PNone;
42+
import com.oracle.truffle.api.nodes.Node;
43+
44+
public class HasInheritedAttributeNode extends Node {
45+
private final String attribute;
46+
@Child private LookupInheritedAttributeNode lookupInheritedAttributeNode = LookupInheritedAttributeNode.create();
47+
48+
private HasInheritedAttributeNode(String attribute) {
49+
this.attribute = attribute;
50+
}
51+
52+
public boolean execute(Object object) {
53+
return lookupInheritedAttributeNode.execute(object, attribute) != PNone.NO_VALUE;
54+
}
55+
56+
public static HasInheritedAttributeNode create(String attribute) {
57+
return new HasInheritedAttributeNode(attribute);
58+
}
59+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates.
3+
*
4+
* The Universal Permissive License (UPL), Version 1.0
5+
*
6+
* Subject to the condition set forth below, permission is hereby granted to any
7+
* person obtaining a copy of this software, associated documentation and/or data
8+
* (collectively the "Software"), free of charge and under any and all copyright
9+
* rights in the Software, and any and all patent rights owned or freely
10+
* licensable by each licensor hereunder covering either (i) the unmodified
11+
* Software as contributed to or provided by such licensor, or (ii) the Larger
12+
* Works (as defined below), to deal in both
13+
*
14+
* (a) the Software, and
15+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
16+
* one is included with the Software (each a "Larger Work" to which the
17+
* Software is contributed by such licensors),
18+
*
19+
* without restriction, including without limitation the rights to copy, create
20+
* derivative works of, display, perform, and distribute the Software and make,
21+
* use, sell, offer for sale, import, export, have made, and have sold the
22+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
23+
* either these or other terms.
24+
*
25+
* This license is subject to the following condition:
26+
*
27+
* The above copyright notice and either this complete permission notice or at a
28+
* minimum a reference to the UPL must be included in all copies or substantial
29+
* portions of the Software.
30+
*
31+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37+
* SOFTWARE.
38+
*/
39+
package com.oracle.graal.python.nodes.datamodel;
40+
41+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__CALL__;
42+
43+
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
44+
import com.oracle.graal.python.builtins.objects.function.PFunction;
45+
import com.oracle.graal.python.builtins.objects.function.PythonCallable;
46+
import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
47+
import com.oracle.graal.python.builtins.objects.method.PMethod;
48+
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
49+
import com.oracle.truffle.api.dsl.Specialization;
50+
51+
public abstract class IsCallableNode extends PDataModelEmulationNode {
52+
@Child private LookupInheritedAttributeNode callAttrGetterNode = LookupInheritedAttributeNode.create();
53+
54+
protected static boolean isNoCallable(Object callee) {
55+
return !(callee instanceof PythonCallable);
56+
}
57+
58+
@Specialization(guards = {"isNoCallable(callable) || isClass(callable)"})
59+
protected boolean isSpecialCallable(Object callable) {
60+
Object call = callAttrGetterNode.execute(callable, __CALL__);
61+
return !isNoCallable(call);
62+
}
63+
64+
@Specialization
65+
protected boolean isMethod(@SuppressWarnings("unused") PMethod callable) {
66+
return true;
67+
}
68+
69+
@Specialization
70+
protected boolean isBuiltinMethod(@SuppressWarnings("unused") PBuiltinMethod callable) {
71+
return true;
72+
}
73+
74+
@Specialization
75+
protected boolean isFunctionCall(@SuppressWarnings("unused") PFunction callable) {
76+
return true;
77+
}
78+
79+
@Specialization
80+
protected boolean isBuiltinFunctionCall(@SuppressWarnings("unused") PBuiltinFunction callable) {
81+
return true;
82+
}
83+
84+
public static IsCallableNode create() {
85+
return IsCallableNodeGen.create();
86+
}
87+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates.
3+
*
4+
* The Universal Permissive License (UPL), Version 1.0
5+
*
6+
* Subject to the condition set forth below, permission is hereby granted to any
7+
* person obtaining a copy of this software, associated documentation and/or data
8+
* (collectively the "Software"), free of charge and under any and all copyright
9+
* rights in the Software, and any and all patent rights owned or freely
10+
* licensable by each licensor hereunder covering either (i) the unmodified
11+
* Software as contributed to or provided by such licensor, or (ii) the Larger
12+
* Works (as defined below), to deal in both
13+
*
14+
* (a) the Software, and
15+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
16+
* one is included with the Software (each a "Larger Work" to which the
17+
* Software is contributed by such licensors),
18+
*
19+
* without restriction, including without limitation the rights to copy, create
20+
* derivative works of, display, perform, and distribute the Software and make,
21+
* use, sell, offer for sale, import, export, have made, and have sold the
22+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
23+
* either these or other terms.
24+
*
25+
* This license is subject to the following condition:
26+
*
27+
* The above copyright notice and either this complete permission notice or at a
28+
* minimum a reference to the UPL must be included in all copies or substantial
29+
* portions of the Software.
30+
*
31+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37+
* SOFTWARE.
38+
*/
39+
package com.oracle.graal.python.nodes.datamodel;
40+
41+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__ENTER__;
42+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__EXIT__;
43+
44+
import com.oracle.graal.python.nodes.attributes.HasInheritedAttributeNode;
45+
import com.oracle.truffle.api.dsl.Specialization;
46+
import com.oracle.truffle.api.profiles.ConditionProfile;
47+
48+
public abstract class IsContextManagerNode extends PDataModelEmulationNode {
49+
@Child private HasInheritedAttributeNode hasEnterNode = HasInheritedAttributeNode.create(__ENTER__);
50+
@Child private HasInheritedAttributeNode hasExitNode = HasInheritedAttributeNode.create(__EXIT__);
51+
52+
private final ConditionProfile profile = ConditionProfile.createBinaryProfile();
53+
54+
@Specialization
55+
public boolean isContextManager(Object object) {
56+
return profile.profile(hasEnterNode.execute(object) && hasExitNode.execute(object));
57+
}
58+
59+
public static IsContextManagerNode create() {
60+
return IsContextManagerNodeGen.create();
61+
}
62+
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates.
3+
*
4+
* The Universal Permissive License (UPL), Version 1.0
5+
*
6+
* Subject to the condition set forth below, permission is hereby granted to any
7+
* person obtaining a copy of this software, associated documentation and/or data
8+
* (collectively the "Software"), free of charge and under any and all copyright
9+
* rights in the Software, and any and all patent rights owned or freely
10+
* licensable by each licensor hereunder covering either (i) the unmodified
11+
* Software as contributed to or provided by such licensor, or (ii) the Larger
12+
* Works (as defined below), to deal in both
13+
*
14+
* (a) the Software, and
15+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
16+
* one is included with the Software (each a "Larger Work" to which the
17+
* Software is contributed by such licensors),
18+
*
19+
* without restriction, including without limitation the rights to copy, create
20+
* derivative works of, display, perform, and distribute the Software and make,
21+
* use, sell, offer for sale, import, export, have made, and have sold the
22+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
23+
* either these or other terms.
24+
*
25+
* This license is subject to the following condition:
26+
*
27+
* The above copyright notice and either this complete permission notice or at a
28+
* minimum a reference to the UPL must be included in all copies or substantial
29+
* portions of the Software.
30+
*
31+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37+
* SOFTWARE.
38+
*/
39+
package com.oracle.graal.python.nodes.datamodel;
40+
41+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__ITER__;
42+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__NEXT__;
43+
44+
import com.oracle.graal.python.builtins.objects.PNone;
45+
import com.oracle.graal.python.builtins.objects.array.PCharArray;
46+
import com.oracle.graal.python.builtins.objects.array.PDoubleArray;
47+
import com.oracle.graal.python.builtins.objects.array.PIntArray;
48+
import com.oracle.graal.python.builtins.objects.array.PLongArray;
49+
import com.oracle.graal.python.builtins.objects.iterator.PZip;
50+
import com.oracle.graal.python.builtins.objects.range.PRange;
51+
import com.oracle.graal.python.nodes.attributes.HasInheritedAttributeNode;
52+
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
53+
import com.oracle.graal.python.runtime.sequence.PSequence;
54+
import com.oracle.truffle.api.dsl.Specialization;
55+
import com.oracle.truffle.api.profiles.ConditionProfile;
56+
57+
public abstract class IsIterableNode extends PDataModelEmulationNode {
58+
@Child private HasInheritedAttributeNode hasNextNode = HasInheritedAttributeNode.create(__NEXT__);
59+
@Child private LookupInheritedAttributeNode getIterNode = LookupInheritedAttributeNode.create();
60+
61+
private final ConditionProfile profileIter = ConditionProfile.createBinaryProfile();
62+
private final ConditionProfile profileNext = ConditionProfile.createBinaryProfile();
63+
64+
@Specialization
65+
public boolean isIterable(@SuppressWarnings("unused") PRange range) {
66+
return true;
67+
}
68+
69+
@Specialization
70+
public boolean isIterable(@SuppressWarnings("unused") PIntArray array) {
71+
return true;
72+
}
73+
74+
@Specialization
75+
public boolean isIterable(@SuppressWarnings("unused") PLongArray array) {
76+
return true;
77+
}
78+
79+
@Specialization
80+
public boolean isIterable(@SuppressWarnings("unused") PDoubleArray array) {
81+
return true;
82+
}
83+
84+
@Specialization
85+
public boolean isIterable(@SuppressWarnings("unused") PCharArray array) {
86+
return true;
87+
}
88+
89+
@Specialization
90+
public boolean isIterable(@SuppressWarnings("unused") PSequence sequence) {
91+
return true;
92+
}
93+
94+
@Specialization
95+
public boolean isIterable(@SuppressWarnings("unused") String str) {
96+
return true;
97+
}
98+
99+
@Specialization
100+
public boolean isIterable(@SuppressWarnings("unused") PZip zip) {
101+
return true;
102+
}
103+
104+
@Specialization
105+
public boolean isIterable(Object object) {
106+
Object iterMethod = getIterNode.execute(object, __ITER__);
107+
if (profileIter.profile(iterMethod != PNone.NO_VALUE)) {
108+
return iterMethod != PNone.NONE;
109+
} else {
110+
return profileNext.profile(hasNextNode.execute(object));
111+
}
112+
}
113+
114+
public static IsIterableNode create() {
115+
return IsIterableNodeGen.create();
116+
}
117+
}

0 commit comments

Comments
 (0)