Skip to content

Commit 92430b3

Browse files
committed
Make METH_STATIC work
1 parent 08e40f7 commit 92430b3

File tree

9 files changed

+130
-90
lines changed

9 files changed

+130
-90
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2299,7 +2299,7 @@ int start(byte[] bs) {
22992299

23002300
// static bytes.maketrans()
23012301
// static bytearray.maketrans()
2302-
@Builtin(name = "maketrans", minNumOfPositionalArgs = 3, isClassmethod = true)
2302+
@Builtin(name = "maketrans", minNumOfPositionalArgs = 3, isStaticmethod = true)
23032303
@GenerateNodeFactory
23042304
public abstract static class MakeTransNode extends PythonBuiltinNode {
23052305

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3946,14 +3946,15 @@ private static boolean checkLayout(Object methodDef) {
39463946

39473947
@TruffleBoundary
39483948
private static PRootNode createWrapperRootNode(PythonLanguage language, int flags, String name) {
3949+
boolean isStatic = CExtContext.isMethStatic(flags);
39493950
if (CExtContext.isMethNoArgs(flags)) {
3950-
return new MethNoargsRoot(language, name, PExternalFunctionWrapper.NOARGS);
3951+
return new MethNoargsRoot(language, name, isStatic, PExternalFunctionWrapper.NOARGS);
39513952
} else if (CExtContext.isMethO(flags)) {
3952-
return new MethORoot(language, name, PExternalFunctionWrapper.O);
3953+
return new MethORoot(language, name, isStatic, PExternalFunctionWrapper.O);
39533954
} else if (CExtContext.isMethKeywords(flags)) {
3954-
return new MethKeywordsRoot(language, name, PExternalFunctionWrapper.KEYWORDS);
3955+
return new MethKeywordsRoot(language, name, isStatic, PExternalFunctionWrapper.KEYWORDS);
39553956
} else if (CExtContext.isMethVarargs(flags)) {
3956-
return new MethVarargsRoot(language, name, PExternalFunctionWrapper.VARARGS);
3957+
return new MethVarargsRoot(language, name, isStatic, PExternalFunctionWrapper.VARARGS);
39573958
}
39583959
throw new IllegalStateException("illegal method flags");
39593960
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java

Lines changed: 88 additions & 77 deletions
Large diffs are not rendered by default.

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtContext.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,10 @@ public static boolean isMethFastcallWithKeywords(int flags) {
150150
return (flags & METH_FASTCALL) != 0 && (flags & METH_KEYWORDS) != 0;
151151
}
152152

153+
public static boolean isMethStatic(int flags) {
154+
return (flags & METH_STATIC) != 0;
155+
}
156+
153157
public static boolean isClassOrStaticMethod(int flags) {
154158
return flags > 0 && (flags & (METH_CLASS | METH_STATIC)) != 0;
155159
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PBuiltinFunction.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ public int getFlags() {
134134
return flags;
135135
}
136136

137+
public boolean isStatic() {
138+
return (flags & CExtContext.METH_STATIC) != 0;
139+
}
140+
137141
@TruffleBoundary
138142
public static int getFlags(Builtin builtin, RootCallTarget callTarget) {
139143
return getFlags(builtin, ((PRootNode) callTarget.getRootNode()).getSignature());

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ protected static Object doIt(PMethod self) {
130130

131131
@Specialization
132132
protected static Object doIt(PBuiltinMethod self) {
133+
if (self.getFunction().isStatic()) {
134+
return PNone.NONE;
135+
}
133136
return self.getSelf();
134137
}
135138
}
@@ -176,7 +179,10 @@ Object getModule(VirtualFrame frame, PBuiltinMethod self, @SuppressWarnings("unu
176179
@Cached PyObjectLookupAttr lookup,
177180
@CachedLibrary("self") DynamicObjectLibrary dylib) {
178181
Object module = dylib.getOrDefault(self, __MODULE__, PNone.NO_VALUE);
179-
if (module == PNone.NO_VALUE) {
182+
if (module != PNone.NO_VALUE) {
183+
return module;
184+
}
185+
if (self.getSelf() instanceof PythonModule) {
180186
/*
181187
* 'getThreadStateNode' acts as a branch profile. This indirect call is done to
182188
* easily support calls to this builtin with and without virtual frame, and because
@@ -189,9 +195,8 @@ Object getModule(VirtualFrame frame, PBuiltinMethod self, @SuppressWarnings("unu
189195
} finally {
190196
IndirectCallContext.exit(frame, language, getContext(), state);
191197
}
192-
} else {
193-
return module;
194198
}
199+
return PNone.NONE;
195200
}
196201

197202
@Specialization(guards = "!isNoValue(value)", limit = "2")

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,14 @@ public void setCallable(Object callable) {
7575

7676
@SuppressWarnings("unchecked")
7777
public Object boundToObject(PythonBuiltinClassType binding, PythonObjectFactory factory) {
78-
if (GetClassNode.getUncached().execute(this) != PythonBuiltinClassType.PStaticmethod && callable instanceof BoundBuiltinCallable) {
79-
return factory.createBuiltinClassmethodFromCallableObj(((BoundBuiltinCallable<Object>) callable).boundToObject(binding, factory));
78+
if (GetClassNode.getUncached().execute(this) != PythonBuiltinClassType.PStaticmethod) {
79+
if (callable instanceof BoundBuiltinCallable) {
80+
return factory.createBuiltinClassmethodFromCallableObj(((BoundBuiltinCallable<Object>) callable).boundToObject(binding, factory));
81+
}
82+
} else {
83+
if (callable instanceof PBuiltinMethod) {
84+
return factory.createStaticmethodFromCallableObj(((PBuiltinMethod) callable).getFunction().boundToObject(binding, factory));
85+
}
8086
}
8187
return this;
8288
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1054,7 +1054,7 @@ static String doGeneric(Object self,
10541054
}
10551055

10561056
// str.maketrans()
1057-
@Builtin(name = "maketrans", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 4, isClassmethod = true)
1057+
@Builtin(name = "maketrans", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 4, isStaticmethod = true)
10581058
@GenerateNodeFactory
10591059
public abstract static class MakeTransNode extends PythonQuaternaryBuiltinNode {
10601060

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectFactory.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,11 @@
112112
import com.oracle.graal.python.builtins.objects.iterator.PSequenceIterator;
113113
import com.oracle.graal.python.builtins.objects.iterator.PStringIterator;
114114
import com.oracle.graal.python.builtins.objects.iterator.PZip;
115-
import com.oracle.graal.python.builtins.objects.keywrapper.PKeyWrapper;
116115
import com.oracle.graal.python.builtins.objects.itertools.PChain;
117116
import com.oracle.graal.python.builtins.objects.itertools.PRepeat;
118117
import com.oracle.graal.python.builtins.objects.itertools.PTee;
119118
import com.oracle.graal.python.builtins.objects.itertools.PTeeDataObject;
119+
import com.oracle.graal.python.builtins.objects.keywrapper.PKeyWrapper;
120120
import com.oracle.graal.python.builtins.objects.list.PList;
121121
import com.oracle.graal.python.builtins.objects.map.PMap;
122122
import com.oracle.graal.python.builtins.objects.mappingproxy.PMappingproxy;
@@ -632,7 +632,16 @@ public final PDecoratedMethod createStaticmethod(Object cls) {
632632
}
633633

634634
public final PDecoratedMethod createStaticmethodFromCallableObj(Object callable) {
635-
return trace(new PDecoratedMethod(PythonBuiltinClassType.PStaticmethod, PythonBuiltinClassType.PStaticmethod.getInstanceShape(getLanguage()), callable));
635+
Object func = callable;
636+
if (func instanceof PBuiltinFunction) {
637+
/*
638+
* CPython's C static methods contain an object of type `builtin_function_or_method`
639+
* (our PBuiltinMethod). Their self points to their type, but when called they get NULL
640+
* as the first argument instead.
641+
*/
642+
func = createBuiltinMethod(((PBuiltinFunction) func).getEnclosingType(), (PBuiltinFunction) func);
643+
}
644+
return trace(new PDecoratedMethod(PythonBuiltinClassType.PStaticmethod, PythonBuiltinClassType.PStaticmethod.getInstanceShape(getLanguage()), func));
636645
}
637646

638647
/*

0 commit comments

Comments
 (0)