@@ -296,21 +296,23 @@ private void threadMain(RubyThread thread, Node currentNode, Supplier<Object> ta
296
296
final Object result = task .get ();
297
297
setThreadValue (thread , result );
298
298
// Handlers in the same order as in FiberManager
299
+ // Each catch must either setThreadValue() (before rethrowing) or setException()
299
300
} catch (KillException e ) {
300
301
setThreadValue (thread , Nil .INSTANCE );
301
302
} catch (ThreadDeath e ) { // Context#close(true)
303
+ setThreadValue (thread , Nil .INSTANCE );
302
304
throw e ;
303
305
} catch (RaiseException e ) {
304
306
setException (thread , e .getException (), currentNode );
305
307
} catch (DynamicReturnException e ) {
306
308
setException (thread , context .getCoreExceptions ().unexpectedReturn (currentNode ), currentNode );
307
309
} catch (ExitException e ) {
308
- rethrowOnMainThread (currentNode , e );
309
310
setThreadValue (thread , Nil .INSTANCE );
311
+ rethrowOnMainThread (currentNode , e );
310
312
} catch (Throwable e ) {
311
313
final RuntimeException runtimeException = printInternalError (e );
312
- rethrowOnMainThread (currentNode , runtimeException );
313
314
setThreadValue (thread , Nil .INSTANCE );
315
+ rethrowOnMainThread (currentNode , runtimeException );
314
316
} finally {
315
317
assert thread .value != null || thread .exception != null ;
316
318
cleanupKillOtherFibers (thread );
@@ -345,18 +347,18 @@ private void setThreadValue(RubyThread thread, Object value) {
345
347
}
346
348
347
349
private void setException (RubyThread thread , RubyException exception , Node currentNode ) {
348
- // A Thread is always shared (Thread.list)
349
- SharedObjects .propagate (language , thread , exception );
350
-
351
350
// We materialize the backtrace eagerly here, as the exception escapes the thread and needs
352
351
// to capture the backtrace from this thread.
353
352
final RaiseException truffleException = exception .backtrace .getRaiseException ();
354
353
if (truffleException != null ) {
355
354
TruffleStackTrace .fillIn (truffleException );
356
355
}
357
356
358
- final RubyThread mainThread = context .getThreadManager ().getRootThread ();
357
+ // A Thread is always shared (Thread.list)
358
+ SharedObjects .propagate (language , thread , exception );
359
+ thread .exception = exception ;
359
360
361
+ final RubyThread mainThread = context .getThreadManager ().getRootThread ();
360
362
if (thread != mainThread ) {
361
363
final boolean isSystemExit = exception instanceof RubySystemExit ;
362
364
@@ -373,7 +375,6 @@ private void setException(RubyThread thread, RubyException exception, Node curre
373
375
.raiseInThread (language , context , mainThread , exception , currentNode );
374
376
}
375
377
}
376
- thread .exception = exception ;
377
378
}
378
379
379
380
// Share the Ruby Thread before it can be accessed concurrently, and before it is added to Thread.list
0 commit comments