Skip to content

Commit

Permalink
[Truffle] New system for options.
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed Nov 25, 2016
1 parent b19ae98 commit ed6e12e
Show file tree
Hide file tree
Showing 17 changed files with 388 additions and 12 deletions.
Expand Up @@ -778,7 +778,7 @@ private String grabOptionalValue() {

private static void checkProperties() {
for (String propertyName : System.getProperties().stringPropertyNames()) {
if (propertyName.startsWith("jruby.")) {
if (propertyName.startsWith("jruby.") && !propertyName.startsWith("jruby.truffle.")) {
if (!isPropertySupported(propertyName)) {
System.err.println("jruby: warning: unknown property " + propertyName);
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/util/cli/Options.java
Expand Up @@ -296,7 +296,7 @@ public class Options {

public static final Option<Integer> TRUFFLE_INSTRUMENTATION_SERVER_PORT = integer(TRUFFLE, "truffle.instrumentation_server_port", 0, "Port number to run an HTTP server on that provides instrumentation services");
public static final Option<Boolean> TRUFFLE_EXCEPTIONS_STORE_JAVA = bool(TRUFFLE, "truffle.exceptions.store_java", false, "Store the Java exception with the Ruby backtrace");
public static final Option<Boolean> TRUFFLE_EXCEPTIONS_PRINT_JAVA = bool(TRUFFLE, "truffle.exceptions.print_java", false, "Print Java exceptions at the point of translating them to Ruby exceptions.");
//public static final Option<Boolean> TRUFFLE_EXCEPTIONS_PRINT_JAVA = bool(TRUFFLE, "truffle.exceptions.print_java", false, "Print Java exceptions at the point of translating them to Ruby exceptions.");
public static final Option<Boolean> TRUFFLE_EXCEPTIONS_PRINT_UNCAUGHT_JAVA = bool(TRUFFLE, "truffle.exceptions.print_uncaught_java", false, "Print uncaught Java exceptions at the point of translating them to Ruby exceptions.");
public static final Option<Boolean> TRUFFLE_BACKTRACES_HIDE_CORE_FILES = bool(TRUFFLE, "truffle.backtraces.hide_core_files", true, "Hide core source files in backtraces, like MRI does.");
public static final Option<Boolean> TRUFFLE_BACKTRACES_INTERLEAVE_JAVA = bool(TRUFFLE, "truffle.backtraces.interleave_java", false, "Interleave Java stacktraces into the Ruby backtrace.");
Expand Down
4 changes: 2 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/Options.java
Expand Up @@ -33,7 +33,7 @@
import static org.jruby.util.cli.Options.TRUFFLE_ENCODING_COMPATIBLE_QUERY_CACHE;
import static org.jruby.util.cli.Options.TRUFFLE_ENCODING_LOADED_CLASSES_CACHE;
import static org.jruby.util.cli.Options.TRUFFLE_EVAL_CACHE;
import static org.jruby.util.cli.Options.TRUFFLE_EXCEPTIONS_PRINT_JAVA;
//import static org.jruby.util.cli.Options.TRUFFLE_EXCEPTIONS_PRINT_JAVA;
import static org.jruby.util.cli.Options.TRUFFLE_EXCEPTIONS_PRINT_UNCAUGHT_JAVA;
import static org.jruby.util.cli.Options.TRUFFLE_EXCEPTIONS_STORE_JAVA;
import static org.jruby.util.cli.Options.TRUFFLE_HASH_PACKED_ARRAY_MAX;
Expand Down Expand Up @@ -159,7 +159,7 @@ public class Options {

public final int INSTRUMENTATION_SERVER_PORT = TRUFFLE_INSTRUMENTATION_SERVER_PORT.load();
public final boolean EXCEPTIONS_STORE_JAVA = TRUFFLE_EXCEPTIONS_STORE_JAVA.load();
public final boolean EXCEPTIONS_PRINT_JAVA = TRUFFLE_EXCEPTIONS_PRINT_JAVA.load();
//public final boolean EXCEPTIONS_PRINT_JAVA = TRUFFLE_EXCEPTIONS_PRINT_JAVA.load();
public final boolean EXCEPTIONS_PRINT_UNCAUGHT_JAVA = TRUFFLE_EXCEPTIONS_PRINT_UNCAUGHT_JAVA.load();
public final boolean BACKTRACES_HIDE_CORE_FILES = TRUFFLE_BACKTRACES_HIDE_CORE_FILES.load();
public final boolean BACKTRACES_INTERLEAVE_JAVA = TRUFFLE_BACKTRACES_INTERLEAVE_JAVA.load();
Expand Down
14 changes: 14 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/RubyContext.java
Expand Up @@ -46,6 +46,8 @@
import org.jruby.truffle.language.methods.DeclarationContext;
import org.jruby.truffle.language.methods.InternalMethod;
import org.jruby.truffle.language.objects.shared.SharedObjects;
import org.jruby.truffle.options.NewOptions;
import org.jruby.truffle.options.OptionsBuilder;
import org.jruby.truffle.platform.NativePlatform;
import org.jruby.truffle.platform.NativePlatformFactory;
import org.jruby.truffle.stdlib.CoverageManager;
Expand All @@ -66,6 +68,8 @@ public class RubyContext extends ExecutionContext {

private final TruffleLanguage.Env env;

private final NewOptions newOptions;

private final RubyInstanceConfig instanceConfig;
private final String jrubyHome;
private String originalInputFile;
Expand Down Expand Up @@ -110,6 +114,12 @@ public class RubyContext extends ExecutionContext {
public RubyContext(RubyInstanceConfig instanceConfig, TruffleLanguage.Env env) {
this.instanceConfig = instanceConfig;
this.env = env;

final OptionsBuilder optionsBuilder = new OptionsBuilder();
optionsBuilder.set(env.getConfig());
optionsBuilder.set(System.getProperties());
newOptions = optionsBuilder.build();

this.jrubyHome = setupJRubyHome();
this.currentDirectory = System.getProperty("user.dir");

Expand Down Expand Up @@ -458,4 +468,8 @@ public InputStream getSyntaxCheckInputStream() {
public void setSyntaxCheckInputStream(InputStream syntaxCheckInputStream) {
this.syntaxCheckInputStream = syntaxCheckInputStream;
}

public NewOptions getNewOptions() {
return newOptions;
}
}
4 changes: 3 additions & 1 deletion truffle/src/main/java/org/jruby/truffle/RubyEngine.java
Expand Up @@ -13,6 +13,7 @@
import com.oracle.truffle.api.source.Source;
import com.oracle.truffle.api.vm.PolyglotEngine;
import org.jruby.RubyInstanceConfig;
import org.jruby.truffle.options.OptionsCatalogue;
import org.jruby.truffle.platform.graal.Graal;
import org.jruby.util.cli.Options;

Expand All @@ -35,6 +36,7 @@ public RubyEngine(RubyInstanceConfig instanceConfig) {

engine = PolyglotEngine.newBuilder()
.config(RubyLanguage.MIME_TYPE, INSTANCE_CONFIG_KEY, instanceConfig)
.config(RubyLanguage.MIME_TYPE, OptionsCatalogue.ARGUMENTS.getName(), instanceConfig.getArgv())
.build();
Main.printTruffleTimeMetric("before-load-context");
context = engine.eval(loadSource("Truffle::Boot.context", "context")).as(RubyContext.class);
Expand Down Expand Up @@ -70,7 +72,7 @@ public int doCheckSyntax(InputStream in, String filename) {
boolean status = checkSyntax(in, filename);

// check other scripts specified on argv
for (String arg : context.getInstanceConfig().getArgv()) {
for (String arg : context.getNewOptions().ARGUMENTS) {
status = status && checkFileSyntax(arg);
}

Expand Down
Expand Up @@ -133,7 +133,7 @@ public abstract static class OriginalArgvNode extends CoreMethodNode {
@TruffleBoundary
@Specialization
public DynamicObject originalArgv() {
final String[] argv = getContext().getInstanceConfig().getArgv();
final String[] argv = getContext().getNewOptions().ARGUMENTS;
final Object[] array = new Object[argv.length];

for (int n = 0; n < array.length; n++) {
Expand Down
Expand Up @@ -100,7 +100,7 @@ public List<String> formatBacktrace(RubyContext context, DynamicObject exception
try {
lines.add(formatLine(activations, n, exception));
} catch (Exception e) {
if (context.getOptions().EXCEPTIONS_PRINT_JAVA) {
if (context.getNewOptions().EXCEPTIONS_PRINT_JAVA) {
e.printStackTrace();
}

Expand Down
Expand Up @@ -74,7 +74,7 @@ public Object execute(VirtualFrame frame) {

@TruffleBoundary
private DynamicObject translate(ArithmeticException exception) {
if (getContext().getOptions().EXCEPTIONS_PRINT_JAVA) {
if (getContext().getNewOptions().EXCEPTIONS_PRINT_JAVA) {
exception.printStackTrace();
}

Expand All @@ -83,7 +83,7 @@ private DynamicObject translate(ArithmeticException exception) {

@TruffleBoundary
private DynamicObject translate(StackOverflowError error) {
if (getContext().getOptions().EXCEPTIONS_PRINT_JAVA) {
if (getContext().getNewOptions().EXCEPTIONS_PRINT_JAVA) {
error.printStackTrace();
}

Expand All @@ -92,7 +92,7 @@ private DynamicObject translate(StackOverflowError error) {

@TruffleBoundary
private DynamicObject translate(IllegalArgumentException exception) {
if (getContext().getOptions().EXCEPTIONS_PRINT_JAVA) {
if (getContext().getNewOptions().EXCEPTIONS_PRINT_JAVA) {
exception.printStackTrace();
}

Expand All @@ -107,7 +107,7 @@ private DynamicObject translate(IllegalArgumentException exception) {

@TruffleBoundary
private DynamicObject translate(UnsupportedSpecializationException exception) {
if (getContext().getOptions().EXCEPTIONS_PRINT_JAVA) {
if (getContext().getNewOptions().EXCEPTIONS_PRINT_JAVA) {
exception.printStackTrace();
}

Expand Down Expand Up @@ -175,7 +175,7 @@ private DynamicObject translate(UnsupportedSpecializationException exception) {

@TruffleBoundary
public DynamicObject translate(Throwable throwable) {
if (getContext().getOptions().EXCEPTIONS_PRINT_JAVA
if (getContext().getNewOptions().EXCEPTIONS_PRINT_JAVA
|| getContext().getOptions().EXCEPTIONS_PRINT_UNCAUGHT_JAVA) {
throwable.printStackTrace();
}
Expand Down
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.options;

public class BooleanOptionDescription extends OptionDescription {

private final boolean defaultValue;

public BooleanOptionDescription(String name, String description, boolean defaultValue) {
super(name, description);
this.defaultValue = defaultValue;
}

@Override
public Object getDefaultValue() {
return defaultValue;
}

@Override
public Object checkValue(Object value) {
if (value instanceof Boolean) {
return value;
} else if (value instanceof String) {
switch ((String) value) {
case "true":
return true;
case "false":
return false;
default:
throw new OptionTypeException();
}
} else {
throw new OptionTypeException();
}
}

}
25 changes: 25 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/options/NewOptions.java
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.options;

// This file would be automatically generated from the list of options in the text file.

public class NewOptions {

public final String[] ARGUMENTS;

public final boolean EXCEPTIONS_PRINT_JAVA;

NewOptions(OptionsBuilder builder) {
ARGUMENTS = builder.getOrDefault(OptionsCatalogue.ARGUMENTS);
EXCEPTIONS_PRINT_JAVA = builder.getOrDefault(OptionsCatalogue.EXCEPTIONS_PRINT_JAVA);
}

}
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.options;

public abstract class OptionDescription {

private final String name;
private final String description;

public OptionDescription(String name, String description) {
this.name = name;
this.description = description;
}

public String getName() {
return name;
}

public String getDescription() {
return description;
}

public abstract Object getDefaultValue();

public abstract Object checkValue(Object value);

}
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.options;

public class OptionTypeException extends UnsupportedOperationException {

}
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.options;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class OptionsBuilder {

private final String LEGACY_PREFIX = "jruby.truffle.";

private final Map<OptionDescription, Object> options = new HashMap<>();

public void set(Properties properties) {
for (Map.Entry<Object, Object> property : properties.entrySet()) {
final String name = (String) property.getKey();

if (name.startsWith(LEGACY_PREFIX)) {
set(name.substring(LEGACY_PREFIX.length()), property.getValue());
}
}
}

public void set(Map<String, Object> properties) {
for (Map.Entry<String, Object> property : properties.entrySet()) {
set(property.getKey(), property.getValue());
}
}

private void set(String name, Object value) {
final OptionDescription description = OptionsCatalogue.fromName(name);

if (description == null) {
//throw new UnsupportedOperationException(name);

// Don't throw for now - not all the options are transalted across
return;
}

options.put(description, description.checkValue(value));
}

public NewOptions build() {
return new NewOptions(this);
}

<T> T getOrDefault(OptionDescription description) {
Object value = options.get(description);

if (value == null) {
value = description.getDefaultValue();
}

return (T) value;
}

}
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.options;

// This file would be automatically generated from the list of options in the text file.

public class OptionsCatalogue {

public static final OptionDescription ARGUMENTS = new StringArrayOptionDescription("arguments", "Foo bar baz", new String[0]);

public static final OptionDescription EXCEPTIONS_PRINT_JAVA = new BooleanOptionDescription("exceptions.print_java", "Foo baz bar", false);

public static OptionDescription fromName(String name) {
switch (name) {
case "arguments":
return ARGUMENTS;
case "exceptions.print_java":
return EXCEPTIONS_PRINT_JAVA;
default:
return null;
}
}

}

0 comments on commit ed6e12e

Please sign in to comment.