Skip to content

Commit 928acd1

Browse files
committed
[Truffle] Thread#raise.
1 parent 0e93ab9 commit 928acd1

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

core/src/main/java/org/jruby/truffle/nodes/core/ThreadNodes.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
*/
1010
package org.jruby.truffle.nodes.core;
1111

12+
import com.oracle.truffle.api.frame.VirtualFrame;
1213
import com.oracle.truffle.api.source.*;
1314
import com.oracle.truffle.api.dsl.*;
1415
import org.jruby.RubyThread.Status;
16+
import org.jruby.truffle.nodes.dispatch.DispatchHeadNode;
1517
import org.jruby.truffle.runtime.*;
1618
import org.jruby.truffle.runtime.control.RaiseException;
1719
import org.jruby.truffle.runtime.control.ThreadExitException;
@@ -195,6 +197,48 @@ public RubyNilClass pass() {
195197

196198
}
197199

200+
@CoreMethod(names = "raise", required = 1, optional = 1)
201+
public abstract static class RaiseNode extends CoreMethodNode {
202+
203+
@Child protected DispatchHeadNode initialize;
204+
205+
public RaiseNode(RubyContext context, SourceSection sourceSection) {
206+
super(context, sourceSection);
207+
initialize = new DispatchHeadNode(context);
208+
}
209+
210+
public RaiseNode(RaiseNode prev) {
211+
super(prev);
212+
initialize = prev.initialize;
213+
}
214+
215+
@Specialization
216+
public RubyNilClass raise(VirtualFrame frame, RubyThread thread, RubyString message, UndefinedPlaceholder undefined) {
217+
return raise(frame, thread, getContext().getCoreLibrary().getRuntimeErrorClass(), message);
218+
}
219+
220+
@Specialization
221+
public RubyNilClass raise(VirtualFrame frame, final RubyThread thread, RubyClass exceptionClass, RubyString message) {
222+
final RubyBasicObject exception = exceptionClass.newInstance(this);
223+
initialize.call(frame, exception, "initialize", null, message);
224+
final RaiseException exceptionWrapper = new RaiseException(exception);
225+
226+
getContext().getSafepointManager().pauseAllThreadsAndExecute(new Consumer<Boolean>() {
227+
228+
@Override
229+
public void accept(Boolean isPausingThread) {
230+
if (getContext().getThreadManager().getCurrentThread() == thread) {
231+
throw exceptionWrapper;
232+
}
233+
}
234+
235+
});
236+
237+
return getContext().getCoreLibrary().getNilObject();
238+
}
239+
240+
}
241+
198242
@CoreMethod(names = "status")
199243
public abstract static class StatusNode extends CoreMethodNode {
200244

core/src/main/java/org/jruby/truffle/runtime/subsystems/SafepointManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public void poll() {
7777
}
7878

7979
public void pauseAllThreadsAndExecute(final Consumer<Boolean> action) {
80-
CompilerAsserts.neverPartOfCompilation();
80+
CompilerDirectives.transferToInterpreter();
8181

8282
try {
8383
lock.lock();

0 commit comments

Comments
 (0)