|
9 | 9 | */ |
10 | 10 | package org.jruby.truffle.nodes.core; |
11 | 11 |
|
| 12 | +import com.oracle.truffle.api.frame.VirtualFrame; |
12 | 13 | import com.oracle.truffle.api.source.*; |
13 | 14 | import com.oracle.truffle.api.dsl.*; |
14 | 15 | import org.jruby.RubyThread.Status; |
| 16 | +import org.jruby.truffle.nodes.dispatch.DispatchHeadNode; |
15 | 17 | import org.jruby.truffle.runtime.*; |
16 | 18 | import org.jruby.truffle.runtime.control.RaiseException; |
17 | 19 | import org.jruby.truffle.runtime.control.ThreadExitException; |
@@ -195,6 +197,48 @@ public RubyNilClass pass() { |
195 | 197 |
|
196 | 198 | } |
197 | 199 |
|
| 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 | + |
198 | 242 | @CoreMethod(names = "status") |
199 | 243 | public abstract static class StatusNode extends CoreMethodNode { |
200 | 244 |
|
|
0 commit comments