43
43
import static com .oracle .graal .python .nodes .SpecialMethodNames .__EQ__ ;
44
44
45
45
import java .util .ArrayList ;
46
+ import java .util .Collection ;
47
+ import java .util .HashSet ;
48
+ import java .util .Iterator ;
46
49
import java .util .List ;
47
50
import java .util .Set ;
48
51
53
56
import com .oracle .graal .python .builtins .objects .cext .NativeMemberNames ;
54
57
import com .oracle .graal .python .builtins .objects .cext .PythonAbstractNativeObject ;
55
58
import com .oracle .graal .python .builtins .objects .cext .PythonNativeClass ;
59
+ import com .oracle .graal .python .builtins .objects .cext .PythonNativeVoidPtr ;
60
+ import com .oracle .graal .python .builtins .objects .common .HashingStorage ;
61
+ import com .oracle .graal .python .builtins .objects .common .HashingStorage .Equivalence ;
56
62
import com .oracle .graal .python .builtins .objects .common .SequenceStorageNodes ;
63
+ import com .oracle .graal .python .builtins .objects .dict .PDict ;
57
64
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
58
65
import com .oracle .graal .python .builtins .objects .type .ManagedPythonClass .FlagsContainer ;
59
66
import com .oracle .graal .python .builtins .objects .type .TypeNodesFactory .GetBaseClassesNodeGen ;
68
75
import com .oracle .graal .python .nodes .PGuards ;
69
76
import com .oracle .graal .python .nodes .PNodeWithContext ;
70
77
import com .oracle .graal .python .nodes .SpecialMethodNames ;
78
+ import com .oracle .graal .python .nodes .truffle .PythonTypes ;
71
79
import com .oracle .graal .python .runtime .sequence .storage .MroSequenceStorage ;
72
80
import com .oracle .graal .python .runtime .sequence .storage .SequenceStorage ;
73
81
import com .oracle .truffle .api .CompilerAsserts ;
77
85
import com .oracle .truffle .api .dsl .Fallback ;
78
86
import com .oracle .truffle .api .dsl .ImportStatic ;
79
87
import com .oracle .truffle .api .dsl .Specialization ;
88
+ import com .oracle .truffle .api .dsl .TypeSystemReference ;
80
89
import com .oracle .truffle .api .interop .ForeignAccess ;
81
90
import com .oracle .truffle .api .interop .Message ;
91
+ import com .oracle .truffle .api .interop .TruffleObject ;
82
92
import com .oracle .truffle .api .interop .UnknownIdentifierException ;
83
93
import com .oracle .truffle .api .interop .UnsupportedMessageException ;
84
94
import com .oracle .truffle .api .nodes .Node ;
@@ -285,6 +295,8 @@ public static GetSuperClassNode create() {
285
295
286
296
}
287
297
298
+ @ TypeSystemReference (PythonTypes .class )
299
+ @ ImportStatic (NativeMemberNames .class )
288
300
public abstract static class GetSubclassesNode extends PNodeWithContext {
289
301
290
302
public abstract Set <AbstractPythonClass > execute (Object obj );
@@ -299,18 +311,108 @@ Set<AbstractPythonClass> doPythonClass(PythonBuiltinClassType obj) {
299
311
return getBuiltinPythonClass (obj ).getSubClasses ();
300
312
}
301
313
314
+ @ Specialization
315
+ @ TruffleBoundary
316
+ Set <AbstractPythonClass > doNativeClass (PythonNativeClass obj ,
317
+ @ Cached ("create(TP_SUBCLASSES)" ) GetTypeMemberNode getTpSubclassesNode ,
318
+ @ Cached ("createClassProfile()" ) ValueProfile profile ) {
319
+ Object tpSubclasses = getTpSubclassesNode .execute (obj );
320
+
321
+ Object profiled = profile .profile (tpSubclasses );
322
+ if (profiled instanceof PDict ) {
323
+ return wrapDict (profiled );
324
+ }
325
+ CompilerDirectives .transferToInterpreter ();
326
+ throw new IllegalStateException ("invalid subclasses dict " + profiled .getClass ().getName ());
327
+ }
328
+
302
329
@ TruffleBoundary
303
330
public static Set <AbstractPythonClass > doSlowPath (Object obj ) {
304
331
if (obj instanceof ManagedPythonClass ) {
305
332
return ((ManagedPythonClass ) obj ).getSubClasses ();
306
333
} else if (obj instanceof PythonBuiltinClassType ) {
307
334
return PythonLanguage .getCore ().lookupType ((PythonBuiltinClassType ) obj ).getSubClasses ();
308
335
} else if (PGuards .isNativeClass (obj )) {
309
- // TODO implement
336
+ Object tpSubclasses = GetTypeMemberNode .doSlowPath (obj , NativeMemberNames .TP_SUBCLASSES );
337
+ if (tpSubclasses instanceof PDict ) {
338
+ return wrapDict (tpSubclasses );
339
+ }
340
+ throw new IllegalStateException ("invalid subclasses dict " + tpSubclasses .getClass ().getName ());
310
341
}
311
342
throw new IllegalStateException ("unknown type " + obj .getClass ().getName ());
312
343
}
313
344
345
+ private static Set <AbstractPythonClass > wrapDict (Object tpSubclasses ) {
346
+ return new Set <AbstractPythonClass >() {
347
+ private final PDict dict = (PDict ) tpSubclasses ;
348
+
349
+ public int size () {
350
+ return dict .getDictStorage ().length ();
351
+ }
352
+
353
+ public boolean isEmpty () {
354
+ return size () == 0 ;
355
+ }
356
+
357
+ public boolean contains (Object o ) {
358
+ HashingStorage s = dict .getDictStorage ();
359
+ Equivalence equiv = HashingStorage .getSlowPathEquivalence (o );
360
+ for (Object val : s .values ()) {
361
+ if (equiv .equals (o , val )) {
362
+ return true ;
363
+ }
364
+ }
365
+ return false ;
366
+ }
367
+
368
+ @ SuppressWarnings ("unchecked" )
369
+ public Iterator <AbstractPythonClass > iterator () {
370
+ return (Iterator <AbstractPythonClass >) dict .getDictStorage ().values ();
371
+ }
372
+
373
+ public Object [] toArray () {
374
+ return dict .getDictStorage ().valuesAsArray ();
375
+ }
376
+
377
+ public <T > T [] toArray (T [] a ) {
378
+ throw new UnsupportedOperationException ();
379
+ }
380
+
381
+ public boolean add (AbstractPythonClass e ) {
382
+ if (PGuards .isNativeClass (e )) {
383
+ dict .setItem (PythonNativeClass .cast (e ).getPtr (), e );
384
+ }
385
+ dict .setItem (new PythonNativeVoidPtr ((TruffleObject ) e ), e );
386
+ return true ;
387
+ }
388
+
389
+ public boolean remove (Object o ) {
390
+ throw new UnsupportedOperationException ();
391
+ }
392
+
393
+ public boolean containsAll (Collection <?> c ) {
394
+ throw new UnsupportedOperationException ();
395
+ }
396
+
397
+ public boolean addAll (Collection <? extends AbstractPythonClass > c ) {
398
+ throw new UnsupportedOperationException ();
399
+ }
400
+
401
+ public boolean retainAll (Collection <?> c ) {
402
+ throw new UnsupportedOperationException ();
403
+ }
404
+
405
+ public boolean removeAll (Collection <?> c ) {
406
+ throw new UnsupportedOperationException ();
407
+ }
408
+
409
+ public void clear () {
410
+ throw new UnsupportedOperationException ();
411
+ }
412
+
413
+ };
414
+ }
415
+
314
416
public static GetSubclassesNode create () {
315
417
return GetSubclassesNodeGen .create ();
316
418
}
0 commit comments