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: 5a4d4e8b61fd
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 7b1b15876bd8
Choose a head ref
  • 5 commits
  • 9 files changed
  • 1 contributor

Commits on Feb 17, 2016

  1. Copy the full SHA
    07f4c87 View commit details
  2. Copy the full SHA
    c468c77 View commit details
  3. Copy the full SHA
    11210b0 View commit details
  4. 1
    Copy the full SHA
    9766552 View commit details
  5. [Truffle] Remove print_interleaved_backtrace, as we can do it with -X…

    …truffle.backtraces.interleave_java now.
    chrisseaton committed Feb 17, 2016
    Copy the full SHA
    7b1b158 View commit details
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/util/cli/Options.java
Original file line number Diff line number Diff line change
@@ -261,9 +261,11 @@ public class Options {
public static final Option<Integer> TRUFFLE_PACK_RECOVER_LOOP_MIN = integer(TRUFFLE, "truffle.pack.recover", 32, "If a pack or unpack expression is longer than this, attempt to recover loops.");

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_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.");
public static final Option<Integer> TRUFFLE_BACKTRACES_LIMIT = integer(TRUFFLE, "truffle.backtraces.limit", 9999, "Limit the size of Ruby backtraces.");
public static final Option<Boolean> TRUFFLE_BACKTRACES_OMIT_UNUSED = bool(TRUFFLE, "truffle.backtraces.omit_unused", true, "Omit backtraces that should be unused as they have pure rescue expressions.");
public static final Option<Boolean> TRUFFLE_INCLUDE_CORE_FILE_CALLERS_IN_SET_TRACE_FUNC = bool(TRUFFLE, "truffle.set_trace_func.include_core_file_callers", false, "Include internal core library calls in set_trace_func output.");
24 changes: 20 additions & 4 deletions truffle/src/main/java/org/jruby/truffle/core/CoreLibrary.java
Original file line number Diff line number Diff line change
@@ -931,8 +931,12 @@ public DynamicObject frozenError(String className, Node currentNode) {
}

public DynamicObject argumentError(String message, Node currentNode) {
return argumentError(message, currentNode, null);
}

public DynamicObject argumentError(String message, Node currentNode, Throwable javaThrowable) {
CompilerAsserts.neverPartOfCompilation();
return ExceptionNodes.createRubyException(argumentErrorClass, StringOperations.createString(context, StringOperations.encodeRope(message, UTF8Encoding.INSTANCE)), context.getCallStack().getBacktrace(currentNode));
return ExceptionNodes.createRubyException(argumentErrorClass, StringOperations.createString(context, StringOperations.encodeRope(message, UTF8Encoding.INSTANCE)), context.getCallStack().getBacktrace(currentNode, javaThrowable));
}

public DynamicObject argumentErrorOutOfRange(Node currentNode) {
@@ -1030,8 +1034,12 @@ public DynamicObject noBlockToYieldTo(Node currentNode) {
}

public DynamicObject typeError(String message, Node currentNode) {
return typeError(message, currentNode, null);
}

public DynamicObject typeError(String message, Node currentNode, Throwable javaThrowable) {
CompilerAsserts.neverPartOfCompilation();
return ExceptionNodes.createRubyException(typeErrorClass, StringOperations.createString(context, StringOperations.encodeRope(message, UTF8Encoding.INSTANCE)), context.getCallStack().getBacktrace(currentNode));
return ExceptionNodes.createRubyException(typeErrorClass, StringOperations.createString(context, StringOperations.encodeRope(message, UTF8Encoding.INSTANCE)), context.getCallStack().getBacktrace(currentNode, javaThrowable));
}

public DynamicObject typeErrorAllocatorUndefinedFor(DynamicObject rubyClass, Node currentNode) {
@@ -1237,8 +1245,12 @@ public DynamicObject loadErrorCannotLoad(String name, Node currentNode) {
}

public DynamicObject zeroDivisionError(Node currentNode) {
return zeroDivisionError(currentNode, null);
}

public DynamicObject zeroDivisionError(Node currentNode, ArithmeticException exception) {
CompilerAsserts.neverPartOfCompilation();
return ExceptionNodes.createRubyException(context.getCoreLibrary().getZeroDivisionErrorClass(), StringOperations.createString(context, StringOperations.encodeRope("divided by 0", UTF8Encoding.INSTANCE)), context.getCallStack().getBacktrace(currentNode));
return ExceptionNodes.createRubyException(context.getCoreLibrary().getZeroDivisionErrorClass(), StringOperations.createString(context, StringOperations.encodeRope("divided by 0", UTF8Encoding.INSTANCE)), context.getCallStack().getBacktrace(currentNode, exception));
}

public DynamicObject notImplementedError(String message, Node currentNode) {
@@ -1292,8 +1304,12 @@ public DynamicObject rangeError(String message, Node currentNode) {
}

public DynamicObject internalError(String message, Node currentNode) {
return internalError(message, currentNode);
}

public DynamicObject internalError(String message, Node currentNode, Throwable javaThrowable) {
CompilerAsserts.neverPartOfCompilation();
return ExceptionNodes.createRubyException(context.getCoreLibrary().getRubyTruffleErrorClass(), StringOperations.createString(context, StringOperations.encodeRope("internal implementation error - " + message, UTF8Encoding.INSTANCE)), context.getCallStack().getBacktrace(currentNode));
return ExceptionNodes.createRubyException(context.getCoreLibrary().getRubyTruffleErrorClass(), StringOperations.createString(context, StringOperations.encodeRope("internal implementation error - " + message, UTF8Encoding.INSTANCE)), context.getCallStack().getBacktrace(currentNode, javaThrowable));
}

public DynamicObject regexpError(String message, Node currentNode) {
Original file line number Diff line number Diff line change
@@ -692,30 +692,6 @@ public DynamicObject printBacktrace() {

}

@CoreMethod(names = "print_interleaved_backtrace", onSingleton = true)
public abstract static class PrintInterleavedBacktraceNode extends CoreMethodNode {

public PrintInterleavedBacktraceNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

@TruffleBoundary
@Specialization
public DynamicObject printInterleavedBacktrace() {
final List<String> rubyBacktrace = BacktraceFormatter.createDefaultFormatter(getContext())
.formatBacktrace(getContext(), null, getContext().getCallStack().getBacktrace(this));

final StackTraceElement[] javaStacktrace = new Exception().getStackTrace();

for (String line : BacktraceInterleaver.interleave(rubyBacktrace, javaStacktrace)) {
System.err.println(line);
}

return nil();
}

}

@CoreMethod(names = "ast", onSingleton = true, required = 1)
public abstract static class ASTNode extends CoreMethodArrayArgumentsNode {

Original file line number Diff line number Diff line change
@@ -83,28 +83,42 @@ private InternalMethod getMethod(FrameInstance frame) {
return RubyArguments.getMethod(frame.getFrame(FrameInstance.FrameAccess.READ_ONLY, true).getArguments());
}

public Backtrace getBacktrace(Node currentNode, Throwable javaThrowable) {
return getBacktrace(currentNode, 0, false, null, javaThrowable);
}

public Backtrace getBacktrace(Node currentNode) {
return getBacktrace(currentNode, 0);
return getBacktrace(currentNode, 0, false, null, null);
}

public Backtrace getBacktrace(Node currentNode, int omit) {
return getBacktrace(currentNode, omit, null);
return getBacktrace(currentNode, omit, false, null, null);
}

public Backtrace getBacktrace(Node currentNode, int omit, DynamicObject exception) {
return getBacktrace(currentNode, omit, false, exception);
return getBacktrace(currentNode, omit, false, exception, null);
}

public Backtrace getBacktrace(Node currentNode,
final int omit,
final boolean filterNullSourceSection,
DynamicObject exception) {
return getBacktrace(currentNode, omit, filterNullSourceSection, exception, null);
}

public Backtrace getBacktrace(Node currentNode, final int omit,
final boolean filterNullSourceSection, DynamicObject exception) {
public Backtrace getBacktrace(Node currentNode,
final int omit,
final boolean filterNullSourceSection,
DynamicObject exception,
Throwable javaThrowable) {
CompilerAsserts.neverPartOfCompilation();

if (exception != null
&& context.getOptions().BACKTRACES_OMIT_UNUSED
&& DisablingBacktracesNode.areBacktracesDisabled()
&& ModuleOperations.assignableTo(Layouts.BASIC_OBJECT.getLogicalClass(exception),
context.getCoreLibrary().getStandardErrorClass())) {
return new Backtrace(new Activation[]{Activation.OMITTED_UNUSED});
return new Backtrace(new Activation[]{Activation.OMITTED_UNUSED}, null);
}

final int limit = context.getOptions().BACKTRACES_LIMIT;
@@ -150,7 +164,15 @@ public Object visitFrame(FrameInstance frameInstance) {

});

return new Backtrace(activations.toArray(new Activation[activations.size()]));
if (context.getOptions().EXCEPTIONS_STORE_JAVA || context.getOptions().BACKTRACES_INTERLEAVE_JAVA) {
if (javaThrowable == null) {
javaThrowable = new Exception();
}
} else {
javaThrowable = null;
}

return new Backtrace(activations.toArray(new Activation[activations.size()]), javaThrowable);
}

private boolean ignoreFrame(FrameInstance frameInstance) {
Original file line number Diff line number Diff line change
@@ -10,9 +10,7 @@
package org.jruby.truffle.language;

/**
* The {@link NotProvided} instance represents an argument which was <i>not provided</i>.
* This is necessary as we need to differentiate based on the number of passed arguments
* and there is not a single default value that fits for omitted arguments.
* Represents a value that was not provided by the user, such as optional arguments to a core library node.
*/
public final class NotProvided {

2 changes: 2 additions & 0 deletions truffle/src/main/java/org/jruby/truffle/language/Options.java
Original file line number Diff line number Diff line change
@@ -65,9 +65,11 @@ public class Options {
// Debugging

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_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();
public final int BACKTRACES_LIMIT = TRUFFLE_BACKTRACES_LIMIT.load();
public final boolean BACKTRACES_OMIT_UNUSED = TRUFFLE_BACKTRACES_OMIT_UNUSED.load();
public final boolean INCLUDE_CORE_FILE_CALLERS_IN_SET_TRACE_FUNC = TRUFFLE_INCLUDE_CORE_FILE_CALLERS_IN_SET_TRACE_FUNC.load();
Original file line number Diff line number Diff line change
@@ -16,13 +16,19 @@
public class Backtrace {

private final Activation[] activations;
private final Throwable javaThrowable;

public Backtrace(Activation[] activations) {
public Backtrace(Activation[] activations, Throwable javaThrowable) {
this.activations = activations;
this.javaThrowable = javaThrowable;
}

public List<Activation> getActivations() {
return Collections.unmodifiableList(Arrays.asList(activations));
}

public Throwable getJavaThrowable() {
return javaThrowable;
}

}
Original file line number Diff line number Diff line change
@@ -112,6 +112,10 @@ public List<String> formatBacktrace(RubyContext context, DynamicObject exception
}
}

if (backtrace.getJavaThrowable() != null && context.getOptions().BACKTRACES_INTERLEAVE_JAVA) {
return BacktraceInterleaver.interleave(lines, backtrace.getJavaThrowable().getStackTrace());
}

return lines;
}

Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@ private DynamicObject translate(ArithmeticException exception) {
exception.printStackTrace();
}

return getContext().getCoreLibrary().zeroDivisionError(this);
return getContext().getCoreLibrary().zeroDivisionError(this, exception);
}

private DynamicObject translate(UnsupportedSpecializationException exception) {
@@ -144,9 +144,9 @@ private DynamicObject translate(UnsupportedSpecializationException exception) {

switch (unsupportedOperationBehavior) {
case TYPE_ERROR:
return getContext().getCoreLibrary().typeError(builder.toString(), this);
return getContext().getCoreLibrary().typeError(builder.toString(), this, exception);
case ARGUMENT_ERROR:
return getContext().getCoreLibrary().argumentError(builder.toString(), this);
return getContext().getCoreLibrary().argumentError(builder.toString(), this, exception);
default:
throw new UnsupportedOperationException();
}
@@ -158,9 +158,9 @@ public DynamicObject translate(Throwable throwable) {
}

if (throwable.getStackTrace().length > 0) {
return getContext().getCoreLibrary().internalError(String.format("%s %s %s", throwable.getClass().getSimpleName(), throwable.getMessage(), throwable.getStackTrace()[0].toString()), this);
return getContext().getCoreLibrary().internalError(String.format("%s %s %s", throwable.getClass().getSimpleName(), throwable.getMessage(), throwable.getStackTrace()[0].toString()), this, throwable);
} else {
return getContext().getCoreLibrary().internalError(String.format("%s %s ???", throwable.getClass().getSimpleName(), throwable.getMessage()), this);
return getContext().getCoreLibrary().internalError(String.format("%s %s ???", throwable.getClass().getSimpleName(), throwable.getMessage()), this, throwable);
}
}