Skip to content

Commit

Permalink
Showing 9 changed files with 98 additions and 129 deletions.
36 changes: 19 additions & 17 deletions core/src/main/java/org/jruby/RubyException.java
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
* Copyright (C) 2004 Stefan Matthias Aust <sma@3plus4.de>
* Copyright (C) 2005 David Corbin <dcorbin@users.sf.net>
* Copyright (C) 2006 Michael Studman <codehaus@michaelstudman.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
@@ -68,7 +68,7 @@ protected RubyException(Ruby runtime, RubyClass rubyClass) {

public RubyException(Ruby runtime, RubyClass rubyClass, String message) {
super(runtime, rubyClass);

this.message = message == null ? runtime.getNil() : runtime.newString(message);
}

@@ -83,12 +83,16 @@ public IRubyObject initialize(IRubyObject[] args, Block block) {

@JRubyMethod
public IRubyObject backtrace() {
IRubyObject bt = getBacktrace();
return bt;
return getBacktrace();
}

@JRubyMethod(required = 1)
public IRubyObject set_backtrace(IRubyObject obj) {
setBacktrace(obj);
return backtrace();
}

private void setBacktrace(IRubyObject obj) {
if (obj.isNil()) {
backtrace = null;
} else if (isArrayOfStrings(obj)) {
@@ -98,15 +102,13 @@ public IRubyObject set_backtrace(IRubyObject obj) {
} else {
throw getRuntime().newTypeError("backtrace must be Array of String or a single String");
}

return backtrace();
}

@JRubyMethod(omit = true)
public IRubyObject backtrace_locations(ThreadContext context) {
Ruby runtime = context.runtime;
RubyStackTraceElement[] elements = backtraceData.getBacktrace(runtime);

return RubyThread.Location.newLocationArray(runtime, elements);
}

@@ -239,17 +241,17 @@ public void prepareIntegratedBacktrace(ThreadContext context, StackTraceElement[
}

public void forceBacktrace(IRubyObject backtrace) {
backtraceData = BacktraceData.EMPTY;
set_backtrace(backtrace);
backtraceData = (backtrace != null && backtrace.isNil()) ? null : BacktraceData.EMPTY;
setBacktrace(backtrace);
}

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

public void initBacktrace() {
Ruby runtime = getRuntime();
if (backtraceData == null) {
@@ -300,16 +302,16 @@ public void printBacktrace(PrintStream errorStream, int skip) {
private void printStackTraceLine(PrintStream errorStream, IRubyObject stackTraceLine) {
errorStream.print("\tfrom " + stackTraceLine + '\n');
}

private boolean isArrayOfStrings(IRubyObject backtrace) {
if (!(backtrace instanceof RubyArray)) return false;
if (!(backtrace instanceof RubyArray)) return false;

IRubyObject[] elements = ((RubyArray) backtrace).toJavaArray();

for (int i = 0 ; i < elements.length ; i++) {
if (!(elements[i] instanceof RubyString)) return false;
}

return true;
}

9 changes: 5 additions & 4 deletions core/src/main/java/org/jruby/exceptions/RaiseException.java
Original file line number Diff line number Diff line change
@@ -131,13 +131,13 @@ public RaiseException(Ruby runtime, RubyClass excptnClass, String msg, IRubyObje
preRaise(context, backtrace);
}

public RaiseException(RubyException exception, boolean isNativeException) {
public RaiseException(RubyException exception, boolean nativeException) {
super(exception.message.toString());
if (DEBUG) {
Thread.dumpStack();
}
this.nativeException = isNativeException;
setException(exception, isNativeException);
this.nativeException = nativeException;
setException(exception, nativeException);
preRaise(exception.getRuntime().getCurrentContext());
}

@@ -213,7 +213,7 @@ private boolean requiresBacktrace(ThreadContext context) {
// We can only omit backtraces of descendents of Standard error for 'foo rescue nil'
return context.exceptionRequiresBacktrace ||
(debugMode != null && debugMode.isTrue()) ||
!exception.kind_of_p(context, context.runtime.getStandardError()).isTrue();
! context.runtime.getStandardError().isInstance(exception);
}

private void preRaise(ThreadContext context, IRubyObject backtrace) {
@@ -229,6 +229,7 @@ private void preRaise(ThreadContext context, IRubyObject backtrace) {
exception.prepareBacktrace(context, nativeException);
} else {
exception.forceBacktrace(backtrace);
if ( backtrace.isNil() ) return;
}

// call Throwable.setStackTrace so that when RaiseException appears nested inside another exception,
62 changes: 62 additions & 0 deletions core/src/test/java/org/jruby/exceptions/TestRaiseException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2015 JRuby.
*/
package org.jruby.exceptions;

import org.jruby.RubyArray;
import org.jruby.RubyClass;
import org.jruby.RubyException;
import org.jruby.runtime.backtrace.RubyStackTraceElement;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.test.TestRubyBase;

public class TestRaiseException extends TestRubyBase {

public void testBacktrace() {
IRubyObject ex = runtime.evalScriptlet("ex = nil; " +
"begin; raise 'with-bracktrace'; rescue => e; ex = e end; ex"
);
assertEquals("org.jruby.RubyException", ex.getClass().getName());
IRubyObject backtrace = ((RubyException) ex).getBacktrace();
assertNotNil( backtrace );
assertFalse( ((RubyArray) backtrace).isEmpty() );
}

public void testJavaGeneratedBacktrace() {
final int count = runtime.getBacktraceCount();

final RubyClass RuntimeError = runtime.getRuntimeError();
RaiseException re = new RaiseException(runtime, RuntimeError, "", false);
IRubyObject backtrace = re.getException().backtrace();
assertNotNil( backtrace );
assertTrue( ((RubyArray) backtrace).isEmpty() );

assertNotSame( RubyStackTraceElement.EMPTY_ARRAY, re.getException().getBacktraceElements() );

assertEquals( count + 1, runtime.getBacktraceCount() );
}

public void testJavaGeneratedNilBacktrace() {
final int count = runtime.getBacktraceCount();
IRubyObject backtrace = runtime.getNil();

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

assertNil( re.getException().getBacktrace() );
assertSame( RubyStackTraceElement.EMPTY_ARRAY, re.getException().getBacktraceElements() );

assertEquals( count, runtime.getBacktraceCount() );
}

private void assertNil(IRubyObject val) {
assertTrue("expected: " + val.inspect() + " to be nil", val.isNil());
}

private void assertNotNil(IRubyObject val) {
assertFalse("expected: " + val.inspect() + " to not be nil", val.isNil());
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* Copyright (c) 2015, 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:
*
@@ -38,14 +38,9 @@ public abstract class ReadBERNode extends PackNode {

@Child private FixnumOrBignumNode fixnumOrBignumNode;

private final int length;
private final boolean ignoreStar;

public ReadBERNode(RubyContext context, int length, boolean ignoreStar) {
public ReadBERNode(RubyContext context) {
super(context);
fixnumOrBignumNode = FixnumOrBignumNode.create(context, null);
this.length = length;
this.ignoreStar = ignoreStar;
}

@Specialization
Original file line number Diff line number Diff line change
@@ -97,10 +97,10 @@ public Object read(VirtualFrame frame, byte[] source) {

if (a != -1 && b != -1) {
if (c == -1 && s == '=') {
if ((b & 15) > 0) throw new FormatException("invalid base64");
if ((b & 15) != 0) throw new FormatException("invalid base64");
lElem[index++] = (byte)((a << 2 | b >> 4) & 255);
} else if(c != -1 && s == '=') {
if ((c & 3) > 0) throw new FormatException("invalid base64");
if ((c & 3) != 0) throw new FormatException("invalid base64");
lElem[index++] = (byte)((a << 2 | b >> 4) & 255);
lElem[index++] = (byte)((b << 4 | c >> 2) & 255);
}
Original file line number Diff line number Diff line change
@@ -31,11 +31,8 @@
})
public abstract class ReadMIMEStringNode extends PackNode {

private final int length;

public ReadMIMEStringNode(RubyContext context, int length) {
public ReadMIMEStringNode(RubyContext context) {
super(context);
this.length = length;
}

@Specialization
@@ -44,8 +41,6 @@ public Object read(VirtualFrame frame, byte[] source) {

final ByteBuffer encode = ByteBuffer.wrap(source, getSourcePosition(frame), getSourceLength(frame) - getSourcePosition(frame));

int occurrences = length;

byte[] lElem = new byte[Math.max(encode.remaining(),0)];
int index = 0;
for(;;) {
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* Copyright (c) 2015, 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:
*
@@ -37,31 +37,10 @@
})
public abstract class ReadUUStringNode extends PackNode {

private final int length;
private final boolean ignoreStar;

public ReadUUStringNode(RubyContext context, int length, boolean ignoreStar) {
public ReadUUStringNode(RubyContext context) {
super(context);
this.length = length;
this.ignoreStar = ignoreStar;
}

/*@Specialization
public Object write(long bytes) {
throw new NoImplicitConversionException(bytes, "String");
}

@Specialization(guards = "isEmpty(bytes)")
public Object writeEmpty(VirtualFrame frame, ByteList bytes) {
return null;
}
@Specialization(guards = "!isEmpty(bytes)")
public Object write(VirtualFrame frame, ByteList bytes) {
writeBytes(frame, encode(bytes));
return null;
}*/

@Specialization
protected Object encode(VirtualFrame frame, byte[] source) {
CompilerDirectives.transferToInterpreter();
Original file line number Diff line number Diff line change
@@ -183,7 +183,7 @@ public void exitUtf8Character(PackParser.Utf8CharacterContext ctx) {
public void exitBerInteger(PackParser.BerIntegerContext ctx) {
appendNode(applyCount(ctx.count(),
WriteValueNodeGen.create(context,
ReadBERNodeGen.create(context, 0, false, new SourceNode()))));
ReadBERNodeGen.create(context, new SourceNode()))));
}

@Override
@@ -276,45 +276,18 @@ public void exitHexStringLowFirst(PackParser.HexStringLowFirstContext ctx) {
public void exitUuString(PackParser.UuStringContext ctx) {
//unify(PackEncoding.US_ASCII);

final int length;
final boolean ignoreStar;

if (ctx.count() == null) {
length = 1;
ignoreStar = false;
} else if (ctx.count().INT() == null) {
length = 0;
ignoreStar = true;
} else {
length = Integer.parseInt(ctx.count().INT().getText());
ignoreStar = false;
}

appendNode(
WriteValueNodeGen.create(context,
ReadUUStringNodeGen.create(context, length, ignoreStar,
ReadUUStringNodeGen.create(context,
new SourceNode())));
}

@Override
public void exitMimeString(PackParser.MimeStringContext ctx) {
//unify(PackEncoding.US_ASCII);

int length;

if (ctx.INT() == null) {
length = 72;
} else {
length = Integer.parseInt(ctx.INT().getText());

if (length <= 1) {
length = 72;
}
}

appendNode(WriteValueNodeGen.create(context,
ReadMIMEStringNodeGen.create(context, length, new SourceNode())));

ReadMIMEStringNodeGen.create(context, new SourceNode())));
}

@Override
@@ -505,40 +478,6 @@ private PackNode readIntegerX(int size, ByteOrder byteOrder, PackNode readNode,
return convert;
}

private void binaryString(byte padding, boolean padOnNull, boolean appendNull, PackParser.CountContext count) {
unify(PackEncoding.ASCII_8BIT);

final boolean pad;
final int width;

if (count != null && count.INT() != null) {
pad = true;
width = Integer.parseInt(count.INT().getText());
} else {
pad = false;

if (count != null && count.INT() == null) {
padOnNull = false;
}

width = 1;
}

final boolean takeAll;

if (count != null && count.INT() == null) {
takeAll = true;
} else {
takeAll = false;
}

appendNode(WriteBinaryStringNodeGen.create(context, pad, padOnNull,
width, padding, takeAll, appendNull,
ReadStringNodeGen.create(context, true, "to_str",
false, context.getCoreLibrary().getNilObject(), new SourceNode())));

}

private void bitString(ByteOrder byteOrder, PackParser.CountContext ctx) {
final boolean star;
final int length;
@@ -587,9 +526,5 @@ private PackNode applyCount(PackParser.CountContext count, PackNode node) {
return new StarNode(context, node);
}
}

private void unify(PackEncoding other) {
encoding = encoding.unifyWith(other);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* Copyright (c) 2015, 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:
*
@@ -11,7 +11,7 @@

public class MissingValue {

public static MissingValue INSTANCE = new MissingValue();
public static final MissingValue INSTANCE = new MissingValue();

private MissingValue() {
}

0 comments on commit faf6e90

Please sign in to comment.