Skip to content

Commit e1dc3a3

Browse files
bjfisheregon
authored andcommitted
Fixed status and output when SystemExit is subclassed and raised
1 parent 6326341 commit e1dc3a3

File tree

6 files changed

+30
-5
lines changed

6 files changed

+30
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Bug fixes:
2121
* Fixed parsing of `--jvm` as an application argument (#2108).
2222
* Fix `rb_rescue2` to ignore the end marker `(VALUE)0` (#2127, #2130).
2323
* Fix `String#{chomp, chomp!}` issue with invalid encoded strings (#2133).
24+
* Fix status and output when SystemExit is subclassed and raised (#2128)
2425

2526
Compatibility:
2627

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
require_relative '../../spec_helper'
2+
3+
describe "SystemExit" do
4+
it "sets the exit status and exits silently when raised" do
5+
code = 'raise SystemExit.new(7)'
6+
result = ruby_exe(code, args: "2>&1")
7+
result.should == ""
8+
$?.exitstatus.should == 7
9+
end
10+
11+
it "sets the exit status and exits silently when raised when subclassed" do
12+
code = 'class CustomExit < SystemExit; end; raise CustomExit.new(8)'
13+
result = ruby_exe(code, args: "2>&1")
14+
result.should == ""
15+
$?.exitstatus.should == 8
16+
end
17+
end
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
slow:SystemExit sets the exit status and exits silently when raised
2+
slow:SystemExit sets the exit status and exits silently when raised when subclassed

src/main/java/org/truffleruby/core/kernel/AtExitManager.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616

1717
import org.truffleruby.RubyContext;
1818
import org.truffleruby.core.exception.RubyException;
19-
import org.truffleruby.core.klass.RubyClass;
2019
import org.truffleruby.core.proc.ProcOperations;
2120
import org.truffleruby.core.proc.RubyProc;
2221
import org.truffleruby.language.control.ExitException;
2322
import org.truffleruby.language.control.RaiseException;
2423

2524
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
25+
import org.truffleruby.language.objects.IsANode;
2626

2727
public class AtExitManager {
2828

@@ -83,9 +83,9 @@ public List<RubyProc> getHandlers() {
8383
}
8484

8585
public static boolean isSilentException(RubyContext context, RubyException rubyException) {
86-
final RubyClass logicalClass = rubyException.getLogicalClass();
87-
return logicalClass == context.getCoreLibrary().systemExitClass ||
88-
logicalClass == context.getCoreLibrary().signalExceptionClass;
86+
final IsANode isANode = IsANode.getUncached();
87+
return isANode.executeIsA(rubyException, context.getCoreLibrary().systemExitClass) ||
88+
isANode.executeIsA(rubyException, context.getCoreLibrary().signalExceptionClass);
8989
}
9090

9191
private static void handleAtExitException(RubyContext context, RubyException rubyException) {

src/main/java/org/truffleruby/language/exceptions/TopLevelRaiseHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.truffleruby.language.dispatch.DispatchNode;
2121

2222
import com.oracle.truffle.api.CompilerDirectives;
23+
import org.truffleruby.language.objects.IsANodeGen;
2324

2425
public class TopLevelRaiseHandler extends RubyContextNode {
2526

@@ -66,7 +67,7 @@ public int execute(Runnable body) {
6667
}
6768

6869
private int statusFromException(RubyException exception) {
69-
if (exception.getLogicalClass() == coreLibrary().systemExitClass) {
70+
if (IsANodeGen.getUncached().executeIsA(exception, coreLibrary().systemExitClass)) {
7071
final Object status = DynamicObjectLibrary.getUncached().getOrDefault(exception, "@status", null);
7172
return IntegerCastNodeGen.getUncached().executeCastInt(status);
7273
} else {

src/main/java/org/truffleruby/language/objects/IsANode.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ public static IsANode create() {
2828
return IsANodeGen.create();
2929
}
3030

31+
public static IsANode getUncached() {
32+
return IsANodeGen.getUncached();
33+
}
34+
3135
public abstract boolean executeIsA(Object self, RubyModule module);
3236

3337
@Specialization(

0 commit comments

Comments
 (0)