|
42 | 42 |
|
43 | 43 | import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError;
|
44 | 44 | import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
|
| 45 | +import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_SUBCLASS_CHECK; |
45 | 46 | import static com.oracle.graal.python.builtins.objects.type.TypeBuiltins.TYPE_FLAGS;
|
46 | 47 | import static com.oracle.graal.python.builtins.objects.type.TypeBuiltins.TYPE_ITEMSIZE;
|
47 | 48 | import static com.oracle.graal.python.builtins.objects.type.TypeFlags.BASETYPE;
|
@@ -1380,34 +1381,37 @@ public abstract static class IsTypeNode extends Node {
|
1380 | 1381 | public abstract boolean execute(Object obj);
|
1381 | 1382 |
|
1382 | 1383 | @Specialization
|
1383 |
| - boolean doManagedClass(@SuppressWarnings("unused") PythonClass obj) { |
| 1384 | + static boolean doManagedClass(@SuppressWarnings("unused") PythonClass obj) { |
1384 | 1385 | return true;
|
1385 | 1386 | }
|
1386 | 1387 |
|
1387 | 1388 | @Specialization
|
1388 |
| - boolean doManagedClass(@SuppressWarnings("unused") PythonBuiltinClass obj) { |
| 1389 | + static boolean doManagedClass(@SuppressWarnings("unused") PythonBuiltinClass obj) { |
1389 | 1390 | return true;
|
1390 | 1391 | }
|
1391 | 1392 |
|
1392 | 1393 | @Specialization
|
1393 |
| - boolean doBuiltinType(@SuppressWarnings("unused") PythonBuiltinClassType obj) { |
| 1394 | + static boolean doBuiltinType(@SuppressWarnings("unused") PythonBuiltinClassType obj) { |
1394 | 1395 | return true;
|
1395 | 1396 | }
|
1396 | 1397 |
|
1397 | 1398 | @Specialization
|
1398 |
| - boolean doNativeClass(PythonAbstractNativeObject obj, |
| 1399 | + static boolean doNativeClass(PythonAbstractNativeObject obj, |
1399 | 1400 | @Cached IsBuiltinClassProfile profile,
|
1400 |
| - @Cached GetClassNode getClassNode) { |
1401 |
| - // TODO(fa): this check may not be enough since a type object may indirectly inherit |
1402 |
| - // from 'type' |
1403 |
| - // CPython has two different checks if some object is a type: |
1404 |
| - // 1. test if type flag 'Py_TPFLAGS_TYPE_SUBCLASS' is set |
1405 |
| - // 2. test if attribute '__bases__' is a tuple |
1406 |
| - return profile.profileClass(getClassNode.execute(obj), PythonBuiltinClassType.PythonClass); |
| 1401 | + @Cached GetClassNode getClassNode, |
| 1402 | + @Cached CExtNodes.PCallCapiFunction nativeTypeCheck) { |
| 1403 | + Object type = getClassNode.execute(obj); |
| 1404 | + if (profile.profileClass(type, PythonBuiltinClassType.PythonClass)) { |
| 1405 | + return true; |
| 1406 | + } |
| 1407 | + if (PythonNativeClass.isInstance(type)) { |
| 1408 | + return (int) nativeTypeCheck.call(FUN_SUBCLASS_CHECK, obj.getPtr()) == 1; |
| 1409 | + } |
| 1410 | + return false; |
1407 | 1411 | }
|
1408 | 1412 |
|
1409 | 1413 | @Fallback
|
1410 |
| - boolean doOther(@SuppressWarnings("unused") Object obj) { |
| 1414 | + static boolean doOther(@SuppressWarnings("unused") Object obj) { |
1411 | 1415 | return false;
|
1412 | 1416 | }
|
1413 | 1417 |
|
@@ -1477,37 +1481,43 @@ public abstract static class GetInstanceShape extends PNodeWithContext {
|
1477 | 1481 | public abstract Shape execute(Object clazz);
|
1478 | 1482 |
|
1479 | 1483 | @Specialization(guards = "clazz == cachedClazz", limit = "1")
|
1480 |
| - Shape doBuiltinClassTypeCached(@SuppressWarnings("unused") PythonBuiltinClassType clazz, |
| 1484 | + static Shape doBuiltinClassTypeCached(@SuppressWarnings("unused") PythonBuiltinClassType clazz, |
1481 | 1485 | @Shared("lang") @CachedLanguage PythonLanguage lang,
|
1482 | 1486 | @Cached("clazz") PythonBuiltinClassType cachedClazz) {
|
1483 | 1487 | return cachedClazz.getInstanceShape(lang);
|
1484 | 1488 | }
|
1485 | 1489 |
|
1486 | 1490 | @Specialization(replaces = "doBuiltinClassTypeCached")
|
1487 |
| - Shape doBuiltinClassType(PythonBuiltinClassType clazz, |
| 1491 | + static Shape doBuiltinClassType(PythonBuiltinClassType clazz, |
1488 | 1492 | @Shared("lang") @CachedLanguage PythonLanguage lang) {
|
1489 | 1493 | return clazz.getInstanceShape(lang);
|
1490 | 1494 | }
|
1491 | 1495 |
|
1492 | 1496 | @Specialization(guards = "clazz == cachedClazz", assumptions = "singleContextAssumption()")
|
1493 |
| - Shape doBuiltinClassCached(@SuppressWarnings("unused") PythonBuiltinClass clazz, |
| 1497 | + static Shape doBuiltinClassCached(@SuppressWarnings("unused") PythonBuiltinClass clazz, |
1494 | 1498 | @Cached("clazz") PythonBuiltinClass cachedClazz) {
|
1495 | 1499 | return cachedClazz.getInstanceShape();
|
1496 | 1500 | }
|
1497 | 1501 |
|
1498 | 1502 | @Specialization(guards = "clazz == cachedClazz", assumptions = "singleContextAssumption()")
|
1499 |
| - Shape doClassCached(@SuppressWarnings("unused") PythonClass clazz, |
| 1503 | + static Shape doClassCached(@SuppressWarnings("unused") PythonClass clazz, |
1500 | 1504 | @Cached("clazz") PythonClass cachedClazz) {
|
1501 | 1505 | return cachedClazz.getInstanceShape();
|
1502 | 1506 | }
|
1503 | 1507 |
|
1504 | 1508 | @Specialization(replaces = {"doClassCached", "doBuiltinClassCached"})
|
1505 |
| - Shape doManagedClass(PythonManagedClass clazz) { |
| 1509 | + static Shape doManagedClass(PythonManagedClass clazz) { |
1506 | 1510 | return clazz.getInstanceShape();
|
1507 | 1511 | }
|
1508 | 1512 |
|
| 1513 | + @Specialization |
| 1514 | + static Shape doNativeClass(@SuppressWarnings("unused") PythonAbstractNativeObject clazz, |
| 1515 | + @Shared("lang") @CachedLanguage PythonLanguage lang) { |
| 1516 | + return lang.getEmptyShape(); |
| 1517 | + } |
| 1518 | + |
1509 | 1519 | @Specialization(guards = {"!isManagedClass(clazz)", "!isPythonBuiltinClassType(clazz)"})
|
1510 |
| - Shape doError(@SuppressWarnings("unused") Object clazz, |
| 1520 | + static Shape doError(@SuppressWarnings("unused") Object clazz, |
1511 | 1521 | @Cached PRaiseNode raise) {
|
1512 | 1522 | throw raise.raise(PythonBuiltinClassType.SystemError, ErrorMessages.CANNOT_GET_SHAPE_OF_NATIVE_CLS);
|
1513 | 1523 | }
|
|
0 commit comments