Skip to content

Commit 89ec6d9

Browse files
committed
Allow arbitrary (callable) objects in methods.
1 parent 9bc24c3 commit 89ec6d9

File tree

8 files changed

+57
-105
lines changed

8 files changed

+57
-105
lines changed

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,10 +1698,12 @@ public String doIt(PFunction func) {
16981698
return NodeUtil.printTreeToString(func.getCallTarget().getRootNode());
16991699
}
17001700

1701-
@Specialization
1701+
@Specialization(guards = "isFunction(method.getFunction())")
17021702
@TruffleBoundary
17031703
public String doIt(PMethod method) {
1704-
return NodeUtil.printTreeToString(method.getCallTarget().getRootNode());
1704+
// cast ensured by guard
1705+
PFunction fun = (PFunction) method.getFunction();
1706+
return NodeUtil.printTreeToString(fun.getCallTarget().getRootNode());
17051707
}
17061708

17071709
@Specialization
@@ -1715,6 +1717,10 @@ public String doIt(PCode code) {
17151717
public Object doit(Object object) {
17161718
return "truffle ast dump not supported for " + object.toString();
17171719
}
1720+
1721+
protected static boolean isFunction(Object callee) {
1722+
return callee instanceof PFunction;
1723+
}
17181724
}
17191725

17201726
@Builtin(name = "input", keywordArguments = {"prompt"})

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

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
import com.oracle.graal.python.builtins.objects.function.PythonCallable;
5353
import com.oracle.graal.python.builtins.objects.ints.PInt;
5454
import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
55-
import com.oracle.graal.python.builtins.objects.method.PMethod;
5655
import com.oracle.graal.python.nodes.argument.CreateArgumentsNode;
5756
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
5857
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -196,12 +195,6 @@ Object signal(int signum, PBuiltinFunction handler) {
196195
return installSignalHandler(signum, handler, handler.getCallTarget(), createArgs.execute(new Object[]{signum, PNone.NONE}));
197196
}
198197

199-
@Specialization
200-
@TruffleBoundary
201-
Object signal(int signum, PMethod handler) {
202-
return installSignalHandler(signum, handler, handler.getCallTarget(), createArgs.executeWithSelf(handler.getSelf(), new Object[]{signum, PNone.NONE}));
203-
}
204-
205198
@Specialization
206199
@TruffleBoundary
207200
Object signal(int signum, PFunction handler) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/BuiltinMethodBuiltins.java

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,21 @@
3838
import com.oracle.graal.python.builtins.PythonBuiltins;
3939
import com.oracle.graal.python.builtins.objects.PNone;
4040
import com.oracle.graal.python.builtins.objects.function.AbstractFunctionBuiltins;
41+
import com.oracle.graal.python.builtins.objects.function.PFunction;
4142
import com.oracle.graal.python.builtins.objects.module.PythonModule;
43+
import com.oracle.graal.python.nodes.SpecialAttributeNames;
44+
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
4245
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
4346
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
4447
import com.oracle.graal.python.nodes.object.GetLazyClassNode;
45-
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
48+
import com.oracle.graal.python.nodes.util.CastToStringNode;
4649
import com.oracle.graal.python.runtime.exception.PException;
4750
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4851
import com.oracle.truffle.api.dsl.Cached;
4952
import com.oracle.truffle.api.dsl.Fallback;
5053
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
5154
import com.oracle.truffle.api.dsl.NodeFactory;
5255
import com.oracle.truffle.api.dsl.Specialization;
53-
import com.oracle.truffle.api.dsl.TypeSystemReference;
5456

5557
@CoreFunctions(extendClasses = {PythonBuiltinClassType.PBuiltinMethod})
5658
public class BuiltinMethodBuiltins extends PythonBuiltins {
@@ -61,22 +63,22 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
6163
}
6264

6365
@Builtin(name = __REPR__, fixedNumOfPositionalArgs = 1)
64-
@TypeSystemReference(PythonArithmeticTypes.class)
6566
@GenerateNodeFactory
6667
public abstract static class ReprNode extends PythonUnaryBuiltinNode {
6768
boolean isBuiltinFunction(PBuiltinMethod self) {
6869
return self.getSelf() instanceof PythonModule;
6970
}
7071

7172
boolean isBuiltinFunction(PMethod self) {
72-
return self.getSelf() instanceof PythonModule && self.getFunction().getEnclosingClassName() == null;
73+
return self.getSelf() instanceof PythonModule && self.getFunction() instanceof PFunction && ((PFunction) self.getFunction()).getEnclosingClassName() == null;
7374
}
7475

7576
@Specialization(guards = "isBuiltinFunction(self)")
7677
@TruffleBoundary
77-
Object reprBuiltinFunction(PMethod self) {
78+
Object reprBuiltinFunction(PMethod self,
79+
@Cached("createGetAttributeNode()") GetAttributeNode getNameNode) {
7880
// (tfel): this only happens for builtin modules ... I think
79-
return String.format("<built-in function %s>", self.getName());
81+
return String.format("<built-in function %s>", getNameNode.executeObject(self.getFunction()));
8082
}
8183

8284
@Specialization(guards = "isBuiltinFunction(self)")
@@ -95,8 +97,13 @@ Object reprBuiltinMethod(PBuiltinMethod self,
9597
@Specialization(guards = "!isBuiltinFunction(self)")
9698
@TruffleBoundary
9799
Object reprBuiltinMethod(PMethod self,
98-
@Cached("create()") GetLazyClassNode getClassNode) {
99-
return String.format("<built-in method %s of %s object at 0x%x>", self.getName(), getClassNode.execute(self.getSelf()).getName(), self.hashCode());
100+
@Cached("create()") GetLazyClassNode getClassNode,
101+
@Cached("createGetAttributeNode()") GetAttributeNode getNameNode) {
102+
return String.format("<built-in method %s of %s object at 0x%x>", getNameNode.executeObject(self.getFunction()), getClassNode.execute(self.getSelf()).getName(), self.hashCode());
103+
}
104+
105+
protected static GetAttributeNode createGetAttributeNode() {
106+
return GetAttributeNode.create(SpecialAttributeNames.__NAME__, null);
100107
}
101108
}
102109

@@ -109,8 +116,10 @@ String doBuiltinMethod(PBuiltinMethod self) {
109116
}
110117

111118
@Specialization
112-
String doBuiltinMethod(PMethod self) {
113-
return doMethod(self.getName(), self.getSelf());
119+
String doBuiltinMethod(PMethod self,
120+
@Cached("createGetAttributeNode()") GetAttributeNode getNameNode,
121+
@Cached("create()") CastToStringNode castToStringNode) {
122+
return doMethod(castToStringNode.execute(getNameNode.executeObject(self.getFunction())), self.getSelf());
114123
}
115124

116125
private String doMethod(String name, Object owner) {
@@ -125,6 +134,10 @@ Object doGeneric(@SuppressWarnings("unused") Object obj) {
125134
throw raiseCannotPickle();
126135
}
127136

137+
protected static GetAttributeNode createGetAttributeNode() {
138+
return GetAttributeNode.create(SpecialAttributeNames.__NAME__, null);
139+
}
140+
128141
private PException raiseCannotPickle() {
129142
throw raise(TypeError, "can't pickle function objects");
130143
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/MethodBuiltins.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,18 @@
4242
import com.oracle.graal.python.builtins.PythonBuiltins;
4343
import com.oracle.graal.python.builtins.objects.PNone;
4444
import com.oracle.graal.python.builtins.objects.function.FunctionBuiltins;
45+
import com.oracle.graal.python.nodes.SpecialAttributeNames;
46+
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
4547
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
4648
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
4749
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
4850
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
4951
import com.oracle.graal.python.nodes.object.GetLazyClassNode;
50-
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
5152
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5253
import com.oracle.truffle.api.dsl.Cached;
5354
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
5455
import com.oracle.truffle.api.dsl.NodeFactory;
5556
import com.oracle.truffle.api.dsl.Specialization;
56-
import com.oracle.truffle.api.dsl.TypeSystemReference;
5757

5858
@CoreFunctions(extendClasses = PythonBuiltinClassType.PMethod)
5959
public class MethodBuiltins extends PythonBuiltins {
@@ -88,14 +88,18 @@ protected Object doIt(PMethod self,
8888
}
8989

9090
@Builtin(name = __REPR__, fixedNumOfPositionalArgs = 1)
91-
@TypeSystemReference(PythonArithmeticTypes.class)
9291
@GenerateNodeFactory
9392
public abstract static class ReprNode extends PythonUnaryBuiltinNode {
9493
@Specialization
9594
@TruffleBoundary
9695
Object reprMethod(PMethod self,
97-
@Cached("create()") GetLazyClassNode getClassNode) {
98-
return String.format("<built-in method %s of %s object at 0x%x>", self.getName(), getClassNode.execute(self.getSelf()).getName(), self.hashCode());
96+
@Cached("create()") GetLazyClassNode getClassNode,
97+
@Cached("createGetAttributeNode()") GetAttributeNode getNameAttrNode) {
98+
return String.format("<built-in method %s of %s object at 0x%x>", getNameAttrNode.executeObject(self.getFunction()), getClassNode.execute(self.getSelf()).getName(), self.hashCode());
99+
}
100+
101+
protected static GetAttributeNode createGetAttributeNode() {
102+
return GetAttributeNode.create(SpecialAttributeNames.__NAME__, null);
99103
}
100104
}
101105

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/PMethod.java

Lines changed: 7 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -25,77 +25,32 @@
2525
*/
2626
package com.oracle.graal.python.builtins.objects.method;
2727

28-
import com.oracle.graal.python.builtins.objects.cell.PCell;
29-
import com.oracle.graal.python.builtins.objects.function.Arity;
30-
import com.oracle.graal.python.builtins.objects.function.PFunction;
31-
import com.oracle.graal.python.builtins.objects.function.PGeneratorFunction;
32-
import com.oracle.graal.python.builtins.objects.function.PythonCallable;
3328
import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
34-
import com.oracle.graal.python.builtins.objects.object.PythonObject;
3529
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
36-
import com.oracle.truffle.api.RootCallTarget;
30+
import com.oracle.truffle.api.CompilerAsserts;
3731

38-
public final class PMethod extends PythonBuiltinObject implements PythonCallable {
32+
public final class PMethod extends PythonBuiltinObject {
3933

40-
private final PFunction function;
34+
private final Object function;
4135
private final Object self;
42-
private final RootCallTarget callTarget;
4336

44-
public PMethod(LazyPythonClass cls, Object self, PFunction function) {
37+
public PMethod(LazyPythonClass cls, Object self, Object function) {
4538
super(cls);
4639
this.self = self;
4740
this.function = function;
48-
this.callTarget = function.getCallTarget();
4941
}
5042

51-
public PFunction getFunction() {
43+
public Object getFunction() {
5244
return function;
5345
}
5446

5547
public Object getSelf() {
5648
return self;
5749
}
5850

59-
public PythonObject getGlobals() {
60-
return function.getGlobals();
61-
}
62-
63-
@Override
64-
public PCell[] getClosure() {
65-
return function.getClosure();
66-
}
67-
68-
@Override
69-
public boolean isGeneratorFunction() {
70-
return function instanceof PGeneratorFunction;
71-
}
72-
73-
@Override
74-
public PGeneratorFunction asGeneratorFunction() {
75-
if (function instanceof PGeneratorFunction) {
76-
return (PGeneratorFunction) function;
77-
} else {
78-
return null;
79-
}
80-
}
81-
82-
@Override
83-
public RootCallTarget getCallTarget() {
84-
return callTarget;
85-
}
86-
87-
@Override
88-
public Arity getArity() {
89-
return function.getArity();
90-
}
91-
92-
@Override
93-
public String getName() {
94-
return function.getName();
95-
}
96-
9751
@Override
9852
public String toString() {
99-
return "<method '" + function.getName() + "' of " + self + " object at " + function.hashCode() + ">";
53+
CompilerAsserts.neverPartOfCompilation();
54+
return "<method '" + function + "' of " + self + " object at " + function.hashCode() + ">";
10055
}
10156
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallDispatchNode.java

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import com.oracle.graal.python.builtins.objects.function.PKeyword;
3232
import com.oracle.graal.python.builtins.objects.function.PythonCallable;
3333
import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
34-
import com.oracle.graal.python.builtins.objects.method.PMethod;
3534
import com.oracle.graal.python.runtime.PythonOptions;
3635
import com.oracle.truffle.api.Assumption;
3736
import com.oracle.truffle.api.RootCallTarget;
@@ -68,22 +67,6 @@ protected Assumption singleContextAssumption() {
6867

6968
public abstract Object executeCall(VirtualFrame frame, Object callee, Object[] arguments, PKeyword[] keywords);
7069

71-
@SuppressWarnings("unused")
72-
@Specialization(guards = "method.getFunction() == cachedCallee", limit = "getCallSiteInlineCacheMaxDepth()", assumptions = "singleContextAssumption()")
73-
protected Object callMethod(VirtualFrame frame, PMethod method, Object[] arguments, PKeyword[] keywords,
74-
@Cached("method.getFunction()") PFunction cachedCallee,
75-
@Cached("createInvokeNode(cachedCallee)") InvokeNode invoke) {
76-
return invoke.execute(frame, arguments, keywords);
77-
}
78-
79-
@SuppressWarnings("unused")
80-
@Specialization(guards = "method.getFunction().getCallTarget() == ct", limit = "getCallSiteInlineCacheMaxDepth()")
81-
protected Object callMethod(VirtualFrame frame, PMethod method, Object[] arguments, PKeyword[] keywords,
82-
@Cached("method.getFunction().getCallTarget()") RootCallTarget ct,
83-
@Cached("createCtInvokeNode(method)") CallTargetInvokeNode invoke) {
84-
return invoke.execute(frame, method.getGlobals(), method.getClosure(), arguments, keywords);
85-
}
86-
8770
@SuppressWarnings("unused")
8871
@Specialization(guards = "method.getFunction() == cachedCallee", limit = "getCallSiteInlineCacheMaxDepth()", assumptions = "singleContextAssumption()")
8972
protected Object callBuiltinMethod(VirtualFrame frame, PBuiltinMethod method, Object[] arguments, PKeyword[] keywords,
@@ -124,7 +107,7 @@ protected Object callFunction(VirtualFrame frame, PBuiltinFunction callee, Objec
124107
return invoke.execute(frame, callee.getGlobals(), callee.getClosure(), arguments, keywords);
125108
}
126109

127-
@Specialization(replaces = {"callMethod", "callBuiltinMethod", "callFunction"})
110+
@Specialization(replaces = {"callBuiltinMethod", "callFunction"})
128111
protected Object callGeneric(VirtualFrame frame, PythonCallable callee, Object[] arguments, PKeyword[] keywords,
129112
@Cached("create()") GenericInvokeNode invoke) {
130113
return invoke.execute(frame, callee, arguments, keywords);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/CallNode.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,10 @@ private CallDispatchNode ensureDispatch() {
111111
}
112112

113113
@Specialization
114-
protected Object methodCall(VirtualFrame frame, PMethod callable, Object[] arguments, PKeyword[] keywords) {
115-
return ensureDispatch().executeCall(frame, callable, ensureCreateArguments().executeWithSelf(callable.getSelf(), arguments), keywords);
114+
protected Object methodCall(VirtualFrame frame, PMethod callable, Object[] arguments, PKeyword[] keywords,
115+
@Cached("create(__CALL__)") LookupInheritedAttributeNode callAttrGetterNode,
116+
@Cached("create()") CallVarargsMethodNode callCallNode) {
117+
return specialCall(frame, callable.getFunction(), arguments, keywords, callAttrGetterNode, callCallNode);
116118
}
117119

118120
@Specialization

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/InvokeNode.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import com.oracle.graal.python.builtins.objects.function.PKeyword;
3535
import com.oracle.graal.python.builtins.objects.function.PythonCallable;
3636
import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
37-
import com.oracle.graal.python.builtins.objects.method.PMethod;
3837
import com.oracle.graal.python.builtins.objects.object.PythonObject;
3938
import com.oracle.graal.python.nodes.PRootNode;
4039
import com.oracle.graal.python.nodes.argument.ApplyKeywordsNode;
@@ -65,16 +64,13 @@ protected static boolean shouldInlineGenerators() {
6564
}
6665

6766
@TruffleBoundary
68-
protected static RootCallTarget getCallTarget(PythonCallable callee) {
67+
protected static RootCallTarget getCallTarget(Object callee) {
6968
RootCallTarget callTarget;
70-
PythonCallable actualCallee = callee;
69+
Object actualCallee = callee;
7170
if (actualCallee instanceof PFunction) {
72-
callTarget = actualCallee.getCallTarget();
73-
} else if (actualCallee instanceof PMethod) {
74-
PMethod method = (PMethod) actualCallee;
75-
callTarget = method.getFunction().getCallTarget();
71+
callTarget = ((PFunction) actualCallee).getCallTarget();
7672
} else if (actualCallee instanceof PBuiltinFunction) {
77-
callTarget = callee.getCallTarget();
73+
callTarget = ((PBuiltinFunction) callee).getCallTarget();
7874
} else if (callee instanceof PBuiltinMethod) {
7975
PBuiltinMethod method = (PBuiltinMethod) callee;
8076
PBuiltinFunction internalFunc = method.getFunction();
@@ -110,7 +106,7 @@ protected static Arity getArity(PythonCallable callee) {
110106
return callee.getArity();
111107
}
112108

113-
protected static boolean isBuiltin(PythonCallable callee) {
109+
protected static boolean isBuiltin(Object callee) {
114110
return callee instanceof PBuiltinFunction || callee instanceof PBuiltinMethod;
115111
}
116112
}

0 commit comments

Comments
 (0)