Skip to content

Commit e51bf26

Browse files
committed
intrinsify python_cext.py/PyInstanceMethod_New()
1 parent 2ff3778 commit e51bf26

File tree

11 files changed

+293
-37
lines changed

11 files changed

+293
-37
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
import com.oracle.graal.python.builtins.modules.bz2.BZ2DecompressorBuiltins;
111111
import com.oracle.graal.python.builtins.modules.bz2.BZ2ModuleBuiltins;
112112
import com.oracle.graal.python.builtins.modules.cext.PythonCextBytesBuiltins;
113+
import com.oracle.graal.python.builtins.modules.cext.PythonCextClassBuiltins;
113114
import com.oracle.graal.python.builtins.modules.cext.PythonCextComplexBuiltins;
114115
import com.oracle.graal.python.builtins.modules.cext.PythonCextCEvalBuiltins;
115116
import com.oracle.graal.python.builtins.modules.cext.PythonCextCodeBuiltins;
@@ -265,6 +266,7 @@
265266
import com.oracle.graal.python.builtins.objects.method.BuiltinMethodBuiltins;
266267
import com.oracle.graal.python.builtins.objects.method.ClassmethodBuiltins;
267268
import com.oracle.graal.python.builtins.objects.method.DecoratedMethodBuiltins;
269+
import com.oracle.graal.python.builtins.objects.method.InstancemethodBuiltins;
268270
import com.oracle.graal.python.builtins.objects.method.MethodBuiltins;
269271
import com.oracle.graal.python.builtins.objects.method.PMethod;
270272
import com.oracle.graal.python.builtins.objects.method.StaticmethodBuiltins;
@@ -423,6 +425,7 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed)
423425
new DecoratedMethodBuiltins(),
424426
new ClassmethodBuiltins(),
425427
new StaticmethodBuiltins(),
428+
new InstancemethodBuiltins(),
426429
new SimpleNamespaceBuiltins(),
427430
new PolyglotModuleBuiltins(),
428431
new ObjectBuiltins(),
@@ -494,6 +497,7 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed)
494497
new PythonCextCEvalBuiltins(),
495498
new PythonCextCodeBuiltins(),
496499
new PythonCextComplexBuiltins(),
500+
new PythonCextClassBuiltins(),
497501
new PythonCextDescrBuiltins(),
498502
new PythonCextDictBuiltins(),
499503
new PythonCextErrBuiltins(),

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2021, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2022, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -150,6 +150,7 @@ public enum PythonBuiltinClassType implements TruffleObject {
150150
PSocket("socket", "_socket"),
151151
PStaticmethod("staticmethod", BUILTINS, Flags.PUBLIC_BASE_WDICT),
152152
PClassmethod("classmethod", BUILTINS, Flags.PUBLIC_BASE_WDICT),
153+
PInstancemethod("instancemethod", BUILTINS, Flags.PUBLIC_BASE_WDICT),
153154
PScandirIterator("ScandirIterator", "posix", Flags.PRIVATE_DERIVED_WODICT),
154155
PDirEntry("DirEntry", "posix", Flags.PUBLIC_DERIVED_WODICT),
155156
LsprofProfiler("Profiler", "_lsprof"),

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import static com.oracle.graal.python.nodes.BuiltinNames.BYTEARRAY;
3535
import static com.oracle.graal.python.nodes.BuiltinNames.BYTES;
3636
import static com.oracle.graal.python.nodes.BuiltinNames.CLASSMETHOD;
37+
import static com.oracle.graal.python.nodes.BuiltinNames.INSTANCEMETHOD;
3738
import static com.oracle.graal.python.nodes.BuiltinNames.COMPLEX;
3839
import static com.oracle.graal.python.nodes.BuiltinNames.DICT;
3940
import static com.oracle.graal.python.nodes.BuiltinNames.DICT_ITEMITERATOR;
@@ -3362,6 +3363,15 @@ Object doObjectIndirect(Object self, @SuppressWarnings("unused") Object callable
33623363
}
33633364
}
33643365

3366+
@Builtin(name = INSTANCEMETHOD, minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PInstancemethod, isPublic = false, doc = "instancemethod(function)\n\nBind a function to a class.")
3367+
@GenerateNodeFactory
3368+
public abstract static class InstancemethodNode extends PythonBinaryBuiltinNode {
3369+
@Specialization
3370+
Object doObjectIndirect(Object self, @SuppressWarnings("unused") Object callable) {
3371+
return factory().createInstancemethod(self);
3372+
}
3373+
}
3374+
33653375
@Builtin(name = STATICMETHOD, minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PStaticmethod)
33663376
@GenerateNodeFactory
33673377
public abstract static class StaticmethodNode extends PythonBinaryBuiltinNode {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright (c) 2022, 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.builtins.modules.cext;
42+
43+
import com.oracle.graal.python.builtins.Builtin;
44+
import java.util.List;
45+
import com.oracle.graal.python.builtins.CoreFunctions;
46+
import com.oracle.graal.python.builtins.Python3Core;
47+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
48+
import com.oracle.graal.python.builtins.PythonBuiltins;
49+
import com.oracle.graal.python.builtins.objects.method.PDecoratedMethod;
50+
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
51+
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
52+
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
53+
import com.oracle.truffle.api.dsl.NodeFactory;
54+
import com.oracle.truffle.api.dsl.Specialization;
55+
56+
@CoreFunctions(extendsModule = PythonCextBuiltins.PYTHON_CEXT)
57+
@GenerateNodeFactory
58+
public final class PythonCextClassBuiltins extends PythonBuiltins {
59+
60+
@Override
61+
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
62+
return PythonCextClassBuiltinsFactory.getFactories();
63+
}
64+
65+
@Override
66+
public void initialize(Python3Core core) {
67+
super.initialize(core);
68+
}
69+
70+
@Builtin(name = "PyInstanceMethod_New", minNumOfPositionalArgs = 1)
71+
@GenerateNodeFactory
72+
public abstract static class PyInstancemethodNewNode extends PythonUnaryBuiltinNode {
73+
@Specialization
74+
public Object staticmethod(Object func) {
75+
PDecoratedMethod res = factory().createInstancemethod(PythonBuiltinClassType.PInstancemethod);
76+
res.setCallable(func);
77+
return res;
78+
}
79+
}
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* Copyright (c) 2022, 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.builtins.objects.method;
42+
43+
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
44+
import static com.oracle.graal.python.nodes.ErrorMessages.FIRST_ARG_MUST_BE_CALLABLE_S;
45+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DOC__;
46+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__FUNC__;
47+
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__NAME__;
48+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__CALL__;
49+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GETATTRIBUTE__;
50+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GET__;
51+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__INIT__;
52+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__REPR__;
53+
54+
import java.util.List;
55+
56+
import com.oracle.graal.python.builtins.Builtin;
57+
import com.oracle.graal.python.builtins.CoreFunctions;
58+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
59+
import com.oracle.graal.python.builtins.PythonBuiltins;
60+
import com.oracle.graal.python.builtins.objects.PNone;
61+
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
62+
import com.oracle.graal.python.builtins.objects.function.PKeyword;
63+
import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins;
64+
import com.oracle.graal.python.lib.PyCallableCheckNode;
65+
import com.oracle.graal.python.lib.PyObjectGetAttr;
66+
import com.oracle.graal.python.nodes.PGuards;
67+
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
68+
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
69+
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
70+
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
71+
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
72+
import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
73+
import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode.VarargsBuiltinDirectInvocationNotSupported;
74+
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
75+
import com.oracle.graal.python.runtime.exception.PException;
76+
import com.oracle.graal.python.util.PythonUtils;
77+
import com.oracle.truffle.api.dsl.Cached;
78+
import com.oracle.truffle.api.dsl.Cached.Shared;
79+
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
80+
import com.oracle.truffle.api.dsl.ImportStatic;
81+
import com.oracle.truffle.api.dsl.NodeFactory;
82+
import com.oracle.truffle.api.dsl.Specialization;
83+
import com.oracle.truffle.api.frame.VirtualFrame;
84+
85+
@CoreFunctions(extendClasses = {PythonBuiltinClassType.PInstancemethod})
86+
public class InstancemethodBuiltins extends PythonBuiltins {
87+
88+
@Override
89+
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
90+
return InstancemethodBuiltinsFactory.getFactories();
91+
}
92+
93+
@Builtin(name = __INIT__, minNumOfPositionalArgs = 2)
94+
@GenerateNodeFactory
95+
abstract static class InitNode extends PythonBinaryBuiltinNode {
96+
@Specialization(guards = "checkCallableNode.execute(callable)", limit = "1")
97+
protected static PNone init(PDecoratedMethod self, Object callable,
98+
@Shared("checkCallable") @SuppressWarnings("unused") @Cached PyCallableCheckNode checkCallableNode) {
99+
self.setCallable(callable);
100+
return PNone.NONE;
101+
}
102+
103+
@Specialization(guards = "!checkCallableNode.execute(callable)", limit = "1")
104+
protected PNone noCallble(@SuppressWarnings("unused") PDecoratedMethod self, Object callable,
105+
@Shared("checkCallable") @SuppressWarnings("unused") @Cached PyCallableCheckNode checkCallableNode) {
106+
throw raise(TypeError, FIRST_ARG_MUST_BE_CALLABLE_S, callable);
107+
}
108+
}
109+
110+
@Builtin(name = __FUNC__, minNumOfPositionalArgs = 1, isGetter = true)
111+
@GenerateNodeFactory
112+
abstract static class FuncNode extends PythonUnaryBuiltinNode {
113+
@Specialization
114+
protected static Object func(PDecoratedMethod self) {
115+
return self.getCallable();
116+
}
117+
}
118+
119+
@ImportStatic(PGuards.class)
120+
@Builtin(name = __GETATTRIBUTE__, minNumOfPositionalArgs = 2)
121+
@GenerateNodeFactory
122+
public abstract static class GetattributeNode extends PythonBuiltinNode {
123+
@Specialization
124+
protected static Object doIt(VirtualFrame frame, PDecoratedMethod self, Object key,
125+
@Cached ObjectBuiltins.GetAttributeNode objectGetattrNode,
126+
@Cached PyObjectGetAttr getAttrNode,
127+
@Cached IsBuiltinClassProfile errorProfile) {
128+
try {
129+
return objectGetattrNode.execute(frame, self, key);
130+
} catch (PException e) {
131+
e.expectAttributeError(errorProfile);
132+
return getAttrNode.execute(frame, self.getCallable(), key);
133+
}
134+
}
135+
}
136+
137+
@Builtin(name = __DOC__, maxNumOfPositionalArgs = 1, isGetter = true)
138+
@GenerateNodeFactory
139+
abstract static class DocNode extends PythonUnaryBuiltinNode {
140+
@Specialization
141+
static Object doc(VirtualFrame frame, PDecoratedMethod self,
142+
@Cached PyObjectGetAttr getAttr) {
143+
return getAttr.execute(frame, self.getCallable(), __DOC__);
144+
}
145+
}
146+
147+
@Builtin(name = __CALL__, minNumOfPositionalArgs = 1, takesVarArgs = true, takesVarKeywordArgs = true)
148+
@GenerateNodeFactory
149+
public abstract static class CallNode extends PythonVarargsBuiltinNode {
150+
@Specialization
151+
protected static Object doIt(VirtualFrame frame, PDecoratedMethod self, Object[] arguments, PKeyword[] keywords,
152+
@Cached CallNode callNode) {
153+
return callNode.execute(frame, self.getCallable(), arguments, keywords);
154+
}
155+
156+
@Override
157+
public Object varArgExecute(VirtualFrame frame, @SuppressWarnings("unused") Object self, Object[] arguments, PKeyword[] keywords) throws VarargsBuiltinDirectInvocationNotSupported {
158+
Object[] argsWithoutSelf = new Object[arguments.length - 1];
159+
PythonUtils.arraycopy(arguments, 1, argsWithoutSelf, 0, argsWithoutSelf.length);
160+
return execute(frame, arguments[0], argsWithoutSelf, keywords);
161+
}
162+
}
163+
164+
@Builtin(name = __GET__, minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3)
165+
@GenerateNodeFactory
166+
public abstract static class GetNode extends PythonTernaryBuiltinNode {
167+
@Specialization
168+
Object doGeneric(PDecoratedMethod self, Object obj, @SuppressWarnings("unused") Object cls) {
169+
if (obj == null || obj == PNone.NONE) {
170+
return self.getCallable();
171+
}
172+
return factory().createMethod(obj, self.getCallable());
173+
}
174+
}
175+
176+
@Builtin(name = __REPR__, minNumOfPositionalArgs = 1)
177+
@GenerateNodeFactory
178+
abstract static class ReprNode extends PythonUnaryBuiltinNode {
179+
@Specialization
180+
static Object reprBuiltinFunction(VirtualFrame frame, PDecoratedMethod self,
181+
@Cached PyObjectGetAttr getNameNode) {
182+
return PythonUtils.format("<instancemethod %s at 0x%x>", getNameNode.execute(frame, self.getCallable(), __NAME__), PythonAbstractObject.systemHashCode(self.getCallable()));
183+
}
184+
}
185+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -50,7 +50,7 @@
5050
import com.oracle.truffle.api.object.Shape;
5151

5252
/**
53-
* Storage for both classmethods and staticmethods
53+
* Storage for classmethods, staticmethods and instancemethods
5454
*/
5555
public class PDecoratedMethod extends PythonBuiltinObject implements BoundBuiltinCallable<Object> {
5656
private Object callable;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/TypeNodes.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ static long doBuiltinClassType(PythonBuiltinClassType clazz) {
221221
case PBuiltinMethod:
222222
result = DEFAULT | HAVE_GC | HAVE_VECTORCALL;
223223
break;
224+
case PInstancemethod:
225+
result = DEFAULT | HAVE_GC;
226+
break;
224227
case GetSetDescriptor:
225228
case MemberDescriptor:
226229
case PMappingproxy:

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ public abstract class BuiltinNames {
144144
public static final String RANGE = "range";
145145
public static final String VARS = "vars";
146146
public static final String CLASSMETHOD = "classmethod";
147+
public static final String INSTANCEMETHOD = "instancemethod";
147148
public static final String GETATTR = "getattr";
148149
public static final String LOCALS = "locals";
149150
public static final String REPR = "repr";

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ public abstract class ErrorMessages {
276276
public static final String FILL_CHAR_MUST_BE_LENGTH_1 = "The fill character must be exactly one character long";
277277
public static final String FILTER_SPEC_MUST_BE_DICT = "Filter specifier must be a dict or dict-like object";
278278
public static final String FILTER_SPECIFIER_MUST_HAVE = "Filter specifier must have an \"id\" entry";
279-
public static final String FIRST_ARG_MUST_BE_CALLABLE_S = "first argument must be callable%s";
279+
public static final String FIRST_ARG_MUST_BE_CALLABLE_S = "first argument must be callable %s";
280280
public static final String FIRST_ARG_MUST_BE_S_OR_TUPLE_NOT_P = "%s first arg must be %s or a tuple of str, not %p";
281281
public static final String FIRST_TWO_MAKETRANS_ARGS_MUST_HAVE_EQ_LENGTH = "the first two maketrans arguments must have equal length";
282282
public static final String S_FOR_ISLICE_MUST_BE = "% for islice() must be None or an integer: 0 <= x <= sys.maxsize.";

0 commit comments

Comments
 (0)