fastruby 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +6 -0
- data/Rakefile +1 -1
- data/lib/fastruby/exceptions.rb +0 -10
- data/lib/fastruby/translator.rb +333 -382
- data/lib/fastruby.rb +1 -1
- data/spec/block/redo_spec.rb +67 -0
- data/spec/block/retry_spec.rb +135 -0
- data/spec/exception/base_spec.rb +39 -0
- data/spec/exception/ensure_spec.rb +52 -0
- data/spec/{exception_spec.rb → exception/exc_trap_spec.rb} +0 -154
- data/spec/exception/syntaxis_spec.rb +89 -0
- data/spec/flow_control/for_spec.rb +40 -0
- data/spec/jump/next_spec.rb +36 -0
- metadata +12 -6
- data/spec/block/callcc_spec.rb +0 -115
data/lib/fastruby/translator.rb
CHANGED
@@ -46,15 +46,14 @@ module FastRuby
|
|
46
46
|
@init_extra = Array.new
|
47
47
|
@frame_struct = "struct {
|
48
48
|
void* parent_frame;
|
49
|
-
void* target_frame;
|
50
49
|
void* plocals;
|
51
50
|
jmp_buf jmp;
|
52
51
|
VALUE return_value;
|
53
|
-
VALUE exception;
|
54
52
|
int rescue;
|
55
53
|
VALUE last_error;
|
56
|
-
void* stack_chunk;
|
57
54
|
VALUE next_recv;
|
55
|
+
int targetted;
|
56
|
+
struct FASTRUBYTHREADDATA* thread_data;
|
58
57
|
}"
|
59
58
|
|
60
59
|
@block_struct = "struct {
|
@@ -66,6 +65,14 @@ module FastRuby
|
|
66
65
|
extra_code << "
|
67
66
|
#include \"node.h\"
|
68
67
|
|
68
|
+
#define FASTRUBY_TAG_RETURN 0x80
|
69
|
+
#define FASTRUBY_TAG_NEXT 0x81
|
70
|
+
#define FASTRUBY_TAG_BREAK 0x82
|
71
|
+
#define FASTRUBY_TAG_RAISE 0x83
|
72
|
+
#define FASTRUBY_TAG_REDO 0x84
|
73
|
+
#define FASTRUBY_TAG_RETRY 0x85
|
74
|
+
#define TAG_RAISE 0x6
|
75
|
+
|
69
76
|
#ifndef __INLINE_FASTRUBY_BASE
|
70
77
|
#include \"#{FastRuby.fastruby_load_path}/../ext/fastruby_base/fastruby_base.inl\"
|
71
78
|
#define __INLINE_FASTRUBY_BASE
|
@@ -130,63 +137,10 @@ module FastRuby
|
|
130
137
|
#{caller.join("\n")}
|
131
138
|
*/
|
132
139
|
|
133
|
-
"
|
134
|
-
extra_code << "static struct STACKCHUNKREFRENCE* get_stack_chunk_reference_from_context() {
|
135
|
-
struct STACKCHUNKREFERENCE* stack_chunk_reference;
|
136
|
-
VALUE current_thread = rb_thread_current();
|
137
|
-
VALUE rb_stack_chunk_reference = rb_ivar_get(current_thread,#{intern_num :_fastruby_stack_chunk_reference});
|
138
|
-
if (rb_stack_chunk_reference == Qnil) {
|
139
|
-
rb_stack_chunk_reference = rb_stack_chunk_reference_create();
|
140
|
-
rb_ivar_set(current_thread,#{intern_num :_fastruby_stack_chunk_reference},rb_stack_chunk_reference);
|
141
|
-
}
|
142
|
-
|
143
|
-
Data_Get_Struct(rb_stack_chunk_reference,struct STACKCHUNKREFERENCE,stack_chunk_reference);
|
144
|
-
|
145
|
-
return (void*)stack_chunk_reference;
|
146
|
-
}
|
147
|
-
|
148
|
-
static struct STACKCHUNK* get_stack_chunk_from_context(
|
149
|
-
struct STACKCHUNKREFERENCE** stack_chunk_reference,
|
150
|
-
VALUE* rb_stack_chunk
|
151
|
-
) {
|
152
|
-
struct STACKCHUNK* stack_chunk = 0;
|
153
|
-
*stack_chunk_reference = (void*)get_stack_chunk_reference_from_context();
|
154
|
-
*rb_stack_chunk = stack_chunk_reference_retrieve(*stack_chunk_reference);
|
155
|
-
if (*rb_stack_chunk != Qnil) {
|
156
|
-
Data_Get_Struct(*rb_stack_chunk,void,stack_chunk);
|
157
|
-
}
|
158
|
-
|
159
|
-
return stack_chunk;
|
160
|
-
}
|
161
|
-
|
162
|
-
static struct STACKCHUNK* create_stack_chunk_from_context(
|
163
|
-
struct STACKCHUNKREFERENCE** stack_chunk_reference,
|
164
|
-
VALUE* rb_stack_chunk_p
|
165
|
-
) {
|
166
|
-
|
167
|
-
struct STACKCHUNK* stack_chunk;
|
168
|
-
VALUE rb_stack_chunk = rb_stack_chunk_create(Qnil);
|
169
|
-
|
170
|
-
if (*stack_chunk_reference == 0) {
|
171
|
-
*stack_chunk_reference = (void*)get_stack_chunk_reference_from_context();
|
172
|
-
}
|
173
|
-
|
174
|
-
stack_chunk_reference_assign(*stack_chunk_reference, rb_stack_chunk);
|
175
|
-
Data_Get_Struct(rb_stack_chunk,void,stack_chunk);
|
176
|
-
|
177
|
-
*rb_stack_chunk_p = rb_stack_chunk;
|
178
|
-
|
179
|
-
return stack_chunk;
|
180
|
-
}
|
181
|
-
|
182
140
|
"
|
183
141
|
end
|
184
142
|
end
|
185
143
|
|
186
|
-
def on_block
|
187
|
-
yield
|
188
|
-
end
|
189
|
-
|
190
144
|
def to_c(tree)
|
191
145
|
return "Qnil" unless tree
|
192
146
|
send("to_c_" + tree[0].to_s, tree);
|
@@ -368,14 +322,10 @@ module FastRuby
|
|
368
322
|
VALUE ret = rb_funcall(#{str_recv}, #{intern_num call_tree[2]}, 0);
|
369
323
|
|
370
324
|
// freeze all stacks
|
371
|
-
|
372
|
-
VALUE rb_stack_chunk_reference = rb_ivar_get(current_thread,#{intern_num :_fastruby_stack_chunk_reference});
|
325
|
+
struct FASTRUBYTHREADDATA* thread_data = rb_current_thread_data();
|
373
326
|
|
374
|
-
if (
|
375
|
-
|
376
|
-
Data_Get_Struct(rb_stack_chunk_reference, struct STACKCHUNKREFERENCE, stack_chunk_reference);
|
377
|
-
|
378
|
-
VALUE rb_stack_chunk = stack_chunk_reference_retrieve(stack_chunk_reference);
|
327
|
+
if (thread_data != 0) {
|
328
|
+
VALUE rb_stack_chunk = thread_data->rb_stack_chunk;
|
379
329
|
|
380
330
|
// add reference to stack chunk to lambda object
|
381
331
|
rb_ivar_set(ret,#{intern_num :_fastruby_stack_chunk},rb_stack_chunk);
|
@@ -408,39 +358,44 @@ module FastRuby
|
|
408
358
|
#{@locals_struct} *plocals = (void*)_plocals;
|
409
359
|
|
410
360
|
frame.plocals = plocals;
|
411
|
-
frame.stack_chunk = 0;
|
412
361
|
frame.parent_frame = 0;
|
413
362
|
frame.return_value = Qnil;
|
414
|
-
frame.target_frame = &frame;
|
415
|
-
frame.exception = Qnil;
|
416
363
|
frame.rescue = 0;
|
364
|
+
frame.targetted = 0;
|
365
|
+
frame.thread_data = rb_current_thread_data();
|
417
366
|
|
418
367
|
// create a fake parent frame representing the lambda method frame and a fake locals scope
|
419
368
|
VALUE old_call_frame = ((typeof(plocals))(pframe->plocals))->call_frame;
|
420
369
|
((typeof(plocals))(pframe->plocals))->call_frame = LONG2FIX(pframe);
|
421
370
|
|
422
|
-
|
423
|
-
|
424
|
-
if (
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
371
|
+
int aux = setjmp(frame.jmp);
|
372
|
+
if (aux != 0) {
|
373
|
+
if (aux == FASTRUBY_TAG_BREAK) {
|
374
|
+
return frame.return_value;
|
375
|
+
} else if (aux == FASTRUBY_TAG_NEXT) {
|
376
|
+
return pframe->thread_data->accumulator;
|
377
|
+
} else if (aux == FASTRUBY_TAG_REDO) {
|
378
|
+
// do nothing and let execute the block again
|
379
|
+
} else if (aux == FASTRUBY_TAG_RAISE) {
|
380
|
+
rb_funcall(((typeof(plocals))(pframe->plocals))->self, #{intern_num :raise}, 1, frame.thread_data->exception);
|
381
|
+
return Qnil;
|
382
|
+
} else {
|
383
|
+
if (aux == FASTRUBY_TAG_RETURN) {
|
384
|
+
if (((typeof(pframe))(FIX2LONG(plocals->pframe)))->targetted == 1) {
|
432
385
|
((typeof(plocals))(pframe->plocals))->call_frame = old_call_frame;
|
433
|
-
return pframe->return_value;
|
386
|
+
return ((typeof(plocals))(pframe->plocals))->return_value;
|
434
387
|
} else {
|
435
388
|
rb_raise(rb_eLocalJumpError, \"unexpected return\");
|
436
389
|
}
|
390
|
+
} else {
|
391
|
+
rb_raise(rb_eLocalJumpError, \"unexpected return\");
|
437
392
|
}
|
438
|
-
}
|
439
|
-
((typeof(plocals))(pframe->plocals))->call_frame = old_call_frame;
|
440
|
-
return frame.return_value;
|
441
|
-
}
|
442
393
|
|
394
|
+
((typeof(plocals))(pframe->plocals))->call_frame = old_call_frame;
|
395
|
+
return frame.return_value;
|
443
396
|
|
397
|
+
}
|
398
|
+
}
|
444
399
|
|
445
400
|
#{str_arg_initialization}
|
446
401
|
#{str_impl}
|
@@ -461,49 +416,38 @@ module FastRuby
|
|
461
416
|
#{@locals_struct} *plocals = (void*)_plocals;
|
462
417
|
|
463
418
|
frame.plocals = plocals;
|
464
|
-
frame.stack_chunk = 0;
|
465
419
|
frame.parent_frame = 0;
|
466
420
|
frame.return_value = Qnil;
|
467
|
-
frame.target_frame = &frame;
|
468
|
-
frame.exception = Qnil;
|
469
421
|
frame.rescue = 0;
|
422
|
+
frame.targetted = 0;
|
423
|
+
frame.thread_data = rb_current_thread_data();
|
470
424
|
|
471
425
|
// create a fake parent frame representing the lambda method frame and a fake locals scope
|
472
426
|
VALUE old_call_frame = ((typeof(plocals))(pframe->plocals))->call_frame;
|
473
427
|
((typeof(plocals))(pframe->plocals))->call_frame = LONG2FIX(pframe);
|
474
428
|
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
if (plocals->
|
486
|
-
|
429
|
+
int aux = setjmp(frame.jmp);
|
430
|
+
if (aux != 0) {
|
431
|
+
if (aux == FASTRUBY_TAG_NEXT) {
|
432
|
+
return pframe->thread_data->accumulator;
|
433
|
+
} else if (aux == FASTRUBY_TAG_REDO) {
|
434
|
+
// do nothing and let execute the block again
|
435
|
+
} else if (aux == FASTRUBY_TAG_RAISE) {
|
436
|
+
rb_funcall(((typeof(plocals))(pframe->plocals))->self, #{intern_num :raise}, 1, frame.thread_data->exception);
|
437
|
+
return Qnil;
|
438
|
+
} else {
|
439
|
+
if (((typeof(pframe))(FIX2LONG(plocals->pframe)))->targetted == 1) {
|
440
|
+
|
441
|
+
if (plocals->active == Qfalse) {
|
442
|
+
rb_raise(rb_eLocalJumpError,\"return from proc-closure\");
|
443
|
+
} else {
|
444
|
+
((typeof(plocals))(pframe->plocals))->call_frame = old_call_frame;
|
445
|
+
rb_jump_tag(aux);
|
446
|
+
}
|
487
447
|
} else {
|
488
|
-
(
|
489
|
-
VALUE ex = rb_funcall(
|
490
|
-
#{literal_value FastRuby::Context::UnwindFastrubyFrame},
|
491
|
-
#{intern_num :new},
|
492
|
-
3,
|
493
|
-
pframe->exception,
|
494
|
-
LONG2FIX(pframe->target_frame),
|
495
|
-
pframe->return_value
|
496
|
-
);
|
497
|
-
|
498
|
-
rb_funcall(plocals->self, #{intern_num :raise}, 1, ex);
|
448
|
+
rb_raise(rb_eLocalJumpError, \"unexpected return\");
|
499
449
|
}
|
500
|
-
} else {
|
501
|
-
rb_raise(rb_eLocalJumpError, \"unexpected return\");
|
502
450
|
}
|
503
|
-
}
|
504
|
-
}
|
505
|
-
|
506
|
-
rb_raise(rb_eLocalJumpError, \"break from proc-closure\");
|
507
451
|
}
|
508
452
|
|
509
453
|
#{str_arg_initialization}
|
@@ -527,32 +471,24 @@ module FastRuby
|
|
527
471
|
#{@locals_struct} *plocals = (void*)_plocals;
|
528
472
|
|
529
473
|
frame.plocals = plocals;
|
530
|
-
frame.stack_chunk = 0;
|
531
474
|
frame.parent_frame = 0;
|
532
475
|
frame.return_value = Qnil;
|
533
|
-
frame.target_frame = &frame;
|
534
|
-
frame.exception = Qnil;
|
535
476
|
frame.rescue = 0;
|
477
|
+
frame.targetted = 0;
|
478
|
+
frame.thread_data = rb_current_thread_data();
|
536
479
|
|
537
|
-
|
538
|
-
|
539
|
-
if (pframe->target_frame == (void*)-3) {
|
540
|
-
return pframe->return_value;
|
541
|
-
}
|
480
|
+
int aux = setjmp(frame.jmp);
|
481
|
+
if (aux != 0) {
|
542
482
|
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
);
|
551
|
-
|
552
|
-
rb_funcall(plocals->self, #{intern_num :raise}, 1, ex);
|
483
|
+
if (aux == FASTRUBY_TAG_NEXT) {
|
484
|
+
return pframe->thread_data->accumulator;
|
485
|
+
} else if (aux == FASTRUBY_TAG_REDO) {
|
486
|
+
// do nothing and let execute the block again
|
487
|
+
} else {
|
488
|
+
rb_jump_tag(aux);
|
489
|
+
return frame.return_value;
|
553
490
|
}
|
554
|
-
|
555
|
-
}
|
491
|
+
}
|
556
492
|
|
557
493
|
|
558
494
|
#{str_arg_initialization}
|
@@ -589,25 +525,24 @@ module FastRuby
|
|
589
525
|
|
590
526
|
frame.plocals = (void*)_locals;
|
591
527
|
frame.parent_frame = parent_frame;
|
592
|
-
frame.stack_chunk = parent_frame->stack_chunk;
|
593
528
|
frame.return_value = Qnil;
|
594
|
-
frame.target_frame = &frame;
|
595
|
-
frame.exception = Qnil;
|
596
529
|
frame.rescue = 0;
|
530
|
+
frame.targetted = 0;
|
531
|
+
frame.thread_data = parent_frame->thread_data;
|
532
|
+
if (frame.thread_data == 0) frame.thread_data = rb_current_thread_data();
|
597
533
|
|
598
534
|
plocals = frame.plocals;
|
599
535
|
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
536
|
+
int aux = setjmp(frame.jmp);
|
537
|
+
if (aux != 0) {
|
538
|
+
if (pframe->targetted == 0) {
|
539
|
+
if (aux == FASTRUBY_TAG_NEXT) {
|
540
|
+
return pframe->thread_data->accumulator;
|
541
|
+
} else if (aux == FASTRUBY_TAG_REDO) {
|
542
|
+
// do nothing and let execute the block again
|
543
|
+
} else {
|
544
|
+
longjmp(((typeof(pframe))_parent_frame)->jmp,aux);
|
604
545
|
}
|
605
|
-
// raise exception
|
606
|
-
((typeof(pframe))_parent_frame)->exception = pframe->exception;
|
607
|
-
((typeof(pframe))_parent_frame)->target_frame = pframe->target_frame;
|
608
|
-
((typeof(pframe))_parent_frame)->return_value = pframe->return_value;
|
609
|
-
|
610
|
-
longjmp(((typeof(pframe))_parent_frame)->jmp,1);
|
611
546
|
}
|
612
547
|
|
613
548
|
}
|
@@ -629,29 +564,7 @@ module FastRuby
|
|
629
564
|
caller_code = nil
|
630
565
|
convention_global_name = add_global_name("int",0)
|
631
566
|
|
632
|
-
|
633
|
-
value_cast = ( ["VALUE"]*(call_tree[3].size) ).join(",") + ", VALUE, VALUE"
|
634
|
-
|
635
|
-
str_called_code_args = call_tree[3][1..-1].map{|subtree| to_c subtree}.join(",")
|
636
|
-
|
637
|
-
caller_code = proc { |name| "
|
638
|
-
static VALUE #{name}(VALUE param, VALUE pframe) {
|
639
|
-
#{@block_struct} block;
|
640
|
-
#{@locals_struct} *plocals = (void*)param;
|
641
|
-
|
642
|
-
block.block_function_address = (void*)#{anonymous_function(&block_code)};
|
643
|
-
block.block_function_param = (void*)param;
|
644
|
-
|
645
|
-
// call to #{call_tree[2]}
|
646
|
-
|
647
|
-
return ((VALUE(*)(#{value_cast}))#{encode_address(recvtype,signature,mname,call_tree,inference_complete,convention_global_name)})(#{str_recv}, (VALUE)&block, (VALUE)pframe, #{str_called_code_args});
|
648
|
-
}
|
649
|
-
"
|
650
|
-
}
|
651
|
-
|
652
|
-
else
|
653
|
-
caller_code = proc { |name| "
|
654
|
-
static VALUE #{name}(VALUE param, VALUE pframe) {
|
567
|
+
call_frame_struct_code = "
|
655
568
|
#{@block_struct} block;
|
656
569
|
#{@locals_struct} *plocals = (void*)param;
|
657
570
|
|
@@ -662,27 +575,52 @@ module FastRuby
|
|
662
575
|
#{@frame_struct} call_frame;
|
663
576
|
|
664
577
|
call_frame.parent_frame = (void*)pframe;
|
665
|
-
call_frame.target_frame = 0;
|
666
578
|
call_frame.plocals = plocals;
|
667
579
|
call_frame.return_value = Qnil;
|
668
|
-
call_frame.
|
669
|
-
call_frame.
|
580
|
+
call_frame.targetted = 0;
|
581
|
+
call_frame.thread_data = rb_current_thread_data();
|
670
582
|
|
671
583
|
VALUE old_call_frame = plocals->call_frame;
|
672
584
|
plocals->call_frame = LONG2FIX(&call_frame);
|
673
585
|
|
674
|
-
|
586
|
+
int aux = setjmp(call_frame.jmp);
|
587
|
+
if (aux != 0) {
|
675
588
|
#{@frame_struct}* pframe_ = (void*)pframe;
|
676
589
|
|
677
|
-
if (
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
590
|
+
if (aux == FASTRUBY_TAG_RETRY ) {
|
591
|
+
// do nothing and let the call execute again
|
592
|
+
} else {
|
593
|
+
if (call_frame.targetted == 0) {
|
594
|
+
longjmp(pframe_->jmp,aux);
|
595
|
+
}
|
682
596
|
|
683
|
-
|
684
|
-
|
597
|
+
plocals->call_frame = old_call_frame;
|
598
|
+
return call_frame.return_value;
|
599
|
+
}
|
685
600
|
}
|
601
|
+
"
|
602
|
+
|
603
|
+
if call_args_tree.size > 1
|
604
|
+
value_cast = ( ["VALUE"]*(call_tree[3].size) ).join(",") + ", VALUE, VALUE"
|
605
|
+
|
606
|
+
str_called_code_args = call_tree[3][1..-1].map{|subtree| to_c subtree}.join(",")
|
607
|
+
|
608
|
+
caller_code = proc { |name| "
|
609
|
+
static VALUE #{name}(VALUE param, VALUE pframe) {
|
610
|
+
// call to #{call_tree[2]}
|
611
|
+
#{call_frame_struct_code}
|
612
|
+
|
613
|
+
VALUE ret = ((VALUE(*)(#{value_cast}))#{encode_address(recvtype,signature,mname,call_tree,inference_complete,convention_global_name)})(#{str_recv}, (VALUE)&block, (VALUE)&call_frame, #{str_called_code_args});
|
614
|
+
plocals->call_frame = old_call_frame;
|
615
|
+
return ret;
|
616
|
+
}
|
617
|
+
"
|
618
|
+
}
|
619
|
+
|
620
|
+
else
|
621
|
+
caller_code = proc { |name| "
|
622
|
+
static VALUE #{name}(VALUE param, VALUE pframe) {
|
623
|
+
#{call_frame_struct_code}
|
686
624
|
|
687
625
|
// call to #{call_tree[2]}
|
688
626
|
VALUE ret = ((VALUE(*)(VALUE,VALUE,VALUE))#{encode_address(recvtype,signature,mname,call_tree,inference_complete,convention_global_name)})(#{str_recv}, (VALUE)&block, (VALUE)&call_frame);
|
@@ -746,24 +684,30 @@ module FastRuby
|
|
746
684
|
pframe = (typeof(pframe))&call_frame;
|
747
685
|
|
748
686
|
call_frame.parent_frame = (void*)pframe;
|
749
|
-
call_frame.target_frame = 0;
|
750
687
|
call_frame.plocals = plocals;
|
751
688
|
call_frame.return_value = Qnil;
|
752
|
-
call_frame.
|
753
|
-
call_frame.
|
689
|
+
call_frame.targetted = 0;
|
690
|
+
call_frame.thread_data = old_pframe->thread_data;
|
691
|
+
if (call_frame.thread_data == 0) call_frame.thread_data = rb_current_thread_data();
|
754
692
|
|
755
693
|
VALUE old_call_frame = plocals->call_frame;
|
756
694
|
plocals->call_frame = LONG2FIX(&call_frame);
|
757
695
|
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
old_pframe->
|
762
|
-
longjmp(old_pframe->jmp,1);
|
696
|
+
int aux = setjmp(call_frame.jmp);
|
697
|
+
if (aux != 0) {
|
698
|
+
if (call_frame.targetted == 0) {
|
699
|
+
longjmp(old_pframe->jmp,aux);
|
763
700
|
}
|
764
701
|
|
765
|
-
|
766
|
-
|
702
|
+
if (aux == FASTRUBY_TAG_BREAK) {
|
703
|
+
plocals->call_frame = old_call_frame;
|
704
|
+
return call_frame.return_value;
|
705
|
+
} else if (aux == FASTRUBY_TAG_RETRY ) {
|
706
|
+
// do nothing and let the call execute again
|
707
|
+
} else {
|
708
|
+
plocals->call_frame = old_call_frame;
|
709
|
+
return call_frame.return_value;
|
710
|
+
}
|
767
711
|
}
|
768
712
|
|
769
713
|
VALUE ret = #{inner_code};
|
@@ -847,16 +791,14 @@ module FastRuby
|
|
847
791
|
|
848
792
|
def to_c_return(tree)
|
849
793
|
inline_block "
|
850
|
-
pframe->target_frame = ((typeof(pframe))FIX2LONG(plocals->pframe));
|
851
794
|
plocals->return_value = #{to_c(tree[1])};
|
852
|
-
pframe->
|
853
|
-
longjmp(pframe->jmp,
|
795
|
+
((typeof(pframe))FIX2LONG(plocals->pframe))->targetted = 1;
|
796
|
+
longjmp(pframe->jmp, FASTRUBY_TAG_RETURN);
|
854
797
|
return Qnil;
|
855
798
|
"
|
856
799
|
end
|
857
800
|
|
858
801
|
def to_c_break(tree)
|
859
|
-
if @on_block
|
860
802
|
inline_block(
|
861
803
|
"
|
862
804
|
|
@@ -866,35 +808,63 @@ module FastRuby
|
|
866
808
|
target_frame_ = (void*)FIX2LONG(plocals->call_frame);
|
867
809
|
|
868
810
|
if (target_frame_ == 0) {
|
869
|
-
|
811
|
+
pframe->thread_data->exception = #{literal_value LocalJumpError.exception};
|
812
|
+
longjmp(pframe->jmp,FASTRUBY_TAG_RAISE);
|
813
|
+
return Qnil;
|
870
814
|
}
|
871
815
|
|
872
816
|
plocals->call_frame = LONG2FIX(0);
|
873
817
|
|
874
|
-
|
875
|
-
|
876
|
-
pframe->exception = Qnil;
|
877
|
-
longjmp(pframe->jmp,
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
818
|
+
target_frame_->return_value = value;
|
819
|
+
target_frame_->targetted = 1;
|
820
|
+
pframe->thread_data->exception = Qnil;
|
821
|
+
longjmp(pframe->jmp,FASTRUBY_TAG_BREAK);"
|
822
|
+
)
|
823
|
+
end
|
824
|
+
|
825
|
+
def to_c_retry(tree)
|
826
|
+
inline_block(
|
827
|
+
"
|
828
|
+
typeof(pframe) target_frame_;
|
829
|
+
target_frame_ = (void*)FIX2LONG(plocals->call_frame);
|
830
|
+
|
831
|
+
if (target_frame_ == 0) {
|
832
|
+
pframe->thread_data->exception = rb_funcall(rb_eLocalJumpError, #{intern_num :exception},0);
|
833
|
+
longjmp(pframe->jmp, FASTRUBY_TAG_RAISE);
|
884
834
|
return Qnil;
|
885
|
-
|
835
|
+
}
|
836
|
+
|
837
|
+
target_frame_->targetted = 1;
|
838
|
+
longjmp(pframe->jmp,FASTRUBY_TAG_RETRY);"
|
839
|
+
)
|
840
|
+
end
|
886
841
|
|
842
|
+
def to_c_redo(tree)
|
843
|
+
if @on_block
|
844
|
+
inline_block "
|
845
|
+
longjmp(pframe->jmp,FASTRUBY_TAG_REDO);
|
846
|
+
return Qnil;
|
847
|
+
"
|
848
|
+
else
|
849
|
+
inline_block "
|
850
|
+
pframe->thread_data->exception = #{literal_value LocalJumpError.exception};
|
851
|
+
longjmp(pframe->jmp,FASTRUBY_TAG_RAISE);
|
852
|
+
return Qnil;
|
853
|
+
"
|
887
854
|
end
|
888
855
|
end
|
889
856
|
|
890
857
|
def to_c_next(tree)
|
891
858
|
if @on_block
|
892
|
-
|
859
|
+
inline_block "
|
860
|
+
pframe->thread_data->accumulator = #{tree[1] ? to_c(tree[1]) : "Qnil"};
|
861
|
+
longjmp(pframe->jmp,FASTRUBY_TAG_NEXT);
|
862
|
+
return Qnil;
|
863
|
+
"
|
893
864
|
else
|
894
865
|
inline_block("
|
895
|
-
pframe->
|
896
|
-
pframe->
|
897
|
-
longjmp(pframe->jmp,1);
|
866
|
+
pframe->thread_data->exception = #{literal_value LocalJumpError.exception};
|
867
|
+
longjmp(pframe->jmp,FASTRUBY_TAG_RAISE);
|
898
868
|
return Qnil;
|
899
869
|
")
|
900
870
|
|
@@ -988,19 +958,19 @@ module FastRuby
|
|
988
958
|
|
989
959
|
code = tree[2..-2].map{|subtree|
|
990
960
|
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
961
|
+
# this subtree is a when
|
962
|
+
subtree[1][1..-1].map{|subsubtree|
|
963
|
+
c_calltree = s(:call, nil, :inline_c, s(:arglist, s(:str, tmpvarname), s(:false)))
|
964
|
+
calltree = s(:call, subsubtree, :===, s(:arglist, c_calltree))
|
995
965
|
"
|
996
966
|
if (RTEST(#{to_c_call(calltree, tmpvarname)})) {
|
997
967
|
return #{to_c(subtree[2])};
|
998
968
|
}
|
999
969
|
|
1000
970
|
"
|
1001
|
-
|
971
|
+
}.join("\n")
|
1002
972
|
|
1003
|
-
|
973
|
+
}.join("\n")
|
1004
974
|
|
1005
975
|
inline_block "
|
1006
976
|
|
@@ -1082,22 +1052,21 @@ module FastRuby
|
|
1082
1052
|
if (nd_type(body) == NODE_CFUNC) {
|
1083
1053
|
struct {
|
1084
1054
|
void* parent_frame;
|
1085
|
-
void* target_frame;
|
1086
1055
|
void* plocals;
|
1087
1056
|
jmp_buf jmp;
|
1088
1057
|
VALUE return_value;
|
1089
|
-
VALUE exception;
|
1090
1058
|
int rescue;
|
1091
1059
|
VALUE last_error;
|
1092
|
-
|
1060
|
+
VALUE next_recv;
|
1061
|
+
int targetted;
|
1062
|
+
struct FASTRUBYTHREADDATA* thread_data;
|
1093
1063
|
} frame;
|
1094
1064
|
|
1095
|
-
frame.stack_chunk = 0;
|
1096
|
-
frame.target_frame = 0;
|
1097
1065
|
frame.parent_frame = 0;
|
1098
1066
|
frame.rescue = 0;
|
1099
|
-
frame.exception = Qnil;
|
1100
1067
|
frame.return_value = Qnil;
|
1068
|
+
frame.thread_data = rb_current_thread_data();
|
1069
|
+
frame.targetted = 0;
|
1101
1070
|
|
1102
1071
|
int argc = body->nd_argc;
|
1103
1072
|
|
@@ -1117,21 +1086,12 @@ module FastRuby
|
|
1117
1086
|
|
1118
1087
|
int aux = setjmp(frame.jmp);
|
1119
1088
|
if (aux != 0) {
|
1120
|
-
if (
|
1121
|
-
rb_funcall(self, #{intern_num :raise}, 1, frame.exception);
|
1089
|
+
if (aux == FASTRUBY_TAG_RAISE) {
|
1090
|
+
rb_funcall(self, #{intern_num :raise}, 1, frame.thread_data->exception);
|
1122
1091
|
}
|
1123
1092
|
|
1124
|
-
if (frame.
|
1125
|
-
|
1126
|
-
#{literal_value FastRuby::Context::UnwindFastrubyFrame},
|
1127
|
-
#{intern_num :new},
|
1128
|
-
3,
|
1129
|
-
frame.exception,
|
1130
|
-
LONG2FIX(frame.target_frame),
|
1131
|
-
frame.return_value
|
1132
|
-
);
|
1133
|
-
|
1134
|
-
rb_funcall(self, #{intern_num :raise}, 1, ex);
|
1093
|
+
if (frame.targetted == 0) {
|
1094
|
+
rb_jump_tag(aux);
|
1135
1095
|
}
|
1136
1096
|
|
1137
1097
|
return Qnil;
|
@@ -1299,13 +1259,12 @@ module FastRuby
|
|
1299
1259
|
void* block_address = 0;
|
1300
1260
|
VALUE block_param = Qnil;
|
1301
1261
|
|
1302
|
-
frame.stack_chunk = 0;
|
1303
1262
|
frame.plocals = 0;
|
1304
1263
|
frame.parent_frame = 0;
|
1305
1264
|
frame.return_value = Qnil;
|
1306
|
-
frame.target_frame = &frame;
|
1307
|
-
frame.exception = Qnil;
|
1308
1265
|
frame.rescue = 0;
|
1266
|
+
frame.targetted = 0;
|
1267
|
+
frame.thread_data = rb_current_thread_data();
|
1309
1268
|
|
1310
1269
|
if (rb_block_given_p()) {
|
1311
1270
|
block_address = #{
|
@@ -1321,7 +1280,7 @@ module FastRuby
|
|
1321
1280
|
|
1322
1281
|
int aux = setjmp(frame.jmp);
|
1323
1282
|
if (aux != 0) {
|
1324
|
-
rb_funcall(self, #{intern_num :raise}, 1, frame.exception);
|
1283
|
+
rb_funcall(self, #{intern_num :raise}, 1, frame.thread_data->exception);
|
1325
1284
|
}
|
1326
1285
|
|
1327
1286
|
|
@@ -1389,35 +1348,38 @@ module FastRuby
|
|
1389
1348
|
#{@frame_struct} frame;
|
1390
1349
|
#{@frame_struct} *pframe;
|
1391
1350
|
|
1392
|
-
frame.stack_chunk = 0;
|
1393
1351
|
frame.parent_frame = 0;
|
1394
1352
|
frame.return_value = Qnil;
|
1395
|
-
frame.target_frame = &frame;
|
1396
|
-
frame.exception = Qnil;
|
1397
1353
|
frame.rescue = 0;
|
1354
|
+
frame.targetted = 0;
|
1355
|
+
frame.thread_data = rb_current_thread_data();
|
1398
1356
|
|
1399
1357
|
|
1400
1358
|
int stack_chunk_instantiated = 0;
|
1401
1359
|
VALUE rb_previous_stack_chunk = Qnil;
|
1402
|
-
VALUE
|
1403
|
-
|
1404
|
-
struct STACKCHUNKREFERENCE* stack_chunk_reference = 0;
|
1360
|
+
VALUE rb_stack_chunk = frame.thread_data->rb_stack_chunk;
|
1361
|
+
struct STACKCHUNK* stack_chunk = 0;
|
1405
1362
|
|
1406
|
-
if (
|
1407
|
-
|
1363
|
+
if (rb_stack_chunk != Qnil) {
|
1364
|
+
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
1408
1365
|
}
|
1409
1366
|
|
1410
|
-
if (
|
1367
|
+
if (stack_chunk == 0 || (stack_chunk == 0 ? 0 : stack_chunk_frozen(stack_chunk)) ) {
|
1411
1368
|
rb_previous_stack_chunk = rb_stack_chunk;
|
1412
1369
|
rb_gc_register_address(&rb_stack_chunk);
|
1413
1370
|
stack_chunk_instantiated = 1;
|
1414
1371
|
|
1415
|
-
|
1372
|
+
rb_stack_chunk = rb_stack_chunk_create(Qnil);
|
1373
|
+
frame.thread_data->rb_stack_chunk = rb_stack_chunk;
|
1374
|
+
|
1375
|
+
rb_ivar_set(rb_stack_chunk, #{intern_num :_parent_stack_chunk}, rb_previous_stack_chunk);
|
1376
|
+
|
1377
|
+
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
1416
1378
|
}
|
1417
1379
|
|
1418
|
-
int previous_stack_position = stack_chunk_get_current_position(
|
1380
|
+
int previous_stack_position = stack_chunk_get_current_position(stack_chunk);
|
1419
1381
|
|
1420
|
-
plocals = (typeof(plocals))stack_chunk_alloc(
|
1382
|
+
plocals = (typeof(plocals))stack_chunk_alloc(stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
|
1421
1383
|
plocals->active = Qtrue;
|
1422
1384
|
plocals->pframe = LONG2FIX(&frame);
|
1423
1385
|
frame.plocals = plocals;
|
@@ -1428,17 +1390,11 @@ module FastRuby
|
|
1428
1390
|
|
1429
1391
|
int aux = setjmp(pframe->jmp);
|
1430
1392
|
if (aux != 0) {
|
1431
|
-
stack_chunk_set_current_position(
|
1393
|
+
stack_chunk_set_current_position(stack_chunk, previous_stack_position);
|
1432
1394
|
|
1433
1395
|
if (stack_chunk_instantiated) {
|
1434
1396
|
rb_gc_unregister_address(&rb_stack_chunk);
|
1435
|
-
|
1436
|
-
}
|
1437
|
-
|
1438
|
-
if (pframe->target_frame != pframe) {
|
1439
|
-
// raise exception
|
1440
|
-
plocals->active = Qfalse;
|
1441
|
-
return Qnil;
|
1397
|
+
frame.thread_data->rb_stack_chunk = rb_previous_stack_chunk;
|
1442
1398
|
}
|
1443
1399
|
|
1444
1400
|
plocals->active = Qfalse;
|
@@ -1456,11 +1412,11 @@ module FastRuby
|
|
1456
1412
|
plocals->call_frame = LONG2FIX(0);
|
1457
1413
|
|
1458
1414
|
VALUE ret = #{to_c impl_tree};
|
1459
|
-
stack_chunk_set_current_position(
|
1415
|
+
stack_chunk_set_current_position(stack_chunk, previous_stack_position);
|
1460
1416
|
|
1461
1417
|
if (stack_chunk_instantiated) {
|
1462
1418
|
rb_gc_unregister_address(&rb_stack_chunk);
|
1463
|
-
|
1419
|
+
frame.thread_data->rb_stack_chunk = rb_previous_stack_chunk;
|
1464
1420
|
}
|
1465
1421
|
|
1466
1422
|
plocals->active = Qfalse;
|
@@ -1486,36 +1442,40 @@ module FastRuby
|
|
1486
1442
|
#{@frame_struct} *pframe;
|
1487
1443
|
|
1488
1444
|
frame.parent_frame = (void*)_parent_frame;
|
1489
|
-
frame.stack_chunk = ((typeof(pframe))_parent_frame)->stack_chunk;
|
1490
1445
|
frame.return_value = Qnil;
|
1491
|
-
frame.target_frame = &frame;
|
1492
|
-
frame.exception = Qnil;
|
1493
1446
|
frame.rescue = 0;
|
1447
|
+
frame.targetted = 0;
|
1448
|
+
frame.thread_data = ((typeof(pframe))_parent_frame)->thread_data;
|
1449
|
+
if (frame.thread_data == 0) frame.thread_data = rb_current_thread_data();
|
1494
1450
|
|
1495
1451
|
int stack_chunk_instantiated = 0;
|
1496
1452
|
VALUE rb_previous_stack_chunk = Qnil;
|
1497
|
-
VALUE
|
1498
|
-
|
1499
|
-
struct STACKCHUNKREFERENCE* stack_chunk_reference = 0;
|
1453
|
+
VALUE rb_stack_chunk = frame.thread_data->rb_stack_chunk;
|
1454
|
+
struct STACKCHUNK* stack_chunk = 0;
|
1500
1455
|
|
1501
|
-
if (
|
1502
|
-
|
1456
|
+
if (rb_stack_chunk != Qnil) {
|
1457
|
+
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
1503
1458
|
}
|
1504
1459
|
|
1505
|
-
if (
|
1460
|
+
if (stack_chunk == 0 || (stack_chunk == 0 ? 0 : stack_chunk_frozen(stack_chunk)) ) {
|
1506
1461
|
rb_previous_stack_chunk = rb_stack_chunk;
|
1507
1462
|
rb_gc_register_address(&rb_stack_chunk);
|
1508
1463
|
stack_chunk_instantiated = 1;
|
1509
1464
|
|
1510
|
-
|
1465
|
+
rb_stack_chunk = rb_stack_chunk_create(Qnil);
|
1466
|
+
frame.thread_data->rb_stack_chunk = rb_stack_chunk;
|
1467
|
+
|
1468
|
+
rb_ivar_set(rb_stack_chunk, #{intern_num :_parent_stack_chunk}, rb_previous_stack_chunk);
|
1469
|
+
|
1470
|
+
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
1511
1471
|
}
|
1512
1472
|
|
1513
1473
|
|
1514
1474
|
#{@locals_struct} *plocals;
|
1515
1475
|
|
1516
|
-
int previous_stack_position = stack_chunk_get_current_position(
|
1476
|
+
int previous_stack_position = stack_chunk_get_current_position(stack_chunk);
|
1517
1477
|
|
1518
|
-
plocals = (typeof(plocals))stack_chunk_alloc(
|
1478
|
+
plocals = (typeof(plocals))stack_chunk_alloc(stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
|
1519
1479
|
frame.plocals = plocals;
|
1520
1480
|
plocals->active = Qtrue;
|
1521
1481
|
plocals->pframe = LONG2FIX(&frame);
|
@@ -1530,20 +1490,15 @@ module FastRuby
|
|
1530
1490
|
if (aux != 0) {
|
1531
1491
|
plocals->active = Qfalse;
|
1532
1492
|
|
1533
|
-
stack_chunk_set_current_position(
|
1493
|
+
stack_chunk_set_current_position(stack_chunk, previous_stack_position);
|
1534
1494
|
|
1535
1495
|
if (stack_chunk_instantiated) {
|
1536
1496
|
rb_gc_unregister_address(&rb_stack_chunk);
|
1537
|
-
|
1497
|
+
frame.thread_data->rb_stack_chunk = rb_previous_stack_chunk;
|
1538
1498
|
}
|
1539
1499
|
|
1540
|
-
if (pframe->
|
1541
|
-
|
1542
|
-
((typeof(pframe))_parent_frame)->exception = pframe->exception;
|
1543
|
-
((typeof(pframe))_parent_frame)->target_frame = pframe->target_frame;
|
1544
|
-
((typeof(pframe))_parent_frame)->return_value = pframe->return_value;
|
1545
|
-
|
1546
|
-
longjmp(((typeof(pframe))_parent_frame)->jmp,1);
|
1500
|
+
if (pframe->targetted == 0) {
|
1501
|
+
longjmp(((typeof(pframe))_parent_frame)->jmp,aux);
|
1547
1502
|
}
|
1548
1503
|
|
1549
1504
|
return plocals->return_value;
|
@@ -1565,11 +1520,11 @@ module FastRuby
|
|
1565
1520
|
}
|
1566
1521
|
|
1567
1522
|
VALUE __ret = #{to_c impl_tree};
|
1568
|
-
stack_chunk_set_current_position(
|
1523
|
+
stack_chunk_set_current_position(stack_chunk, previous_stack_position);
|
1569
1524
|
|
1570
1525
|
if (stack_chunk_instantiated) {
|
1571
1526
|
rb_gc_unregister_address(&rb_stack_chunk);
|
1572
|
-
|
1527
|
+
frame.thread_data->rb_stack_chunk = rb_previous_stack_chunk;
|
1573
1528
|
}
|
1574
1529
|
|
1575
1530
|
plocals->active = Qfalse;
|
@@ -1711,14 +1666,25 @@ module FastRuby
|
|
1711
1666
|
resbody_tree = tree[2]
|
1712
1667
|
else_tree = tree[3]
|
1713
1668
|
|
1714
|
-
|
1715
|
-
|
1716
|
-
|
1717
|
-
|
1718
|
-
|
1719
|
-
|
1669
|
+
trapcode = "rb_eException";
|
1670
|
+
if resbody_tree[1][1]
|
1671
|
+
trapcode = to_c(resbody_tree[1][1])
|
1672
|
+
end
|
1673
|
+
|
1674
|
+
frame_call(
|
1675
|
+
frame(to_c(tree[1])+";","
|
1676
|
+
if (aux == FASTRUBY_TAG_RAISE) {
|
1677
|
+
if (rb_obj_is_kind_of(frame.thread_data->exception,#{trapcode}) == Qtrue)
|
1678
|
+
{
|
1679
|
+
// trap exception
|
1680
|
+
frame.targetted = 1;
|
1681
|
+
|
1682
|
+
#{to_c(resbody_tree[2])};
|
1683
|
+
}
|
1720
1684
|
}
|
1721
1685
|
", else_tree ? to_c(else_tree) : nil, 1)
|
1686
|
+
|
1687
|
+
)
|
1722
1688
|
end
|
1723
1689
|
end
|
1724
1690
|
|
@@ -1746,9 +1712,8 @@ module FastRuby
|
|
1746
1712
|
args = tree[3]
|
1747
1713
|
|
1748
1714
|
return inline_block("
|
1749
|
-
pframe->
|
1750
|
-
pframe->
|
1751
|
-
longjmp(pframe->jmp, 1);
|
1715
|
+
pframe->thread_data->exception = rb_funcall(#{to_c args[1]}, #{intern_num :exception},0);
|
1716
|
+
longjmp(pframe->jmp, FASTRUBY_TAG_RAISE);
|
1752
1717
|
return Qnil;
|
1753
1718
|
")
|
1754
1719
|
end
|
@@ -1874,34 +1839,37 @@ module FastRuby
|
|
1874
1839
|
typeof(&frame) pframe = &frame;
|
1875
1840
|
#{@locals_struct} *plocals;
|
1876
1841
|
|
1877
|
-
frame.stack_chunk = 0;
|
1878
1842
|
frame.parent_frame = 0;
|
1879
1843
|
frame.return_value = Qnil;
|
1880
|
-
frame.target_frame = &frame;
|
1881
|
-
frame.exception = Qnil;
|
1882
1844
|
frame.rescue = 0;
|
1845
|
+
frame.targetted = 0;
|
1846
|
+
frame.thread_data = rb_current_thread_data();
|
1883
1847
|
|
1884
1848
|
int stack_chunk_instantiated = 0;
|
1885
1849
|
VALUE rb_previous_stack_chunk = Qnil;
|
1886
|
-
VALUE
|
1887
|
-
|
1888
|
-
struct STACKCHUNKREFERENCE* stack_chunk_reference = 0;
|
1850
|
+
VALUE rb_stack_chunk = frame.thread_data->rb_stack_chunk;
|
1851
|
+
struct STACKCHUNK* stack_chunk = 0;
|
1889
1852
|
|
1890
|
-
if (
|
1891
|
-
|
1853
|
+
if (rb_stack_chunk != Qnil) {
|
1854
|
+
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
1892
1855
|
}
|
1893
1856
|
|
1894
|
-
if (
|
1857
|
+
if (stack_chunk == 0 || (stack_chunk == 0 ? 0 : stack_chunk_frozen(stack_chunk)) ) {
|
1895
1858
|
rb_previous_stack_chunk = rb_stack_chunk;
|
1896
1859
|
rb_gc_register_address(&rb_stack_chunk);
|
1897
1860
|
stack_chunk_instantiated = 1;
|
1898
1861
|
|
1899
|
-
|
1862
|
+
rb_stack_chunk = rb_stack_chunk_create(Qnil);
|
1863
|
+
frame.thread_data->rb_stack_chunk = rb_stack_chunk;
|
1864
|
+
|
1865
|
+
rb_ivar_set(rb_stack_chunk, #{intern_num :_parent_stack_chunk}, rb_previous_stack_chunk);
|
1866
|
+
|
1867
|
+
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
1900
1868
|
}
|
1901
1869
|
|
1902
|
-
int previous_stack_position = stack_chunk_get_current_position(
|
1870
|
+
int previous_stack_position = stack_chunk_get_current_position(stack_chunk);
|
1903
1871
|
|
1904
|
-
plocals = (typeof(plocals))stack_chunk_alloc(
|
1872
|
+
plocals = (typeof(plocals))stack_chunk_alloc(stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
|
1905
1873
|
|
1906
1874
|
frame.plocals = plocals;
|
1907
1875
|
plocals->active = Qtrue;
|
@@ -1910,11 +1878,11 @@ module FastRuby
|
|
1910
1878
|
|
1911
1879
|
#{to_c tree};
|
1912
1880
|
|
1913
|
-
stack_chunk_set_current_position(
|
1881
|
+
stack_chunk_set_current_position(stack_chunk, previous_stack_position);
|
1914
1882
|
|
1915
1883
|
if (stack_chunk_instantiated) {
|
1916
1884
|
rb_gc_unregister_address(&rb_stack_chunk);
|
1917
|
-
|
1885
|
+
frame.thread_data->rb_stack_chunk = rb_previous_stack_chunk;
|
1918
1886
|
}
|
1919
1887
|
|
1920
1888
|
plocals->active = Qfalse;
|
@@ -1978,6 +1946,13 @@ module FastRuby
|
|
1978
1946
|
end
|
1979
1947
|
end
|
1980
1948
|
|
1949
|
+
def to_c_for(tree)
|
1950
|
+
alter_tree = tree.dup
|
1951
|
+
alter_tree[0] = :iter
|
1952
|
+
alter_tree[1] = [:call, alter_tree[1], :each, [:arglist]]
|
1953
|
+
to_c alter_tree
|
1954
|
+
end
|
1955
|
+
|
1981
1956
|
def to_c_while(tree)
|
1982
1957
|
inline_block("
|
1983
1958
|
while (#{to_c tree[1]}) {
|
@@ -2101,36 +2076,6 @@ module FastRuby
|
|
2101
2076
|
end
|
2102
2077
|
|
2103
2078
|
def protected_block(inner_code, always_rescue = false,repass_var = nil, nolocals = false)
|
2104
|
-
wrapper_code = "
|
2105
|
-
if (pframe->last_error != Qnil) {
|
2106
|
-
if (CLASS_OF(pframe->last_error)==#{literal_value FastRuby::Context::UnwindFastrubyFrame}) {
|
2107
|
-
#{@frame_struct} *pframe = (void*)param;
|
2108
|
-
|
2109
|
-
pframe->target_frame = (void*)FIX2LONG(rb_ivar_get(pframe->last_error, #{intern_num :@target_frame}));
|
2110
|
-
pframe->exception = rb_ivar_get(pframe->last_error, #{intern_num :@ex});
|
2111
|
-
pframe->return_value = rb_ivar_get(pframe->last_error, #{intern_num :@return_value});
|
2112
|
-
|
2113
|
-
longjmp(pframe->jmp, 1);
|
2114
|
-
return Qnil;
|
2115
|
-
|
2116
|
-
} else {
|
2117
|
-
|
2118
|
-
// raise emulation
|
2119
|
-
#{@frame_struct} *pframe = (void*)param;
|
2120
|
-
pframe->target_frame = (void*)-1;
|
2121
|
-
pframe->exception = pframe->last_error;
|
2122
|
-
longjmp(pframe->jmp, 1);
|
2123
|
-
return Qnil;
|
2124
|
-
}
|
2125
|
-
|
2126
|
-
} else {
|
2127
|
-
if (pframe->target_frame != pframe) {
|
2128
|
-
longjmp(pframe->jmp, 1);
|
2129
|
-
}
|
2130
|
-
}
|
2131
|
-
"
|
2132
|
-
|
2133
|
-
|
2134
2079
|
body = nil
|
2135
2080
|
rescue_args = nil
|
2136
2081
|
if repass_var
|
@@ -2143,12 +2088,12 @@ module FastRuby
|
|
2143
2088
|
typeof(frame)* parent_frame = ((typeof(pframe))((void**)param)[0]);
|
2144
2089
|
|
2145
2090
|
frame.parent_frame = 0;
|
2146
|
-
frame.target_frame = 0;
|
2147
2091
|
frame.return_value = Qnil;
|
2148
|
-
frame.exception = Qnil;
|
2149
2092
|
frame.rescue = 0;
|
2150
2093
|
frame.last_error = Qnil;
|
2151
|
-
frame.
|
2094
|
+
frame.targetted = 0;
|
2095
|
+
frame.thread_data = parent_frame->thread_data;
|
2096
|
+
if (frame.thread_data == 0) frame.thread_data = rb_current_thread_data();
|
2152
2097
|
|
2153
2098
|
pframe = &frame;
|
2154
2099
|
|
@@ -2158,12 +2103,14 @@ module FastRuby
|
|
2158
2103
|
"
|
2159
2104
|
}
|
2160
2105
|
|
2161
|
-
|
2162
|
-
|
2163
|
-
parent_frame->exception = frame.exception;
|
2164
|
-
parent_frame->return_value = frame.return_value;
|
2106
|
+
int aux = setjmp(frame.jmp);
|
2107
|
+
if (aux != 0) {
|
2165
2108
|
|
2166
|
-
|
2109
|
+
if (frame.targetted == 1) {
|
2110
|
+
return frame.return_value;
|
2111
|
+
} else {
|
2112
|
+
rb_jump_tag(aux);
|
2113
|
+
}
|
2167
2114
|
}
|
2168
2115
|
|
2169
2116
|
VALUE #{repass_var} = (VALUE)((void**)param)[1];
|
@@ -2184,12 +2131,12 @@ module FastRuby
|
|
2184
2131
|
typeof(frame)* parent_frame = (typeof(pframe))param;
|
2185
2132
|
|
2186
2133
|
frame.parent_frame = 0;
|
2187
|
-
frame.target_frame = 0;
|
2188
2134
|
frame.return_value = Qnil;
|
2189
|
-
frame.exception = Qnil;
|
2190
2135
|
frame.rescue = 0;
|
2191
2136
|
frame.last_error = Qnil;
|
2192
|
-
frame.
|
2137
|
+
frame.targetted = 0;
|
2138
|
+
frame.thread_data = parent_frame->thread_data;
|
2139
|
+
if (frame.thread_data == 0) frame.thread_data = rb_current_thread_data();
|
2193
2140
|
|
2194
2141
|
pframe = &frame;
|
2195
2142
|
|
@@ -2199,12 +2146,14 @@ module FastRuby
|
|
2199
2146
|
"
|
2200
2147
|
}
|
2201
2148
|
|
2202
|
-
|
2203
|
-
|
2204
|
-
parent_frame->exception = frame.exception;
|
2205
|
-
parent_frame->return_value = frame.return_value;
|
2149
|
+
int aux = setjmp(frame.jmp);
|
2150
|
+
if (aux != 0) {
|
2206
2151
|
|
2207
|
-
|
2152
|
+
if (frame.targetted == 1) {
|
2153
|
+
return frame.return_value;
|
2154
|
+
} else {
|
2155
|
+
rb_jump_tag(aux);
|
2156
|
+
}
|
2208
2157
|
}
|
2209
2158
|
|
2210
2159
|
return #{inner_code};
|
@@ -2215,18 +2164,30 @@ module FastRuby
|
|
2215
2164
|
rescue_args = "(VALUE)pframe"
|
2216
2165
|
end
|
2217
2166
|
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2221
|
-
|
2167
|
+
wrapper_code = " if (state != 0) {
|
2168
|
+
if (state < 0x80) {
|
2169
|
+
|
2170
|
+
if (state == TAG_RAISE) {
|
2171
|
+
// raise emulation
|
2172
|
+
pframe->thread_data->exception = rb_eval_string(\"$!\");
|
2173
|
+
longjmp(pframe->jmp, FASTRUBY_TAG_RAISE);
|
2174
|
+
return Qnil;
|
2175
|
+
} else {
|
2176
|
+
rb_jump_tag(state);
|
2177
|
+
}
|
2178
|
+
} else {
|
2179
|
+
longjmp(pframe->jmp, state);
|
2222
2180
|
}
|
2223
|
-
|
2224
|
-
|
2181
|
+
|
2182
|
+
}
|
2183
|
+
"
|
2184
|
+
|
2185
|
+
rescue_code = "rb_protect(#{body},#{rescue_args},&state)"
|
2225
2186
|
|
2226
2187
|
if always_rescue
|
2227
2188
|
inline_block "
|
2189
|
+
int state;
|
2228
2190
|
pframe->last_error = Qnil;
|
2229
|
-
pframe->target_frame = pframe;
|
2230
2191
|
VALUE result = #{rescue_code};
|
2231
2192
|
|
2232
2193
|
#{wrapper_code}
|
@@ -2236,23 +2197,21 @@ module FastRuby
|
|
2236
2197
|
else
|
2237
2198
|
inline_block "
|
2238
2199
|
VALUE result;
|
2200
|
+
int state;
|
2239
2201
|
pframe->last_error = Qnil;
|
2240
2202
|
|
2241
2203
|
if (pframe->rescue) {
|
2242
2204
|
result = #{rescue_code};
|
2205
|
+
#{wrapper_code}
|
2243
2206
|
} else {
|
2244
2207
|
return #{inner_code};
|
2245
2208
|
}
|
2246
2209
|
|
2247
|
-
#{wrapper_code}
|
2248
|
-
|
2249
2210
|
return result;
|
2250
2211
|
", repass_var, nolocals
|
2251
2212
|
end
|
2252
|
-
|
2253
2213
|
end
|
2254
2214
|
|
2255
|
-
|
2256
2215
|
def func_frame
|
2257
2216
|
"
|
2258
2217
|
#{@locals_struct} *plocals = malloc(sizeof(typeof(*plocals)));
|
@@ -2261,11 +2220,11 @@ module FastRuby
|
|
2261
2220
|
|
2262
2221
|
frame.plocals = plocals;
|
2263
2222
|
frame.parent_frame = (void*)_parent_frame;
|
2264
|
-
frame.stack_chunk = ((typeof(pframe))_parent_frame)->stack_chunk;
|
2265
2223
|
frame.return_value = Qnil;
|
2266
|
-
frame.target_frame = &frame;
|
2267
|
-
frame.exception = Qnil;
|
2268
2224
|
frame.rescue = 0;
|
2225
|
+
frame.targetted = 0;
|
2226
|
+
frame.thread_data = ((typeof(pframe))_parent_frame)->thread_data;
|
2227
|
+
if (frame.thread_data == 0) frame.thread_data = rb_current_thread_data();
|
2269
2228
|
|
2270
2229
|
plocals->pframe = LONG2FIX(&frame);
|
2271
2230
|
|
@@ -2277,12 +2236,8 @@ module FastRuby
|
|
2277
2236
|
int aux = setjmp(pframe->jmp);
|
2278
2237
|
if (aux != 0) {
|
2279
2238
|
|
2280
|
-
if (pframe->
|
2281
|
-
|
2282
|
-
((typeof(pframe))_parent_frame)->exception = pframe->exception;
|
2283
|
-
((typeof(pframe))_parent_frame)->target_frame = pframe->target_frame;
|
2284
|
-
((typeof(pframe))_parent_frame)->return_value = pframe->return_value;
|
2285
|
-
longjmp(((typeof(pframe))_parent_frame)->jmp,1);
|
2239
|
+
if (pframe->targetted == 0) {
|
2240
|
+
longjmp(((typeof(pframe))_parent_frame)->jmp,aux);
|
2286
2241
|
}
|
2287
2242
|
|
2288
2243
|
return plocals->return_value;
|
@@ -2547,12 +2502,12 @@ module FastRuby
|
|
2547
2502
|
|
2548
2503
|
parent_frame = (void*)param;
|
2549
2504
|
|
2550
|
-
frame.stack_chunk = parent_frame->stack_chunk;
|
2551
2505
|
frame.parent_frame = (void*)param;
|
2552
2506
|
frame.plocals = parent_frame->plocals;
|
2553
|
-
frame.target_frame = &frame;
|
2554
|
-
frame.exception = Qnil;
|
2555
2507
|
frame.rescue = #{rescued ? rescued : "parent_frame->rescue"};
|
2508
|
+
frame.targetted = 0;
|
2509
|
+
frame.thread_data = parent_frame->thread_data;
|
2510
|
+
if (frame.thread_data == 0) frame.thread_data = rb_current_thread_data();
|
2556
2511
|
|
2557
2512
|
plocals = frame.plocals;
|
2558
2513
|
pframe = &frame;
|
@@ -2567,12 +2522,8 @@ module FastRuby
|
|
2567
2522
|
|
2568
2523
|
#{jmp_code};
|
2569
2524
|
|
2570
|
-
if (original_frame->
|
2571
|
-
pframe->
|
2572
|
-
pframe->target_frame = original_frame->target_frame;
|
2573
|
-
pframe->return_value = original_frame->return_value;
|
2574
|
-
|
2575
|
-
longjmp(pframe->jmp,1);
|
2525
|
+
if (original_frame->targetted == 0) {
|
2526
|
+
longjmp(pframe->jmp,aux);
|
2576
2527
|
}
|
2577
2528
|
|
2578
2529
|
return last_expression;
|