fastruby 0.0.7 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +6 -0
- data/Rakefile +3 -2
- data/ext/fastruby_base/extconf.rb +7 -0
- data/ext/fastruby_base/fastruby_base.c +5 -0
- data/lib/fastruby/translator.rb +523 -116
- data/lib/fastruby.rb +1 -1
- data/spec/block/break_spec.rb +46 -0
- data/spec/block/callcc_spec.rb +115 -0
- data/spec/block/lambda_spec.rb +181 -0
- metadata +10 -6
data/lib/fastruby/translator.rb
CHANGED
@@ -53,6 +53,7 @@ module FastRuby
|
|
53
53
|
VALUE exception;
|
54
54
|
int rescue;
|
55
55
|
VALUE last_error;
|
56
|
+
void* stack_chunk;
|
56
57
|
}"
|
57
58
|
|
58
59
|
@block_struct = "struct {
|
@@ -61,8 +62,14 @@ module FastRuby
|
|
61
62
|
}"
|
62
63
|
|
63
64
|
|
64
|
-
extra_code <<
|
65
|
-
|
65
|
+
extra_code << "
|
66
|
+
#include \"node.h\"
|
67
|
+
|
68
|
+
#ifndef __INLINE_FASTRUBY_BASE
|
69
|
+
#include \"#{FastRuby.fastruby_load_path}/../ext/fastruby_base/fastruby_base.inl\"
|
70
|
+
#define __INLINE_FASTRUBY_BASE
|
71
|
+
#endif
|
72
|
+
"
|
66
73
|
|
67
74
|
ruby_code = "
|
68
75
|
$LOAD_PATH << #{FastRuby.fastruby_load_path.inspect}
|
@@ -73,6 +80,8 @@ module FastRuby
|
|
73
80
|
rb_eval_string(#{ruby_code.inspect});
|
74
81
|
"
|
75
82
|
|
83
|
+
|
84
|
+
|
76
85
|
@common_func = common_func
|
77
86
|
if common_func
|
78
87
|
extra_code << "static VALUE _rb_gvar_set(void* ge,VALUE value) {
|
@@ -82,7 +91,13 @@ module FastRuby
|
|
82
91
|
"
|
83
92
|
|
84
93
|
extra_code << "static VALUE re_yield(int argc, VALUE* argv, VALUE param, VALUE _parent_frame) {
|
85
|
-
|
94
|
+
VALUE yield_args = rb_ary_new4(argc,argv);
|
95
|
+
VALUE* yield_args_p = &yield_args;
|
96
|
+
|
97
|
+
#{@frame_struct}* pframe;
|
98
|
+
pframe = (typeof(pframe))_parent_frame;
|
99
|
+
|
100
|
+
return #{protected_block("rb_yield_splat(*(VALUE*)yield_args_p)",true,"yield_args_p",true)};
|
86
101
|
}"
|
87
102
|
|
88
103
|
extra_code << "static VALUE _rb_ivar_set(VALUE recv,ID idvar, VALUE value) {
|
@@ -106,6 +121,55 @@ module FastRuby
|
|
106
121
|
#{caller.join("\n")}
|
107
122
|
*/
|
108
123
|
|
124
|
+
"
|
125
|
+
extra_code << "static struct STACKCHUNKREFRENCE* get_stack_chunk_reference_from_context() {
|
126
|
+
struct STACKCHUNKREFERENCE* stack_chunk_reference;
|
127
|
+
VALUE current_thread = rb_thread_current();
|
128
|
+
VALUE rb_stack_chunk_reference = rb_ivar_get(current_thread,#{intern_num :_fastruby_stack_chunk_reference});
|
129
|
+
if (rb_stack_chunk_reference == Qnil) {
|
130
|
+
rb_stack_chunk_reference = rb_stack_chunk_reference_create();
|
131
|
+
rb_ivar_set(current_thread,#{intern_num :_fastruby_stack_chunk_reference},rb_stack_chunk_reference);
|
132
|
+
}
|
133
|
+
|
134
|
+
Data_Get_Struct(rb_stack_chunk_reference,struct STACKCHUNKREFERENCE,stack_chunk_reference);
|
135
|
+
|
136
|
+
return (void*)stack_chunk_reference;
|
137
|
+
}
|
138
|
+
|
139
|
+
static struct STACKCHUNK* get_stack_chunk_from_context(
|
140
|
+
struct STACKCHUNKREFERENCE** stack_chunk_reference,
|
141
|
+
VALUE* rb_stack_chunk
|
142
|
+
) {
|
143
|
+
struct STACKCHUNK* stack_chunk = 0;
|
144
|
+
*stack_chunk_reference = (void*)get_stack_chunk_reference_from_context();
|
145
|
+
*rb_stack_chunk = stack_chunk_reference_retrieve(*stack_chunk_reference);
|
146
|
+
if (*rb_stack_chunk != Qnil) {
|
147
|
+
Data_Get_Struct(*rb_stack_chunk,void,stack_chunk);
|
148
|
+
}
|
149
|
+
|
150
|
+
return stack_chunk;
|
151
|
+
}
|
152
|
+
|
153
|
+
static struct STACKCHUNK* create_stack_chunk_from_context(
|
154
|
+
struct STACKCHUNKREFERENCE** stack_chunk_reference,
|
155
|
+
VALUE* rb_stack_chunk_p
|
156
|
+
) {
|
157
|
+
|
158
|
+
struct STACKCHUNK* stack_chunk;
|
159
|
+
VALUE rb_stack_chunk = rb_stack_chunk_create(Qnil);
|
160
|
+
|
161
|
+
if (*stack_chunk_reference == 0) {
|
162
|
+
*stack_chunk_reference = (void*)get_stack_chunk_reference_from_context();
|
163
|
+
}
|
164
|
+
|
165
|
+
stack_chunk_reference_assign(*stack_chunk_reference, rb_stack_chunk);
|
166
|
+
Data_Get_Struct(rb_stack_chunk,void,stack_chunk);
|
167
|
+
|
168
|
+
*rb_stack_chunk_p = rb_stack_chunk;
|
169
|
+
|
170
|
+
return stack_chunk;
|
171
|
+
}
|
172
|
+
|
109
173
|
"
|
110
174
|
end
|
111
175
|
end
|
@@ -225,13 +289,13 @@ module FastRuby
|
|
225
289
|
to_c(subtree)
|
226
290
|
}.join(";")
|
227
291
|
|
228
|
-
if anonymous_impl[-1][0] != :return
|
292
|
+
if anonymous_impl[-1][0] != :return and anonymous_impl[-1][0] != :break and anonymous_impl[-1][0] != :next
|
229
293
|
str_impl = str_impl + ";last_expression = (#{to_c(anonymous_impl[-1])});"
|
230
294
|
else
|
231
295
|
str_impl = str_impl + ";#{to_c(anonymous_impl[-1])};"
|
232
296
|
end
|
233
297
|
else
|
234
|
-
if anonymous_impl[0] != :return
|
298
|
+
if anonymous_impl[0] != :return and anonymous_impl[0] != :break and anonymous_impl[0] != :next
|
235
299
|
str_impl = str_impl + ";last_expression = (#{to_c(anonymous_impl)});"
|
236
300
|
else
|
237
301
|
str_impl = str_impl + ";#{to_c(anonymous_impl)};"
|
@@ -278,33 +342,92 @@ module FastRuby
|
|
278
342
|
str_recv = to_c recv_tree
|
279
343
|
str_recv = "plocals->self" unless recv_tree
|
280
344
|
|
345
|
+
execute_code = if mname == :lambda or mname == :proc
|
346
|
+
"VALUE ret = rb_funcall(#{str_recv}, #{intern_num call_tree[2]}, 0);
|
347
|
+
|
348
|
+
// freeze all stacks
|
349
|
+
VALUE current_thread = rb_thread_current();
|
350
|
+
VALUE rb_stack_chunk_reference = rb_ivar_get(current_thread,#{intern_num :_fastruby_stack_chunk_reference});
|
351
|
+
|
352
|
+
if (rb_stack_chunk_reference != Qnil) {
|
353
|
+
struct STACKCHUNKREFERENCE* stack_chunk_reference;
|
354
|
+
Data_Get_Struct(rb_stack_chunk_reference, struct STACKCHUNKREFERENCE, stack_chunk_reference);
|
355
|
+
|
356
|
+
VALUE rb_stack_chunk = stack_chunk_reference_retrieve(stack_chunk_reference);
|
357
|
+
|
358
|
+
// add reference to stack chunk to lambda object
|
359
|
+
rb_ivar_set(ret,#{intern_num :_fastruby_stack_chunk},rb_stack_chunk);
|
360
|
+
|
361
|
+
// freeze the complete chain of stack chunks
|
362
|
+
while (rb_stack_chunk != Qnil) {
|
363
|
+
struct STACKCHUNK* stack_chunk;
|
364
|
+
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
365
|
+
|
366
|
+
stack_chunk_freeze(stack_chunk);
|
367
|
+
|
368
|
+
rb_stack_chunk = rb_ivar_get(rb_stack_chunk,#{intern_num :_parent_stack_chunk});
|
369
|
+
}
|
370
|
+
}
|
371
|
+
|
372
|
+
return ret;
|
373
|
+
"
|
374
|
+
else
|
375
|
+
"return rb_funcall(#{str_recv}, #{intern_num call_tree[2]}, 0);"
|
376
|
+
end
|
377
|
+
|
281
378
|
rb_funcall_caller_code = proc { |name| "
|
282
379
|
static VALUE #{name}(VALUE param) {
|
283
380
|
// call to #{call_tree[2]}
|
284
381
|
#{str_lvar_initialization}
|
285
|
-
|
382
|
+
#{execute_code}
|
286
383
|
}
|
287
384
|
"
|
288
385
|
}
|
289
386
|
end
|
290
387
|
|
388
|
+
target_escape_code = if mname == :lambda or mname == :proc
|
389
|
+
"
|
390
|
+
// create a fake parent frame representing the lambda method frame and a fake locals scope
|
391
|
+
#{@locals_struct} fake_locals;
|
392
|
+
#{@frame_struct} fake_frame;
|
291
393
|
|
292
|
-
|
293
|
-
|
294
|
-
// block for call to #{call_tree[2]}
|
295
|
-
VALUE last_expression = Qnil;
|
394
|
+
fake_frame.plocals = (void*)&fake_locals;
|
395
|
+
fake_frame.parent_frame = 0;
|
296
396
|
|
297
|
-
|
298
|
-
#{@frame_struct} *pframe = (void*)&frame;
|
299
|
-
#{@locals_struct} *plocals = (void*)_plocals;
|
397
|
+
fake_locals.pframe = LONG2FIX(&fake_frame);
|
300
398
|
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
399
|
+
VALUE old_call_frame = ((typeof(fake_locals)*)(pframe->plocals))->call_frame;
|
400
|
+
((typeof(fake_locals)*)(pframe->plocals))->call_frame = LONG2FIX(pframe);
|
401
|
+
|
402
|
+
frame.parent_frame = (void*)&fake_frame;
|
403
|
+
|
404
|
+
if (setjmp(frame.jmp) != 0) {
|
405
|
+
|
406
|
+
if (pframe->target_frame != pframe) {
|
407
|
+
if (pframe->target_frame == (void*)-3) {
|
408
|
+
return pframe->return_value;
|
409
|
+
} else if (pframe->target_frame == (void*)-1) {
|
410
|
+
rb_funcall(((typeof(fake_locals)*)(pframe->plocals))->self, #{intern_num :raise}, 1, frame.exception);
|
411
|
+
return Qnil;
|
412
|
+
} else {
|
413
|
+
if (pframe->target_frame == (void*)FIX2LONG(plocals->pframe)) {
|
414
|
+
((typeof(fake_locals)*)(pframe->plocals))->call_frame = old_call_frame;
|
415
|
+
return pframe->return_value;
|
416
|
+
} else if (pframe->target_frame == (void*)&fake_frame) {
|
417
|
+
((typeof(fake_locals)*)(pframe->plocals))->call_frame = old_call_frame;
|
418
|
+
return fake_locals.return_value;
|
419
|
+
} else {
|
420
|
+
rb_raise(rb_eLocalJumpError, \"unexpected return\");
|
421
|
+
}
|
422
|
+
}
|
423
|
+
}
|
424
|
+
((typeof(fake_locals)*)(pframe->plocals))->call_frame = old_call_frame;
|
425
|
+
return frame.return_value;
|
426
|
+
}
|
307
427
|
|
428
|
+
"
|
429
|
+
else
|
430
|
+
"
|
308
431
|
if (setjmp(frame.jmp) != 0) {
|
309
432
|
if (pframe->target_frame != pframe) {
|
310
433
|
if (pframe->target_frame == (void*)-3) {
|
@@ -321,14 +444,38 @@ module FastRuby
|
|
321
444
|
);
|
322
445
|
|
323
446
|
rb_funcall(plocals->self, #{intern_num :raise}, 1, ex);
|
447
|
+
}
|
448
|
+
return frame.return_value;
|
324
449
|
}
|
325
|
-
|
326
|
-
|
450
|
+
|
451
|
+
"
|
452
|
+
end
|
453
|
+
|
454
|
+
rb_funcall_block_code = proc { |name| "
|
455
|
+
static VALUE #{name}(VALUE arg, VALUE _plocals) {
|
456
|
+
// block for call to #{call_tree[2]}
|
457
|
+
VALUE last_expression = Qnil;
|
458
|
+
|
459
|
+
#{@frame_struct} frame;
|
460
|
+
#{@frame_struct} *pframe = (void*)&frame;
|
461
|
+
#{@locals_struct} *plocals = (void*)_plocals;
|
462
|
+
|
463
|
+
frame.plocals = plocals;
|
464
|
+
frame.stack_chunk = 0;
|
465
|
+
frame.parent_frame = 0;
|
466
|
+
frame.return_value = Qnil;
|
467
|
+
frame.target_frame = &frame;
|
468
|
+
frame.exception = Qnil;
|
469
|
+
frame.rescue = 0;
|
470
|
+
|
471
|
+
#{target_escape_code}
|
327
472
|
|
328
473
|
|
329
474
|
#{str_arg_initialization}
|
330
475
|
#{str_impl}
|
331
476
|
|
477
|
+
#{"((typeof(fake_locals)*)(pframe->plocals))->call_frame = old_call_frame;" if mname == :lambda or mname == :proc}
|
478
|
+
|
332
479
|
return last_expression;
|
333
480
|
}
|
334
481
|
"
|
@@ -360,6 +507,7 @@ module FastRuby
|
|
360
507
|
|
361
508
|
frame.plocals = (void*)_locals;
|
362
509
|
frame.parent_frame = parent_frame;
|
510
|
+
frame.stack_chunk = parent_frame->stack_chunk;
|
363
511
|
frame.return_value = Qnil;
|
364
512
|
frame.target_frame = &frame;
|
365
513
|
frame.exception = Qnil;
|
@@ -376,6 +524,7 @@ module FastRuby
|
|
376
524
|
((typeof(pframe))_parent_frame)->exception = pframe->exception;
|
377
525
|
((typeof(pframe))_parent_frame)->target_frame = pframe->target_frame;
|
378
526
|
((typeof(pframe))_parent_frame)->return_value = pframe->return_value;
|
527
|
+
|
379
528
|
longjmp(((typeof(pframe))_parent_frame)->jmp,1);
|
380
529
|
}
|
381
530
|
|
@@ -427,9 +576,36 @@ module FastRuby
|
|
427
576
|
block.block_function_address = (void*)#{anonymous_function(&block_code)};
|
428
577
|
block.block_function_param = (void*)param;
|
429
578
|
|
430
|
-
//
|
579
|
+
// create a call_frame
|
580
|
+
#{@frame_struct} call_frame;
|
581
|
+
|
582
|
+
call_frame.parent_frame = (void*)pframe;
|
583
|
+
call_frame.target_frame = 0;
|
584
|
+
call_frame.plocals = plocals;
|
585
|
+
call_frame.return_value = Qnil;
|
586
|
+
call_frame.exception = Qnil;
|
587
|
+
call_frame.stack_chunk = ((typeof(&call_frame))pframe)->stack_chunk;
|
431
588
|
|
432
|
-
|
589
|
+
VALUE old_call_frame = plocals->call_frame;
|
590
|
+
plocals->call_frame = LONG2FIX(&call_frame);
|
591
|
+
|
592
|
+
if (setjmp(call_frame.jmp) != 0) {
|
593
|
+
#{@frame_struct}* pframe_ = (void*)pframe;
|
594
|
+
|
595
|
+
if (call_frame.target_frame != &call_frame) {
|
596
|
+
pframe_->target_frame = call_frame.target_frame;
|
597
|
+
pframe_->exception = call_frame.exception;
|
598
|
+
longjmp(pframe_->jmp,1);
|
599
|
+
}
|
600
|
+
|
601
|
+
plocals->call_frame = old_call_frame;
|
602
|
+
return call_frame.return_value;
|
603
|
+
}
|
604
|
+
|
605
|
+
// call to #{call_tree[2]}
|
606
|
+
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);
|
607
|
+
plocals->call_frame = old_call_frame;
|
608
|
+
return ret;
|
433
609
|
}
|
434
610
|
"
|
435
611
|
}
|
@@ -440,12 +616,51 @@ module FastRuby
|
|
440
616
|
return #{anonymous_function(&caller_code)}((VALUE)plocals, (VALUE)pframe);
|
441
617
|
} else {
|
442
618
|
return #{
|
443
|
-
|
619
|
+
frame_call(
|
620
|
+
protected_block("rb_iterate(#{anonymous_function(&rb_funcall_caller_code)}, (VALUE)pframe, #{anonymous_function(&rb_funcall_block_code)}, (VALUE)plocals)", true)
|
621
|
+
)
|
444
622
|
};
|
445
623
|
}
|
446
624
|
"
|
447
625
|
end
|
448
626
|
|
627
|
+
def frame_call(inner_code)
|
628
|
+
inline_block "
|
629
|
+
|
630
|
+
|
631
|
+
// create a call_frame
|
632
|
+
#{@frame_struct} call_frame;
|
633
|
+
typeof(call_frame)* old_pframe = (void*)pframe;
|
634
|
+
|
635
|
+
pframe = (typeof(pframe))&call_frame;
|
636
|
+
|
637
|
+
call_frame.parent_frame = (void*)pframe;
|
638
|
+
call_frame.target_frame = 0;
|
639
|
+
call_frame.plocals = plocals;
|
640
|
+
call_frame.return_value = Qnil;
|
641
|
+
call_frame.exception = Qnil;
|
642
|
+
call_frame.stack_chunk = ((typeof(&call_frame))pframe)->stack_chunk;
|
643
|
+
|
644
|
+
VALUE old_call_frame = plocals->call_frame;
|
645
|
+
plocals->call_frame = LONG2FIX(&call_frame);
|
646
|
+
|
647
|
+
if (setjmp(call_frame.jmp) != 0) {
|
648
|
+
if (call_frame.target_frame != &call_frame) {
|
649
|
+
old_pframe->target_frame = call_frame.target_frame;
|
650
|
+
old_pframe->exception = call_frame.exception;
|
651
|
+
longjmp(old_pframe->jmp,1);
|
652
|
+
}
|
653
|
+
|
654
|
+
plocals->call_frame = old_call_frame;
|
655
|
+
return call_frame.return_value;
|
656
|
+
}
|
657
|
+
|
658
|
+
VALUE ret = #{inner_code};
|
659
|
+
plocals->call_frame = old_call_frame;
|
660
|
+
return ret;
|
661
|
+
"
|
662
|
+
end
|
663
|
+
|
449
664
|
def to_c_yield(tree)
|
450
665
|
|
451
666
|
block_code = proc { |name| "
|
@@ -456,10 +671,10 @@ module FastRuby
|
|
456
671
|
pframe = (void*)frame_param;
|
457
672
|
plocals = (void*)pframe->plocals;
|
458
673
|
|
459
|
-
if (plocals->block_function_address == 0) {
|
674
|
+
if (FIX2LONG(plocals->block_function_address) == 0) {
|
460
675
|
rb_raise(rb_eLocalJumpError, \"no block given\");
|
461
676
|
} else {
|
462
|
-
return ((VALUE(*)(int,VALUE*,VALUE,VALUE))plocals->block_function_address)(#{tree.size-1}, block_args, plocals->block_function_param, (VALUE)pframe);
|
677
|
+
return ((VALUE(*)(int,VALUE*,VALUE,VALUE))FIX2LONG(plocals->block_function_address))(#{tree.size-1}, block_args, FIX2LONG(plocals->block_function_param), (VALUE)pframe);
|
463
678
|
}
|
464
679
|
}
|
465
680
|
"
|
@@ -520,15 +735,27 @@ module FastRuby
|
|
520
735
|
end
|
521
736
|
|
522
737
|
def to_c_return(tree)
|
523
|
-
"pframe->target_frame = ((typeof(pframe))plocals->pframe); plocals->return_value = #{to_c(tree[1])}; longjmp(pframe->jmp, 1); return Qnil;\n"
|
738
|
+
"pframe->target_frame = ((typeof(pframe))FIX2LONG(plocals->pframe)); plocals->return_value = #{to_c(tree[1])}; pframe->return_value = plocals->return_value; longjmp(pframe->jmp, 1); return Qnil;\n"
|
524
739
|
end
|
525
740
|
|
526
741
|
def to_c_break(tree)
|
527
742
|
if @on_block
|
528
743
|
inline_block(
|
529
744
|
"
|
530
|
-
|
531
|
-
|
745
|
+
|
746
|
+
VALUE value = #{tree[1] ? to_c(tree[1]) : "Qnil"};
|
747
|
+
|
748
|
+
typeof(pframe) target_frame_;
|
749
|
+
target_frame_ = (void*)FIX2LONG(plocals->call_frame);
|
750
|
+
|
751
|
+
if (target_frame_ == 0) {
|
752
|
+
rb_raise(rb_eLocalJumpError, \"illegal break\");
|
753
|
+
}
|
754
|
+
|
755
|
+
plocals->call_frame = LONG2FIX(0);
|
756
|
+
|
757
|
+
pframe->target_frame = target_frame_;
|
758
|
+
pframe->return_value = value;
|
532
759
|
pframe->exception = Qnil;
|
533
760
|
longjmp(pframe->jmp,1);"
|
534
761
|
)
|
@@ -744,8 +971,11 @@ module FastRuby
|
|
744
971
|
VALUE return_value;
|
745
972
|
VALUE exception;
|
746
973
|
int rescue;
|
974
|
+
VALUE last_error;
|
975
|
+
void* stack_chunk;
|
747
976
|
} frame;
|
748
977
|
|
978
|
+
frame.stack_chunk = 0;
|
749
979
|
frame.target_frame = 0;
|
750
980
|
frame.parent_frame = 0;
|
751
981
|
frame.rescue = 0;
|
@@ -890,35 +1120,15 @@ module FastRuby
|
|
890
1120
|
|
891
1121
|
def initialize_method_structs(args_tree)
|
892
1122
|
@locals_struct = "struct {
|
893
|
-
void* block_function_address;
|
894
|
-
VALUE block_function_param;
|
895
|
-
jmp_buf jmp;
|
896
1123
|
VALUE return_value;
|
897
|
-
|
1124
|
+
VALUE pframe;
|
1125
|
+
VALUE block_function_address;
|
1126
|
+
VALUE block_function_param;
|
1127
|
+
VALUE call_frame;
|
898
1128
|
#{@locals.map{|l| "VALUE #{l};\n"}.join}
|
899
1129
|
#{args_tree[1..-1].map{|arg| "VALUE #{arg};\n"}.join};
|
900
1130
|
}"
|
901
1131
|
|
902
|
-
if @common_func
|
903
|
-
init_extra << "
|
904
|
-
#{@frame_struct} frame;
|
905
|
-
#{@locals_struct} locals;
|
906
|
-
|
907
|
-
locals.return_value = Qnil;
|
908
|
-
locals.pframe = &frame;
|
909
|
-
locals.self = rb_cObject;
|
910
|
-
|
911
|
-
frame.target_frame = 0;
|
912
|
-
frame.plocals = (void*)&locals;
|
913
|
-
frame.return_value = Qnil;
|
914
|
-
frame.exception = Qnil;
|
915
|
-
frame.rescue = 0;
|
916
|
-
frame.last_error = Qnil;
|
917
|
-
|
918
|
-
typeof(&frame) pframe = &frame;
|
919
|
-
"
|
920
|
-
end
|
921
|
-
|
922
1132
|
end
|
923
1133
|
|
924
1134
|
def to_c_method_defs(tree)
|
@@ -940,11 +1150,11 @@ module FastRuby
|
|
940
1150
|
#{func_frame}
|
941
1151
|
|
942
1152
|
#{args_tree[1..-1].map { |arg|
|
943
|
-
"
|
1153
|
+
"plocals->#{arg} = #{arg};\n"
|
944
1154
|
}.join("") }
|
945
1155
|
|
946
|
-
|
947
|
-
|
1156
|
+
plocals->block_function_address = LONG2FIX(block_address);
|
1157
|
+
plocals->block_function_param = LONG2FIX(block_param);
|
948
1158
|
|
949
1159
|
return #{to_c impl_tree};
|
950
1160
|
}"
|
@@ -971,7 +1181,7 @@ module FastRuby
|
|
971
1181
|
void* block_address = 0;
|
972
1182
|
VALUE block_param = Qnil;
|
973
1183
|
|
974
|
-
|
1184
|
+
frame.stack_chunk = 0;
|
975
1185
|
frame.plocals = 0;
|
976
1186
|
frame.parent_frame = 0;
|
977
1187
|
frame.return_value = Qnil;
|
@@ -1057,19 +1267,41 @@ module FastRuby
|
|
1057
1267
|
|
1058
1268
|
ret = "VALUE #{@alt_method_name || method_name}() {
|
1059
1269
|
|
1060
|
-
#{@locals_struct}
|
1061
|
-
#{@locals_struct} *plocals = (void*)&locals;
|
1270
|
+
#{@locals_struct} *plocals;
|
1062
1271
|
#{@frame_struct} frame;
|
1063
1272
|
#{@frame_struct} *pframe;
|
1064
1273
|
|
1065
|
-
frame.
|
1274
|
+
frame.stack_chunk = 0;
|
1066
1275
|
frame.parent_frame = 0;
|
1067
1276
|
frame.return_value = Qnil;
|
1068
1277
|
frame.target_frame = &frame;
|
1069
1278
|
frame.exception = Qnil;
|
1070
1279
|
frame.rescue = 0;
|
1071
1280
|
|
1072
|
-
|
1281
|
+
|
1282
|
+
int stack_chunk_instantiated = 0;
|
1283
|
+
VALUE rb_previous_stack_chunk = Qnil;
|
1284
|
+
VALUE current_thread = rb_thread_current();
|
1285
|
+
VALUE rb_stack_chunk = Qnil;
|
1286
|
+
struct STACKCHUNKREFERENCE* stack_chunk_reference = 0;
|
1287
|
+
|
1288
|
+
if (frame.stack_chunk == 0) {
|
1289
|
+
frame.stack_chunk = get_stack_chunk_from_context(&stack_chunk_reference,&rb_stack_chunk);
|
1290
|
+
}
|
1291
|
+
|
1292
|
+
if (frame.stack_chunk == 0 || (frame.stack_chunk == 0 ? 0 : stack_chunk_frozen(frame.stack_chunk)) ) {
|
1293
|
+
rb_previous_stack_chunk = rb_stack_chunk;
|
1294
|
+
rb_gc_register_address(&rb_stack_chunk);
|
1295
|
+
stack_chunk_instantiated = 1;
|
1296
|
+
|
1297
|
+
frame.stack_chunk = create_stack_chunk_from_context(&stack_chunk_reference,&rb_stack_chunk);
|
1298
|
+
}
|
1299
|
+
|
1300
|
+
int previous_stack_position = stack_chunk_get_current_position(frame.stack_chunk);
|
1301
|
+
|
1302
|
+
plocals = (typeof(plocals))stack_chunk_alloc(frame.stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
|
1303
|
+
plocals->pframe = LONG2FIX(&frame);
|
1304
|
+
frame.plocals = plocals;
|
1073
1305
|
|
1074
1306
|
pframe = (void*)&frame;
|
1075
1307
|
|
@@ -1077,9 +1309,11 @@ module FastRuby
|
|
1077
1309
|
|
1078
1310
|
int aux = setjmp(pframe->jmp);
|
1079
1311
|
if (aux != 0) {
|
1312
|
+
stack_chunk_set_current_position(frame.stack_chunk, previous_stack_position);
|
1080
1313
|
|
1081
|
-
if (
|
1082
|
-
|
1314
|
+
if (stack_chunk_instantiated) {
|
1315
|
+
rb_gc_unregister_address(&rb_stack_chunk);
|
1316
|
+
stack_chunk_reference_assign(stack_chunk_reference, rb_previous_stack_chunk);
|
1083
1317
|
}
|
1084
1318
|
|
1085
1319
|
if (pframe->target_frame != pframe) {
|
@@ -1090,16 +1324,26 @@ module FastRuby
|
|
1090
1324
|
return plocals->return_value;
|
1091
1325
|
}
|
1092
1326
|
|
1093
|
-
|
1327
|
+
plocals->self = self;
|
1094
1328
|
|
1095
1329
|
#{args_tree[1..-1].map { |arg|
|
1096
|
-
"
|
1330
|
+
"plocals->#{arg} = #{arg};\n"
|
1097
1331
|
}.join("") }
|
1098
1332
|
|
1099
|
-
|
1100
|
-
|
1333
|
+
plocals->block_function_address = LONG2FIX(0);
|
1334
|
+
plocals->block_function_param = LONG2FIX(Qnil);
|
1335
|
+
plocals->call_frame = LONG2FIX(0);
|
1336
|
+
|
1337
|
+
VALUE ret = #{to_c impl_tree};
|
1338
|
+
stack_chunk_set_current_position(frame.stack_chunk, previous_stack_position);
|
1339
|
+
|
1340
|
+
if (stack_chunk_instantiated) {
|
1341
|
+
rb_gc_unregister_address(&rb_stack_chunk);
|
1342
|
+
stack_chunk_reference_assign(stack_chunk_reference, rb_previous_stack_chunk);
|
1343
|
+
}
|
1344
|
+
|
1345
|
+
return ret;
|
1101
1346
|
|
1102
|
-
return #{to_c impl_tree};
|
1103
1347
|
}"
|
1104
1348
|
|
1105
1349
|
add_main
|
@@ -1116,22 +1360,94 @@ module FastRuby
|
|
1116
1360
|
|
1117
1361
|
ret = "VALUE #{@alt_method_name || method_name}(#{strargs}) {
|
1118
1362
|
|
1119
|
-
#{
|
1363
|
+
#{@frame_struct} frame;
|
1364
|
+
#{@frame_struct} *pframe;
|
1365
|
+
|
1366
|
+
frame.parent_frame = (void*)_parent_frame;
|
1367
|
+
frame.stack_chunk = ((typeof(pframe))_parent_frame)->stack_chunk;
|
1368
|
+
frame.return_value = Qnil;
|
1369
|
+
frame.target_frame = &frame;
|
1370
|
+
frame.exception = Qnil;
|
1371
|
+
frame.rescue = 0;
|
1372
|
+
|
1373
|
+
int stack_chunk_instantiated = 0;
|
1374
|
+
VALUE rb_previous_stack_chunk = Qnil;
|
1375
|
+
VALUE current_thread = rb_thread_current();
|
1376
|
+
VALUE rb_stack_chunk = Qnil;
|
1377
|
+
struct STACKCHUNKREFERENCE* stack_chunk_reference = 0;
|
1378
|
+
|
1379
|
+
if (frame.stack_chunk == 0) {
|
1380
|
+
frame.stack_chunk = get_stack_chunk_from_context(&stack_chunk_reference,&rb_stack_chunk);
|
1381
|
+
}
|
1382
|
+
|
1383
|
+
if (frame.stack_chunk == 0 || (frame.stack_chunk == 0 ? 0 : stack_chunk_frozen(frame.stack_chunk)) ) {
|
1384
|
+
rb_previous_stack_chunk = rb_stack_chunk;
|
1385
|
+
rb_gc_register_address(&rb_stack_chunk);
|
1386
|
+
stack_chunk_instantiated = 1;
|
1387
|
+
|
1388
|
+
frame.stack_chunk = create_stack_chunk_from_context(&stack_chunk_reference,&rb_stack_chunk);
|
1389
|
+
}
|
1390
|
+
|
1391
|
+
|
1392
|
+
#{@locals_struct} *plocals;
|
1393
|
+
|
1394
|
+
int previous_stack_position = stack_chunk_get_current_position(frame.stack_chunk);
|
1395
|
+
|
1396
|
+
plocals = (typeof(plocals))stack_chunk_alloc(frame.stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
|
1397
|
+
frame.plocals = plocals;
|
1398
|
+
plocals->pframe = LONG2FIX(&frame);
|
1399
|
+
plocals->call_frame = LONG2FIX(0);
|
1400
|
+
|
1401
|
+
pframe = (void*)&frame;
|
1402
|
+
|
1403
|
+
#{@block_struct} *pblock;
|
1404
|
+
VALUE last_expression = Qnil;
|
1405
|
+
|
1406
|
+
int aux = setjmp(pframe->jmp);
|
1407
|
+
if (aux != 0) {
|
1408
|
+
stack_chunk_set_current_position(frame.stack_chunk, previous_stack_position);
|
1409
|
+
|
1410
|
+
if (stack_chunk_instantiated) {
|
1411
|
+
rb_gc_unregister_address(&rb_stack_chunk);
|
1412
|
+
stack_chunk_reference_assign(stack_chunk_reference, rb_previous_stack_chunk);
|
1413
|
+
}
|
1414
|
+
|
1415
|
+
if (pframe->target_frame != pframe) {
|
1416
|
+
// raise exception
|
1417
|
+
((typeof(pframe))_parent_frame)->exception = pframe->exception;
|
1418
|
+
((typeof(pframe))_parent_frame)->target_frame = pframe->target_frame;
|
1419
|
+
((typeof(pframe))_parent_frame)->return_value = pframe->return_value;
|
1420
|
+
|
1421
|
+
longjmp(((typeof(pframe))_parent_frame)->jmp,1);
|
1422
|
+
}
|
1423
|
+
|
1424
|
+
return plocals->return_value;
|
1425
|
+
}
|
1426
|
+
|
1427
|
+
plocals->self = self;
|
1120
1428
|
|
1121
1429
|
#{args_tree[1..-1].map { |arg|
|
1122
|
-
"
|
1430
|
+
"plocals->#{arg} = #{arg};\n"
|
1123
1431
|
}.join("") }
|
1124
1432
|
|
1125
1433
|
pblock = (void*)block;
|
1126
1434
|
if (pblock) {
|
1127
|
-
|
1128
|
-
|
1435
|
+
plocals->block_function_address = LONG2FIX(pblock->block_function_address);
|
1436
|
+
plocals->block_function_param = LONG2FIX(pblock->block_function_param);
|
1129
1437
|
} else {
|
1130
|
-
|
1131
|
-
|
1438
|
+
plocals->block_function_address = LONG2FIX(0);
|
1439
|
+
plocals->block_function_param = LONG2FIX(Qnil);
|
1440
|
+
}
|
1441
|
+
|
1442
|
+
VALUE __ret = #{to_c impl_tree};
|
1443
|
+
stack_chunk_set_current_position(frame.stack_chunk, previous_stack_position);
|
1444
|
+
|
1445
|
+
if (stack_chunk_instantiated) {
|
1446
|
+
rb_gc_unregister_address(&rb_stack_chunk);
|
1447
|
+
stack_chunk_reference_assign(stack_chunk_reference, rb_previous_stack_chunk);
|
1132
1448
|
}
|
1133
1449
|
|
1134
|
-
return
|
1450
|
+
return __ret;
|
1135
1451
|
}"
|
1136
1452
|
|
1137
1453
|
add_main
|
@@ -1396,12 +1712,12 @@ module FastRuby
|
|
1396
1712
|
old_locals_struct = @locals_struct
|
1397
1713
|
|
1398
1714
|
@locals = locals
|
1399
|
-
|
1400
|
-
void* block_function_address;
|
1401
|
-
VALUE block_function_param;
|
1402
|
-
jmp_buf jmp;
|
1715
|
+
@locals_struct = "struct {
|
1403
1716
|
VALUE return_value;
|
1404
|
-
|
1717
|
+
VALUE pframe;
|
1718
|
+
VALUE block_function_address;
|
1719
|
+
VALUE block_function_param;
|
1720
|
+
VALUE call_frame;
|
1405
1721
|
#{@locals.map{|l| "VALUE #{l};\n"}.join}
|
1406
1722
|
}"
|
1407
1723
|
|
@@ -1428,20 +1744,51 @@ module FastRuby
|
|
1428
1744
|
fun = anonymous_function { |method_name| "static VALUE #{method_name}(VALUE self) {
|
1429
1745
|
|
1430
1746
|
#{@frame_struct} frame;
|
1431
|
-
#{@locals_struct} locals;
|
1432
1747
|
typeof(&frame) pframe = &frame;
|
1433
|
-
|
1748
|
+
#{@locals_struct} *plocals;
|
1434
1749
|
|
1435
|
-
frame.
|
1750
|
+
frame.stack_chunk = 0;
|
1436
1751
|
frame.parent_frame = 0;
|
1437
1752
|
frame.return_value = Qnil;
|
1438
1753
|
frame.target_frame = &frame;
|
1439
1754
|
frame.exception = Qnil;
|
1440
1755
|
frame.rescue = 0;
|
1441
1756
|
|
1442
|
-
|
1757
|
+
int stack_chunk_instantiated = 0;
|
1758
|
+
VALUE rb_previous_stack_chunk = Qnil;
|
1759
|
+
VALUE current_thread = rb_thread_current();
|
1760
|
+
VALUE rb_stack_chunk = Qnil;
|
1761
|
+
struct STACKCHUNKREFERENCE* stack_chunk_reference = 0;
|
1762
|
+
|
1763
|
+
if (frame.stack_chunk == 0) {
|
1764
|
+
frame.stack_chunk = get_stack_chunk_from_context(&stack_chunk_reference,&rb_stack_chunk);
|
1765
|
+
}
|
1766
|
+
|
1767
|
+
if (frame.stack_chunk == 0 || (frame.stack_chunk == 0 ? 0 : stack_chunk_frozen(frame.stack_chunk)) ) {
|
1768
|
+
rb_previous_stack_chunk = rb_stack_chunk;
|
1769
|
+
rb_gc_register_address(&rb_stack_chunk);
|
1770
|
+
stack_chunk_instantiated = 1;
|
1771
|
+
|
1772
|
+
frame.stack_chunk = create_stack_chunk_from_context(&stack_chunk_reference,&rb_stack_chunk);
|
1773
|
+
}
|
1774
|
+
|
1775
|
+
int previous_stack_position = stack_chunk_get_current_position(frame.stack_chunk);
|
1776
|
+
|
1777
|
+
plocals = (typeof(plocals))stack_chunk_alloc(frame.stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
|
1778
|
+
|
1779
|
+
frame.plocals = plocals;
|
1780
|
+
plocals->self = self;
|
1781
|
+
plocals->call_frame = LONG2FIX(0);
|
1443
1782
|
|
1444
1783
|
#{to_c tree};
|
1784
|
+
|
1785
|
+
stack_chunk_set_current_position(frame.stack_chunk, previous_stack_position);
|
1786
|
+
|
1787
|
+
if (stack_chunk_instantiated) {
|
1788
|
+
rb_gc_unregister_address(&rb_stack_chunk);
|
1789
|
+
stack_chunk_reference_assign(stack_chunk_reference, rb_previous_stack_chunk);
|
1790
|
+
}
|
1791
|
+
|
1445
1792
|
return Qnil;
|
1446
1793
|
}
|
1447
1794
|
"
|
@@ -1559,7 +1906,7 @@ module FastRuby
|
|
1559
1906
|
@infer_lvar_map[lvar_name] = lvar_type
|
1560
1907
|
return ""
|
1561
1908
|
elsif mname == :block_given?
|
1562
|
-
return "
|
1909
|
+
return "FIX2LONG(plocals->block_function_address) == 0 ? Qfalse : Qtrue"
|
1563
1910
|
elsif mname == :inline_c
|
1564
1911
|
|
1565
1912
|
code = args[1][1]
|
@@ -1583,7 +1930,7 @@ module FastRuby
|
|
1583
1930
|
end
|
1584
1931
|
end
|
1585
1932
|
|
1586
|
-
def inline_block_reference(arg)
|
1933
|
+
def inline_block_reference(arg, nolocals = false)
|
1587
1934
|
code = nil
|
1588
1935
|
|
1589
1936
|
if arg.instance_of? FastRuby::FastRubySexp
|
@@ -1595,7 +1942,8 @@ module FastRuby
|
|
1595
1942
|
anonymous_function{ |name| "
|
1596
1943
|
static VALUE #{name}(VALUE param) {
|
1597
1944
|
#{@frame_struct} *pframe = (void*)param;
|
1598
|
-
|
1945
|
+
|
1946
|
+
#{nolocals ? "" : "#{@locals_struct} *plocals = (void*)pframe->plocals;"}
|
1599
1947
|
VALUE last_expression = Qnil;
|
1600
1948
|
|
1601
1949
|
#{code};
|
@@ -1605,11 +1953,12 @@ module FastRuby
|
|
1605
1953
|
}
|
1606
1954
|
end
|
1607
1955
|
|
1608
|
-
def inline_block(code, repass_var = nil)
|
1956
|
+
def inline_block(code, repass_var = nil, nolocals = false)
|
1609
1957
|
anonymous_function{ |name| "
|
1610
1958
|
static VALUE #{name}(VALUE param#{repass_var ? ",void* " + repass_var : "" }) {
|
1611
1959
|
#{@frame_struct} *pframe = (void*)param;
|
1612
|
-
|
1960
|
+
|
1961
|
+
#{nolocals ? "" : "#{@locals_struct} *plocals = (void*)pframe->plocals;"}
|
1613
1962
|
VALUE last_expression = Qnil;
|
1614
1963
|
|
1615
1964
|
#{code}
|
@@ -1622,28 +1971,16 @@ module FastRuby
|
|
1622
1971
|
"rb_funcall(#{proced.__id__}, #{intern_num :call}, 1, #{parameter})"
|
1623
1972
|
end
|
1624
1973
|
|
1625
|
-
def
|
1626
|
-
frame("return " + inner_code, "
|
1627
|
-
if (original_frame->target_frame == (void*)-2) {
|
1628
|
-
return pframe->return_value;
|
1629
|
-
}
|
1630
|
-
")
|
1631
|
-
end
|
1632
|
-
|
1633
|
-
def protected_block(inner_code, always_rescue = false,repass_var = nil)
|
1974
|
+
def protected_block(inner_code, always_rescue = false,repass_var = nil, nolocals = false)
|
1634
1975
|
wrapper_code = "
|
1635
1976
|
if (pframe->last_error != Qnil) {
|
1636
1977
|
if (CLASS_OF(pframe->last_error)==#{literal_value FastRuby::Context::UnwindFastrubyFrame}) {
|
1637
|
-
|
1978
|
+
#{@frame_struct} *pframe = (void*)param;
|
1638
1979
|
|
1639
1980
|
pframe->target_frame = (void*)FIX2LONG(rb_ivar_get(pframe->last_error, #{intern_num :@target_frame}));
|
1640
1981
|
pframe->exception = rb_ivar_get(pframe->last_error, #{intern_num :@ex});
|
1641
1982
|
pframe->return_value = rb_ivar_get(pframe->last_error, #{intern_num :@return_value});
|
1642
1983
|
|
1643
|
-
if (pframe->target_frame == (void*)-2) {
|
1644
|
-
return pframe->return_value;
|
1645
|
-
}
|
1646
|
-
|
1647
1984
|
longjmp(pframe->jmp, 1);
|
1648
1985
|
return Qnil;
|
1649
1986
|
|
@@ -1657,6 +1994,10 @@ module FastRuby
|
|
1657
1994
|
return Qnil;
|
1658
1995
|
}
|
1659
1996
|
|
1997
|
+
} else {
|
1998
|
+
if (pframe->target_frame != pframe) {
|
1999
|
+
longjmp(pframe->jmp, 1);
|
2000
|
+
}
|
1660
2001
|
}
|
1661
2002
|
"
|
1662
2003
|
|
@@ -1666,8 +2007,36 @@ module FastRuby
|
|
1666
2007
|
if repass_var
|
1667
2008
|
body = anonymous_function{ |name| "
|
1668
2009
|
static VALUE #{name}(VALUE param) {
|
1669
|
-
|
1670
|
-
#{@
|
2010
|
+
|
2011
|
+
#{@frame_struct} frame;
|
2012
|
+
|
2013
|
+
typeof(frame)* pframe;
|
2014
|
+
typeof(frame)* parent_frame = ((typeof(pframe))((void**)param)[0]);
|
2015
|
+
|
2016
|
+
frame.parent_frame = 0;
|
2017
|
+
frame.target_frame = 0;
|
2018
|
+
frame.return_value = Qnil;
|
2019
|
+
frame.exception = Qnil;
|
2020
|
+
frame.rescue = 0;
|
2021
|
+
frame.last_error = Qnil;
|
2022
|
+
frame.stack_chunk = 0;
|
2023
|
+
|
2024
|
+
pframe = &frame;
|
2025
|
+
|
2026
|
+
#{
|
2027
|
+
nolocals ? "frame.plocals = 0;" : "#{@locals_struct}* plocals = parent_frame->plocals;
|
2028
|
+
frame.plocals = plocals;
|
2029
|
+
"
|
2030
|
+
}
|
2031
|
+
|
2032
|
+
if (setjmp(frame.jmp) != 0) {
|
2033
|
+
parent_frame->target_frame = frame.target_frame;
|
2034
|
+
parent_frame->exception = frame.exception;
|
2035
|
+
parent_frame->return_value = frame.return_value;
|
2036
|
+
|
2037
|
+
return frame.return_value;
|
2038
|
+
}
|
2039
|
+
|
1671
2040
|
VALUE #{repass_var} = (VALUE)((void**)param)[1];
|
1672
2041
|
return #{inner_code};
|
1673
2042
|
}
|
@@ -1677,7 +2046,43 @@ module FastRuby
|
|
1677
2046
|
rescue_args = ""
|
1678
2047
|
rescue_args = "(VALUE)(VALUE[]){(VALUE)pframe,(VALUE)#{repass_var}}"
|
1679
2048
|
else
|
1680
|
-
|
2049
|
+
|
2050
|
+
body = anonymous_function{ |name| "
|
2051
|
+
static VALUE #{name}(VALUE param) {
|
2052
|
+
#{@frame_struct} frame;
|
2053
|
+
|
2054
|
+
typeof(frame)* pframe;
|
2055
|
+
typeof(frame)* parent_frame = (typeof(pframe))param;
|
2056
|
+
|
2057
|
+
frame.parent_frame = 0;
|
2058
|
+
frame.target_frame = 0;
|
2059
|
+
frame.return_value = Qnil;
|
2060
|
+
frame.exception = Qnil;
|
2061
|
+
frame.rescue = 0;
|
2062
|
+
frame.last_error = Qnil;
|
2063
|
+
frame.stack_chunk = 0;
|
2064
|
+
|
2065
|
+
pframe = &frame;
|
2066
|
+
|
2067
|
+
#{
|
2068
|
+
nolocals ? "frame.plocals = 0;" : "#{@locals_struct}* plocals = parent_frame->plocals;
|
2069
|
+
frame.plocals = plocals;
|
2070
|
+
"
|
2071
|
+
}
|
2072
|
+
|
2073
|
+
if (setjmp(frame.jmp) != 0) {
|
2074
|
+
parent_frame->target_frame = frame.target_frame;
|
2075
|
+
parent_frame->exception = frame.exception;
|
2076
|
+
parent_frame->return_value = frame.return_value;
|
2077
|
+
|
2078
|
+
return frame.return_value;
|
2079
|
+
}
|
2080
|
+
|
2081
|
+
return #{inner_code};
|
2082
|
+
}
|
2083
|
+
"
|
2084
|
+
}
|
2085
|
+
|
1681
2086
|
rescue_args = "(VALUE)pframe"
|
1682
2087
|
end
|
1683
2088
|
|
@@ -1692,12 +2097,13 @@ module FastRuby
|
|
1692
2097
|
if always_rescue
|
1693
2098
|
inline_block "
|
1694
2099
|
pframe->last_error = Qnil;
|
2100
|
+
pframe->target_frame = pframe;
|
1695
2101
|
VALUE result = #{rescue_code};
|
1696
2102
|
|
1697
2103
|
#{wrapper_code}
|
1698
2104
|
|
1699
2105
|
return result;
|
1700
|
-
", repass_var
|
2106
|
+
", repass_var, nolocals
|
1701
2107
|
else
|
1702
2108
|
inline_block "
|
1703
2109
|
VALUE result;
|
@@ -1712,7 +2118,7 @@ module FastRuby
|
|
1712
2118
|
#{wrapper_code}
|
1713
2119
|
|
1714
2120
|
return result;
|
1715
|
-
", repass_var
|
2121
|
+
", repass_var, nolocals
|
1716
2122
|
end
|
1717
2123
|
|
1718
2124
|
end
|
@@ -1720,19 +2126,19 @@ module FastRuby
|
|
1720
2126
|
|
1721
2127
|
def func_frame
|
1722
2128
|
"
|
1723
|
-
#{@locals_struct}
|
1724
|
-
#{@locals_struct} *plocals = (void*)&locals;
|
2129
|
+
#{@locals_struct} *plocals = malloc(sizeof(typeof(*plocals)));
|
1725
2130
|
#{@frame_struct} frame;
|
1726
2131
|
#{@frame_struct} *pframe;
|
1727
2132
|
|
1728
2133
|
frame.plocals = plocals;
|
1729
2134
|
frame.parent_frame = (void*)_parent_frame;
|
2135
|
+
frame.stack_chunk = ((typeof(pframe))_parent_frame)->stack_chunk;
|
1730
2136
|
frame.return_value = Qnil;
|
1731
2137
|
frame.target_frame = &frame;
|
1732
2138
|
frame.exception = Qnil;
|
1733
2139
|
frame.rescue = 0;
|
1734
2140
|
|
1735
|
-
|
2141
|
+
plocals->pframe = LONG2FIX(&frame);
|
1736
2142
|
|
1737
2143
|
pframe = (void*)&frame;
|
1738
2144
|
|
@@ -1742,10 +2148,6 @@ module FastRuby
|
|
1742
2148
|
int aux = setjmp(pframe->jmp);
|
1743
2149
|
if (aux != 0) {
|
1744
2150
|
|
1745
|
-
if (pframe->target_frame == (void*)-2) {
|
1746
|
-
return pframe->return_value;
|
1747
|
-
}
|
1748
|
-
|
1749
2151
|
if (pframe->target_frame != pframe) {
|
1750
2152
|
// raise exception
|
1751
2153
|
((typeof(pframe))_parent_frame)->exception = pframe->exception;
|
@@ -1757,7 +2159,7 @@ module FastRuby
|
|
1757
2159
|
return plocals->return_value;
|
1758
2160
|
}
|
1759
2161
|
|
1760
|
-
|
2162
|
+
plocals->self = self;
|
1761
2163
|
"
|
1762
2164
|
end
|
1763
2165
|
|
@@ -1932,6 +2334,8 @@ module FastRuby
|
|
1932
2334
|
}
|
1933
2335
|
}
|
1934
2336
|
|
2337
|
+
if (address==0) convention = #{literal_value :ruby};
|
2338
|
+
|
1935
2339
|
#{convention_global_name ? convention_global_name + " = 0;" : ""}
|
1936
2340
|
if (recvtype != Qnil) {
|
1937
2341
|
|
@@ -2014,9 +2418,11 @@ module FastRuby
|
|
2014
2418
|
|
2015
2419
|
parent_frame = (void*)param;
|
2016
2420
|
|
2421
|
+
frame.stack_chunk = parent_frame->stack_chunk;
|
2017
2422
|
frame.parent_frame = (void*)param;
|
2018
2423
|
frame.plocals = parent_frame->plocals;
|
2019
2424
|
frame.target_frame = &frame;
|
2425
|
+
frame.exception = Qnil;
|
2020
2426
|
frame.rescue = #{rescued ? rescued : "parent_frame->rescue"};
|
2021
2427
|
|
2022
2428
|
plocals = frame.plocals;
|
@@ -2036,6 +2442,7 @@ module FastRuby
|
|
2036
2442
|
pframe->exception = original_frame->exception;
|
2037
2443
|
pframe->target_frame = original_frame->target_frame;
|
2038
2444
|
pframe->return_value = original_frame->return_value;
|
2445
|
+
|
2039
2446
|
longjmp(pframe->jmp,1);
|
2040
2447
|
}
|
2041
2448
|
|