121121import com .oracle .graal .python .builtins .objects .slice .SliceNodes .ComputeIndices ;
122122import com .oracle .graal .python .builtins .objects .str .StringBuiltinsClinicProviders .FormatNodeClinicProviderGen ;
123123import com .oracle .graal .python .builtins .objects .str .StringBuiltinsClinicProviders .SplitNodeClinicProviderGen ;
124- import com .oracle .graal .python .builtins .objects .str .StringBuiltinsFactory .EndsWithNodeFactory ;
125124import com .oracle .graal .python .builtins .objects .str .StringBuiltinsFactory .EqNodeFactory ;
126125import com .oracle .graal .python .builtins .objects .str .StringBuiltinsFactory .LtNodeFactory ;
127- import com .oracle .graal .python .builtins .objects .str .StringBuiltinsFactory .StartsWithNodeFactory ;
128126import com .oracle .graal .python .builtins .objects .str .StringNodes .CastToJavaStringCheckedNode ;
129127import com .oracle .graal .python .builtins .objects .str .StringNodes .CastToTruffleStringCheckedNode ;
130128import com .oracle .graal .python .builtins .objects .str .StringNodes .JoinInternalNode ;
175173import com .oracle .truffle .api .dsl .Cached ;
176174import com .oracle .truffle .api .dsl .Cached .Exclusive ;
177175import com .oracle .truffle .api .dsl .Cached .Shared ;
176+ import com .oracle .truffle .api .dsl .GenerateInline ;
178177import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
179178import com .oracle .truffle .api .dsl .GenerateUncached ;
180179import com .oracle .truffle .api .dsl .ImportStatic ;
@@ -588,72 +587,77 @@ static Object doNoString(Object self, @SuppressWarnings("unused") Object other,
588587 }
589588 }
590589
591- abstract static class PrefixSuffixBaseNode extends PythonQuaternaryClinicBuiltinNode {
590+ @ GenerateInline (false ) // footprint reduction 56 -> 39
591+ @ ImportStatic (PGuards .class )
592+ public abstract static class PrefixSuffixNode extends Node {
592593
593- public abstract boolean executeBoolean (VirtualFrame frame , TruffleString self , TruffleString subStr , int start , int end );
594+ enum Op {
595+ PREFIX ,
596+ SUFFIX ;
594597
595- @ Override
596- protected ArgumentClinicProvider getArgumentClinic () {
597- // must be implemented here, because DSL creates a generated node for this class
598- CompilerDirectives .transferToInterpreterAndInvalidate ();
599- throw new AbstractMethodError ();
598+ TruffleString methodName () {
599+ return this == PREFIX ? T_STARTSWITH : T_ENDSWITH ;
600+ }
601+ }
602+
603+ abstract boolean execute (Object self , Object subStr , int start , int end , Op op );
604+
605+ public final boolean startsWith (Object self , Object subStr , int start , int end ) {
606+ return execute (self , subStr , start , end , Op .PREFIX );
607+ }
608+
609+ public final boolean endsWith (Object self , Object subStr , int start , int end ) {
610+ return execute (self , subStr , start , end , Op .SUFFIX );
600611 }
601612
602613 @ Specialization (guards = "!isPTuple(subStrObj)" )
603- boolean doStringPrefixStartEnd (Object selfObj , Object subStrObj , int start , int end ,
614+ static boolean doString (Object selfObj , Object subStrObj , int start , int end , Op op ,
604615 @ Bind ("this" ) Node inliningTarget ,
605616 @ Exclusive @ Cached CastToTruffleStringCheckedNode castSelfNode ,
606617 @ Exclusive @ Cached CastToTruffleStringCheckedNode castPrefixNode ,
607- @ Shared ( "cpLen" ) @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
608- @ Shared ( "regionEqual" ) @ Cached TruffleString .RegionEqualNode regionEqualNode ) {
609- TruffleString self = castSelfNode .cast (inliningTarget , selfObj , ErrorMessages .REQUIRES_STR_OBJECT_BUT_RECEIVED_P , getMethodName (), selfObj );
610- TruffleString subStr = castPrefixNode .cast (inliningTarget , subStrObj , ErrorMessages .FIRST_ARG_MUST_BE_S_OR_TUPLE_NOT_P , getMethodName (), "str" , subStrObj );
618+ @ Shared @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
619+ @ Shared @ Cached TruffleString .RegionEqualNode regionEqualNode ) {
620+ TruffleString self = castSelfNode .cast (inliningTarget , selfObj , ErrorMessages .REQUIRES_STR_OBJECT_BUT_RECEIVED_P , op . methodName (), selfObj );
621+ TruffleString subStr = castPrefixNode .cast (inliningTarget , subStrObj , ErrorMessages .FIRST_ARG_MUST_BE_S_OR_TUPLE_NOT_P , op . methodName (), "str" , subStrObj );
611622 int selfLen = codePointLengthNode .execute (self , TS_ENCODING );
612623 int subStrLen = codePointLengthNode .execute (subStr , TS_ENCODING );
613- return doIt (self , subStr , adjustStartIndex (start , selfLen ), adjustEndIndex (end , selfLen ), selfLen , subStrLen , regionEqualNode );
624+ return doIt (self , subStr , adjustStartIndex (start , selfLen ), adjustEndIndex (end , selfLen ), selfLen , subStrLen , regionEqualNode , op );
614625 }
615626
616627 @ Specialization
617- @ SuppressWarnings ("truffle-static-method" )
618- boolean doTuplePrefixStartEnd (Object selfObj , PTuple subStrs , int start , int end ,
628+ static boolean doTuple (Object selfObj , PTuple subStrs , int start , int end , Op op ,
619629 @ Bind ("this" ) Node inliningTarget ,
620- @ Exclusive @ Cached GetObjectArrayNode getObjectArrayNode ,
621- @ Exclusive @ Cached CastToTruffleStringNode castPrefixNode ,
622- @ Shared ("cpLen" ) @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
623- @ Shared ("regionEqual" ) @ Cached TruffleString .RegionEqualNode regionEqualNode ,
630+ @ Cached GetObjectArrayNode getObjectArrayNode ,
624631 @ Exclusive @ Cached CastToTruffleStringCheckedNode castSelfNode ,
625- @ Cached PRaiseNode .Lazy raiseNode ) {
626- TruffleString self = castSelfNode .cast (inliningTarget , selfObj , ErrorMessages .REQUIRES_STR_OBJECT_BUT_RECEIVED_P , getMethodName (), selfObj );
632+ @ Exclusive @ Cached CastToTruffleStringCheckedNode castPrefixNode ,
633+ @ Shared @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
634+ @ Shared @ Cached TruffleString .RegionEqualNode regionEqualNode ) {
635+ TruffleString self = castSelfNode .cast (inliningTarget , selfObj , ErrorMessages .REQUIRES_STR_OBJECT_BUT_RECEIVED_P , op .methodName (), selfObj );
627636
628637 int selfLen = codePointLengthNode .execute (self , TS_ENCODING );
629638 int cpStart = adjustStartIndex (start , selfLen );
630639 int cpEnd = adjustEndIndex (end , selfLen );
631640
632641 for (Object element : getObjectArrayNode .execute (inliningTarget , subStrs )) {
633- try {
634- TruffleString subStr = castPrefixNode .execute (inliningTarget , element );
635- int subStrLen = codePointLengthNode .execute (subStr , TS_ENCODING );
636- if (doIt (self , subStr , cpStart , cpEnd , selfLen , subStrLen , regionEqualNode )) {
637- return true ;
638- }
639- } catch (CannotCastException e ) {
640- throw raiseNode .get (inliningTarget ).raise (TypeError , ErrorMessages .INVALID_ELEMENT_TYPE , getMethodName (), element );
642+ TruffleString subStr = castPrefixNode .cast (inliningTarget , element , ErrorMessages .INVALID_ELEMENT_TYPE , op .methodName (), element );
643+ int subStrLen = codePointLengthNode .execute (subStr , TS_ENCODING );
644+ if (doIt (self , subStr , cpStart , cpEnd , selfLen , subStrLen , regionEqualNode , op )) {
645+ return true ;
641646 }
642647 }
643648 return false ;
644649 }
645650
646- // the actual operation; will be overridden by subclasses
647- @ SuppressWarnings ("unused" )
648- boolean doIt (TruffleString text , TruffleString subStr , int start , int end , int textLen , int subStrLen , TruffleString .RegionEqualNode regionEqualNode ) {
649- CompilerAsserts .neverPartOfCompilation ();
650- throw new IllegalStateException ("should not reach" );
651- }
651+ private static boolean doIt (TruffleString text , TruffleString subStr , int start , int end , int textLen , int subStrLen , TruffleString .RegionEqualNode regionEqualNode , Op op ) {
652+ // start and end must be normalized indices for 'text'
653+ assert start >= 0 ;
654+ assert end >= 0 && end <= textLen ;
652655
653- @ SuppressWarnings ("unused" )
654- protected TruffleString getMethodName () {
655- CompilerAsserts .neverPartOfCompilation ();
656- throw new IllegalStateException ("should not reach" );
656+ if (end - start < subStrLen ) {
657+ return false ;
658+ }
659+ int fromIndex = op == Op .PREFIX ? start : end - subStrLen ;
660+ return regionEqualNode .execute (text , fromIndex , subStr , 0 , subStrLen , TS_ENCODING );
657661 }
658662 }
659663
@@ -662,33 +666,17 @@ protected TruffleString getMethodName() {
662666 @ ArgumentClinic (name = "start" , conversion = ArgumentClinic .ClinicConversion .SliceIndex , defaultValue = "0" , useDefaultForNone = true )
663667 @ ArgumentClinic (name = "end" , conversion = ArgumentClinic .ClinicConversion .SliceIndex , defaultValue = "Integer.MAX_VALUE" , useDefaultForNone = true )
664668 @ GenerateNodeFactory
665- public abstract static class StartsWithNode extends PrefixSuffixBaseNode {
669+ public abstract static class StartsWithNode extends PythonQuaternaryClinicBuiltinNode {
666670
667671 @ Override
668672 protected ArgumentClinicProvider getArgumentClinic () {
669673 return StringBuiltinsClinicProviders .StartsWithNodeClinicProviderGen .INSTANCE ;
670674 }
671675
672- @ Override
673- boolean doIt (TruffleString text , TruffleString prefix , int start , int end , int textLen , int prefixLen , TruffleString .RegionEqualNode regionEqualNode ) {
674- // start and end must be normalized indices for 'text'
675- assert start >= 0 ;
676- assert end >= 0 && end <= textLen ;
677-
678- if (end - start < prefixLen ) {
679- return false ;
680- }
681- return regionEqualNode .execute (text , start , prefix , 0 , prefixLen , TS_ENCODING );
682- }
683-
684- @ Override
685- protected TruffleString getMethodName () {
686- return T_STARTSWITH ;
687- }
688-
689- @ NeverDefault
690- public static StartsWithNode create () {
691- return StartsWithNodeFactory .create ();
676+ @ Specialization
677+ static boolean doStartsWith (Object self , Object prefix , int start , int end ,
678+ @ Cached PrefixSuffixNode prefixSuffixNode ) {
679+ return prefixSuffixNode .startsWith (self , prefix , start , end );
692680 }
693681 }
694682
@@ -697,33 +685,17 @@ public static StartsWithNode create() {
697685 @ ArgumentClinic (name = "start" , conversion = ArgumentClinic .ClinicConversion .SliceIndex , defaultValue = "0" , useDefaultForNone = true )
698686 @ ArgumentClinic (name = "end" , conversion = ArgumentClinic .ClinicConversion .SliceIndex , defaultValue = "Integer.MAX_VALUE" , useDefaultForNone = true )
699687 @ GenerateNodeFactory
700- public abstract static class EndsWithNode extends PrefixSuffixBaseNode {
688+ public abstract static class EndsWithNode extends PythonQuaternaryClinicBuiltinNode {
701689
702690 @ Override
703691 protected ArgumentClinicProvider getArgumentClinic () {
704692 return StringBuiltinsClinicProviders .EndsWithNodeClinicProviderGen .INSTANCE ;
705693 }
706694
707- @ Override
708- boolean doIt (TruffleString text , TruffleString suffix , int start , int end , int textLen , int suffixLen , TruffleString .RegionEqualNode regionEqualNode ) {
709- // start and end must be normalized indices for 'text'
710- assert start >= 0 ;
711- assert end >= 0 && end <= textLen ;
712-
713- if (end - start < suffixLen ) {
714- return false ;
715- }
716- return regionEqualNode .execute (text , end - suffixLen , suffix , 0 , suffixLen , TS_ENCODING );
717- }
718-
719- @ Override
720- protected TruffleString getMethodName () {
721- return T_ENDSWITH ;
722- }
723-
724- @ NeverDefault
725- public static EndsWithNode create () {
726- return EndsWithNodeFactory .create ();
695+ @ Specialization
696+ static boolean doEndsWith (Object self , Object prefix , int start , int end ,
697+ @ Cached PrefixSuffixNode prefixSuffixNode ) {
698+ return prefixSuffixNode .endsWith (self , prefix , start , end );
727699 }
728700 }
729701
@@ -1029,7 +1001,7 @@ static PDict doString(VirtualFrame frame, Object cls, Object from, Object to, Ob
10291001 }
10301002
10311003 @ Specialization (guards = {"isNoValue(to)" , "isNoValue(z)" })
1032- @ SuppressWarnings ({ "unused" , "truffle-static-method" } )
1004+ @ SuppressWarnings ("unused" )
10331005 static PDict doDict (VirtualFrame frame , Object cls , PDict from , Object to , Object z ,
10341006 @ Bind ("this" ) Node inliningTarget ,
10351007 @ Cached HashingCollectionNodes .GetHashingStorageNode getHashingStorageNode ,
@@ -2694,12 +2666,12 @@ protected ArgumentClinicProvider getArgumentClinic() {
26942666 }
26952667
26962668 @ Specialization
2697- TruffleString remove (VirtualFrame frame , TruffleString self , TruffleString prefix ,
2698- @ Cached StartsWithNode startsWith ,
2669+ static TruffleString remove (TruffleString self , TruffleString prefix ,
2670+ @ Cached PrefixSuffixNode prefixSuffixNode ,
26992671 @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
27002672 @ Cached TruffleString .SubstringNode substringNode ) {
27012673 int prefixLen = codePointLengthNode .execute (prefix , TS_ENCODING );
2702- if (startsWith . executeBoolean ( frame , self , prefix , 0 , prefixLen )) {
2674+ if (prefixSuffixNode . startsWith ( self , prefix , 0 , prefixLen )) {
27032675 int selfLen = codePointLengthNode .execute (self , TS_ENCODING );
27042676 return substringNode .execute (self , prefixLen , selfLen - prefixLen , TS_ENCODING , false );
27052677 }
@@ -2719,14 +2691,14 @@ protected ArgumentClinicProvider getArgumentClinic() {
27192691 }
27202692
27212693 @ Specialization
2722- TruffleString remove (VirtualFrame frame , TruffleString self , TruffleString suffix ,
2694+ static TruffleString remove (TruffleString self , TruffleString suffix ,
27232695 @ Bind ("this" ) Node inliningTarget ,
2724- @ Cached EndsWithNode endsWith ,
2696+ @ Cached PrefixSuffixNode prefixSuffixNode ,
27252697 @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
27262698 @ Cached TruffleString .SubstringNode substringNode ,
27272699 @ Cached InlinedConditionProfile profile ) {
27282700 int selfLen = codePointLengthNode .execute (self , TS_ENCODING );
2729- if (profile .profile (inliningTarget , endsWith . executeBoolean ( frame , self , suffix , 0 , selfLen ))) {
2701+ if (profile .profile (inliningTarget , prefixSuffixNode . endsWith ( self , suffix , 0 , selfLen ))) {
27302702 int suffixLen = codePointLengthNode .execute (suffix , TS_ENCODING );
27312703 return substringNode .execute (self , 0 , selfLen - suffixLen , TS_ENCODING , false );
27322704 }
0 commit comments