Skip to content

Commit 89c1650

Browse files
committed
Make EXECUTION_ACTION, DEFAULT_EXECUTION_ACTION and TO_EXECUTE launcher-only options
* Move most of the logic to RubyLauncher, leaving only loading the main script to Truffle::Boot.main.
1 parent b1ca565 commit 89c1650

File tree

11 files changed

+70
-143
lines changed

11 files changed

+70
-143
lines changed

src/launcher/java/org/truffleruby/launcher/CommandLineOptions.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ public class CommandLineOptions {
4343
boolean showVersion = false;
4444
boolean showCopyright = false;
4545
ShowHelp showHelp = ShowHelp.NONE;
46+
/** What should be done after context is created */
47+
ExecutionAction executionAction = ExecutionAction.NONE;
48+
/** What should be done when no action is set */
49+
DefaultExecutionAction defaultExecutionAction = DefaultExecutionAction.IRB;
50+
/** A thing to be executed: a file, inline script, etc. Used by executionAction when applicable. */
51+
String toExecute = "";
4652

4753
private Map<String, String> options;
4854
private String[] arguments;

src/launcher/java/org/truffleruby/launcher/CommandLineParser.java

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
package org.truffleruby.launcher;
3636

3737
import org.graalvm.options.OptionDescriptor;
38-
import org.truffleruby.shared.options.DefaultExecutionAction;
39-
import org.truffleruby.shared.options.ExecutionAction;
4038
import org.truffleruby.shared.options.OptionsCatalog;
4139
import org.truffleruby.shared.options.Verbosity;
4240

@@ -90,11 +88,11 @@ public void processArguments() throws CommandLineException {
9088
}
9189
assert lastInterpreterArgumentIndex >= 0;
9290

93-
if (config.getOption(OptionsCatalog.EXECUTION_ACTION) == ExecutionAction.UNSET) {
91+
if (config.executionAction == ExecutionAction.UNSET) {
9492
if (argumentIndex < arguments.size()) {
95-
config.setOption(OptionsCatalog.EXECUTION_ACTION, ExecutionAction.FILE);
93+
config.executionAction = ExecutionAction.FILE;
9694
//consume the file name
97-
config.setOption(OptionsCatalog.TO_EXECUTE, getCurrentArgument());
95+
config.toExecute = getCurrentArgument();
9896
argumentIndex++;
9997
}
10098
}
@@ -163,8 +161,8 @@ private void processArgument() throws CommandLineException {
163161
// sole "-" means read from stdin and pass remaining args as ARGV
164162
lastInterpreterArgumentIndex = argumentIndex;
165163

166-
if (config.getOption(OptionsCatalog.EXECUTION_ACTION) == ExecutionAction.UNSET) {
167-
config.setOption(OptionsCatalog.EXECUTION_ACTION, ExecutionAction.STDIN);
164+
if (config.executionAction == ExecutionAction.UNSET) {
165+
config.executionAction = ExecutionAction.STDIN;
168166
} else {
169167
// if other action is set then ignore '-', just threat it as a first script argument,
170168
// and stop option parsing
@@ -218,10 +216,10 @@ private void processArgument() throws CommandLineException {
218216
disallowedInRubyOpts(argument);
219217
final String nextArgument = grabValue(getArgumentError(" -e must be followed by an expression to report"));
220218

221-
final ExecutionAction currentExecutionAction = config.getOption(OptionsCatalog.EXECUTION_ACTION);
219+
final ExecutionAction currentExecutionAction = config.executionAction;
222220
if (currentExecutionAction == ExecutionAction.UNSET || currentExecutionAction == ExecutionAction.INLINE) {
223-
config.setOption(OptionsCatalog.EXECUTION_ACTION, ExecutionAction.INLINE);
224-
config.appendOptionValue(OptionsCatalog.TO_EXECUTE, nextArgument + "\n");
221+
config.executionAction = ExecutionAction.INLINE;
222+
config.toExecute += nextArgument + "\n";
225223
} else {
226224
// ignore option
227225
}
@@ -237,7 +235,7 @@ private void processArgument() throws CommandLineException {
237235
disallowedInRubyOpts(argument);
238236
config.showHelp = ShowHelp.SHORT;
239237
// cancel other execution actions
240-
config.setOption(OptionsCatalog.EXECUTION_ACTION, ExecutionAction.NONE);
238+
config.executionAction = ExecutionAction.NONE;
241239
break;
242240
case 'i':
243241
disallowedInRubyOpts(argument);
@@ -319,9 +317,9 @@ private void processArgument() throws CommandLineException {
319317

320318
String scriptName = grabValue("provide a bin script to execute");
321319

322-
if (config.getOption(OptionsCatalog.EXECUTION_ACTION) == ExecutionAction.UNSET) {
323-
config.setOption(OptionsCatalog.EXECUTION_ACTION, ExecutionAction.PATH);
324-
config.setOption(OptionsCatalog.TO_EXECUTE, scriptName);
320+
if (config.executionAction == ExecutionAction.UNSET) {
321+
config.executionAction = ExecutionAction.PATH;
322+
config.toExecute = scriptName;
325323
} else {
326324
// ignore the option
327325
}
@@ -335,7 +333,7 @@ private void processArgument() throws CommandLineException {
335333
case 'v':
336334
config.setOption(OptionsCatalog.VERBOSITY, Verbosity.TRUE);
337335
config.showVersion = true;
338-
config.setOption(OptionsCatalog.DEFAULT_EXECUTION_ACTION, DefaultExecutionAction.NONE);
336+
config.defaultExecutionAction = DefaultExecutionAction.NONE;
339337
break;
340338
case 'w':
341339
config.setOption(OptionsCatalog.VERBOSITY, Verbosity.TRUE);
@@ -375,7 +373,7 @@ private void processArgument() throws CommandLineException {
375373
disallowedInRubyOpts(argument);
376374
config.showCopyright = true;
377375
// cancel other execution actions
378-
config.setOption(OptionsCatalog.EXECUTION_ACTION, ExecutionAction.NONE);
376+
config.executionAction = ExecutionAction.NONE;
379377
break FOR;
380378
} else if (argument.startsWith("--encoding")) {
381379
if (argument.equals("--encoding")) {
@@ -413,7 +411,7 @@ private void processArgument() throws CommandLineException {
413411
disallowedInRubyOpts(argument);
414412
config.showVersion = true;
415413
// cancel other execution actions
416-
config.setOption(OptionsCatalog.EXECUTION_ACTION, ExecutionAction.NONE);
414+
config.executionAction = ExecutionAction.NONE;
417415
break FOR;
418416
} else if (argument.equals("--debug-frozen-string-literal")) {
419417
warnInternalDebugTool(argument);

src/shared/java/org/truffleruby/shared/options/DefaultExecutionAction.java renamed to src/launcher/java/org/truffleruby/launcher/DefaultExecutionAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* GNU General Public License version 2, or
88
* GNU Lesser General Public License version 2.1.
99
*/
10-
package org.truffleruby.shared.options;
10+
package org.truffleruby.launcher;
1111

1212
public enum DefaultExecutionAction {
1313
NONE,

src/shared/java/org/truffleruby/shared/options/ExecutionAction.java renamed to src/launcher/java/org/truffleruby/launcher/ExecutionAction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* GNU General Public License version 2, or
88
* GNU Lesser General Public License version 2.1.
99
*/
10-
package org.truffleruby.shared.options;
10+
package org.truffleruby.launcher;
1111

1212
public enum ExecutionAction {
1313
UNSET,

src/launcher/java/org/truffleruby/launcher/RubyLauncher.java

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,10 @@
1616
import org.graalvm.polyglot.Engine;
1717
import org.graalvm.polyglot.PolyglotException;
1818
import org.graalvm.polyglot.Source;
19-
import org.truffleruby.shared.options.DefaultExecutionAction;
20-
import org.truffleruby.shared.options.ExecutionAction;
2119
import org.truffleruby.shared.options.OptionsCatalog;
2220
import org.truffleruby.shared.TruffleRuby;
2321
import org.truffleruby.shared.Metrics;
2422

25-
import java.io.IOException;
2623
import java.io.PrintStream;
2724
import java.lang.reflect.Method;
2825
import java.util.ArrayList;
@@ -66,7 +63,7 @@ protected List<String> preprocessArguments(List<String> args, Map<String, String
6663
config = new CommandLineOptions(polyglotOptions);
6764

6865
try {
69-
config.setOption(OptionsCatalog.EXECUTION_ACTION, ExecutionAction.UNSET);
66+
config.executionAction = ExecutionAction.UNSET;
7067

7168
final CommandLineParser argumentCommandLineParser = new CommandLineParser(args, config, true, false);
7269
argumentCommandLineParser.processArguments();
@@ -185,28 +182,48 @@ protected AbortException abortUnrecognizedArgument(String argument) {
185182
}
186183

187184
private int runRubyMain(Context.Builder contextBuilder, CommandLineOptions config) {
188-
if (config.getOption(OptionsCatalog.EXECUTION_ACTION) == ExecutionAction.NONE) {
189-
return 0;
185+
if (config.executionAction == ExecutionAction.UNSET) {
186+
switch (config.defaultExecutionAction) {
187+
case NONE:
188+
return 0;
189+
case STDIN:
190+
config.executionAction = ExecutionAction.STDIN;
191+
break;
192+
case IRB:
193+
config.executionAction = ExecutionAction.PATH;
194+
if (System.console() != null) {
195+
System.err.println("[ruby] WARNING: truffleruby starts IRB when stdin is a TTY instead of reading from stdin, use '-' to read from stdin");
196+
config.executionAction = ExecutionAction.PATH;
197+
config.toExecute = "irb";
198+
} else {
199+
config.executionAction = ExecutionAction.STDIN;
200+
}
201+
break;
202+
}
190203
}
191204

192-
if (config.getOption(OptionsCatalog.EXECUTION_ACTION) == ExecutionAction.UNSET &&
193-
config.getOption(OptionsCatalog.DEFAULT_EXECUTION_ACTION) == DefaultExecutionAction.NONE) {
205+
if (config.executionAction == ExecutionAction.NONE) {
194206
return 0;
195207
}
196208

197209
try (Context context = createContext(contextBuilder, config)) {
198210
Metrics.printTime("before-run");
199-
final Source source;
200-
try {
201-
source = Source.newBuilder(
202-
TruffleRuby.LANGUAGE_ID,
211+
212+
if (config.executionAction == ExecutionAction.PATH) {
213+
String path = context.eval(TruffleRuby.LANGUAGE_ID,
203214
// language=ruby
204-
"Truffle::Boot.main",
205-
TruffleRuby.BOOT_SOURCE_NAME).internal(true).build();
206-
} catch (IOException e) {
207-
throw new RuntimeException(e);
215+
"-> name { Truffle::Boot.find_s_file(name) }").execute(config.toExecute).asString();
216+
config.executionAction = ExecutionAction.FILE;
217+
config.toExecute = path;
208218
}
209-
final int exitCode = context.eval(source).asInt();
219+
220+
final Source source = Source.newBuilder(TruffleRuby.LANGUAGE_ID,
221+
// language=ruby
222+
"-> kind, to_execute { Truffle::Boot.main(kind, to_execute) }",
223+
TruffleRuby.BOOT_SOURCE_NAME).internal(true).buildLiteral();
224+
225+
final String kind = config.executionAction.name();
226+
final int exitCode = context.eval(source).execute(kind, config.toExecute).asInt();
210227
Metrics.printTime("after-run");
211228
return exitCode;
212229
} catch (PolyglotException e) {

src/main/java/org/truffleruby/language/TruffleBootNodes.java

Lines changed: 11 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import org.jcodings.specific.USASCIIEncoding;
2222
import org.jcodings.specific.UTF8Encoding;
2323
import org.truffleruby.Layouts;
24-
import org.truffleruby.RubyLanguage;
2524
import org.truffleruby.builtins.CoreClass;
2625
import org.truffleruby.builtins.CoreMethod;
2726
import org.truffleruby.builtins.CoreMethodArrayArgumentsNode;
@@ -38,7 +37,6 @@
3837
import org.truffleruby.parser.ParserContext;
3938
import org.truffleruby.parser.RubySource;
4039
import org.truffleruby.shared.Metrics;
41-
import org.truffleruby.shared.options.ExecutionAction;
4240
import org.truffleruby.shared.options.OptionsCatalog;
4341

4442
import java.io.IOException;
@@ -90,12 +88,12 @@ protected boolean wasPreinitializedContext() {
9088
}
9189
}
9290

93-
@CoreMethod(names = "main", onSingleton = true)
91+
@CoreMethod(names = "main", onSingleton = true, required = 2)
9492
public abstract static class MainNode extends CoreMethodArrayArgumentsNode {
9593

9694
@TruffleBoundary
9795
@Specialization
98-
public int main(
96+
public int main(DynamicObject kind, DynamicObject toExecute,
9997
@Cached("create()") IndirectCallNode callNode,
10098
@Cached("createPrivate()") CallDispatchHeadNode findSFile,
10199
@Cached("createPrivate()") CallDispatchHeadNode checkSyntax,
@@ -108,18 +106,13 @@ public int main(
108106
try {
109107
source = loadMainSourceSettingDollarZero(
110108
findSFile, makeStringNode,
111-
getContext().getOptions().EXECUTION_ACTION,
112-
getContext().getOptions().TO_EXECUTE.intern());
109+
StringOperations.getString(kind),
110+
StringOperations.getString(toExecute).intern());
113111
} catch (RaiseException e) {
114112
getContext().getDefaultBacktraceFormatter().printRubyExceptionMessageOnEnvStderr(e.getException());
115113
return 1;
116114
}
117115

118-
if (source == null) {
119-
// EXECUTION_ACTION was set to NONE
120-
return 0;
121-
}
122-
123116
if (getContext().getOptions().SYNTAX_CHECK) {
124117
try {
125118
return (int) checkSyntax.call(
@@ -177,61 +170,26 @@ private void setArgvGlobals(StringNodes.MakeStringNode makeStringNode) {
177170
}
178171
}
179172

180-
private RubySource loadMainSourceSettingDollarZero(CallDispatchHeadNode findSFile, StringNodes.MakeStringNode makeStringNode, ExecutionAction executionAction, String toExecute) {
173+
private RubySource loadMainSourceSettingDollarZero(CallDispatchHeadNode findSFile, StringNodes.MakeStringNode makeStringNode, String kind, String toExecute) {
181174
final RubySource source;
182175
final Object dollarZeroValue;
183176
try {
184-
switch (executionAction) {
185-
case UNSET: {
186-
switch (getContext().getOptions().DEFAULT_EXECUTION_ACTION) {
187-
case NONE:
188-
return loadMainSourceSettingDollarZero(findSFile, makeStringNode, ExecutionAction.NONE, toExecute);
189-
case STDIN:
190-
return loadMainSourceSettingDollarZero(findSFile, makeStringNode, ExecutionAction.STDIN, toExecute);
191-
case IRB:
192-
if (System.console() != null) {
193-
RubyLanguage.LOGGER.warning(
194-
"truffleruby starts IRB when stdin is a TTY instead of reading from stdin, use '-' to read from stdin");
195-
return loadMainSourceSettingDollarZero(findSFile, makeStringNode, ExecutionAction.PATH, "irb");
196-
} else {
197-
return loadMainSourceSettingDollarZero(findSFile, makeStringNode, ExecutionAction.STDIN, toExecute);
198-
}
199-
default:
200-
throw new UnsupportedOperationException("unreachable");
201-
}
202-
}
203-
204-
case NONE: {
205-
source = null;
206-
dollarZeroValue = nil();
207-
} break;
208-
209-
case FILE: {
177+
switch (kind) {
178+
case "FILE": {
210179
final MainLoader mainLoader = new MainLoader(getContext());
211180
source = mainLoader.loadFromFile(this, toExecute);
212181
dollarZeroValue = makeStringNode.executeMake(toExecute, UTF8Encoding.INSTANCE, CodeRange.CR_UNKNOWN);
213182
} break;
214183

215-
case PATH: {
216-
final DynamicObject path = (DynamicObject) findSFile.call(
217-
getContext().getCoreLibrary().getTruffleBootModule(),
218-
// language=ruby
219-
"find_s_file",
220-
makeStringNode.executeMake(toExecute, UTF8Encoding.INSTANCE, CodeRange.CR_UNKNOWN));
221-
final MainLoader mainLoader = new MainLoader(getContext());
222-
source = mainLoader.loadFromFile(this, StringOperations.getString(path));
223-
dollarZeroValue = path;
224-
} break;
225-
226-
case STDIN: {
184+
case "STDIN": {
227185
final MainLoader mainLoader = new MainLoader(getContext());
228-
source = mainLoader.loadFromStandardIn(this, toExecute);
186+
source = mainLoader.loadFromStandardIn(this, "-");
229187
dollarZeroValue = makeStringNode.executeMake("-", USASCIIEncoding.INSTANCE, CodeRange.CR_7BIT);
230188
} break;
231189

232-
case INLINE: {
190+
case "INLINE": {
233191
final MainLoader mainLoader = new MainLoader(getContext());
234-
source = mainLoader.loadFromCommandLineArgument();
192+
source = mainLoader.loadFromCommandLineArgument(toExecute);
235193
dollarZeroValue = makeStringNode.executeMake("-e", USASCIIEncoding.INSTANCE, CodeRange.CR_7BIT);
236194
} break;
237195

src/main/java/org/truffleruby/language/loader/MainLoader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ public MainLoader(RubyContext context) {
3636
this.context = context;
3737
}
3838

39-
public RubySource loadFromCommandLineArgument() {
40-
final Source source = Source.newBuilder(TruffleRuby.LANGUAGE_ID, context.getOptions().TO_EXECUTE, "-e").build();
39+
public RubySource loadFromCommandLineArgument(String code) {
40+
final Source source = Source.newBuilder(TruffleRuby.LANGUAGE_ID, code, "-e").build();
4141
return new RubySource(source);
4242
}
4343

src/main/java/org/truffleruby/options/Options.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515

1616
import org.graalvm.options.OptionDescriptor;
1717
import org.graalvm.options.OptionValues;
18-
import org.truffleruby.shared.options.DefaultExecutionAction;
19-
import org.truffleruby.shared.options.ExecutionAction;
2018
import org.truffleruby.shared.options.OptionsCatalog;
2119
import org.truffleruby.shared.options.Verbosity;
2220

@@ -82,10 +80,7 @@ public class Options {
8280
public final boolean ARGV_GLOBALS;
8381
public final boolean IGNORE_LINES_BEFORE_RUBY_SHEBANG;
8482
public final boolean SYNTAX_CHECK;
85-
public final ExecutionAction EXECUTION_ACTION;
86-
public final String TO_EXECUTE;
8783
public final boolean READ_RUBYOPT;
88-
public final DefaultExecutionAction DEFAULT_EXECUTION_ACTION;
8984
public final String[] ARGV_GLOBAL_VALUES;
9085
public final String[] ARGV_GLOBAL_FLAGS;
9186
public final boolean BUILDING_CORE_CEXTS;
@@ -212,10 +207,7 @@ public Options(Env env, OptionValues options) {
212207
ARGV_GLOBALS = options.get(OptionsCatalog.ARGV_GLOBALS_KEY);
213208
IGNORE_LINES_BEFORE_RUBY_SHEBANG = options.get(OptionsCatalog.IGNORE_LINES_BEFORE_RUBY_SHEBANG_KEY);
214209
SYNTAX_CHECK = options.get(OptionsCatalog.SYNTAX_CHECK_KEY);
215-
EXECUTION_ACTION = options.get(OptionsCatalog.EXECUTION_ACTION_KEY);
216-
TO_EXECUTE = options.get(OptionsCatalog.TO_EXECUTE_KEY);
217210
READ_RUBYOPT = options.get(OptionsCatalog.READ_RUBYOPT_KEY);
218-
DEFAULT_EXECUTION_ACTION = options.get(OptionsCatalog.DEFAULT_EXECUTION_ACTION_KEY);
219211
ARGV_GLOBAL_VALUES = options.get(OptionsCatalog.ARGV_GLOBAL_VALUES_KEY);
220212
ARGV_GLOBAL_FLAGS = options.get(OptionsCatalog.ARGV_GLOBAL_FLAGS_KEY);
221213
BUILDING_CORE_CEXTS = options.get(OptionsCatalog.BUILDING_CORE_CEXTS_KEY);
@@ -401,14 +393,8 @@ public Object fromDescriptor(OptionDescriptor descriptor) {
401393
return IGNORE_LINES_BEFORE_RUBY_SHEBANG;
402394
case "ruby.syntax_check":
403395
return SYNTAX_CHECK;
404-
case "ruby.execution_action":
405-
return EXECUTION_ACTION;
406-
case "ruby.to_execute":
407-
return TO_EXECUTE;
408396
case "ruby.read_rubyopt":
409397
return READ_RUBYOPT;
410-
case "ruby.default_execution_action":
411-
return DEFAULT_EXECUTION_ACTION;
412398
case "ruby.argv_global_values":
413399
return ARGV_GLOBAL_VALUES;
414400
case "ruby.argv_global_flags":

0 commit comments

Comments
 (0)