Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Begin cleaning up RaiseException in prep for parallel exceptions.
Browse files Browse the repository at this point in the history
I have long wanted to set up a parallel exception class hierarchy
in Java to match the Ruby hierarchy, so you could rescue Ruby
exceptions by type. This is the beginning of that work.

See #4781
headius committed Sep 6, 2017
1 parent b6a4df9 commit ef66985
Showing 20 changed files with 186 additions and 159 deletions.
15 changes: 7 additions & 8 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -173,7 +173,6 @@
import java.lang.invoke.MethodHandle;
import java.lang.ref.WeakReference;
import java.net.BindException;
import java.nio.channels.ClosedChannelException;
import java.nio.charset.Charset;
import java.security.AccessControlException;
import java.security.SecureRandom;
@@ -3945,7 +3944,7 @@ public RaiseException newNameError(String message, String name, Throwable origEx
}
}

return new RaiseException(new RubyNameError(this, getNameError(), message, name), false);
return new RaiseException(new RubyNameError(this, getNameError(), message, name));
}

/**
@@ -4011,11 +4010,11 @@ public RaiseException newNoMethodError(String message, IRubyObject recv, String
* @return a new NoMethodError
*/
public RaiseException newNoMethodError(String message, String name, IRubyObject args) {
return new RaiseException(new RubyNoMethodError(this, getNoMethodError(), message, name, args), true);
return new RaiseException(new RubyNoMethodError(this, getNoMethodError(), message, name, args));
}

public RaiseException newLocalJumpError(RubyLocalJumpError.Reason reason, IRubyObject exitValue, String message) {
return new RaiseException(new RubyLocalJumpError(this, getLocalJumpError(), message, reason, exitValue), true);
return new RaiseException(new RubyLocalJumpError(this, getLocalJumpError(), message, reason, exitValue));
}

public RaiseException newLocalJumpErrorNoBlock() {
@@ -4144,7 +4143,7 @@ public RaiseException newInvalidByteSequenceError(String message) {
* @return
*/
public RaiseException newRaiseException(RubyClass exceptionClass, String message) {
return new RaiseException(this, exceptionClass, message, true);
return new RaiseException(this, exceptionClass, message);
}

/**
@@ -4160,9 +4159,9 @@ public RaiseException newRaiseException(RubyClass exceptionClass, String message
*/
private RaiseException newLightweightErrnoException(RubyClass exceptionClass, String message) {
if (RubyInstanceConfig.ERRNO_BACKTRACE) {
return new RaiseException(this, exceptionClass, message, true);
return new RaiseException(this, exceptionClass, message);
} else {
return new RaiseException(this, exceptionClass, ERRNO_BACKTRACE_MESSAGE, disabledBacktrace(), true);
return new RaiseException(this, exceptionClass, ERRNO_BACKTRACE_MESSAGE, disabledBacktrace());
}
}

@@ -4755,7 +4754,7 @@ public void secure(int level) {
public RaiseException newNameErrorObject(String message, IRubyObject name) {
RubyException error = new RubyNameError(this, getNameError(), message, name);

return new RaiseException(error, false);
return new RaiseException(error);
}

@Deprecated
9 changes: 7 additions & 2 deletions core/src/main/java/org/jruby/RubyException.java
Original file line number Diff line number Diff line change
@@ -226,13 +226,18 @@ public RubyStackTraceElement[] getBacktraceElements() {
return backtraceData.getBacktrace(getRuntime());
}

public void prepareBacktrace(ThreadContext context, boolean nativeException) {
public void prepareBacktrace(ThreadContext context) {
// if it's null, build a backtrace
if (backtraceData == null) {
backtraceData = context.runtime.getInstanceConfig().getTraceType().getBacktrace(context, nativeException);
backtraceData = context.runtime.getInstanceConfig().getTraceType().getBacktrace(context);
}
}

@Deprecated
public void prepareBacktrace(ThreadContext context, boolean ignored) {
prepareBacktrace(context);
}

/**
* Prepare an "integrated" backtrace that includes the normal Ruby trace plus non-filtered Java frames. Used by
* Java integration to show the Java frames for a JI-called method.
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
@@ -858,7 +858,7 @@ public static IRubyObject raise(ThreadContext context, IRubyObject recv, IRubyOb
case 0:
IRubyObject lastException = runtime.getGlobalVariables().get("$!");
if (lastException.isNil()) {
raise = new RaiseException(runtime, runtime.getRuntimeError(), "", false);
raise = new RaiseException(runtime, runtime.getRuntimeError(), "");
} else {
// non RubyException value is allowed to be assigned as $!.
raise = new RaiseException((RubyException) lastException);
3 changes: 1 addition & 2 deletions core/src/main/java/org/jruby/RubyThread.java
Original file line number Diff line number Diff line change
@@ -59,7 +59,6 @@
import java.util.concurrent.locks.Lock;

import org.jcodings.Encoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.exceptions.RaiseException;
@@ -1299,7 +1298,7 @@ public IRubyObject genericRaise(Ruby runtime, IRubyObject[] args, RubyThread cur
private IRubyObject prepareRaiseException(Ruby runtime, IRubyObject[] args, Block block) {
if (args.length == 0) {
if (errorInfo.isNil()) {
return new RaiseException(runtime, runtime.getRuntimeError(), "", false).getException();
return new RaiseException(runtime, runtime.getRuntimeError(), "").getException();
}
return errorInfo;
}
217 changes: 119 additions & 98 deletions core/src/main/java/org/jruby/exceptions/RaiseException.java
Original file line number Diff line number Diff line change
@@ -34,17 +34,14 @@
***** END LICENSE BLOCK *****/
package org.jruby.exceptions;

import java.io.PrintWriter;
import java.io.StringWriter;

import java.lang.reflect.Member;
import org.jruby.NativeException;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyException;
import org.jruby.RubyInstanceConfig;
import org.jruby.RubyString;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.JavaSites;
import org.jruby.runtime.RubyEvent;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.backtrace.RubyStackTraceElement;
@@ -53,10 +50,10 @@

public class RaiseException extends JumpException {
private static final long serialVersionUID = -7612079169559973951L;
public static final String NO_MESSAGE_AVAILABLE = "No message available";

private RubyException exception;
private String providedMessage;
private boolean nativeException;

/**
* Construct a new RaiseException to wrap the given Ruby exception for Java-land
@@ -65,10 +62,10 @@ public class RaiseException extends JumpException {
* This constructor will generate a backtrace using the Java
* stack trace and the interpreted Ruby frames for the current thread.
*
* @param actException The Ruby exception to wrap
* @param exception The Ruby exception to wrap
*/
public RaiseException(RubyException actException) {
this(actException, false);
public RaiseException(RubyException exception) {
this(exception.getMessageAsJavaString(), exception, null);
}

/**
@@ -82,112 +79,71 @@ public RaiseException(RubyException actException) {
* @param backtrace
*/
public RaiseException(RubyException exception, IRubyObject backtrace) {
super(exception.getMessageAsJavaString());
setException(exception, false);
preRaise(exception.getRuntime().getCurrentContext(), backtrace);
this(exception.getMessageAsJavaString(), exception, backtrace);
}

public RaiseException(Ruby runtime, RubyClass excptnClass, String msg, boolean nativeException) {
super(msg);
if (msg == null) {
msg = "No message available";
}
providedMessage = '(' + excptnClass.getName() + ") " + msg;
this.nativeException = nativeException;
final ThreadContext context = runtime.getCurrentContext();
setException((RubyException) Helpers.invoke(
context,
excptnClass,
"new",
RubyString.newUnicodeString(runtime, msg)),
nativeException);
preRaise(context);
}

public RaiseException(Ruby runtime, RubyClass excptnClass, String msg, IRubyObject backtrace, boolean nativeException) {
super(msg);
if (msg == null) {
msg = "No message available";
}
providedMessage = '(' + excptnClass.getName() + ") " + msg;
this.nativeException = nativeException;
final ThreadContext context = runtime.getCurrentContext();
setException((RubyException) Helpers.invoke(
context,
excptnClass,
"new",
RubyString.newUnicodeString(runtime, msg)),
nativeException);
preRaise(context, backtrace);
public RaiseException(Ruby runtime, RubyClass excptnClass, String msg) {
this(runtime, excptnClass, msg, null);
}

public RaiseException(RubyException exception, boolean nativeException) {
super(exception.getMessageAsJavaString());
this.nativeException = nativeException;
setException(exception, nativeException);
preRaise(exception.getRuntime().getCurrentContext());
}
public RaiseException(Ruby runtime, RubyClass excptnClass, String msg, IRubyObject backtrace) {
super(msg = guardMessage(msg));

public RaiseException(Throwable cause, NativeException nativeException) {
super(nativeException.getMessageAsJavaString(), cause);
providedMessage = super.getMessage(); // cause.getClass().getName() + ": " + message
setException(nativeException, true);
preRaise(nativeException.getRuntime().getCurrentContext(), nativeException.getCause().getStackTrace());
setStackTrace(RaiseException.javaTraceFromRubyTrace(exception.getBacktraceElements()));
}
ThreadContext context = runtime.getCurrentContext();

@Deprecated
public static RaiseException createNativeRaiseException(Ruby runtime, Throwable cause) {
return createNativeRaiseException(runtime, cause, null);
this.providedMessage = formatMessage(excptnClass, msg);
this.exception = constructRubyException(runtime, excptnClass, msg, context);

preRaise(context, backtrace);
}

@Deprecated
public static RaiseException createNativeRaiseException(Ruby runtime, Throwable cause, Member target) {
NativeException nativeException = new NativeException(runtime, runtime.getNativeException(), cause);
protected RaiseException(String providedMessage, RubyException exception, IRubyObject backtrace) {
super(providedMessage);

// FIXME: someday, add back filtering of reflection/handle methods between JRuby and target
this.providedMessage = providedMessage;
this.exception = exception;

return new RaiseException(cause, nativeException);
preRaise(exception.getRuntime().getCurrentContext(), backtrace);
}

private static RubyException constructRubyException(Ruby runtime, RubyClass excptnClass, String msg, ThreadContext context) {
return (RubyException) sites(context)._new.call(context, excptnClass, excptnClass, RubyString.newUnicodeString(runtime, guardMessage(msg)));
}

@Override
public String getMessage() {
if (providedMessage == null) {
providedMessage = '(' + exception.getMetaClass().getBaseName() + ") " + exception.message(exception.getRuntime().getCurrentContext()).asJavaString();
providedMessage = buildMessageFromException(exception);
}
return providedMessage;
}

/**
* Gets the exception
* @return Returns a RubyException
*/
public final RubyException getException() {
return exception;
}
private static String buildMessageFromException(RubyException exception) {
String baseName = exception.getMetaClass().getBaseName();
ThreadContext currentContext = exception.getRuntime().getCurrentContext();
String message = exception.message(currentContext).asJavaString();

private void preRaise(ThreadContext context) {
preRaise(context, (IRubyObject) null);
return formatMessage(baseName, message);
}

private void preRaise(ThreadContext context, StackTraceElement[] javaTrace) {
context.runtime.incrementExceptionCount();
doSetLastError(context);
doCallEventHook(context);
private static String formatMessage(RubyClass excptnClass, String msg) {
return formatMessage(excptnClass.getName(), guardMessage(msg));
}

if (RubyInstanceConfig.LOG_EXCEPTIONS) TraceType.logException(exception);
private static String guardMessage(String msg) {
return msg==null ? NO_MESSAGE_AVAILABLE : msg;
}

if (requiresBacktrace(context)) {
exception.prepareIntegratedBacktrace(context, javaTrace);
}
private static String formatMessage(String baseName, String message) {
return '(' + baseName + ") " + message;
}

private boolean requiresBacktrace(ThreadContext context) {
IRubyObject debugMode;
// We can only omit backtraces of descendents of Standard error for 'foo rescue nil'
return context.exceptionRequiresBacktrace ||
((debugMode = context.runtime.getGlobalVariables().get("$DEBUG")) != null && debugMode.isTrue()) ||
! context.runtime.getStandardError().isInstance(exception);
/**
* Gets the exception
* @return Returns a RubyException
*/
public final RubyException getException() {
return exception;
}

private void preRaise(ThreadContext context, IRubyObject backtrace) {
@@ -200,7 +156,7 @@ private void preRaise(ThreadContext context, IRubyObject backtrace) {
// We can only omit backtraces of descendents of Standard error for 'foo rescue nil'
if (requiresBacktrace(context)) {
if (backtrace == null) {
exception.prepareBacktrace(context, nativeException);
exception.prepareBacktrace(context);
} else {
exception.forceBacktrace(backtrace);
if ( backtrace.isNil() ) return;
@@ -217,6 +173,14 @@ private void preRaise(ThreadContext context, IRubyObject backtrace) {
}
}

private boolean requiresBacktrace(ThreadContext context) {
IRubyObject debugMode;
// We can only omit backtraces of descendents of Standard error for 'foo rescue nil'
return context.exceptionRequiresBacktrace ||
((debugMode = context.runtime.getGlobalVariables().get("$DEBUG")) != null && debugMode.isTrue()) ||
! context.runtime.getStandardError().isInstance(exception);
}

private static void doCallEventHook(final ThreadContext context) {
if (context.runtime.hasEventHooks()) {
context.runtime.callEventHooks(context, RubyEvent.RAISE, context.getFile(), context.getLine(), context.getFrameName(), context.getFrameKlazz());
@@ -227,20 +191,77 @@ private void doSetLastError(final ThreadContext context) {
context.runtime.getGlobalVariables().set("$!", exception);
}

/**
* Sets the exception
* @param newException The exception to set
*/
protected final void setException(RubyException newException, boolean nativeException) {
this.exception = newException;
this.nativeException = nativeException;
}

public static StackTraceElement[] javaTraceFromRubyTrace(RubyStackTraceElement[] trace) {
StackTraceElement[] newTrace = new StackTraceElement[trace.length];
for (int i = 0; i < newTrace.length; i++) {
newTrace[i] = trace[i].asStackTraceElement();
}
return newTrace;
}

private static JavaSites.RaiseExceptionSites sites(ThreadContext context) {
return context.sites.RaiseException;
}

@Deprecated
public RaiseException(Throwable cause, NativeException nativeException) {
this(nativeException.getMessageAsJavaString(), cause, nativeException, null, true);
preRaise(nativeException.getRuntime().getCurrentContext(), nativeException.getCause().getStackTrace());
setStackTrace(RaiseException.javaTraceFromRubyTrace(exception.getBacktraceElements()));
}

@Deprecated
private RaiseException(String providedMessage, Throwable cause, RubyException exception, IRubyObject backtrace, boolean nativeException) {
super(providedMessage, cause);
this.providedMessage = providedMessage;
this.exception = exception;
preRaise(exception.getRuntime().getCurrentContext(), backtrace);
}

@Deprecated
public RaiseException(RubyException exception, IRubyObject backtrace, boolean ignored) {
this(exception, backtrace);
}

@Deprecated
public RaiseException(Ruby runtime, RubyClass excptnClass, String msg, boolean ignored) {
this(runtime, excptnClass, msg);
}

@Deprecated
public RaiseException(Ruby runtime, RubyClass excptnClass, String msg, IRubyObject backtrace, boolean ignored) {
this(runtime, excptnClass, msg, backtrace);
}

@Deprecated
public RaiseException(RubyException exception, boolean ignored) {
this(exception);
}

@Deprecated
public static RaiseException createNativeRaiseException(Ruby runtime, Throwable cause) {
return createNativeRaiseException(runtime, cause, null);
}

@Deprecated
public static RaiseException createNativeRaiseException(Ruby runtime, Throwable cause, Member target) {
NativeException nativeException = new NativeException(runtime, runtime.getNativeException(), cause);

// FIXME: someday, add back filtering of reflection/handle methods between JRuby and target

return new RaiseException(cause, nativeException);
}

@Deprecated
private void preRaise(ThreadContext context, StackTraceElement[] javaTrace) {
context.runtime.incrementExceptionCount();
doSetLastError(context);
doCallEventHook(context);

if (RubyInstanceConfig.LOG_EXCEPTIONS) TraceType.logException(exception);

if (requiresBacktrace(context)) {
exception.prepareIntegratedBacktrace(context, javaTrace);
}
}
}
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ext/JRubyPOSIXHelper.java
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ public static void checkErrno(Ruby runtime, int result) {
String msg = errno.toString();
RubyClass errnoClass = runtime.getErrno().getClass(name);
if (errnoClass != null) {
throw new RaiseException(runtime, errnoClass, msg, true);
throw new RaiseException(runtime, errnoClass, msg);
}
}
}
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ext/ffi/InvalidMemoryIO.java
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ protected RubyClass getErrorClass(Ruby runtime) {
}

protected RaiseException ex() {
return new RaiseException(runtime, getErrorClass(runtime), message, true);
return new RaiseException(runtime, getErrorClass(runtime), message);
}

public ByteOrder order() {
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/ext/ffi/MemoryPointer.java
Original file line number Diff line number Diff line change
@@ -62,7 +62,7 @@ private final IRubyObject init(ThreadContext context, IRubyObject rbTypeSize, in
if (getMemoryIO() == null) {
Ruby runtime = context.runtime;
throw new RaiseException(runtime, runtime.getNoMemoryError(),
String.format("Failed to allocate %d objects of %d bytes", typeSize, count), true);
String.format("Failed to allocate %d objects of %d bytes", typeSize, count));
}

if (block.isGiven()) {
@@ -82,7 +82,7 @@ static MemoryPointer allocate(Ruby runtime, int typeSize, int count, boolean cle
MemoryIO io = Factory.getInstance().allocateDirectMemory(runtime, total > 0 ? total : 1, clear);
if (io == null) {
throw new RaiseException(runtime, runtime.getNoMemoryError(),
String.format("Failed to allocate %d objects of %d bytes", count, typeSize), true);
String.format("Failed to allocate %d objects of %d bytes", count, typeSize));
}

return new MemoryPointer(runtime, runtime.getFFI().memptrClass, io, total, typeSize);
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/ext/fiber/FiberQueue.java
Original file line number Diff line number Diff line change
@@ -98,7 +98,7 @@ public BlockingQueue<IRubyObject> getQueueSafe() {

public synchronized void checkShutdown() {
if (queue == null) {
throw new RaiseException(runtime, runtime.getThreadError(), "queue shut down", false);
throw new RaiseException(runtime, runtime.getThreadError(), "queue shut down");
}
}

@@ -122,7 +122,7 @@ public void push(ThreadContext context, final IRubyObject[] args) {
private IRubyObject pop(ThreadContext context, boolean should_block) {
final BlockingQueue<IRubyObject> queue = getQueueSafe();
if (!should_block && queue.size() == 0) {
throw new RaiseException(context.runtime, context.runtime.getThreadError(), "queue empty", false);
throw new RaiseException(context.runtime, context.runtime.getThreadError(), "queue empty");
}
try {
return context.getThread().executeTask(context, this, takeTask);
Original file line number Diff line number Diff line change
@@ -122,7 +122,7 @@ public static IRubyObject rbuf_fill(IRubyObject recv) {
return buf.concat(readItems);
} else {
RubyClass exc = (RubyClass)(recv.getRuntime().getModule("Timeout").getConstant("Error"));
throw new RaiseException(RubyException.newException(recv.getRuntime(), exc, "execution expired"),false);
throw new RaiseException(RubyException.newException(recv.getRuntime(), exc, "execution expired"));
}
} catch(IOException exception) {
throw recv.getRuntime().newIOErrorFromException(exception);
6 changes: 2 additions & 4 deletions core/src/main/java/org/jruby/ext/socket/SocketUtils.java
Original file line number Diff line number Diff line change
@@ -35,9 +35,7 @@
import jnr.netdb.Service;
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyBoolean;
import org.jruby.RubyClass;
import org.jruby.RubyFixnum;
import org.jruby.RubyInteger;
import org.jruby.RubyNumeric;
import org.jruby.RubyString;
@@ -468,7 +466,7 @@ public static IRubyObject getaddress(ThreadContext context, IRubyObject hostname
}

public static RuntimeException sockerr(Ruby runtime, String msg) {
return new RaiseException(runtime, runtime.getClass("SocketError"), msg, true);
return new RaiseException(runtime, runtime.getClass("SocketError"), msg);
}

public static RuntimeException sockerr_with_trace(Ruby runtime, String msg, StackTraceElement[] trace) {
@@ -478,7 +476,7 @@ public static RuntimeException sockerr_with_trace(Ruby runtime, String msg, Stac
for (int i = 0, il = trace.length; i < il; i++) {
sb.append(eol).append(trace[i].toString());
}
return new RaiseException(runtime, runtime.getClass("SocketError"), sb.toString(), true);
return new RaiseException(runtime, runtime.getClass("SocketError"), sb.toString());
}

public static int getPortFrom(ThreadContext context, IRubyObject _port) {
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ext/thread/Queue.java
Original file line number Diff line number Diff line change
@@ -494,7 +494,7 @@ public boolean isShutdown() {
public synchronized void checkShutdown() {
if (isShutdown()) {
Ruby runtime = getRuntime();
throw new RaiseException(runtime, runtime.getThreadError(), "queue shut down", false);
throw new RaiseException(runtime, runtime.getThreadError(), "queue shut down");
}
}

11 changes: 2 additions & 9 deletions core/src/main/java/org/jruby/ext/zlib/RubyZlib.java
Original file line number Diff line number Diff line change
@@ -34,9 +34,6 @@

import java.lang.reflect.Field;

import java.util.ArrayList;
import java.util.List;

import java.util.zip.CRC32;
import java.util.zip.Adler32;

@@ -52,11 +49,9 @@
import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyModule;

import org.jruby.ast.util.ArgsUtil;
import org.jruby.exceptions.RaiseException;

import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import static org.jruby.runtime.Visibility.*;
@@ -68,8 +63,6 @@

import com.jcraft.jzlib.JZlib;

import static org.jruby.CompatVersion.*;

@JRubyModule(name="Zlib")
public class RubyZlib {
// version
@@ -322,7 +315,7 @@ static RaiseException newDataError(Ruby runtime, String message) {

static RaiseException newZlibError(Ruby runtime, String klass, String message) {
RubyClass errorClass = runtime.getModule("Zlib").getClass(klass);
return new RaiseException(RubyException.newException(runtime, errorClass, message), true);
return new RaiseException(RubyException.newException(runtime, errorClass, message));
}

static RaiseException newGzipFileError(Ruby runtime, String message) {
@@ -346,7 +339,7 @@ static RaiseException newGzipFileError(Ruby runtime, String klass, String messag
RubyException excn = RubyException.newException(runtime, errorClass, message);
// TODO: not yet supported. rewrite GzipReader/Writer with Inflate/Deflate?
excn.setInstanceVariable("@input", runtime.getNil());
return new RaiseException(excn, true);
return new RaiseException(excn);
}

static int FIXNUMARG(IRubyObject obj, int ifnil) {
Original file line number Diff line number Diff line change
@@ -93,7 +93,7 @@ public void alias(String name, String oldName) {
GlobalVariable variable = globalVariables.get(name);

if (variable != null && oldVariable != variable && variable.isTracing()) {
throw new RaiseException(runtime, runtime.getRuntimeError(), "can't alias in tracer", false);
throw new RaiseException(runtime, runtime.getRuntimeError(), "can't alias in tracer");
}

globalVariables.put(name, oldVariable);
3 changes: 1 addition & 2 deletions core/src/main/java/org/jruby/management/Runtime.java
Original file line number Diff line number Diff line change
@@ -28,7 +28,6 @@
***** END LICENSE BLOCK *****/
package org.jruby.management;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.ref.SoftReference;
@@ -104,7 +103,7 @@ private static void dumpThread(Ruby ruby, RubyThread th, Gather gather, PrintWri
ThreadContext tc = th.getContext();
if (tc != null) {
RubyException exc = new RubyException(ruby, ruby.getRuntimeError(), "thread dump");
exc.setBacktraceData(gather.getBacktraceData(tc, th.getNativeThread().getStackTrace(), true));
exc.setBacktraceData(gather.getBacktraceData(tc, th.getNativeThread().getStackTrace()));
pw.println(Format.MRI.printBacktrace(exc, false));
} else {
pw.println(" [no longer alive]");
5 changes: 5 additions & 0 deletions core/src/main/java/org/jruby/runtime/JavaSites.java
Original file line number Diff line number Diff line change
@@ -40,6 +40,7 @@ public class JavaSites {
public final WarningSites Warning = new WarningSites();
public final ZlibSites Zlib = new ZlibSites();
public final TimeoutSites Timeout = new TimeoutSites();
public final RaiseExceptionSites RaiseException = new RaiseExceptionSites();

public static class BasicObjectSites {
public final CallSite respond_to = new FunctionalCachingCallSite("respond_to?");
@@ -409,6 +410,10 @@ public static class TimeoutSites {
public final CallSite timeout = new FunctionalCachingCallSite("timeout");
}

public static class RaiseExceptionSites {
public final CallSite _new = new FunctionalCachingCallSite("new");
}

public static class CheckedSites {
public final RespondToCallSite respond_to_X;
public final CachingCallSite respond_to_missing = new FunctionalCachingCallSite("respond_to_missing?");
6 changes: 3 additions & 3 deletions core/src/main/java/org/jruby/runtime/ThreadContext.java
Original file line number Diff line number Diff line change
@@ -722,7 +722,7 @@ public IRubyObject getConstant(String internedName) {
*/
public void renderCurrentBacktrace(StringBuilder sb) {
TraceType traceType = runtime.getInstanceConfig().getTraceType();
BacktraceData backtraceData = traceType.getBacktrace(this, false);
BacktraceData backtraceData = traceType.getBacktrace(this);
traceType.getFormat().renderBacktrace(backtraceData.getBacktrace(runtime), sb, false);
}

@@ -775,7 +775,7 @@ public IRubyObject createCallerLocations(int level, Integer length, StackTraceEl

private RubyStackTraceElement[] getFullTrace(Integer length, StackTraceElement[] stacktrace) {
if (length != null && length == 0) return RubyStackTraceElement.EMPTY_ARRAY;
return TraceType.Gather.CALLER.getBacktraceData(this, stacktrace, false).getBacktrace(runtime);
return TraceType.Gather.CALLER.getBacktraceData(this, stacktrace).getBacktrace(runtime);
}

private static int safeLength(int level, Integer length, RubyStackTraceElement[] trace) {
@@ -799,7 +799,7 @@ public RubyStackTraceElement[] createWarningBacktrace(Ruby runtime) {
}

public RubyStackTraceElement[] gatherCallerBacktrace() {
return Gather.CALLER.getBacktraceData(this, false).getBacktrace(runtime);
return Gather.CALLER.getBacktraceData(this).getBacktrace(runtime);
}

public boolean isEventHooksEnabled() {
40 changes: 26 additions & 14 deletions core/src/main/java/org/jruby/runtime/backtrace/TraceType.java
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.PrintStream;
import java.util.Arrays;

import org.jruby.Ruby;
import org.jruby.RubyArray;
@@ -40,11 +39,15 @@ public Format getFormat() {
* Get a normal Ruby backtrace, using the current Gather type.
*
* @param context
* @param nativeException
* @return
*/
public BacktraceData getBacktrace(ThreadContext context, boolean nativeException) {
return gather.getBacktraceData(context, nativeException);
public BacktraceData getBacktrace(ThreadContext context) {
return gather.getBacktraceData(context);
}

@Deprecated
public BacktraceData getBacktrace(ThreadContext context, boolean ignored) {
return getBacktrace(context);
}

/**
@@ -169,7 +172,7 @@ public enum Gather {
* Full raw backtraces with all Java frames included.
*/
RAW {
public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace, boolean nativeException) {
public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace) {
return new BacktraceData(
javaTrace,
BacktraceElement.EMPTY_ARRAY,
@@ -183,7 +186,7 @@ public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[]
* A backtrace with interpreted frames intact, but don't remove Java frames.
*/
FULL {
public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace, boolean nativeException) {
public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace) {
return new BacktraceData(
javaTrace,
context.getBacktrace(),
@@ -197,7 +200,7 @@ public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[]
* A normal Ruby-style backtrace, but which includes any non-org.jruby frames
*/
INTEGRATED {
public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace, boolean nativeException) {
public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace) {
return new BacktraceData(
javaTrace,
context.getBacktrace(),
@@ -211,7 +214,7 @@ public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[]
* Normal Ruby-style backtrace, showing only Ruby and core class methods.
*/
NORMAL {
public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace, boolean nativeException) {
public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace) {
return new BacktraceData(
javaTrace,
context.getBacktrace(),
@@ -225,7 +228,7 @@ public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[]
* Normal Ruby-style backtrace, showing only Ruby and core class methods.
*/
CALLER {
public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace, boolean nativeException) {
public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace) {
return new BacktraceData(
javaTrace,
context.getBacktrace(),
@@ -239,18 +242,22 @@ public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[]
* Gather backtrace data for a normal Ruby trace.
*
* @param context
* @param nativeException
* @return
*/
public BacktraceData getBacktraceData(ThreadContext context, boolean nativeException) {
BacktraceData data = getBacktraceData(context, Thread.currentThread().getStackTrace(), nativeException);
public BacktraceData getBacktraceData(ThreadContext context) {
BacktraceData data = getBacktraceData(context, Thread.currentThread().getStackTrace());

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

return data;
}

@Deprecated
public BacktraceData getBacktraceData(ThreadContext context, boolean ignored) {
return getBacktraceData(context);
}

/**
* Gather backtrace data for an integrated trace if the current gather type is "NORMAL", otherwise use the
* current gather type.
@@ -266,15 +273,20 @@ public BacktraceData getIntegratedBacktraceData(ThreadContext context, StackTrac
useGather = INTEGRATED;
}

BacktraceData data = useGather.getBacktraceData(context, javaTrace, false);
BacktraceData data = useGather.getBacktraceData(context, javaTrace);

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

return data;
}

public abstract BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace, boolean nativeException);
public abstract BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace);

@Deprecated
public BacktraceData getBacktraceData(ThreadContext context, StackTraceElement[] javaTrace, boolean ignored) {
return getBacktraceData(context, javaTrace);
}
}

public enum Format {
6 changes: 1 addition & 5 deletions core/src/main/java/org/jruby/util/io/Sockaddr.java
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@
import org.jruby.RubyBoolean;
import org.jruby.exceptions.RaiseException;
import org.jruby.ext.socket.Addrinfo;
import org.jruby.platform.Platform;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
@@ -24,9 +23,6 @@
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.Arrays;

import org.jruby.RubyString;
import org.jruby.ext.socket.SocketUtils;
@@ -349,7 +345,7 @@ public static AddressFamily getAddressFamilyFromSockaddr(Ruby runtime, ByteList
}

private static RuntimeException sockerr(Ruby runtime, String msg) {
return new RaiseException(runtime, runtime.getClass("SocketError"), msg, true);
return new RaiseException(runtime, runtime.getClass("SocketError"), msg);
}

public static SocketAddress sockaddrFromBytes(Ruby runtime, byte[] val) throws IOException {
Original file line number Diff line number Diff line change
@@ -63,7 +63,7 @@ public void testJavaGeneratedBacktrace() {
final int count = runtime.getBacktraceCount();

final RubyClass RuntimeError = runtime.getRuntimeError();
RaiseException re = new RaiseException(runtime, RuntimeError, "", false);
RaiseException re = new RaiseException(runtime, RuntimeError, "");
IRubyObject backtrace = re.getException().backtrace();
assertNotNil( backtrace );
assertTrue( ((RubyArray) backtrace).isEmpty() );
@@ -78,7 +78,7 @@ public void testJavaGeneratedNilBacktrace() {
IRubyObject backtrace = runtime.getNil();

final RubyClass RuntimeError = runtime.getRuntimeError();
RaiseException re = new RaiseException(runtime, RuntimeError, "", backtrace, false);
RaiseException re = new RaiseException(runtime, RuntimeError, "", backtrace);
backtrace = re.getException().backtrace();
assertNil( backtrace );

0 comments on commit ef66985

Please sign in to comment.