Skip to content

Commit 928eedb

Browse files
committed
[GR-27646] Fix invalid type comparison in AbstractObjectIsSubclassNode.
PullRequest: graalpython/1414
2 parents a54afb3 + 0f4ff48 commit 928eedb

File tree

1 file changed

+23
-9
lines changed

1 file changed

+23
-9
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/classes/AbstractObjectIsSubclassNode.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@
4343
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.GetObjectArrayNode;
4444
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
4545
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
46+
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode;
4647
import com.oracle.graal.python.nodes.PNodeWithContext;
4748
import com.oracle.graal.python.runtime.PythonOptions;
4849
import com.oracle.truffle.api.CompilerDirectives;
4950
import com.oracle.truffle.api.dsl.Cached;
51+
import com.oracle.truffle.api.dsl.Cached.Shared;
5052
import com.oracle.truffle.api.dsl.GenerateUncached;
5153
import com.oracle.truffle.api.dsl.ImportStatic;
5254
import com.oracle.truffle.api.dsl.Specialization;
@@ -73,8 +75,10 @@ public final boolean execute(Object derived, Object cls) {
7375
return execute(null, derived, cls);
7476
}
7577

76-
@Specialization(guards = "derived == cls")
77-
boolean isSameClass(@SuppressWarnings("unused") Object derived, @SuppressWarnings("unused") Object cls) {
78+
@Specialization(guards = "isSameMetaObject(isSameTypeNode, derived, cls)", limit = "1")
79+
@SuppressWarnings("unused")
80+
static boolean doSameClass(Object derived, Object cls,
81+
@Shared("isSameType") @Cached IsSameTypeNode isSameTypeNode) {
7882
return true;
7983
}
8084

@@ -84,11 +88,12 @@ protected static int[] observedSize() {
8488
return ary;
8589
}
8690

87-
@Specialization(guards = {"derived != cls", "derived == cachedDerived", "cls == cachedCls"}, limit = "getCallSiteInlineCacheMaxDepth()")
88-
boolean isSubclass(VirtualFrame frame, @SuppressWarnings("unused") Object derived, @SuppressWarnings("unused") Object cls,
91+
@Specialization(guards = {"!isSameMetaObject(isSameTypeNode, derived, cls)", "derived == cachedDerived", "cls == cachedCls"}, limit = "getCallSiteInlineCacheMaxDepth()")
92+
static boolean doSubclass(VirtualFrame frame, @SuppressWarnings("unused") Object derived, @SuppressWarnings("unused") Object cls,
8993
@Cached(value = "observedSize()", dimensions = 1) int[] observedSizeArray,
9094
@Cached("derived") Object cachedDerived,
9195
@Cached("cls") Object cachedCls,
96+
@Cached @SuppressWarnings("unused") IsSameTypeNode isSameTypeNode,
9297
@Cached SequenceStorageNodes.LenNode lenNode,
9398
@Cached AbstractObjectGetBasesNode getBasesNode,
9499
@Cached AbstractObjectIsSubclassNode isSubclassNode,
@@ -114,7 +119,7 @@ boolean isSubclass(VirtualFrame frame, @SuppressWarnings("unused") Object derive
114119
return loopUnexploded(frame, cachedCls, isSubclassNode, basesAry);
115120
}
116121

117-
private static final boolean loopUnexploded(VirtualFrame frame, Object cachedCls, AbstractObjectIsSubclassNode isSubclassNode, Object[] basesAry) {
122+
private static boolean loopUnexploded(VirtualFrame frame, Object cachedCls, AbstractObjectIsSubclassNode isSubclassNode, Object[] basesAry) {
118123
for (Object baseCls : basesAry) {
119124
if (isSubclassNode.execute(frame, baseCls, cachedCls)) {
120125
return true;
@@ -124,7 +129,7 @@ private static final boolean loopUnexploded(VirtualFrame frame, Object cachedCls
124129
}
125130

126131
@ExplodeLoop
127-
private static final boolean loopBases(VirtualFrame frame, Object cachedCls, Object[] bases, AbstractObjectIsSubclassNode isSubclassNode) {
132+
private static boolean loopBases(VirtualFrame frame, Object cachedCls, Object[] bases, AbstractObjectIsSubclassNode isSubclassNode) {
128133
for (int i = 0; i < bases.length; i++) {
129134
if (isSubclassNode.execute(frame, bases[i], cachedCls)) {
130135
return true;
@@ -133,13 +138,14 @@ private static final boolean loopBases(VirtualFrame frame, Object cachedCls, Obj
133138
return false;
134139
}
135140

136-
@Specialization(replaces = {"isSubclass", "isSameClass"})
137-
boolean isSubclassGeneric(VirtualFrame frame, Object derived, Object cls,
141+
@Specialization(replaces = {"doSubclass", "doSameClass"})
142+
static boolean doGeneric(VirtualFrame frame, Object derived, Object cls,
138143
@Cached SequenceStorageNodes.LenNode lenNode,
139144
@Cached AbstractObjectGetBasesNode getBasesNode,
140145
@Cached AbstractObjectIsSubclassNode isSubclassNode,
146+
@Shared("isSameType") @Cached IsSameTypeNode isSameTypeNode,
141147
@Cached GetObjectArrayNode getObjectArrayNode) {
142-
if (derived == cls) {
148+
if (isSameMetaObject(isSameTypeNode, derived, cls)) {
143149
return true;
144150
}
145151

@@ -159,4 +165,12 @@ boolean isSubclassGeneric(VirtualFrame frame, Object derived, Object cls,
159165
private static boolean isEmpty(PTuple bases, SequenceStorageNodes.LenNode lenNode) {
160166
return lenNode.execute(bases.getSequenceStorage()) == 0;
161167
}
168+
169+
/**
170+
* Tests if the two meta objects {@code derived} and {@code cls} are the same. This differs from
171+
* {@link IsSameTypeNode} because it will also accept meta objects that are not classes.
172+
*/
173+
static boolean isSameMetaObject(IsSameTypeNode isSameTypeNode, Object derived, Object cls) {
174+
return derived == cls || isSameTypeNode.execute(derived, cls);
175+
}
162176
}

0 commit comments

Comments
 (0)