111111import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
112112import com .oracle .graal .python .util .PythonUtils ;
113113import com .oracle .truffle .api .CompilerDirectives ;
114+ import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
114115import com .oracle .truffle .api .dsl .Cached ;
115116import com .oracle .truffle .api .dsl .CachedContext ;
116117import com .oracle .truffle .api .dsl .Fallback ;
127128import com .oracle .truffle .api .interop .UnsupportedMessageException ;
128129import com .oracle .truffle .api .interop .UnsupportedTypeException ;
129130import com .oracle .truffle .api .library .CachedLibrary ;
131+ import com .oracle .truffle .api .profiles .BranchProfile ;
130132import 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