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

Commits on Jan 23, 2018

  1. Copy the full SHA
    9fe13cc View commit details

Commits on Jan 24, 2018

  1. Add more backtrace support properly printing out method name. This co…

    …mmit is
    
    a little off in that it assumes the String returned from the properly encoded
    symbol will be the same encoding as the String returned.  Generally this will
    be UTF-8 so it will almost always work.  Not perfect but better.
    enebo committed Jan 24, 2018
    Copy the full SHA
    b7ee8ea View commit details
  2. Copy the full SHA
    fea43fb View commit details
13 changes: 5 additions & 8 deletions core/src/main/java/org/jruby/RubyException.java
Original file line number Diff line number Diff line change
@@ -253,19 +253,16 @@ public void forceBacktrace(IRubyObject backtrace) {
}

public IRubyObject getBacktrace() {
if (backtrace == null) {
initBacktrace();
}
if (backtrace == null) initBacktrace();

return backtrace;
}

public void initBacktrace() {
Ruby runtime = getRuntime();
if (backtraceData == null) {
backtrace = runtime.getNil();
} else {
backtrace = TraceType.generateMRIBacktrace(runtime, backtraceData.getBacktrace(runtime));
}

backtrace = backtraceData == null ?
runtime.getNil() : TraceType.generateMRIBacktrace(runtime, backtraceData.getBacktrace(runtime));
}

@Override
8 changes: 5 additions & 3 deletions core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
@@ -80,6 +80,7 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import static org.jruby.RubyBasicObject.UNDEF;
import static org.jruby.RubyEnumerator.enumeratorizeWithSize;
@@ -766,13 +767,14 @@ public static RubyArray local_variables(ThreadContext context, IRubyObject recv)
@JRubyMethod(name = "local_variables", module = true, visibility = PRIVATE, reads = SCOPE)
public static RubyArray local_variables19(ThreadContext context, IRubyObject recv) {
final Ruby runtime = context.runtime;
HashSet<String> encounteredLocalVariables = new HashSet<String>();
Set<ByteList> encounteredLocalVariables = new HashSet<>();
RubyArray allLocalVariables = runtime.newArray();
DynamicScope currentScope = context.getCurrentScope();

while (currentScope != null) {
for (String name : currentScope.getStaticScope().getVariables()) {
if (IdUtil.isLocal(name) && !encounteredLocalVariables.contains(name)) {
for (ByteList name : currentScope.getStaticScope().getByteVariables()) {
// FIXME: bytelist_love: Make charsetless checking of isLocal.
if (IdUtil.isLocal(name.toString()) && !encounteredLocalVariables.contains(name)) {
allLocalVariables.push(runtime.newSymbol(name));
encounteredLocalVariables.add(name);
}
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyThread.java
Original file line number Diff line number Diff line change
@@ -495,7 +495,7 @@ public IRubyObject path(ThreadContext context) {

@JRubyMethod
public IRubyObject to_s(ThreadContext context) {
return RubyString.newString(context.runtime, element.mriStyleString());
return RubyStackTraceElement.to_s_mri(context, element);
}

public static RubyArray newLocationArray(Ruby runtime, RubyStackTraceElement[] elements) {
3 changes: 1 addition & 2 deletions core/src/main/java/org/jruby/runtime/ThreadContext.java
Original file line number Diff line number Diff line change
@@ -764,11 +764,10 @@ public IRubyObject createCallerBacktrace(int level, Integer length, StackTraceEl
// MRI started returning [] instead of nil some time after 1.9 (#4891)
if (traceLength < 0) return runtime.newEmptyArray();

final RubyClass stringClass = runtime.getString();
final IRubyObject[] traceArray = new IRubyObject[traceLength];

for (int i = 0; i < traceLength; i++) {
traceArray[i] = new RubyString(runtime, stringClass, fullTrace[i + level].mriStyleString());
traceArray[i] = fullTrace[i + level].to_s_mri(this);
}

RubyArray backTrace = RubyArray.newArrayMayCopy(runtime, traceArray);
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package org.jruby.runtime.backtrace;

import org.jruby.RubyString;
import org.jruby.RubySymbol;
import org.jruby.runtime.ThreadContext;
import org.jruby.util.CommonByteLists;

public class RubyStackTraceElement implements java.io.Serializable {
public static final RubyStackTraceElement[] EMPTY_ARRAY = new RubyStackTraceElement[0];

@@ -72,6 +77,22 @@ public String toString() {
return asStackTraceElement().toString();
}

public static RubyString to_s_mri(ThreadContext context, RubyStackTraceElement element) {
RubySymbol methodSym = context.runtime.newSymbol(element.getMethodName());
RubyString line = context.runtime.newString();

line.setEncoding(methodSym.getEncoding());
line.cat(element.getFileName().getBytes());
line.cat(CommonByteLists.COLON);
line.append(context.runtime.newFixnum(element.getLineNumber()));
line.cat(CommonByteLists.SINGLE_QUOTE);
line.cat(methodSym.getBytes());
line.cat(new byte[] {'\''});

return line;
}

@Deprecated
public final CharSequence mriStyleString() {
// return fileName + ':' + lineNumber + ":in `" + methodName + '\'';
return new StringBuilder(fileName.length() + methodName.length() + 12).
34 changes: 12 additions & 22 deletions core/src/main/java/org/jruby/runtime/backtrace/TraceType.java
Original file line number Diff line number Diff line change
@@ -62,14 +62,14 @@ public String printBacktrace(RubyException exception, boolean console) {
return format.printBacktrace(exception, console);
}

public static void logBacktrace(RubyStackTraceElement[] trace) {
public static void logBacktrace(Ruby runtime, RubyStackTraceElement[] trace) {
if (trace == null) trace = RubyStackTraceElement.EMPTY_ARRAY;

final StringBuilder buffer = new StringBuilder(64 + trace.length * 48);

buffer.append("Backtrace generated:\n");

renderBacktraceJRuby(trace, buffer, false);
renderBacktraceJRuby(runtime, trace, buffer, false);

// NOTE: other logXxx method do not remove the new-line
// ... but if this is desired they should do so as well
@@ -246,7 +246,7 @@ public BacktraceData getBacktraceData(ThreadContext context, boolean nativeExcep
BacktraceData data = getBacktraceData(context, Thread.currentThread().getStackTrace(), nativeException);

context.runtime.incrementBacktraceCount();
if (RubyInstanceConfig.LOG_BACKTRACES) logBacktrace(data.getBacktrace(context.runtime));
if (RubyInstanceConfig.LOG_BACKTRACES) logBacktrace(context.runtime, data.getBacktrace(context.runtime));

return data;
}
@@ -269,7 +269,7 @@ public BacktraceData getIntegratedBacktraceData(ThreadContext context, StackTrac
BacktraceData data = useGather.getBacktraceData(context, javaTrace, false);

context.runtime.incrementBacktraceCount();
if (RubyInstanceConfig.LOG_BACKTRACES) logBacktrace(data.getBacktrace(context.runtime));
if (RubyInstanceConfig.LOG_BACKTRACES) logBacktrace(context.runtime, data.getBacktrace(context.runtime));

return data;
}
@@ -300,7 +300,7 @@ public String printBacktrace(RubyException exception, boolean console) {
}

public void renderBacktrace(RubyStackTraceElement[] elts, StringBuilder buffer, boolean color) {
renderBacktraceJRuby(elts, buffer, color);
renderBacktraceJRuby(null, elts, buffer, color);
}
};

@@ -385,14 +385,14 @@ protected static String printBacktraceMRI(RubyException exception, boolean conso
private static final String EVAL_COLOR = "\033[0;33m";
private static final String CLEAR_COLOR = "\033[0m";

public static String printBacktraceJRuby(RubyStackTraceElement[] frames, String type, String message, boolean color) {
public static String printBacktraceJRuby(Ruby runtime, RubyStackTraceElement[] frames, String type, String message, boolean color) {
if (frames == null) frames = RubyStackTraceElement.EMPTY_ARRAY;

StringBuilder buffer = new StringBuilder(64 + frames.length * 48);

buffer.append(type).append(": ").append(message).append('\n');

renderBacktraceJRuby(frames, buffer, color);
renderBacktraceJRuby(runtime, frames, buffer, color);

return buffer.toString();
}
@@ -410,11 +410,10 @@ protected static String printBacktraceJRuby(RubyException exception, boolean con
}
String type = exception.getMetaClass().getName();

RubyStackTraceElement[] frames = exception.getBacktraceElements();
return printBacktraceJRuby(frames, type, message, color);
return printBacktraceJRuby(exception.getRuntime(), exception.getBacktraceElements(), type, message, color);
}

private static void renderBacktraceJRuby(RubyStackTraceElement[] frames, StringBuilder buffer, boolean color) {
private static void renderBacktraceJRuby(Ruby runtime, RubyStackTraceElement[] frames, StringBuilder buffer, boolean color) {
// find longest method name
int longestMethod = 0;
for (RubyStackTraceElement frame : frames) {
@@ -438,7 +437,7 @@ private static void renderBacktraceJRuby(RubyStackTraceElement[] frames, StringB
buffer.append(" ");

// method name
String methodName = frame.getMethodName();
String methodName = runtime == null ? frame.getMethodName() : runtime.newSymbol(frame.getMethodName()).toString();
for (int j = 0; j < longestMethod - methodName.length(); j++) {
buffer.append(' ');
}
@@ -479,20 +478,11 @@ private static void renderBacktraceMRI(RubyStackTraceElement[] trace, String lin
public static IRubyObject generateMRIBacktrace(Ruby runtime, RubyStackTraceElement[] trace) {
if (trace == null) return runtime.getNil();

final RubyClass stringClass = runtime.getString();
ThreadContext context = runtime.getCurrentContext();
final IRubyObject[] traceArray = new IRubyObject[trace.length];
final StringBuilder line = new StringBuilder();

for (int i = 0; i < trace.length; i++) {
RubyStackTraceElement element = trace[i];
line.setLength(0);
line.append( element.getFileName() )
.append(':')
.append( element.getLineNumber() )
.append(":in `")
.append( element.getMethodName() )
.append('\'');
traceArray[i] = new RubyString(runtime, stringClass, line.toString()); // must toString
traceArray[i] = RubyStackTraceElement.to_s_mri(context, trace[i]);
}

return RubyArray.newArrayMayCopy(runtime, traceArray);
3 changes: 3 additions & 0 deletions core/src/main/java/org/jruby/util/CommonByteLists.java
Original file line number Diff line number Diff line change
@@ -6,6 +6,8 @@
public class CommonByteLists {
public static final ByteList AMPERSAND_AMPERSAND = new ByteList(new byte[] {'&', '&'});
public static final ByteList AREF_METHOD = new ByteList(new byte[] {'[', ']'});
public static final ByteList BACKTRACE_IN = new ByteList(new byte[] {':', 'i', 'n', '`'});
public static final ByteList COLON = new ByteList(new byte[] {':'});
public static final ByteList CONSTANTS = new ByteList(new byte[] {'c', 'o', 'n', 's', 't', 'a', 'n', 't', 's'});
public static final ByteList DEFINE_METHOD_METHOD = new ByteList(new byte[] {'d', 'e', 'f', 'i', 'n', 'e', '_', 'm', 'e', 't', 'h', 'o', 'd'});
public static final ByteList EACH = new ByteList(new byte[] {'e', 'a', 'c', 'h'});
@@ -15,6 +17,7 @@ public class CommonByteLists {
public static final ByteList NEW = new ByteList(new byte[] {'n', 'e', 'w'});
public static final ByteList NEW_METHOD = NEW;
public static final ByteList OR_OR = new ByteList(new byte[] {'|', '|'});
public static final ByteList SINGLE_QUOTE = new ByteList(new byte[] {'\''});
public static final ByteList STAR = new ByteList(new byte[] {'*'});
public static final ByteList USING_METHOD = new ByteList(new byte[] {'u', 's', 'i', 'n', 'g'});
}