80
80
import org .truffleruby .interop .ToJavaStringNode ;
81
81
import org .truffleruby .interop .TranslateInteropExceptionNode ;
82
82
import org .truffleruby .core .string .ImmutableRubyString ;
83
- import org .truffleruby .language .LazyWarnNode ;
83
+ import org .truffleruby .language .LazyWarningNode ;
84
84
import org .truffleruby .language .LexicalScope ;
85
85
import org .truffleruby .language .Nil ;
86
86
import org .truffleruby .language .RubyBaseNode ;
87
87
import org .truffleruby .language .RubyDynamicObject ;
88
88
import org .truffleruby .language .RubyGuards ;
89
89
import org .truffleruby .language .RubyRootNode ;
90
- import org .truffleruby .language .WarnNode ;
90
+ import org .truffleruby .language .WarningNode ;
91
91
import org .truffleruby .language .arguments .ArgumentsDescriptor ;
92
92
import org .truffleruby .language .arguments .EmptyArgumentsDescriptor ;
93
93
import org .truffleruby .language .arguments .KeywordArgumentsDescriptor ;
@@ -1046,55 +1046,47 @@ Object rbConstSet(RubyModule module, Object name, Object value,
1046
1046
@ Primitive (name = "rb_gv_get" )
1047
1047
@ ReportPolymorphism
1048
1048
public abstract static class RbGvGetNode extends PrimitiveArrayArgumentsNode {
1049
-
1050
- @ Specialization (guards = "name == cachedName" , limit = "getCacheLimit()" )
1051
- static Object rbGvGetCached (VirtualFrame frame , String name ,
1052
- @ Cached ("name" ) String cachedName ,
1053
- @ Cached ("create(cachedName)" ) ReadGlobalVariableNode readGlobalVariableNode ,
1049
+ @ Specialization
1050
+ Object rbGvGet (VirtualFrame frame , String name ,
1054
1051
@ Cached InlinedBranchProfile notExistsProfile ,
1055
- @ Cached @ Shared LazyWarnNode lazyWarnNode ,
1056
- @ Bind ( "this" ) Node node ) {
1057
- boolean exists = getContext (node ).getCoreLibrary ().globalVariables .contains (cachedName );
1052
+ @ Cached LazyWarningNode lazyWarningNode ,
1053
+ @ Cached RbGvGetInnerNode rbGvGetInnerNode ) {
1054
+ boolean exists = getContext ().getCoreLibrary ().globalVariables .contains (name );
1058
1055
1056
+ // Check if it exists and return if not, before creating the GlobalVariableStorage
1059
1057
if (!exists ) {
1060
- notExistsProfile .enter (node );
1061
- warn (node , lazyWarnNode .get (node ),
1062
- StringUtils .format ("global variable `%s' not initialized" , cachedName ));
1063
-
1058
+ notExistsProfile .enter (this );
1059
+ WarningNode warningNode = lazyWarningNode .get (this );
1060
+ if (warningNode .shouldWarn ()) {
1061
+ warningNode .warningMessage (getContext (this ).getCallStack ().getTopMostUserSourceSection (),
1062
+ StringUtils .format ("global variable `%s' not initialized" , name ));
1063
+ }
1064
1064
return nil ;
1065
1065
}
1066
1066
1067
- return readGlobalVariableNode .execute (frame );
1067
+ return rbGvGetInnerNode .execute (frame , this , name );
1068
1068
}
1069
+ }
1069
1070
1070
- @ TruffleBoundary
1071
- @ Specialization
1072
- Object rbGvGetUncached (String name ,
1073
- @ Cached DispatchNode dispatchNode ,
1074
- @ Cached @ Shared LazyWarnNode lazyWarnNode ) {
1075
- boolean exists = getContext ().getCoreLibrary ().globalVariables .contains (name );
1076
-
1077
- if (!exists ) {
1078
- warn (this , lazyWarnNode .get (this ), StringUtils .format ("global variable `%s' not initialized" , name ));
1079
1071
1080
- return nil ;
1081
- }
1072
+ @ GenerateInline
1073
+ @ GenerateCached (false )
1074
+ public abstract static class RbGvGetInnerNode extends RubyBaseNode {
1082
1075
1083
- return dispatchNode .call (coreLibrary ().topLevelBinding , "eval" , name );
1084
- }
1076
+ public abstract Object execute (VirtualFrame frame , Node node , String name );
1085
1077
1086
- private static void warn (Node node , WarnNode warnNode , String message ) {
1087
- if (warnNode .shouldWarn ()) {
1088
- warnNode .warningMessage (
1089
- getContext (node ).getCallStack ().getTopMostUserSourceSection (),
1090
- message );
1091
- }
1078
+ @ Specialization (guards = "name == cachedName" , limit = "getDefaultCacheLimit()" )
1079
+ static Object rbGvGetCached (VirtualFrame frame , Node node , String name ,
1080
+ @ Cached ("name" ) String cachedName ,
1081
+ @ Cached (value = "create(cachedName)" , inline = false ) ReadGlobalVariableNode readGlobalVariableNode ) {
1082
+ return readGlobalVariableNode .execute (frame );
1092
1083
}
1093
1084
1094
- protected int getCacheLimit () {
1095
- return getLanguage ().options .DEFAULT_CACHE ;
1085
+ @ Specialization
1086
+ static Object rbGvGetUncached (Node node , String name ,
1087
+ @ Cached (inline = false ) DispatchNode dispatchNode ) {
1088
+ return dispatchNode .call (coreLibrary (node ).topLevelBinding , "eval" , name );
1096
1089
}
1097
-
1098
1090
}
1099
1091
1100
1092
@ CoreMethod (names = "cext_module_function" , onSingleton = true , required = 2 )
@@ -1988,60 +1980,28 @@ protected RubyArray compileArgTypes(AbstractTruffleString format, RubyEncoding e
1988
1980
@ ReportPolymorphism
1989
1981
public abstract static class RBSprintfNode extends CoreMethodArrayArgumentsNode {
1990
1982
1991
- @ Specialization (
1992
- guards = {
1993
- "libFormat.isRubyString(format)" ,
1994
- "equalNode.execute(node, libFormat, format, cachedFormat, cachedEncoding)" },
1995
- limit = "2" )
1996
- static RubyString formatCached (Object format , Object stringReader , RubyArray argArray ,
1997
- @ Cached @ Shared ArrayToObjectArrayNode arrayToObjectArrayNode ,
1998
- @ Cached @ Shared RubyStringLibrary libFormat ,
1999
- @ Cached @ Shared InlinedBranchProfile exceptionProfile ,
2000
- @ Cached @ Shared InlinedConditionProfile resizeProfile ,
2001
- @ Cached @ Shared TruffleString .FromByteArrayNode fromByteArrayNode ,
2002
- @ Cached ("asTruffleStringUncached(format)" ) TruffleString cachedFormat ,
2003
- @ Cached ("libFormat.getEncoding(format)" ) RubyEncoding cachedEncoding ,
2004
- @ Cached ("cachedFormat.byteLength(cachedEncoding.tencoding)" ) int cachedFormatLength ,
2005
- @ Cached ("create(compileFormat(cachedFormat, cachedEncoding, stringReader))" ) DirectCallNode formatNode ,
2006
- @ Cached StringHelperNodes .EqualSameEncodingNode equalNode ,
1983
+ @ Specialization (guards = "libFormat.isRubyString(format)" , limit = "1" )
1984
+ static RubyString format (Object format , Object stringReader , RubyArray argArray ,
1985
+ @ Cached ArrayToObjectArrayNode arrayToObjectArrayNode ,
1986
+ @ Cached RubyStringLibrary libFormat ,
1987
+ @ Cached TruffleString .FromByteArrayNode fromByteArrayNode ,
1988
+ @ Cached RBSprintfInnerNode rbSprintfInnerNode ,
1989
+ @ Cached InlinedBranchProfile exceptionProfile ,
1990
+ @ Cached InlinedConditionProfile resizeProfile ,
2007
1991
@ Bind ("this" ) Node node ) {
2008
- final BytesResult result ;
2009
- final Object [] arguments = arrayToObjectArrayNode .executeToObjectArray (argArray );
2010
- try {
2011
- result = (BytesResult ) formatNode .call (new Object []{ arguments , arguments .length , null });
2012
- } catch (FormatException e ) {
2013
- exceptionProfile .enter (node );
2014
- throw FormatExceptionTranslator .translate (getContext (node ), node , e );
2015
- }
2016
-
2017
- return finishFormat (node , cachedFormatLength , result , resizeProfile , fromByteArrayNode );
2018
- }
2019
-
2020
- @ Specialization (guards = "libFormat.isRubyString(format)" , replaces = "formatCached" )
2021
- RubyString formatUncached (Object format , Object stringReader , RubyArray argArray ,
2022
- @ Cached IndirectCallNode formatNode ,
2023
- @ Cached @ Shared InlinedBranchProfile exceptionProfile ,
2024
- @ Cached @ Shared InlinedConditionProfile resizeProfile ,
2025
- @ Cached @ Shared TruffleString .FromByteArrayNode fromByteArrayNode ,
2026
- @ Cached @ Shared ArrayToObjectArrayNode arrayToObjectArrayNode ,
2027
- @ Cached @ Shared RubyStringLibrary libFormat ) {
2028
1992
var tstring = libFormat .getTString (format );
2029
1993
var encoding = libFormat .getEncoding (format );
2030
1994
final Object [] arguments = arrayToObjectArrayNode .executeToObjectArray (argArray );
1995
+
2031
1996
final BytesResult result ;
2032
1997
try {
2033
- result = (BytesResult ) formatNode .call (compileFormat (tstring , encoding , stringReader ),
2034
- new Object []{ arguments , arguments .length , null });
1998
+ result = rbSprintfInnerNode .execute (node , tstring , encoding , stringReader , arguments );
2035
1999
} catch (FormatException e ) {
2036
- exceptionProfile .enter (this );
2037
- throw FormatExceptionTranslator .translate (getContext (), this , e );
2000
+ exceptionProfile .enter (node );
2001
+ throw FormatExceptionTranslator .translate (getContext (node ), node , e );
2038
2002
}
2039
2003
2040
- return finishFormat (this , tstring .byteLength (encoding .tencoding ), result , resizeProfile , fromByteArrayNode );
2041
- }
2042
-
2043
- private static RubyString finishFormat (Node node , int formatLength , BytesResult result ,
2044
- InlinedConditionProfile resizeProfile , TruffleString .FromByteArrayNode fromByteArrayNode ) {
2004
+ int formatLength = tstring .byteLength (encoding .tencoding );
2045
2005
byte [] bytes = result .getOutput ();
2046
2006
2047
2007
if (resizeProfile .profile (node , bytes .length != result .getOutputLength ())) {
@@ -2052,14 +2012,43 @@ private static RubyString finishFormat(Node node, int formatLength, BytesResult
2052
2012
result .getEncoding ().getEncodingForLength (formatLength ));
2053
2013
}
2054
2014
2015
+ }
2016
+
2017
+ @ GenerateInline
2018
+ @ GenerateCached (false )
2019
+ public abstract static class RBSprintfInnerNode extends RubyBaseNode {
2020
+
2021
+ public abstract BytesResult execute (Node node , AbstractTruffleString format , RubyEncoding encoding ,
2022
+ Object stringReader , Object [] arguments );
2023
+
2024
+ @ Specialization (
2025
+ guards = "equalNode.execute(node, format, encoding, cachedFormat, cachedEncoding)" ,
2026
+ limit = "2" )
2027
+ static BytesResult formatCached (
2028
+ Node node , AbstractTruffleString format , RubyEncoding encoding , Object stringReader , Object [] arguments ,
2029
+ @ Cached ("format.asTruffleStringUncached(encoding.tencoding)" ) TruffleString cachedFormat ,
2030
+ @ Cached ("encoding" ) RubyEncoding cachedEncoding ,
2031
+ @ Cached (value = "create(compileFormat(cachedFormat, cachedEncoding, stringReader, node))" ,
2032
+ inline = false ) DirectCallNode formatNode ,
2033
+ @ Cached StringHelperNodes .EqualSameEncodingNode equalNode ) {
2034
+ return (BytesResult ) formatNode .call (new Object []{ arguments , arguments .length , null });
2035
+ }
2036
+
2037
+ @ Specialization (replaces = "formatCached" )
2038
+ static BytesResult formatUncached (
2039
+ Node node , AbstractTruffleString format , RubyEncoding encoding , Object stringReader , Object [] arguments ,
2040
+ @ Cached (inline = false ) IndirectCallNode formatNode ) {
2041
+ return (BytesResult ) formatNode .call (compileFormat (format , encoding , stringReader , node ),
2042
+ new Object []{ arguments , arguments .length , null });
2043
+ }
2044
+
2055
2045
@ TruffleBoundary
2056
- protected RootCallTarget compileFormat (AbstractTruffleString format , RubyEncoding encoding ,
2057
- Object stringReader ) {
2046
+ protected static RootCallTarget compileFormat (AbstractTruffleString format , RubyEncoding encoding ,
2047
+ Object stringReader , Node node ) {
2058
2048
try {
2059
- return new RBSprintfCompiler (getLanguage (), this )
2060
- .compile (format , encoding , stringReader );
2049
+ return new RBSprintfCompiler (getLanguage (node ), node ).compile (format , encoding , stringReader );
2061
2050
} catch (InvalidFormatException e ) {
2062
- throw new RaiseException (getContext (), coreExceptions ().argumentError (e .getMessage (), this ));
2051
+ throw new RaiseException (getContext (node ), coreExceptions (node ).argumentError (e .getMessage (), node ));
2063
2052
}
2064
2053
}
2065
2054
}
0 commit comments