40
40
41
41
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
42
42
import com .oracle .graal .python .nodes .PNode ;
43
+ import com .oracle .truffle .api .dsl .Cached ;
43
44
import com .oracle .truffle .api .dsl .NodeChild ;
44
45
import com .oracle .truffle .api .dsl .NodeChildren ;
45
46
import com .oracle .truffle .api .dsl .Specialization ;
47
+ import com .oracle .truffle .api .nodes .ExplodeLoop ;
46
48
import com .oracle .truffle .api .nodes .NodeInfo ;
47
49
48
50
@ NodeInfo (shortName = "cpython://Objects/abstract.c/abstract_issubclass" )
@@ -58,7 +60,35 @@ public static AbstractObjectIsSubclassNode create(PNode derived, PNode cls) {
58
60
return AbstractObjectIsSubclassNodeGen .create (derived , cls );
59
61
}
60
62
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 ) {
62
92
if (derived == cls ) {
63
93
return true ;
64
94
}
@@ -69,17 +99,10 @@ private boolean isSubclassInternal(Object derived, Object cls) {
69
99
}
70
100
71
101
for (Object baseCls : bases .getArray ()) {
72
- if (isSubclassInternal (baseCls , cls )) {
102
+ if (isSubclassNode . execute (baseCls , cls )) {
73
103
return true ;
74
104
}
75
105
}
76
106
return false ;
77
107
}
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
- }
85
108
}
0 commit comments