Skip to content

Commit 26064fd

Browse files
committed
Factor out special method lookup
1 parent a876ef9 commit 26064fd

File tree

5 files changed

+115
-26
lines changed

5 files changed

+115
-26
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallBinaryNode.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
4848
import com.oracle.graal.python.nodes.PNodeWithContext;
4949
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
50-
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
5150
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
5251
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
5352
import com.oracle.graal.python.nodes.object.GetClassNode;
@@ -133,7 +132,7 @@ public static LookupAndCallBinaryNode create(String name, String rname, Supplier
133132
}
134133

135134
protected Object getMethod(Object receiver, String methodName) {
136-
return LookupAttributeInMRONode.Dynamic.getUncached().execute(GetClassNode.getUncached().execute(receiver), methodName);
135+
return LookupSpecialMethodNode.Dynamic.getUncached().execute(GetClassNode.getUncached().execute(receiver), methodName);
137136
}
138137

139138
protected boolean isReversible() {
@@ -286,8 +285,8 @@ protected static boolean isReflectedObject(Object left, Object right, PythonObje
286285
Object callObject(VirtualFrame frame, Object left, Object right,
287286
@SuppressWarnings("unused") @CachedLibrary("left") PythonObjectLibrary libLeft,
288287
@SuppressWarnings("unused") @CachedLibrary("right") PythonObjectLibrary libRight,
289-
@Cached("create(name)") LookupInheritedAttributeNode getattr) {
290-
Object leftCallable = getattr.execute(left);
288+
@Cached("create(name)") LookupSpecialMethodNode getattr) {
289+
Object leftCallable = getattr.execute(libLeft.getLazyPythonClass(left));
291290
if (leftCallable == PNone.NO_VALUE) {
292291
if (handlerFactory != null) {
293292
return runErrorHandler(left, right);
@@ -300,8 +299,8 @@ Object callObject(VirtualFrame frame, Object left, Object right,
300299

301300
@Specialization(guards = {"isReversible()", "!isReflectedObject(left, right, libLeft, libRight)"}, limit = "2")
302301
Object callObject(VirtualFrame frame, Object left, Object right,
303-
@Cached("create(name)") LookupAttributeInMRONode getattr,
304-
@Cached("create(rname)") LookupAttributeInMRONode getattrR,
302+
@Cached("create(name)") LookupSpecialMethodNode getattr,
303+
@Cached("create(rname)") LookupSpecialMethodNode getattrR,
305304
@CachedLibrary("left") PythonObjectLibrary libLeft,
306305
@CachedLibrary("right") PythonObjectLibrary libRight,
307306
@Cached("create()") TypeNodes.IsSameTypeNode isSameTypeNode,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallTernaryNode.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@
4545
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode;
4646
import com.oracle.graal.python.nodes.PNodeWithContext;
4747
import com.oracle.graal.python.nodes.SpecialMethodNames;
48-
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
49-
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
5048
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
5149
import com.oracle.graal.python.nodes.object.GetClassNode;
5250
import com.oracle.graal.python.util.Supplier;
@@ -71,7 +69,7 @@ public abstract static class NotImplementedHandler extends PNodeWithContext {
7169
@Child private CallTernaryMethodNode dispatchNode = CallTernaryMethodNode.create();
7270
@Child private CallTernaryMethodNode reverseDispatchNode;
7371
@Child private CallTernaryMethodNode thirdDispatchNode;
74-
@Child private LookupInheritedAttributeNode getThirdAttrNode;
72+
@Child private LookupSpecialMethodNode getThirdAttrNode;
7573
@Child private NotImplementedHandler handler;
7674
protected final Supplier<NotImplementedHandler> handlerFactory;
7775

@@ -130,11 +128,11 @@ private CallTernaryMethodNode ensureReverseDispatch() {
130128
return reverseDispatchNode;
131129
}
132130

133-
private LookupInheritedAttributeNode ensureGetAttrZ() {
131+
private LookupSpecialMethodNode ensureGetAttrZ() {
134132
// this also serves as a branch profile
135133
if (getThirdAttrNode == null) {
136134
CompilerDirectives.transferToInterpreterAndInvalidate();
137-
getThirdAttrNode = insert(LookupInheritedAttributeNode.create(name));
135+
getThirdAttrNode = insert(LookupSpecialMethodNode.create(name));
138136
}
139137
return getThirdAttrNode;
140138
}
@@ -154,8 +152,8 @@ Object callObject(
154152
Object v,
155153
Object w,
156154
Object z,
157-
@Cached("create(name)") LookupAttributeInMRONode getattr,
158-
@Cached("create(name)") LookupAttributeInMRONode getattrR,
155+
@Cached("create(name)") LookupSpecialMethodNode getattr,
156+
@Cached("create(name)") LookupSpecialMethodNode getattrR,
159157
@Cached("create()") GetClassNode getClass,
160158
@Cached("create()") GetClassNode getClassR,
161159
@Cached("create()") IsSubtypeNode isSubtype,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallUnaryNode.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,20 @@
4040
*/
4141
package com.oracle.graal.python.nodes.call.special;
4242

43-
import com.oracle.graal.python.util.Supplier;
44-
4543
import com.oracle.graal.python.builtins.objects.PNone;
4644
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
45+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
4746
import com.oracle.graal.python.nodes.PNodeWithContext;
4847
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
49-
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
5048
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
5149
import com.oracle.graal.python.nodes.object.GetClassNode;
50+
import com.oracle.graal.python.util.Supplier;
5251
import com.oracle.truffle.api.CompilerDirectives;
5352
import com.oracle.truffle.api.dsl.Cached;
5453
import com.oracle.truffle.api.dsl.GenerateUncached;
5554
import com.oracle.truffle.api.dsl.Specialization;
5655
import com.oracle.truffle.api.frame.VirtualFrame;
56+
import com.oracle.truffle.api.library.CachedLibrary;
5757
import com.oracle.truffle.api.nodes.Node;
5858
import com.oracle.truffle.api.nodes.UnexpectedResultException;
5959
import com.oracle.truffle.api.profiles.ConditionProfile;
@@ -205,11 +205,12 @@ Object callObject(VirtualFrame frame, PNone receiver,
205205

206206
// Object
207207

208-
@Specialization
208+
@Specialization(limit = "3")
209209
Object callObject(VirtualFrame frame, Object receiver,
210-
@Cached("create(name)") LookupInheritedAttributeNode getattr,
210+
@CachedLibrary("receiver") PythonObjectLibrary lib,
211+
@Cached("create(name)") LookupSpecialMethodNode getattr,
211212
@Cached("create()") CallUnaryMethodNode dispatchNode) {
212-
Object attr = getattr.execute(receiver);
213+
Object attr = getattr.execute(lib.getLazyPythonClass(receiver));
213214
if (attr == PNone.NO_VALUE) {
214215
if (handlerFactory != null) {
215216
if (handler == null) {
@@ -229,13 +230,14 @@ public abstract static class LookupAndCallUnaryDynamicNode extends PNodeWithCont
229230

230231
public abstract Object executeObject(Object receiver, String name);
231232

232-
@Specialization
233+
@Specialization(limit = "3")
233234
static Object doObject(Object receiver, String name,
234-
@Cached LookupInheritedAttributeNode.Dynamic getattr,
235+
@CachedLibrary("receiver") PythonObjectLibrary lib,
236+
@Cached LookupSpecialMethodNode.Dynamic getattr,
235237
@Cached CallUnaryMethodNode dispatchNode,
236238
@Cached("createBinaryProfile()") ConditionProfile profile) {
237239

238-
Object attr = getattr.execute(receiver, name);
240+
Object attr = getattr.execute(lib.getLazyPythonClass(receiver), name);
239241
if (profile.profile(attr != PNone.NO_VALUE)) {
240242
// NOTE: it's safe to pass a 'null' frame since this node can only be used via a
241243
// global state context manager

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallVarargsNode.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,14 @@
4242

4343
import com.oracle.graal.python.builtins.objects.function.PKeyword;
4444
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
45-
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
4645
import com.oracle.truffle.api.dsl.Cached;
4746
import com.oracle.truffle.api.dsl.Specialization;
4847
import com.oracle.truffle.api.frame.VirtualFrame;
4948
import com.oracle.truffle.api.library.CachedLibrary;
5049
import com.oracle.truffle.api.nodes.Node;
5150

5251
public abstract class LookupAndCallVarargsNode extends Node {
53-
private final String name;
52+
protected final String name;
5453
@Child private CallVarargsMethodNode dispatchNode = CallVarargsMethodNode.create();
5554

5655
public abstract Object execute(VirtualFrame frame, Object callable, Object[] arguments);
@@ -66,7 +65,7 @@ public static LookupAndCallVarargsNode create(String name) {
6665
@Specialization(limit = "3")
6766
Object callObject(VirtualFrame frame, Object callable, Object[] arguments,
6867
@CachedLibrary("callable") PythonObjectLibrary plib,
69-
@Cached("create()") LookupAttributeInMRONode.Dynamic getattr) {
70-
return dispatchNode.execute(frame, getattr.execute(plib.getLazyPythonClass(callable), name), arguments, PKeyword.EMPTY_KEYWORDS);
68+
@Cached("create(name)") LookupSpecialMethodNode getattr) {
69+
return dispatchNode.execute(frame, getattr.execute(plib.getLazyPythonClass(callable)), arguments, PKeyword.EMPTY_KEYWORDS);
7170
}
7271
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright (c) 2020, 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.graal.python.nodes.call.special;
42+
43+
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
44+
import com.oracle.truffle.api.dsl.Cached;
45+
import com.oracle.truffle.api.dsl.GenerateUncached;
46+
import com.oracle.truffle.api.dsl.Specialization;
47+
import com.oracle.truffle.api.nodes.Node;
48+
49+
/**
50+
* Similar to CPython's lookup_maybe_method, but returns NO_VALUE instead of raising an exception
51+
* when the method cannot be looked up
52+
*/
53+
public abstract class LookupSpecialMethodNode extends Node {
54+
protected final String name;
55+
56+
public abstract Object execute(Object type);
57+
58+
LookupSpecialMethodNode(String name) {
59+
this.name = name;
60+
}
61+
62+
public static LookupSpecialMethodNode create(String name) {
63+
return LookupSpecialMethodNodeGen.create(name);
64+
}
65+
66+
@Specialization
67+
Object lookup(Object type,
68+
@Cached("create(name)") LookupAttributeInMRONode lookupAttr) {
69+
return lookupAttr.execute(type);
70+
}
71+
72+
@GenerateUncached
73+
public abstract static class Dynamic extends Node {
74+
75+
public abstract Object execute(Object type, Object name);
76+
77+
public static Dynamic create() {
78+
return LookupSpecialMethodNodeGen.DynamicNodeGen.create();
79+
}
80+
81+
public static Dynamic getUncached() {
82+
return LookupSpecialMethodNodeGen.DynamicNodeGen.getUncached();
83+
}
84+
85+
@Specialization
86+
Object lookup(Object type, Object name,
87+
@Cached LookupAttributeInMRONode.Dynamic lookupAttr) {
88+
return lookupAttr.execute(type, name);
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)