Skip to content

Commit 337c3c6

Browse files
eregonbjfish
authored andcommitted
Use separate subclasses for SyntaxError and SystemExit to cleanup the code
* Makes exception interop simpler. TODO: * Nodes for allocate, and accessing the exit stauts. * Store sourceLocation directly as a field of RubySyntaxError. * Replace needless IsANode with instanceof for checking if SystemExit or SyntaxError.
1 parent a0c1ccb commit 337c3c6

File tree

3 files changed

+115
-78
lines changed

3 files changed

+115
-78
lines changed

src/main/java/org/truffleruby/core/exception/RubyException.java

Lines changed: 2 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,12 @@
1111

1212
import java.util.Set;
1313

14-
import com.oracle.truffle.api.CompilerDirectives;
15-
import com.oracle.truffle.api.dsl.Cached;
1614
import com.oracle.truffle.api.dsl.CachedContext;
1715
import com.oracle.truffle.api.interop.ExceptionType;
1816
import com.oracle.truffle.api.interop.InteropLibrary;
19-
import com.oracle.truffle.api.interop.UnsupportedMessageException;
20-
import com.oracle.truffle.api.library.CachedLibrary;
2117
import com.oracle.truffle.api.library.ExportLibrary;
2218
import com.oracle.truffle.api.library.ExportMessage;
2319
import com.oracle.truffle.api.nodes.Node;
24-
import com.oracle.truffle.api.object.DynamicObjectLibrary;
25-
import com.oracle.truffle.api.source.SourceSection;
2620
import org.truffleruby.RubyContext;
2721
import org.truffleruby.RubyLanguage;
2822
import org.truffleruby.core.VMPrimitiveNodes.VMRaiseExceptionNode;
@@ -34,7 +28,6 @@
3428
import org.truffleruby.language.Nil;
3529
import org.truffleruby.language.RubyDynamicObject;
3630
import org.truffleruby.language.backtrace.Backtrace;
37-
import org.truffleruby.language.objects.IsANode;
3831
import org.truffleruby.language.objects.ObjectGraph;
3932
import org.truffleruby.language.objects.ObjectGraphNode;
4033

@@ -100,78 +93,9 @@ public RuntimeException throwException(
10093
throw VMRaiseExceptionNode.reRaiseException(context, this);
10194
}
10295

103-
// TODO (eregon, 01 Nov 2020): these message implementations would be nicer with separate subclasses for SystemExit and SyntaxError.
104-
105-
@ExportMessage
106-
public ExceptionType getExceptionType(
107-
@Cached IsANode isANode) {
108-
// @CachedContext does not work here when running "mx tck"
109-
final RubyContext context = getMetaClass().fields.getContext();
110-
if (isANode.executeIsA(this, context.getCoreLibrary().systemExitClass)) {
111-
return ExceptionType.EXIT;
112-
} else if (isANode.executeIsA(this, context.getCoreLibrary().syntaxErrorClass)) {
113-
return ExceptionType.PARSE_ERROR;
114-
} else {
115-
return ExceptionType.RUNTIME_ERROR;
116-
}
117-
}
118-
119-
@ExportMessage
120-
public int getExceptionExitStatus(
121-
@CachedLibrary("this") InteropLibrary interopLibrary,
122-
@CachedLibrary("this") DynamicObjectLibrary objectLibrary) throws UnsupportedMessageException {
123-
if (interopLibrary.getExceptionType(this) == ExceptionType.EXIT) {
124-
return (int) objectLibrary.getOrDefault(this, "@status", 1);
125-
} else {
126-
throw UnsupportedMessageException.create();
127-
}
128-
}
129-
130-
@ExportMessage
131-
public boolean isExceptionIncompleteSource(
132-
@CachedLibrary("this") InteropLibrary interopLibrary) throws UnsupportedMessageException {
133-
if (interopLibrary.getExceptionType(this) == ExceptionType.PARSE_ERROR) {
134-
return false; // Unknown
135-
} else {
136-
throw UnsupportedMessageException.create();
137-
}
138-
}
139-
140-
@TruffleBoundary
141-
@ExportMessage
142-
public boolean hasSourceLocation(
143-
@CachedLibrary("this") InteropLibrary interopLibrary) {
144-
try {
145-
if (interopLibrary.getExceptionType(this) == ExceptionType.PARSE_ERROR &&
146-
backtrace != null &&
147-
backtrace.getSourceLocation() != null) {
148-
return true;
149-
} else {
150-
final Node location = getLocation();
151-
return location != null && location.getEncapsulatingSourceSection() != null;
152-
}
153-
} catch (UnsupportedMessageException e) {
154-
throw CompilerDirectives.shouldNotReachHere(e);
155-
}
156-
}
157-
158-
@TruffleBoundary
15996
@ExportMessage
160-
public SourceSection getSourceLocation(
161-
@CachedLibrary("this") InteropLibrary interopLibrary) throws UnsupportedMessageException {
162-
if (interopLibrary.getExceptionType(this) == ExceptionType.PARSE_ERROR &&
163-
backtrace != null &&
164-
backtrace.getSourceLocation() != null) {
165-
return backtrace.getSourceLocation();
166-
} else {
167-
final Node location = getLocation();
168-
SourceSection sourceSection = location != null ? location.getEncapsulatingSourceSection() : null;
169-
if (sourceSection != null) {
170-
return sourceSection;
171-
} else {
172-
throw UnsupportedMessageException.create();
173-
}
174-
}
97+
public ExceptionType getExceptionType() {
98+
return ExceptionType.RUNTIME_ERROR;
17599
}
176100
// endregion
177101

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. This
3+
* code is released under a tri EPL/GPL/LGPL license. You can use it,
4+
* redistribute it and/or modify it under the terms of the:
5+
*
6+
* Eclipse Public License version 2.0, or
7+
* GNU General Public License version 2, or
8+
* GNU Lesser General Public License version 2.1.
9+
*/
10+
package org.truffleruby.core.exception;
11+
12+
import org.truffleruby.core.klass.RubyClass;
13+
import org.truffleruby.language.backtrace.Backtrace;
14+
15+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
16+
import com.oracle.truffle.api.interop.ExceptionType;
17+
import com.oracle.truffle.api.interop.InteropLibrary;
18+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
19+
import com.oracle.truffle.api.library.ExportLibrary;
20+
import com.oracle.truffle.api.library.ExportMessage;
21+
import com.oracle.truffle.api.nodes.Node;
22+
import com.oracle.truffle.api.object.Shape;
23+
import com.oracle.truffle.api.source.SourceSection;
24+
25+
@ExportLibrary(InteropLibrary.class)
26+
public class RubySyntaxError extends RubyException {
27+
28+
public RubySyntaxError(RubyClass rubyClass, Shape shape, Object message, Backtrace backtrace, Object cause) {
29+
super(rubyClass, shape, message, backtrace, cause);
30+
}
31+
32+
// region Exception interop
33+
@ExportMessage
34+
public ExceptionType getExceptionType() {
35+
return ExceptionType.PARSE_ERROR;
36+
}
37+
38+
@ExportMessage
39+
public boolean isExceptionIncompleteSource() {
40+
return false; // Unknown
41+
}
42+
43+
@TruffleBoundary
44+
@ExportMessage
45+
public boolean hasSourceLocation() {
46+
if (backtrace != null && backtrace.getSourceLocation() != null) {
47+
return true;
48+
} else {
49+
final Node location = getLocation();
50+
return location != null && location.getEncapsulatingSourceSection() != null;
51+
}
52+
}
53+
54+
@TruffleBoundary
55+
@ExportMessage
56+
public SourceSection getSourceLocation() throws UnsupportedMessageException {
57+
if (backtrace != null && backtrace.getSourceLocation() != null) {
58+
return backtrace.getSourceLocation();
59+
} else {
60+
final Node location = getLocation();
61+
SourceSection sourceSection = location != null ? location.getEncapsulatingSourceSection() : null;
62+
if (sourceSection != null) {
63+
return sourceSection;
64+
} else {
65+
throw UnsupportedMessageException.create();
66+
}
67+
}
68+
}
69+
// endregion
70+
71+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. This
3+
* code is released under a tri EPL/GPL/LGPL license. You can use it,
4+
* redistribute it and/or modify it under the terms of the:
5+
*
6+
* Eclipse Public License version 2.0, or
7+
* GNU General Public License version 2, or
8+
* GNU Lesser General Public License version 2.1.
9+
*/
10+
package org.truffleruby.core.exception;
11+
12+
import org.truffleruby.core.klass.RubyClass;
13+
import org.truffleruby.language.backtrace.Backtrace;
14+
15+
import com.oracle.truffle.api.interop.ExceptionType;
16+
import com.oracle.truffle.api.interop.InteropLibrary;
17+
import com.oracle.truffle.api.library.ExportLibrary;
18+
import com.oracle.truffle.api.library.ExportMessage;
19+
import com.oracle.truffle.api.object.Shape;
20+
21+
@ExportLibrary(InteropLibrary.class)
22+
public class RubySystemExit extends RubyException {
23+
24+
public int exitStatus = 1;
25+
26+
public RubySystemExit(RubyClass rubyClass, Shape shape, Object message, Backtrace backtrace, Object cause) {
27+
super(rubyClass, shape, message, backtrace, cause);
28+
}
29+
30+
// region Exception interop
31+
@ExportMessage
32+
public ExceptionType getExceptionType() {
33+
return ExceptionType.EXIT;
34+
}
35+
36+
@ExportMessage
37+
public int getExceptionExitStatus() {
38+
return exitStatus;
39+
}
40+
// endregion
41+
42+
}

0 commit comments

Comments
 (0)