Skip to content

Commit eeb67f0

Browse files
committed
[hotfix] fix recursion in isSubclass
PullRequest: graalpython-open/29
2 parents e76ed35 + 547de9f commit eeb67f0

File tree

1 file changed

+32
-9
lines changed

1 file changed

+32
-9
lines changed

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

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@
4040

4141
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
4242
import com.oracle.graal.python.nodes.PNode;
43+
import com.oracle.truffle.api.dsl.Cached;
4344
import com.oracle.truffle.api.dsl.NodeChild;
4445
import com.oracle.truffle.api.dsl.NodeChildren;
4546
import com.oracle.truffle.api.dsl.Specialization;
47+
import com.oracle.truffle.api.nodes.ExplodeLoop;
4648
import com.oracle.truffle.api.nodes.NodeInfo;
4749

4850
@NodeInfo(shortName = "cpython://Objects/abstract.c/abstract_issubclass")
@@ -58,7 +60,35 @@ public static AbstractObjectIsSubclassNode create(PNode derived, PNode cls) {
5860
return AbstractObjectIsSubclassNodeGen.create(derived, cls);
5961
}
6062

61-
private boolean isSubclassInternal(Object derived, Object cls) {
63+
public abstract boolean execute(Object derived, Object cls);
64+
65+
@Specialization(guards = "derived == cls")
66+
boolean isSameClass(@SuppressWarnings("unused") Object derived, @SuppressWarnings("unused") Object cls) {
67+
return true;
68+
}
69+
70+
@Specialization(guards = {"derived != cls", "derived == cachedDerived", "cls == cachedCls"}, limit = "getCallSiteInlineCacheMaxDepth()")
71+
boolean isSubclass(@SuppressWarnings("unused") Object derived, @SuppressWarnings("unused") Object cls,
72+
@Cached("derived") Object cachedDerived,
73+
@Cached("cls") Object cachedCls,
74+
@Cached("create()") AbstractObjectIsSubclassNode isSubclassNode) {
75+
// TODO: Investigate adding @ExplodeLoop when the bases is constant in length (guard)
76+
PTuple bases = getBasesNode.execute(cachedDerived);
77+
if (bases == null || bases.isEmpty()) {
78+
return false;
79+
}
80+
81+
for (Object baseCls : bases.getArray()) {
82+
if (isSubclassNode.execute(baseCls, cachedCls)) {
83+
return true;
84+
}
85+
}
86+
return false;
87+
}
88+
89+
@Specialization(replaces = {"isSubclass", "isSameClass"})
90+
boolean isSubclassGeneric(Object derived, Object cls,
91+
@Cached("create()") AbstractObjectIsSubclassNode isSubclassNode) {
6292
if (derived == cls) {
6393
return true;
6494
}
@@ -69,17 +99,10 @@ private boolean isSubclassInternal(Object derived, Object cls) {
6999
}
70100

71101
for (Object baseCls : bases.getArray()) {
72-
if (isSubclassInternal(baseCls, cls)) {
102+
if (isSubclassNode.execute(baseCls, cls)) {
73103
return true;
74104
}
75105
}
76106
return false;
77107
}
78-
79-
public abstract boolean execute(Object derived, Object cls);
80-
81-
@Specialization
82-
public boolean isSubclass(Object derived, Object cls) {
83-
return isSubclassInternal(derived, cls);
84-
}
85108
}

0 commit comments

Comments
 (0)