Skip to content

Commit 07a2e61

Browse files
committed
[GR-30482] Make GetClassNode return lazy class
PullRequest: graalpython/1762
2 parents 848f826 + 438f0f1 commit 07a2e61

File tree

116 files changed

+684
-853
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

116 files changed

+684
-853
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 27 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@
5252
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
5353
import com.oracle.graal.python.nodes.ErrorMessages;
5454
import com.oracle.graal.python.nodes.PRaiseNode;
55-
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
56-
import com.oracle.graal.python.nodes.interop.PForeignToPTypeNode;
5755
import com.oracle.graal.python.runtime.GilNode;
5856
import com.oracle.graal.python.runtime.PythonContext;
57+
import com.oracle.graal.python.util.PythonUtils;
5958
import com.oracle.truffle.api.CompilerAsserts;
6059
import com.oracle.truffle.api.CompilerDirectives;
6160
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
@@ -66,20 +65,18 @@
6665
import com.oracle.truffle.api.dsl.Fallback;
6766
import com.oracle.truffle.api.dsl.Specialization;
6867
import com.oracle.truffle.api.frame.VirtualFrame;
69-
import com.oracle.truffle.api.interop.ArityException;
70-
import com.oracle.truffle.api.interop.InteropLibrary;
7168
import com.oracle.truffle.api.interop.TruffleObject;
72-
import com.oracle.truffle.api.interop.UnknownIdentifierException;
73-
import com.oracle.truffle.api.interop.UnsupportedMessageException;
74-
import com.oracle.truffle.api.interop.UnsupportedTypeException;
7569
import com.oracle.truffle.api.library.CachedLibrary;
7670
import com.oracle.truffle.api.library.ExportLibrary;
7771
import com.oracle.truffle.api.library.ExportMessage;
72+
import com.oracle.truffle.api.library.Message;
73+
import com.oracle.truffle.api.library.ReflectionLibrary;
7874
import com.oracle.truffle.api.object.Shape;
7975
import com.oracle.truffle.api.profiles.ConditionProfile;
8076

81-
@ExportLibrary(InteropLibrary.class)
8277
@ExportLibrary(PythonObjectLibrary.class)
78+
// InteropLibrary is proxied through ReflectionLibrary
79+
@ExportLibrary(ReflectionLibrary.class)
8380
public enum PythonBuiltinClassType implements TruffleObject {
8481

8582
ForeignObject(FOREIGN, Flags.PRIVATE_DERIVED_WODICT),
@@ -601,137 +598,12 @@ public final Shape getInstanceShape(PythonLanguage lang) {
601598
PStringIO.base = PTextIOBase;
602599
}
603600

604-
/* InteropLibrary messages */
605-
@SuppressWarnings("static-method")
606-
@ExportMessage
607-
public boolean isExecutable() {
608-
return true;
609-
}
610-
611-
@ExportMessage
612-
public Object execute(Object[] arguments,
613-
@CachedLibrary(limit = "1") InteropLibrary lib,
614-
@CachedContext(PythonLanguage.class) PythonContext context) throws UnsupportedTypeException, ArityException, UnsupportedMessageException {
615-
return lib.execute(context.getCore().lookupType(this), arguments);
616-
}
617-
618-
@SuppressWarnings("static-method")
619-
@ExportMessage
620-
public boolean isInstantiable() {
621-
return true;
622-
}
623-
624-
@ExportMessage
625-
public Object instantiate(Object[] arguments,
626-
@CachedLibrary(limit = "1") InteropLibrary lib,
627-
@CachedContext(PythonLanguage.class) PythonContext context) throws UnsupportedTypeException, ArityException, UnsupportedMessageException {
628-
return lib.instantiate(context.getCore().lookupType(this), arguments);
629-
}
630-
631-
@SuppressWarnings("static-method")
632-
@ExportMessage
633-
public boolean hasMembers() {
634-
return true;
635-
}
636-
637-
@ExportMessage
638-
public Object getMembers(boolean includeInternal,
639-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
640-
@CachedContext(PythonLanguage.class) PythonContext context) throws UnsupportedMessageException {
641-
return lib.getMembers(context.getCore().lookupType(this), includeInternal);
642-
}
643-
644-
@ExportMessage
645-
public boolean isMemberReadable(String key,
646-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
647-
@CachedContext(PythonLanguage.class) PythonContext context) {
648-
return lib.isMemberReadable(context.getCore().lookupType(this), key);
649-
}
650-
651-
@ExportMessage
652-
public Object readMember(String key,
653-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
654-
@CachedContext(PythonLanguage.class) PythonContext context) throws UnsupportedMessageException, UnknownIdentifierException {
655-
return lib.readMember(context.getCore().lookupType(this), key);
656-
}
657-
658-
@ExportMessage
659-
public boolean isMemberModifiable(String key,
660-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
661-
@CachedContext(PythonLanguage.class) PythonContext context) {
662-
return lib.isMemberModifiable(context.getCore().lookupType(this), key);
663-
}
664-
601+
// Proxy InteropLibrary messages to the PythonBuiltinClass
665602
@ExportMessage
666-
public boolean isMemberInsertable(String key,
667-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
668-
@CachedContext(PythonLanguage.class) PythonContext context) {
669-
return lib.isMemberInsertable(context.getCore().lookupType(this), key);
670-
}
671-
672-
@ExportMessage
673-
public void writeMember(String key, Object value,
674-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
675-
@CachedContext(PythonLanguage.class) PythonContext context)
676-
throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException {
677-
lib.writeMember(context.getCore().lookupType(this), key, value);
678-
}
679-
680-
@ExportMessage
681-
public boolean isMemberRemovable(String key,
682-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
683-
@CachedContext(PythonLanguage.class) PythonContext context) {
684-
return lib.isMemberRemovable(context.getCore().lookupType(this), key);
685-
}
686-
687-
@ExportMessage
688-
public void removeMember(String key,
689-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
690-
@CachedContext(PythonLanguage.class) PythonContext context) throws UnsupportedMessageException, UnknownIdentifierException {
691-
lib.removeMember(context.getCore().lookupType(this), key);
692-
}
693-
694-
@ExportMessage
695-
public boolean isMemberInvocable(String key,
696-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
697-
@CachedContext(PythonLanguage.class) PythonContext context) {
698-
return lib.isMemberInvocable(context.getCore().lookupType(this), key);
699-
}
700-
701-
@ExportMessage
702-
public Object invokeMember(String key, Object[] arguments,
703-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
704-
@CachedContext(PythonLanguage.class) PythonContext context)
705-
throws UnsupportedMessageException, ArityException, UnknownIdentifierException, UnsupportedTypeException {
706-
return lib.invokeMember(context.getCore().lookupType(this), key, arguments);
707-
}
708-
709-
@ExportMessage
710-
public boolean isMemberInternal(String key,
711-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
712-
@CachedContext(PythonLanguage.class) PythonContext context) {
713-
return lib.isMemberInternal(context.getCore().lookupType(this), key);
714-
}
715-
716-
@ExportMessage
717-
public boolean hasMemberReadSideEffects(String key,
718-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
719-
@CachedContext(PythonLanguage.class) PythonContext context) {
720-
return lib.hasMemberReadSideEffects(context.getCore().lookupType(this), key);
721-
}
722-
723-
@ExportMessage
724-
public boolean hasMemberWriteSideEffects(String key,
725-
@Shared("interop") @CachedLibrary(limit = "1") InteropLibrary lib,
726-
@CachedContext(PythonLanguage.class) PythonContext context) {
727-
return lib.hasMemberWriteSideEffects(context.getCore().lookupType(this), key);
728-
}
729-
730-
@ExportMessage
731-
static boolean isSequenceType(PythonBuiltinClassType type,
732-
@CachedContext(PythonLanguage.class) PythonContext context,
733-
@Shared("pol") @CachedLibrary(limit = "1") PythonObjectLibrary lib) {
734-
return lib.isSequenceType(context.getCore().lookupType(type));
603+
public Object send(Message message, Object[] args,
604+
@CachedLibrary(limit = "1") ReflectionLibrary lib,
605+
@CachedContext(PythonLanguage.class) PythonContext context) throws Exception {
606+
return lib.send(context.getCore().lookupType(this), message, args);
735607
}
736608

737609
@ExportMessage
@@ -842,35 +714,6 @@ public boolean isLazyPythonClass() {
842714
return true;
843715
}
844716

845-
@ExportMessage
846-
static boolean isMetaObject(@SuppressWarnings("unused") PythonBuiltinClassType self) {
847-
return true;
848-
}
849-
850-
@ExportMessage
851-
static boolean isMetaInstance(PythonBuiltinClassType self, Object instance,
852-
@CachedLibrary(limit = "3") PythonObjectLibrary lib,
853-
@Cached PForeignToPTypeNode convert,
854-
@Cached IsSubtypeNode isSubtype,
855-
@Cached.Exclusive @Cached GilNode gil) {
856-
boolean mustRelease = gil.acquire();
857-
try {
858-
return isSubtype.execute(lib.getLazyPythonClass(convert.executeConvert(instance)), self);
859-
} finally {
860-
gil.release(mustRelease);
861-
}
862-
}
863-
864-
@ExportMessage
865-
static String getMetaSimpleName(PythonBuiltinClassType self) {
866-
return self.getName();
867-
}
868-
869-
@ExportMessage
870-
static String getMetaQualifiedName(PythonBuiltinClassType self) {
871-
return self.getPrintName();
872-
}
873-
874717
public static boolean isExceptionType(PythonBuiltinClassType type) {
875718
return type.isException;
876719
}
@@ -880,6 +723,22 @@ public static boolean isExceptionType(PythonBuiltinClassType type) {
880723
*/
881724
@ExportMessage
882725
String asPStringWithState(@SuppressWarnings("unused") ThreadState state) {
883-
return getPrintName();
726+
return PythonUtils.format("<class '%s'>", getPrintName());
727+
}
728+
729+
@ExportMessage
730+
public Object lookupAndCallSpecialMethodWithState(ThreadState state, String methodName, Object[] arguments,
731+
@CachedLibrary("this") PythonObjectLibrary plib,
732+
@Shared("methodLib") @CachedLibrary(limit = "2") PythonObjectLibrary methodLib) {
733+
Object method = plib.lookupAttributeOnTypeStrict(this, methodName);
734+
return methodLib.callUnboundMethodWithState(method, state, this, arguments);
735+
}
736+
737+
@ExportMessage
738+
public Object lookupAndCallRegularMethodWithState(ThreadState state, String methodName, Object[] arguments,
739+
@CachedLibrary("this") PythonObjectLibrary plib,
740+
@Shared("methodLib") @CachedLibrary(limit = "2") PythonObjectLibrary methodLib) {
741+
Object method = plib.lookupAttributeStrictWithState(this, state, methodName);
742+
return methodLib.callObjectWithState(method, state, arguments);
884743
}
885744
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -856,8 +856,8 @@ public Object reversed(VirtualFrame frame, Object cls, Object sequence,
856856
@Cached("create(__REVERSED__)") LookupAttributeInMRONode reversedNode,
857857
@Cached("create(__LEN__)") LookupAndCallUnaryNode lenNode,
858858
@Cached("create(__GETITEM__)") LookupSpecialMethodNode getItemNode,
859-
@Cached("createBinaryProfile()") ConditionProfile noReversedProfile,
860-
@Cached("createBinaryProfile()") ConditionProfile noGetItemProfile) {
859+
@Cached ConditionProfile noReversedProfile,
860+
@Cached ConditionProfile noGetItemProfile) {
861861
Object sequenceKlass = lib.getLazyPythonClass(sequence);
862862
Object reversed = reversedNode.execute(sequenceKlass);
863863
if (noReversedProfile.profile(reversed == PNone.NO_VALUE)) {
@@ -1381,7 +1381,7 @@ Object createInt(Object cls, int arg, @SuppressWarnings("unused") PNone base) {
13811381

13821382
@Specialization(guards = "isNoValue(base)")
13831383
Object createInt(Object cls, long arg, @SuppressWarnings("unused") PNone base,
1384-
@Cached("createBinaryProfile()") ConditionProfile isIntProfile) {
1384+
@Cached ConditionProfile isIntProfile) {
13851385
if (isPrimitiveInt(cls)) {
13861386
int intValue = (int) arg;
13871387
if (isIntProfile.profile(intValue == arg)) {
@@ -1624,7 +1624,7 @@ private String toString(PBytesLike pByteArray) {
16241624
public abstract static class BoolNode extends PythonBinaryBuiltinNode {
16251625
@Specialization(limit = "getCallSiteInlineCacheMaxDepth()")
16261626
public static boolean bool(VirtualFrame frame, Object cls, Object obj,
1627-
@Cached("createBinaryProfile()") ConditionProfile hasFrame,
1627+
@Cached ConditionProfile hasFrame,
16281628
@CachedLibrary("obj") PythonObjectLibrary lib) {
16291629
if (hasFrame.profile(frame != null)) {
16301630
return lib.isTrueWithState(obj, PArguments.getThreadState(frame));
@@ -1715,7 +1715,7 @@ Object doBuiltinTypeType(PythonBuiltinClassType self, Object[] varargs, PKeyword
17151715

17161716
@Specialization(guards = "self.needsNativeAllocation()")
17171717
Object doNativeObjectIndirect(VirtualFrame frame, PythonManagedClass self, Object[] varargs, PKeyword[] kwargs,
1718-
@Cached("create()") GetMroNode getMroNode) {
1718+
@Cached GetMroNode getMroNode) {
17191719
checkExcessArgs(self, varargs, kwargs);
17201720
if (self.isAbstractClass()) {
17211721
throw getReportAbstractClassNode().execute(frame, self);
@@ -2113,7 +2113,7 @@ public abstract static class TupleNode extends PythonBinaryBuiltinNode {
21132113

21142114
@Specialization(guards = "!isNativeClass(cls)")
21152115
protected static PTuple constructTuple(VirtualFrame frame, Object cls, Object iterable,
2116-
@Cached("create()") TupleNodes.ConstructTupleNode constructTupleNode) {
2116+
@Cached TupleNodes.ConstructTupleNode constructTupleNode) {
21172117
return constructTupleNode.execute(frame, cls, iterable);
21182118
}
21192119

@@ -2424,10 +2424,12 @@ private PythonClass typeMetaclass(VirtualFrame frame, String name, PTuple bases,
24242424
basesArray = new PythonAbstractClass[array.length];
24252425
for (int i = 0; i < array.length; i++) {
24262426
// TODO: deal with non-class bases
2427-
if (!PGuards.isPythonClass(array[i])) {
2428-
throw raise(NotImplementedError, "creating a class with non-class bases");
2429-
} else {
2427+
if (PythonAbstractClass.isInstance(array[i])) {
24302428
basesArray[i] = (PythonAbstractClass) array[i];
2429+
} else if (array[i] instanceof PythonBuiltinClassType) {
2430+
basesArray[i] = getCore().lookupType((PythonBuiltinClassType) array[i]);
2431+
} else {
2432+
throw raise(NotImplementedError, "creating a class with non-class bases");
24312433
}
24322434
}
24332435
}
@@ -2867,7 +2869,7 @@ protected static TypeNode create() {
28672869

28682870
@Specialization(guards = {"!isNoValue(bases)", "!isNoValue(dict)"})
28692871
Object typeGeneric(VirtualFrame frame, Object cls, Object name, Object bases, Object dict, PKeyword[] kwds,
2870-
@Cached("create()") TypeNode nextTypeNode,
2872+
@Cached TypeNode nextTypeNode,
28712873
@CachedLibrary(limit = "3") PythonObjectLibrary lib) {
28722874
if (PGuards.isNoValue(bases) && !PGuards.isNoValue(dict) || !PGuards.isNoValue(bases) && PGuards.isNoValue(dict)) {
28732875
throw raise(TypeError, ErrorMessages.TAKES_D_OR_D_ARGS, "type()", 1, 3);
@@ -3413,20 +3415,20 @@ public abstract static class CreateSliceNode extends PythonBuiltinNode {
34133415
@Specialization(guards = {"isNoValue(second)", "isNoValue(third)"})
34143416
@SuppressWarnings("unused")
34153417
static Object stop(VirtualFrame frame, Object cls, Object first, Object second, Object third,
3416-
@Cached("create()") SliceLiteralNode sliceNode) {
3418+
@Cached SliceLiteralNode sliceNode) {
34173419
return sliceNode.execute(frame, PNone.NONE, first, PNone.NONE);
34183420
}
34193421

34203422
@Specialization(guards = {"!isNoValue(second)", "isNoValue(third)"})
34213423
@SuppressWarnings("unused")
34223424
static Object startStop(VirtualFrame frame, Object cls, Object first, Object second, Object third,
3423-
@Cached("create()") SliceLiteralNode sliceNode) {
3425+
@Cached SliceLiteralNode sliceNode) {
34243426
return sliceNode.execute(frame, first, second, PNone.NONE);
34253427
}
34263428

34273429
@Specialization(guards = {"!isNoValue(second)", "!isNoValue(third)"})
34283430
static Object slice(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object first, Object second, Object third,
3429-
@Cached("create()") SliceLiteralNode sliceNode) {
3431+
@Cached SliceLiteralNode sliceNode) {
34303432
return sliceNode.execute(frame, first, second, third);
34313433
}
34323434
}

0 commit comments

Comments
 (0)