18
18
import com .oracle .truffle .api .nodes .ExplodeLoop ;
19
19
import com .oracle .truffle .api .profiles .BranchProfile ;
20
20
import com .oracle .truffle .api .profiles .ConditionProfile ;
21
+
21
22
import org .truffleruby .SuppressFBWarnings ;
22
23
import org .truffleruby .builtins .CoreMethod ;
23
24
import org .truffleruby .builtins .CoreMethodArrayArgumentsNode ;
34
35
import org .truffleruby .core .string .RubyString ;
35
36
import org .truffleruby .core .string .StringNodes ;
36
37
import org .truffleruby .core .string .StringUtils ;
38
+ import org .truffleruby .core .thread .RubyThread ;
37
39
import org .truffleruby .language .NotProvided ;
38
40
import org .truffleruby .language .RubyDynamicObject ;
39
41
import org .truffleruby .language .Visibility ;
@@ -840,20 +842,6 @@ public abstract static class ToSNode extends CoreMethodArrayArgumentsNode {
840
842
* still not entirely correct. JRuby seems to be correct, but their logic is tied up in their printf
841
843
* implementation. Also see our FormatFloatNode, which I suspect is also deficient or under-tested. */
842
844
843
- private static final DecimalFormat DF_NO_EXP ;
844
- private static final DecimalFormat DF_SMALL_EXP ;
845
- private static final DecimalFormat DF_LARGE_EXP ;
846
-
847
- static {
848
- final DecimalFormatSymbols smallExpSymbols = new DecimalFormatSymbols (Locale .ENGLISH );
849
- smallExpSymbols .setExponentSeparator ("e" );
850
- final DecimalFormatSymbols largeExpSymbols = new DecimalFormatSymbols (Locale .ENGLISH );
851
- largeExpSymbols .setExponentSeparator ("e+" );
852
- DF_NO_EXP = new DecimalFormat ("0.0################" );
853
- DF_SMALL_EXP = new DecimalFormat ("0.0################E00" , smallExpSymbols );
854
- DF_LARGE_EXP = new DecimalFormat ("0.0################E00" , largeExpSymbols );
855
- }
856
-
857
845
@ Specialization (guards = "value == POSITIVE_INFINITY" )
858
846
protected RubyString toSPositiveInfinity (double value ,
859
847
@ Cached ("specialValueRope(POSITIVE_INFINITY)" ) Rope cachedRope ) {
@@ -874,32 +862,35 @@ protected RubyString toSNaN(double value,
874
862
875
863
@ Specialization (guards = "hasNoExp(value)" )
876
864
protected RubyString toSNoExp (double value ) {
877
- return makeStringNode .executeMake (makeRopeNoExp (value ), Encodings .US_ASCII , CodeRange .CR_7BIT );
865
+ return makeStringNode .executeMake (makeRopeNoExp (value , getLanguage ().getCurrentThread ()),
866
+ Encodings .US_ASCII , CodeRange .CR_7BIT );
878
867
}
879
868
880
869
@ Specialization (guards = "hasLargeExp(value)" )
881
870
protected RubyString toSLargeExp (double value ) {
882
- return makeStringNode .executeMake (makeRopeLargeExp (value ), Encodings .US_ASCII , CodeRange .CR_7BIT );
871
+ return makeStringNode .executeMake (makeRopeLargeExp (value , getLanguage ().getCurrentThread ()),
872
+ Encodings .US_ASCII , CodeRange .CR_7BIT );
883
873
}
884
874
885
875
@ Specialization (guards = "hasSmallExp(value)" )
886
876
protected RubyString toSSmallExp (double value ) {
887
- return makeStringNode .executeMake (makeRopeSmallExp (value ), Encodings .US_ASCII , CodeRange .CR_7BIT );
877
+ return makeStringNode .executeMake (makeRopeSmallExp (value , getLanguage ().getCurrentThread ()),
878
+ Encodings .US_ASCII , CodeRange .CR_7BIT );
888
879
}
889
880
890
881
@ TruffleBoundary
891
- private String makeRopeNoExp (double value ) {
892
- return DF_NO_EXP .format (value );
882
+ private String makeRopeNoExp (double value , RubyThread thread ) {
883
+ return getNoExpFormat ( thread ) .format (value );
893
884
}
894
885
895
886
@ TruffleBoundary
896
- private String makeRopeSmallExp (double value ) {
897
- return DF_SMALL_EXP .format (value );
887
+ private String makeRopeSmallExp (double value , RubyThread thread ) {
888
+ return getSmallExpFormat ( thread ) .format (value );
898
889
}
899
890
900
891
@ TruffleBoundary
901
- private String makeRopeLargeExp (double value ) {
902
- return DF_LARGE_EXP .format (value );
892
+ private String makeRopeLargeExp (double value , RubyThread thread ) {
893
+ return getLargeExpFormat ( thread ) .format (value );
903
894
}
904
895
905
896
protected static boolean hasNoExp (double value ) {
@@ -920,6 +911,33 @@ protected static boolean hasSmallExp(double value) {
920
911
protected static Rope specialValueRope (double value ) {
921
912
return RopeOperations .encodeAscii (Double .toString (value ), Encodings .US_ASCII .jcoding );
922
913
}
914
+
915
+ private DecimalFormat getNoExpFormat (RubyThread thread ) {
916
+ if (thread .noExpFormat == null ) {
917
+ final DecimalFormatSymbols noExpSymbols = new DecimalFormatSymbols (Locale .ENGLISH );
918
+ thread .noExpFormat = new DecimalFormat ("0.0################" , noExpSymbols );
919
+ }
920
+ return thread .noExpFormat ;
921
+ }
922
+
923
+ private DecimalFormat getSmallExpFormat (RubyThread thread ) {
924
+ if (thread .smallExpFormat == null ) {
925
+ final DecimalFormatSymbols smallExpSymbols = new DecimalFormatSymbols (Locale .ENGLISH );
926
+ smallExpSymbols .setExponentSeparator ("e" );
927
+ thread .smallExpFormat = new DecimalFormat ("0.0################E00" , smallExpSymbols );
928
+ }
929
+ return thread .smallExpFormat ;
930
+ }
931
+
932
+ private DecimalFormat getLargeExpFormat (RubyThread thread ) {
933
+ if (thread .largeExpFormat == null ) {
934
+ final DecimalFormatSymbols largeExpSymbols = new DecimalFormatSymbols (Locale .ENGLISH );
935
+ largeExpSymbols .setExponentSeparator ("e+" );
936
+ thread .largeExpFormat = new DecimalFormat ("0.0################E00" , largeExpSymbols );
937
+ }
938
+ return thread .largeExpFormat ;
939
+ }
940
+
923
941
}
924
942
925
943
@ NonStandard
0 commit comments