Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 360f62cfe9f7
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 53c49936659f
Choose a head ref
  • 3 commits
  • 3 files changed
  • 1 contributor

Commits on Jan 7, 2017

  1. 2
    Copy the full SHA
    9ee7b59 View commit details
  2. Copy the full SHA
    f419aa7 View commit details
  3. Copy the full SHA
    53c4993 View commit details
64 changes: 59 additions & 5 deletions truffle/src/main/java/org/jruby/truffle/Main.java
Original file line number Diff line number Diff line change
@@ -44,20 +44,23 @@
*/
package org.jruby.truffle;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.TruffleOptions;
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.vm.PolyglotEngine;
import org.jruby.truffle.language.control.JavaException;
import org.jruby.truffle.options.ArgumentProcessor;
import org.jruby.truffle.options.MainExitException;
import org.jruby.truffle.options.OptionsBuilder;
import org.jruby.truffle.options.OptionsCatalog;
import org.jruby.truffle.options.OutputStrings;
import org.jruby.truffle.options.RubyInstanceConfig;
import org.jruby.truffle.platform.graal.Graal;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.management.ManagementFactory;

@@ -72,7 +75,7 @@ public static void main(String[] args) {
final RubyInstanceConfig config = new RubyInstanceConfig();

try {
config.processArguments(args);
processArguments(config, args);
} catch (MainExitException mee) {
if (!mee.isAborted()) {
config.getError().println(mee.getMessage());
@@ -89,7 +92,7 @@ public static void main(String[] args) {
final int exitCode;

if (config.getShouldRunInterpreter()) {
final String filename = config.displayedFileName();
final String filename = displayedFileName(config);

final PolyglotEngine engine;
final RubyContext context;
@@ -99,7 +102,7 @@ public static void main(String[] args) {
.config(RubyLanguage.MIME_TYPE, OptionsCatalog.REQUIRED_LIBRARIES.getName(), config.getRequiredLibraries().toArray(new String[]{}))
.config(RubyLanguage.MIME_TYPE, OptionsCatalog.INLINE_SCRIPT.getName(), config.inlineScript())
.config(RubyLanguage.MIME_TYPE, OptionsCatalog.ARGUMENTS.getName(), config.getArgv())
.config(RubyLanguage.MIME_TYPE, OptionsCatalog.DISPLAYED_FILE_NAME.getName(), config.displayedFileName())
.config(RubyLanguage.MIME_TYPE, OptionsCatalog.DISPLAYED_FILE_NAME.getName(), filename)
.config(RubyLanguage.MIME_TYPE, OptionsCatalog.DEBUG.getName(), config.isDebug())
.config(RubyLanguage.MIME_TYPE, OptionsCatalog.VERBOSITY.getName(), config.getVerbosity().ordinal())
.config(RubyLanguage.MIME_TYPE, OptionsCatalog.FROZEN_STRING_LITERALS.getName(), config.isFrozenStringLiteral())
@@ -120,7 +123,7 @@ public static void main(String[] args) {
exitCode = 1;
} else if (config.getShouldCheckSyntax()) {
// check syntax only and exit
exitCode = checkSyntax(engine, context, config.getScriptSource(), filename);
exitCode = checkSyntax(engine, context, getScriptSource(config), filename);
} else {
if (!Graal.isGraal() && context.getOptions().GRAAL_WARNING_UNLESS) {
Log.performanceOnce("This JVM does not have the Graal compiler - performance will be limited - " +
@@ -149,6 +152,57 @@ public static void main(String[] args) {
System.exit(exitCode);
}

public static void processArguments(RubyInstanceConfig config, String[] arguments) {
new ArgumentProcessor(arguments, config).processArguments();

Object rubyoptObj = System.getenv("RUBYOPT");
String rubyopt = rubyoptObj == null ? null : rubyoptObj.toString();

if (rubyopt != null && rubyopt.length() != 0) {
String[] rubyoptArgs = rubyopt.split("\\s+");
if (rubyoptArgs.length != 0) {
new ArgumentProcessor(rubyoptArgs, false, true, true, config).processArguments();
}
}

if (!TruffleOptions.AOT && !config.doesHaveScriptArgv() && !config.shouldUsePathScript() && System.console() != null) {
config.setUsePathScript("irb");
}
}

public static InputStream getScriptSource(RubyInstanceConfig config) {
try {
// KCode.NONE is used because KCODE does not affect parse in Ruby 1.8
// if Ruby 2.0 encoding pragmas are implemented, this will need to change
if (config.isInlineScript()) {
return new ByteArrayInputStream(config.inlineScript());
} else if (config.isForceStdin() || config.getScriptFileName() == null) {
return System.in;
} else {
final String script = config.getScriptFileName();
return new FileInputStream(script);
}
} catch (IOException e) {
throw new JavaException(e);
}
}

public static String displayedFileName(RubyInstanceConfig config) {
if (config.isInlineScript()) {
if (config.getScriptFileName() != null) {
return config.getScriptFileName();
} else {
return "-e";
}
} else if (config.shouldUsePathScript()) {
return "-S";
} else if (config.isForceStdin() || config.getScriptFileName() == null) {
return "-";
} else {
return config.getScriptFileName();
}
}

private static void printUsage(RubyInstanceConfig config, boolean force) {
if (config.getShouldPrintUsage() || force) {
config.getOutput().print(OutputStrings.getBasicUsageHelp());
Original file line number Diff line number Diff line change
@@ -117,8 +117,6 @@ public void processArguments() {
}

public void processArguments(boolean inline) {
checkProperties();

while (argumentIndex < arguments.size() && isInterpreterArgument(arguments.get(argumentIndex).originalValue)) {
processArgument();
argumentIndex++;
@@ -250,8 +248,7 @@ private void processArgument() {
break FOR;
case 'F':
disallowedInRubyOpts(argument);
config.setInputFieldSeparator(grabValue(getArgumentError(" -F must be followed by a pattern for input field separation")));
break FOR;
throw new UnsupportedOperationException();
case 'h':
disallowedInRubyOpts(argument);
config.setShouldPrintUsage(true);
@@ -281,35 +278,30 @@ private void processArgument() {
grabValue(getArgumentError(" -J-cp must be followed by a path expression"));
}
break FOR;
case 'K': // @Deprecated TODO no longer relevant in Ruby 2.x
case 'K':
String eArg = grabValue(getArgumentError("provide a value for -K"));

config.setKCode(KCode.create(eArg));

// source encoding
config.setSourceEncoding(config.getKCode().getEncoding().toString());
// TODO CS 6-Jan-17
//config.setSourceEncoding(config.getKCode().getEncoding().toString());

// set external encoding if not already specified
if (config.getExternalEncoding() == null) {
config.setExternalEncoding(config.getKCode().getEncoding().toString());
}

break;

case 'l':
disallowedInRubyOpts(argument);
config.setProcessLineEnds(true);
break;
throw new UnsupportedOperationException();
case 'n':
disallowedInRubyOpts(argument);
config.setAssumeLoop(true);
//config.setKernelGsubDefined(true);
break;
throw new UnsupportedOperationException();
case 'p':
disallowedInRubyOpts(argument);
config.setAssumePrinting(true);
config.setAssumeLoop(true);
//config.setKernelGsubDefined(true);
break;
throw new UnsupportedOperationException();
case 'r':
config.getRequiredLibraries().add(grabValue(getArgumentError("-r must be followed by a package to require")));
break FOR;
@@ -622,53 +614,6 @@ private String grabOptionalValue() {
return null;
}

private static final Set<String> KNOWN_PROPERTIES = new HashSet<>(16, 1);

static {
//Options.addPropertyNames(KNOWN_PROPERTIES);
KNOWN_PROPERTIES.add("jruby.home");
KNOWN_PROPERTIES.add("jruby.script");
KNOWN_PROPERTIES.add("jruby.shell");
KNOWN_PROPERTIES.add("jruby.lib");
KNOWN_PROPERTIES.add("jruby.bindir");
KNOWN_PROPERTIES.add("jruby.jar");
KNOWN_PROPERTIES.add("jruby.compat.version");
KNOWN_PROPERTIES.add("jruby.reflection");
KNOWN_PROPERTIES.add("jruby.thread.pool.enabled");
KNOWN_PROPERTIES.add("jruby.memory.max");
KNOWN_PROPERTIES.add("jruby.stack.max");
}

private static final List<String> KNOWN_PROPERTY_PREFIXES = new ArrayList<>(4);

static {
KNOWN_PROPERTY_PREFIXES.add("jruby.openssl.");
}

private static void checkProperties() {
for (String propertyName : System.getProperties().stringPropertyNames()) {
if (propertyName.startsWith("jruby.") && !propertyName.startsWith("jruby.truffle.")) {
if (!isPropertySupported(propertyName)) {
System.err.println("jruby: warning: unknown property " + propertyName);
}
}
}
}

private static boolean isPropertySupported(String propertyName) {
if (KNOWN_PROPERTIES.contains(propertyName)) {
return true;
}

for (String prefix : KNOWN_PROPERTY_PREFIXES) {
if (propertyName.startsWith(prefix)) {
return true;
}
}

return false;
}

private static final Map<String, BiFunction<ArgumentProcessor, Boolean, Boolean>> FEATURES;

static {
180 changes: 33 additions & 147 deletions truffle/src/main/java/org/jruby/truffle/options/RubyInstanceConfig.java
Original file line number Diff line number Diff line change
@@ -28,99 +28,52 @@
***** END LICENSE BLOCK *****/
package org.jruby.truffle.options;

import com.oracle.truffle.api.TruffleOptions;
import org.jruby.truffle.core.string.KCode;
import org.jruby.truffle.language.control.JavaException;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

/**
* A structure used to configure new JRuby instances. All publicly-tweakable
* aspects of Ruby can be modified here, including those settable by command-
* line options, those available through JVM properties, and those suitable for
* embedding.
*/
@SuppressWarnings("unused")
public class RubyInstanceConfig {

public RubyInstanceConfig() {
currentDirectory = System.getProperty("user.dir", "/");
environment = new HashMap<>();
environment.putAll(System.getenv());
}

public void processArguments(String[] arguments) {
final ArgumentProcessor processor = new ArgumentProcessor(arguments, this);
processor.processArguments();
processArgumentsWithRubyopts();
if (!TruffleOptions.AOT && !hasScriptArgv && !usePathScript && System.console() != null) {
setUsePathScript("irb");
}
}

public void processArgumentsWithRubyopts() {
// environment defaults to System.getenv normally
Object rubyoptObj = environment.get("RUBYOPT");
String rubyopt = rubyoptObj == null ? null : rubyoptObj.toString();

if (rubyopt == null || rubyopt.length() == 0) return;
public class RubyInstanceConfig {

String[] rubyoptArgs = rubyopt.split("\\s+");
if (rubyoptArgs.length != 0) {
new ArgumentProcessor(rubyoptArgs, false, true, true, this).processArguments();
}
}
private boolean xFlag;
private PrintStream output = System.out;
private PrintStream error = System.err;
private String currentDirectory = System.getProperty("user.dir", "/");
private String[] argv = {};
private String internalEncoding;
private String externalEncoding;
private List<String> loadPaths = new ArrayList<>();
private StringBuffer inlineScript = new StringBuffer();
private boolean hasInlineScript;
private boolean usePathScript;
private String scriptFileName;
private Collection<String> requiredLibraries = new LinkedHashSet<>();
private boolean argvGlobalsOn;
private Map<String, String> optionGlobals = new HashMap<>();
private boolean split;
private Verbosity verbosity = Verbosity.FALSE;
private boolean debug;
private boolean showVersion;
private boolean showCopyright;
private boolean shouldRunInterpreter = true;
private boolean shouldPrintUsage;
private boolean shouldCheckSyntax;
private String inPlaceBackupExtension;
private boolean disableGems;
private boolean hasScriptArgv;
private boolean frozenStringLiteral;
private KCode kcode;
private boolean forceStdin;

public byte[] inlineScript() {
return inlineScript.toString().getBytes();
}

public InputStream getScriptSource() {
try {
// KCode.NONE is used because KCODE does not affect parse in Ruby 1.8
// if Ruby 2.0 encoding pragmas are implemented, this will need to change
if (hasInlineScript) {
return new ByteArrayInputStream(inlineScript());
} else if (isForceStdin() || getScriptFileName() == null) {
return System.in;
} else {
final String script = getScriptFileName();
return new FileInputStream(script);
}
} catch (IOException e) {
throw new JavaException(e);
}
}

public String displayedFileName() {
if (hasInlineScript) {
if (scriptFileName != null) {
return scriptFileName;
} else {
return "-e";
}
} else if (usePathScript) {
return "-S";
} else if (isForceStdin() || getScriptFileName() == null) {
return "-";
} else {
return getScriptFileName();
}
}

public PrintStream getOutput() {
return output;
}
@@ -197,18 +150,6 @@ public String getScriptFileName() {
return scriptFileName;
}

public void setAssumeLoop(boolean assumeLoop) {
this.assumeLoop = assumeLoop;
}

public void setAssumePrinting(boolean assumePrinting) {
this.assumePrinting = assumePrinting;
}

public void setProcessLineEnds(boolean processLineEnds) {
this.processLineEnds = processLineEnds;
}

public void setSplit(boolean split) {
this.split = split;
}
@@ -265,10 +206,6 @@ public boolean getShouldCheckSyntax() {
return shouldCheckSyntax;
}

public void setInputFieldSeparator(String inputFieldSeparator) {
this.inputFieldSeparator = inputFieldSeparator;
}

public void setInternalEncoding(String internalEncoding) {
this.internalEncoding = internalEncoding;
}
@@ -329,56 +266,9 @@ public void setFrozenStringLiteral(boolean frozenStringLiteral) {
this.frozenStringLiteral = frozenStringLiteral;
}

/**
* Indicates whether the script must be extracted from script source
*/
private boolean xFlag = false;

/**
* Indicates whether the script has a shebang line or not
*/
private PrintStream output = System.out;
private PrintStream error = System.err;

private String currentDirectory;

/** Environment variables; defaults to System.getenv() in constructor */
private Map<String, String> environment;
private String[] argv = {};

private String internalEncoding = null;
private String externalEncoding = null;

// from CommandlineParser
private List<String> loadPaths = new ArrayList<>();
private StringBuffer inlineScript = new StringBuffer();
private boolean hasInlineScript = false;
private boolean usePathScript = false;
private String scriptFileName = null;
private Collection<String> requiredLibraries = new LinkedHashSet<>();
private boolean argvGlobalsOn = false;
private boolean assumeLoop = false;
private boolean assumePrinting = false;
private Map<String, String> optionGlobals = new HashMap<>();
private boolean processLineEnds = false;
private boolean split = false;
private Verbosity verbosity = Verbosity.FALSE;
private boolean debug = false;
private boolean showVersion = false;
private boolean showCopyright = false;
private boolean shouldRunInterpreter = true;
private boolean shouldPrintUsage = false;
private boolean shouldPrintProperties=false;
private boolean shouldCheckSyntax = false;
private String inputFieldSeparator = null;
private String inPlaceBackupExtension = null;
private boolean disableGems = false;
private boolean hasScriptArgv = false;
private boolean frozenStringLiteral = false;
private KCode kcode;
private String sourceEncoding;

private boolean forceStdin = false;
public boolean doesHaveScriptArgv() {
return hasScriptArgv;
}

public Verbosity getVerbosity() {
return verbosity;
@@ -392,10 +282,6 @@ public KCode getKCode() {
return kcode;
}

public void setSourceEncoding(String sourceEncoding) {
this.sourceEncoding = sourceEncoding;
}

public void setUsePathScript(String name) {
scriptFileName = name;
usePathScript = true;