Skip to content

Commit 8b41c3a

Browse files
committed
Fix specialization inconsistency in foreign obejct __str__
1 parent d781a53 commit 8b41c3a

File tree

1 file changed

+57
-86
lines changed

1 file changed

+57
-86
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java

Lines changed: 57 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
112112
import com.oracle.graal.python.util.PythonUtils;
113113
import com.oracle.truffle.api.CompilerDirectives;
114+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
114115
import com.oracle.truffle.api.dsl.Cached;
115116
import com.oracle.truffle.api.dsl.CachedContext;
116117
import com.oracle.truffle.api.dsl.Fallback;
@@ -127,6 +128,7 @@
127128
import com.oracle.truffle.api.interop.UnsupportedMessageException;
128129
import com.oracle.truffle.api.interop.UnsupportedTypeException;
129130
import com.oracle.truffle.api.library.CachedLibrary;
131+
import com.oracle.truffle.api.profiles.BranchProfile;
130132
import com.oracle.truffle.api.profiles.ConditionProfile;
131133

132134
@CoreFunctions(extendClasses = PythonBuiltinClassType.ForeignObject)
@@ -809,95 +811,61 @@ protected Object doIt(Object object,
809811
abstract static class StrNode extends PythonUnaryBuiltinNode {
810812
protected final String method = __STR__;
811813
@Child private LookupAndCallUnaryNode callStrNode;
814+
@Child private CastToListNode castToListNode;
812815
@Child protected PythonUnaryBuiltinNode objectStrNode;
813816

814-
@Specialization(guards = {"lib.isNull(object)"})
815-
protected Object doNull(VirtualFrame frame, @SuppressWarnings("unused") Object object,
816-
@SuppressWarnings("unused") @CachedLibrary(limit = "3") InteropLibrary lib) {
817-
return getCallStrNode().executeObject(frame, PNone.NONE);
818-
}
819-
820-
@Specialization(guards = {"lib.isBoolean(object)"})
821-
protected Object doBool(VirtualFrame frame, Object object,
822-
@CachedLibrary(limit = "3") InteropLibrary lib) {
823-
try {
824-
return getCallStrNode().executeObject(frame, lib.asBoolean(object));
825-
} catch (UnsupportedMessageException e) {
826-
CompilerDirectives.transferToInterpreterAndInvalidate();
827-
throw new IllegalStateException("foreign object claims to be boxed, but does not support the appropriate unbox message");
828-
}
829-
}
830-
831-
@Specialization(guards = {"lib.isString(object)"})
832-
protected Object doStr(VirtualFrame frame, Object object,
833-
@CachedLibrary(limit = "3") InteropLibrary lib) {
834-
try {
835-
return getCallStrNode().executeObject(frame, lib.asString(object));
836-
} catch (UnsupportedMessageException e) {
837-
CompilerDirectives.transferToInterpreterAndInvalidate();
838-
throw new IllegalStateException("foreign object claims to be boxed, but does not support the appropriate unbox message");
839-
}
840-
}
841-
842-
@Specialization(guards = {"lib.fitsInLong(object)"})
843-
protected Object doLong(VirtualFrame frame, Object object,
844-
@CachedLibrary(limit = "3") InteropLibrary lib) {
845-
try {
846-
return getCallStrNode().executeObject(frame, lib.asLong(object));
847-
} catch (UnsupportedMessageException e) {
848-
CompilerDirectives.transferToInterpreterAndInvalidate();
849-
throw new IllegalStateException("foreign object claims to be boxed, but does not support the appropriate unbox message");
850-
}
851-
}
852-
853-
@Specialization(guards = {"lib.fitsInDouble(object)"})
854-
protected Object doDouble(VirtualFrame frame, Object object,
855-
@CachedLibrary(limit = "3") InteropLibrary lib) {
856-
try {
857-
return getCallStrNode().executeObject(frame, lib.asDouble(object));
858-
} catch (UnsupportedMessageException e) {
859-
CompilerDirectives.transferToInterpreterAndInvalidate();
860-
throw new IllegalStateException("foreign object claims to be boxed, but does not support the appropriate unbox message");
861-
}
862-
}
863-
864-
@Specialization(guards = {"lib.hasArrayElements(object)"})
865-
protected Object doArray(VirtualFrame frame, Object object,
866-
@Cached CastToListNode asList,
867-
@CachedLibrary(limit = "3") InteropLibrary lib) {
817+
@Specialization
818+
Object str(VirtualFrame frame, Object object,
819+
@CachedLibrary(limit = "3") InteropLibrary lib,
820+
@Cached BranchProfile isNull,
821+
@Cached BranchProfile isBoolean,
822+
@Cached BranchProfile isString,
823+
@Cached BranchProfile isLong,
824+
@Cached BranchProfile isDouble,
825+
@Cached BranchProfile isArray,
826+
@Cached BranchProfile isHostObject) {
868827
try {
869-
long size = lib.getArraySize(object);
870-
if (size <= Integer.MAX_VALUE && size >= 0) {
871-
PForeignArrayIterator iterable = factory().createForeignArrayIterator(object);
872-
return getCallStrNode().executeObject(frame, asList.execute(frame, iterable));
828+
if (lib.isNull(object)) {
829+
isNull.enter();
830+
return getCallStrNode().executeObject(frame, PNone.NONE);
831+
} else if (lib.isBoolean(object)) {
832+
isBoolean.enter();
833+
return getCallStrNode().executeObject(frame, lib.asBoolean(object));
834+
} else if (lib.isString(object)) {
835+
isString.enter();
836+
return getCallStrNode().executeObject(frame, lib.asString(object));
837+
} else if (lib.fitsInLong(object)) {
838+
isLong.enter();
839+
return getCallStrNode().executeObject(frame, lib.asLong(object));
840+
} else if (lib.fitsInDouble(object)) {
841+
isDouble.enter();
842+
return getCallStrNode().executeObject(frame, lib.asDouble(object));
843+
} else if (lib.hasArrayElements(object)) {
844+
isArray.enter();
845+
long size = lib.getArraySize(object);
846+
if (size <= Integer.MAX_VALUE && size >= 0) {
847+
PForeignArrayIterator iterable = factory().createForeignArrayIterator(object);
848+
return getCallStrNode().executeObject(frame, getCastToListNode().execute(frame, iterable));
849+
}
850+
} else if (getContext().getEnv().isHostObject(object)) {
851+
isHostObject.enter();
852+
boolean isMetaObject = lib.isMetaObject(object);
853+
Object metaObject = isMetaObject
854+
? object
855+
: lib.hasMetaObject(object) ? lib.getMetaObject(object) : null;
856+
if (metaObject != null) {
857+
Object displayName = lib.toDisplayString(metaObject);
858+
String text = createDisplayName(isMetaObject, displayName);
859+
return PythonUtils.format("<%s at 0x%x>", text, PythonAbstractObject.systemHashCode(object));
860+
}
873861
}
874862
} catch (UnsupportedMessageException e) {
875-
// fall through
876-
}
877-
return doIt(frame, object);
878-
}
879-
880-
@Specialization(guards = "getContext().getEnv().isHostObject(self)")
881-
Object doHostObject(VirtualFrame frame, Object self,
882-
@CachedLibrary(limit = "3") InteropLibrary lib) {
883-
try {
884-
boolean isMetaObject = lib.isMetaObject(self);
885-
Object metaObject = isMetaObject
886-
? self
887-
: lib.hasMetaObject(self) ? lib.getMetaObject(self) : null;
888-
if (metaObject != null) {
889-
Object displayName = lib.toDisplayString(metaObject);
890-
String text = createDisplayName(isMetaObject, displayName);
891-
return PythonUtils.format("<%s at 0x%x>", text, PythonAbstractObject.systemHashCode(self));
892-
}
893-
894-
} catch (UnsupportedMessageException ex) {
895-
// do nothing
863+
// Fall back to the generic impl
896864
}
897-
return doIt(frame, self);
865+
return getObjectStrNode().call(frame, object);
898866
}
899867

900-
@CompilerDirectives.TruffleBoundary
868+
@TruffleBoundary
901869
private static String createDisplayName(boolean isMetaObject, Object object) {
902870
StringBuilder sb = new StringBuilder();
903871
sb.append(isMetaObject ? "JavaClass[" : "JavaObject[");
@@ -906,11 +874,6 @@ private static String createDisplayName(boolean isMetaObject, Object object) {
906874
return sb.toString();
907875
}
908876

909-
@Fallback
910-
protected Object doIt(VirtualFrame frame, Object object) {
911-
return getObjectStrNode().call(frame, object);
912-
}
913-
914877
private LookupAndCallUnaryNode getCallStrNode() {
915878
if (callStrNode == null) {
916879
CompilerDirectives.transferToInterpreterAndInvalidate();
@@ -919,6 +882,14 @@ private LookupAndCallUnaryNode getCallStrNode() {
919882
return callStrNode;
920883
}
921884

885+
private CastToListNode getCastToListNode() {
886+
if (castToListNode == null) {
887+
CompilerDirectives.transferToInterpreterAndInvalidate();
888+
castToListNode = insert(CastToListNode.create());
889+
}
890+
return castToListNode;
891+
}
892+
922893
protected PythonUnaryBuiltinNode getObjectStrNode() {
923894
if (objectStrNode == null) {
924895
CompilerDirectives.transferToInterpreterAndInvalidate();

0 commit comments

Comments
 (0)