@@ -1441,9 +1441,6 @@ int ruby_in_eval;
1441
1441
static void rb_thread_cleanup _ ((void ));
1442
1442
static void rb_thread_wait_other_threads _ ((void ));
1443
1443
1444
- static int thread_set_raised ();
1445
- static int thread_reset_raised ();
1446
-
1447
1444
static int thread_no_ensure _ ((void ));
1448
1445
1449
1446
static VALUE exception_error ;
@@ -1462,8 +1459,10 @@ error_handle(ex)
1462
1459
int ex ;
1463
1460
{
1464
1461
int status = EXIT_FAILURE ;
1462
+ rb_thread_t th = curr_thread ;
1465
1463
1466
- if (thread_set_raised ()) return EXIT_FAILURE ;
1464
+ if (rb_thread_set_raised (th ))
1465
+ return EXIT_FAILURE ;
1467
1466
switch (ex & TAG_MASK ) {
1468
1467
case 0 :
1469
1468
status = EXIT_SUCCESS ;
@@ -1516,7 +1515,7 @@ error_handle(ex)
1516
1515
rb_bug ("Unknown longjmp status %d" , ex );
1517
1516
break ;
1518
1517
}
1519
- thread_reset_raised ( );
1518
+ rb_thread_reset_raised ( th );
1520
1519
return status ;
1521
1520
}
1522
1521
@@ -2709,6 +2708,7 @@ call_trace_func(event, node, self, id, klass)
2709
2708
NODE * node_save ;
2710
2709
VALUE srcfile ;
2711
2710
const char * event_name ;
2711
+ rb_thread_t th = curr_thread ;
2712
2712
2713
2713
if (!trace_func ) return ;
2714
2714
if (tracing ) return ;
@@ -2740,7 +2740,7 @@ call_trace_func(event, node, self, id, klass)
2740
2740
}
2741
2741
}
2742
2742
PUSH_TAG (PROT_NONE );
2743
- raised = thread_reset_raised ( );
2743
+ raised = rb_thread_reset_raised ( th );
2744
2744
if ((state = EXEC_TAG ()) == 0 ) {
2745
2745
srcfile = rb_str_new2 (ruby_sourcefile ?ruby_sourcefile :"(ruby)" );
2746
2746
event_name = get_event_name (event );
@@ -2752,7 +2752,7 @@ call_trace_func(event, node, self, id, klass)
2752
2752
klass ),
2753
2753
Qundef , 0 );
2754
2754
}
2755
- if (raised ) thread_set_raised ( );
2755
+ if (raised ) rb_thread_set_raised ( th );
2756
2756
POP_TAG ();
2757
2757
POP_FRAME ();
2758
2758
@@ -4571,8 +4571,9 @@ rb_longjmp(tag, mesg)
4571
4571
VALUE mesg ;
4572
4572
{
4573
4573
VALUE at ;
4574
+ rb_thread_t th = curr_thread ;
4574
4575
4575
- if (thread_set_raised ( )) {
4576
+ if (rb_thread_set_raised ( th )) {
4576
4577
ruby_errinfo = exception_error ;
4577
4578
JUMP_TAG (TAG_FATAL );
4578
4579
}
@@ -4586,6 +4587,9 @@ rb_longjmp(tag, mesg)
4586
4587
at = get_backtrace (mesg );
4587
4588
if (NIL_P (at )) {
4588
4589
at = make_backtrace ();
4590
+ if (OBJ_FROZEN (mesg )) {
4591
+ mesg = rb_obj_dup (mesg );
4592
+ }
4589
4593
set_backtrace (mesg , at );
4590
4594
}
4591
4595
}
@@ -4611,7 +4615,7 @@ rb_longjmp(tag, mesg)
4611
4615
ruby_errinfo = mesg ;
4612
4616
}
4613
4617
else if (status ) {
4614
- thread_reset_raised ( );
4618
+ rb_thread_reset_raised ( th );
4615
4619
JUMP_TAG (status );
4616
4620
}
4617
4621
}
@@ -4626,10 +4630,19 @@ rb_longjmp(tag, mesg)
4626
4630
if (!prot_tag ) {
4627
4631
error_print ();
4628
4632
}
4629
- thread_reset_raised ( );
4633
+ rb_thread_raised_clear ( th );
4630
4634
JUMP_TAG (tag );
4631
4635
}
4632
4636
4637
+ void
4638
+ rb_exc_jump (mesg )
4639
+ VALUE mesg ;
4640
+ {
4641
+ rb_thread_raised_clear (rb_curr_thread );
4642
+ ruby_errinfo = mesg ;
4643
+ JUMP_TAG (TAG_RAISE );
4644
+ }
4645
+
4633
4646
void
4634
4647
rb_exc_raise (mesg )
4635
4648
VALUE mesg ;
@@ -5578,18 +5591,11 @@ rb_with_disable_interrupt(proc, data)
5578
5591
static void
5579
5592
stack_check ()
5580
5593
{
5581
- static int overflowing = 0 ;
5594
+ rb_thread_t th = rb_curr_thread ;
5582
5595
5583
- if (!overflowing && ruby_stack_check ()) {
5584
- int state ;
5585
- overflowing = 1 ;
5586
- PUSH_TAG (PROT_NONE );
5587
- if ((state = EXEC_TAG ()) == 0 ) {
5588
- rb_exc_raise (sysstack_error );
5589
- }
5590
- POP_TAG ();
5591
- overflowing = 0 ;
5592
- JUMP_TAG (state );
5596
+ if (!rb_thread_raised_p (th , RAISED_STACKOVERFLOW ) && ruby_stack_check ()) {
5597
+ rb_thread_raised_set (th , RAISED_STACKOVERFLOW );
5598
+ rb_exc_raise (sysstack_error );
5593
5599
}
5594
5600
}
5595
5601
@@ -9987,11 +9993,14 @@ Init_Proc()
9987
9993
9988
9994
rb_global_variable (& exception_error );
9989
9995
exception_error = rb_exc_new2 (rb_eFatal , "exception reentered" );
9996
+ OBJ_TAINT (exception_error );
9997
+ OBJ_FREEZE (exception_error );
9990
9998
9991
9999
rb_eSysStackError = rb_define_class ("SystemStackError" , rb_eStandardError );
9992
10000
rb_global_variable (& sysstack_error );
9993
10001
sysstack_error = rb_exc_new2 (rb_eSysStackError , "stack level too deep" );
9994
10002
OBJ_TAINT (sysstack_error );
10003
+ OBJ_FREEZE (sysstack_error );
9995
10004
9996
10005
rb_cProc = rb_define_class ("Proc" , rb_cObject );
9997
10006
rb_undef_alloc_func (rb_cProc );
@@ -10169,10 +10178,9 @@ extern VALUE rb_last_status;
10169
10178
# endif
10170
10179
#endif
10171
10180
10172
- #define THREAD_RAISED 0x200 /* temporary flag */
10173
10181
#define THREAD_TERMINATING 0x400 /* persistent flag */
10174
- #define THREAD_NO_ENSURE 0x800 /* persistent flag */
10175
- #define THREAD_FLAGS_MASK 0xc00 /* mask for persistent flags */
10182
+ #define THREAD_NO_ENSURE 0x800 /* persistent flag */
10183
+ #define THREAD_FLAGS_MASK 0xfc00 /* mask for persistent flags */
10176
10184
10177
10185
#define FOREACH_THREAD_FROM (f ,x ) x = f; do { x = x->next;
10178
10186
#define END_FOREACH_FROM (f ,x ) } while (x != f)
@@ -10224,19 +10232,25 @@ struct thread_status_t {
10224
10232
(dst)->join = (src)->join, \
10225
10233
0)
10226
10234
10227
- static int
10228
- thread_set_raised ()
10235
+ int
10236
+ rb_thread_set_raised (th )
10237
+ rb_thread_t th ;
10229
10238
{
10230
- if (curr_thread -> flags & THREAD_RAISED ) return 1 ;
10231
- curr_thread -> flags |= THREAD_RAISED ;
10239
+ if (th -> flags & RAISED_EXCEPTION ) {
10240
+ return 1 ;
10241
+ }
10242
+ th -> flags |= RAISED_EXCEPTION ;
10232
10243
return 0 ;
10233
10244
}
10234
10245
10235
- static int
10236
- thread_reset_raised ()
10246
+ int
10247
+ rb_thread_reset_raised (th )
10248
+ rb_thread_t th ;
10237
10249
{
10238
- if (!(curr_thread -> flags & THREAD_RAISED )) return 0 ;
10239
- curr_thread -> flags &= ~THREAD_RAISED ;
10250
+ if (!(th -> flags & RAISED_EXCEPTION )) {
10251
+ return 0 ;
10252
+ }
10253
+ th -> flags &= ~RAISED_EXCEPTION ;
10240
10254
return 1 ;
10241
10255
}
10242
10256
@@ -11374,7 +11388,7 @@ rb_thread_join(th, limit)
11374
11388
if (!rb_thread_dead (th )) return Qfalse ;
11375
11389
}
11376
11390
11377
- if (!NIL_P (th -> errinfo ) && (th -> flags & THREAD_RAISED )) {
11391
+ if (!NIL_P (th -> errinfo ) && (th -> flags & RAISED_EXCEPTION )) {
11378
11392
VALUE oldbt = get_backtrace (th -> errinfo );
11379
11393
VALUE errat = make_backtrace ();
11380
11394
VALUE errinfo = rb_obj_dup (th -> errinfo );
@@ -12250,7 +12264,7 @@ rb_thread_start_0(fn, arg, th)
12250
12264
}
12251
12265
12252
12266
if (state && status != THREAD_TO_KILL && !NIL_P (ruby_errinfo )) {
12253
- th -> flags |= THREAD_RAISED ;
12267
+ th -> flags |= RAISED_EXCEPTION ;
12254
12268
if (state == TAG_FATAL ) {
12255
12269
/* fatal error within this thread, need to stop whole script */
12256
12270
main_thread -> errinfo = ruby_errinfo ;
@@ -12468,7 +12482,7 @@ rb_thread_status(thread)
12468
12482
rb_thread_t th = rb_thread_check (thread );
12469
12483
12470
12484
if (rb_thread_dead (th )) {
12471
- if (!NIL_P (th -> errinfo ) && (th -> flags & THREAD_RAISED ))
12485
+ if (!NIL_P (th -> errinfo ) && (th -> flags & RAISED_EXCEPTION ))
12472
12486
return Qnil ;
12473
12487
return Qfalse ;
12474
12488
}
0 commit comments