fastruby 0.0.14 → 0.0.15

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.
@@ -38,7 +38,6 @@ module FastRuby
38
38
  attr_reader :no_cache
39
39
  attr_reader :init_extra
40
40
  attr_reader :extra_code
41
- attr_reader :yield_signature
42
41
 
43
42
  TranslatorModules.instance.load_under(FastRuby.fastruby_load_path + "/fastruby/translator/modules/")
44
43
  TranslatorModules.instance.modls.each do |modl|
@@ -68,6 +67,12 @@ module FastRuby
68
67
  void* block_function_param;
69
68
  }"
70
69
 
70
+ extra_code << "
71
+ static void frb_jump_tag(int state) {
72
+ VALUE exception = rb_funcall(#{literal_value FastRuby::JumpTagException}, #{intern_num :new},1,INT2FIX(state));
73
+ rb_exc_raise(exception);
74
+ }
75
+ "
71
76
 
72
77
  extra_code << "
73
78
  #include \"node.h\"
@@ -98,11 +103,13 @@ module FastRuby
98
103
  @lambda_node_gvar = add_global_name("NODE*", 0);
99
104
  @proc_node_gvar = add_global_name("NODE*", 0);
100
105
  @procnew_node_gvar = add_global_name("NODE*", 0);
106
+ @callcc_node_gvar = add_global_name("NODE*", 0);
101
107
 
102
108
  init_extra << "
103
109
  #{@lambda_node_gvar} = rb_method_node(rb_cObject, #{intern_num :lambda});
104
110
  #{@proc_node_gvar} = rb_method_node(rb_cObject, #{intern_num :proc});
105
111
  #{@procnew_node_gvar} = rb_method_node(CLASS_OF(rb_cProc), #{intern_num :new});
112
+ #{@callcc_node_gvar} = rb_method_node(rb_mKernel, #{intern_num :callcc});
106
113
  "
107
114
 
108
115
  @common_func = common_func
@@ -145,6 +152,7 @@ module FastRuby
145
152
  */
146
153
 
147
154
  "
155
+
148
156
  end
149
157
  end
150
158
 
@@ -161,7 +169,7 @@ module FastRuby
161
169
  name
162
170
  end
163
171
 
164
- def frame_call(inner_code)
172
+ def frame_call(inner_code, precode = "", postcode = "")
165
173
  inline_block "
166
174
 
167
175
 
@@ -181,24 +189,33 @@ module FastRuby
181
189
  VALUE old_call_frame = plocals->call_frame;
182
190
  plocals->call_frame = LONG2FIX(&call_frame);
183
191
 
192
+ #{precode}
193
+
184
194
  int aux = setjmp(call_frame.jmp);
185
195
  if (aux != 0) {
186
196
  if (call_frame.targetted == 0) {
197
+ #{postcode}
187
198
  longjmp(old_pframe->jmp,aux);
188
199
  }
189
200
 
190
201
  if (aux == FASTRUBY_TAG_BREAK) {
191
202
  plocals->call_frame = old_call_frame;
203
+ #{postcode}
192
204
  return call_frame.return_value;
193
205
  } else if (aux == FASTRUBY_TAG_RETRY ) {
194
206
  // do nothing and let the call execute again
195
207
  } else {
196
208
  plocals->call_frame = old_call_frame;
209
+ #{postcode}
197
210
  return call_frame.return_value;
198
211
  }
199
212
  }
213
+
200
214
 
201
215
  VALUE ret = #{inner_code};
216
+
217
+ #{postcode}
218
+
202
219
  plocals->call_frame = old_call_frame;
203
220
  return ret;
204
221
  "
@@ -207,6 +224,7 @@ module FastRuby
207
224
  def initialize_method_structs(args_tree)
208
225
  @locals_struct = "struct {
209
226
  VALUE return_value;
227
+ VALUE parent_locals;
210
228
  VALUE pframe;
211
229
  VALUE block_function_address;
212
230
  VALUE block_function_param;
@@ -214,94 +232,10 @@ module FastRuby
214
232
  VALUE active;
215
233
  VALUE targetted;
216
234
  #{@locals.map{|l| "VALUE #{l};\n"}.join}
217
- #{args_tree[1..-1].map{|arg| "VALUE #{arg.to_s.gsub("*","")};\n"}.join};
218
235
  }"
219
236
 
220
237
  end
221
238
 
222
- def to_c_method_defs(tree)
223
-
224
- method_name = tree[2]
225
- args_tree = tree[3]
226
-
227
- impl_tree = tree[4][1]
228
-
229
- initialize_method_structs(args_tree)
230
-
231
- strargs = if args_tree.size > 1
232
-
233
- "VALUE self, void* block_address, VALUE block_param, void* _parent_frame, #{args_tree[1..-1].map{|arg| "VALUE #{arg.to_s.gsub("*","")}" }.join(",") }"
234
- else
235
- "VALUE self, void* block_address, VALUE block_param, void* _parent_frame"
236
- end
237
-
238
- extra_code << "static VALUE #{@alt_method_name + "_real"}(#{strargs}) {
239
- #{func_frame}
240
-
241
- #{args_tree[1..-1].map { |arg|
242
- arg = arg.to_s
243
- arg.gsub!("*","")
244
- "plocals->#{arg} = #{arg};\n"
245
- }.join("") }
246
-
247
- plocals->block_function_address = LONG2FIX(block_address);
248
- plocals->block_function_param = LONG2FIX(block_param);
249
-
250
- return #{to_c impl_tree};
251
- }"
252
-
253
- strargs2 = if args_tree.size > 1
254
- "VALUE self, #{args_tree[1..-1].map{|arg| "VALUE #{arg}" }.join(",") }"
255
- else
256
- "VALUE self"
257
- end
258
-
259
- value_cast = ( ["VALUE"]*(args_tree.size+1) ).join(",")
260
- strmethodargs = ""
261
-
262
- if args_tree.size > 1
263
- strmethodargs = "self,block_address,block_param,&frame,#{args_tree[1..-1].map(&:to_s).join(",") }"
264
- else
265
- strmethodargs = "self,block_address,block_param,&frame"
266
- end
267
-
268
- "
269
- VALUE #{@alt_method_name}(#{strargs2}) {
270
- #{@frame_struct} frame;
271
- int argc = #{args_tree.size};
272
- void* block_address = 0;
273
- VALUE block_param = Qnil;
274
-
275
- frame.plocals = 0;
276
- frame.parent_frame = 0;
277
- frame.return_value = Qnil;
278
- frame.rescue = 0;
279
- frame.targetted = 0;
280
- frame.thread_data = rb_current_thread_data();
281
-
282
- if (rb_block_given_p()) {
283
- block_address = #{
284
- anonymous_function{|name|
285
- "static VALUE #{name}(int argc, VALUE* argv, VALUE param) {
286
- return rb_yield_splat(rb_ary_new4(argc,argv));
287
- }"
288
- }
289
- };
290
-
291
- block_param = 0;
292
- }
293
-
294
- int aux = setjmp(frame.jmp);
295
- if (aux != 0) {
296
- rb_funcall(self, #{intern_num :raise}, 1, frame.thread_data->exception);
297
- }
298
-
299
-
300
- return #{@alt_method_name + "_real"}(#{strmethodargs});
301
- }
302
- "
303
- end
304
-
305
239
  def add_main
306
240
  if options[:main]
307
241
 
@@ -374,20 +308,31 @@ module FastRuby
374
308
  end
375
309
 
376
310
  def to_c_method(tree, signature = nil)
377
- method_name = tree[1]
378
- args_tree = tree[2]
379
- impl_tree = tree[3][1]
311
+
312
+ if tree[0] == :defn
313
+ method_name = tree[1]
314
+ original_args_tree = tree[2]
315
+ block_argument = tree[2].find{|x| x.to_s[0] == ?&}
316
+ impl_tree = tree[3][1]
317
+ elsif tree[0] == :defs
318
+ method_name = tree[2]
319
+ original_args_tree = tree[3]
320
+ block_argument = tree[3].find{|x| x.to_s[0] == ?&}
321
+ impl_tree = tree[4][1]
322
+ end
323
+
324
+ args_tree = original_args_tree.select{|x| x.to_s[0] != ?&}
380
325
 
381
326
  if (options[:main])
382
- initialize_method_structs(args_tree)
327
+ initialize_method_structs(original_args_tree)
383
328
 
384
329
  strargs = if args_tree.size > 1
385
- "VALUE block, VALUE _parent_frame, #{(0..signature.size-1).map{|x| "VALUE arg#{x}"}.join(",")}"
330
+ "VALUE self, VALUE block, VALUE _parent_frame, #{(0..signature.size-1).map{|x| "VALUE arg#{x}"}.join(",")}"
386
331
  else
387
- "VALUE block, VALUE _parent_frame"
332
+ "VALUE self, VALUE block, VALUE _parent_frame"
388
333
  end
389
334
 
390
- ret = "VALUE #{@alt_method_name || method_name}() {
335
+ ret = "VALUE #{@alt_method_name || method_name}(VALUE self) {
391
336
 
392
337
  #{@locals_struct} *plocals;
393
338
  #{@frame_struct} frame;
@@ -404,7 +349,7 @@ module FastRuby
404
349
  VALUE rb_previous_stack_chunk = Qnil;
405
350
  VALUE rb_stack_chunk = frame.thread_data->rb_stack_chunk;
406
351
  struct STACKCHUNK* stack_chunk = 0;
407
-
352
+
408
353
  if (rb_stack_chunk != Qnil) {
409
354
  Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
410
355
  }
@@ -425,6 +370,11 @@ module FastRuby
425
370
  int previous_stack_position = stack_chunk_get_current_position(stack_chunk);
426
371
 
427
372
  plocals = (typeof(plocals))stack_chunk_alloc(stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
373
+
374
+ plocals->parent_locals = LONG2FIX(frame.thread_data->last_plocals);
375
+ void* old_parent_locals = frame.thread_data->last_plocals;
376
+ frame.thread_data->last_plocals = plocals;
377
+
428
378
  plocals->active = Qtrue;
429
379
  plocals->targetted = Qfalse;
430
380
  plocals->pframe = LONG2FIX(&frame);
@@ -444,6 +394,7 @@ module FastRuby
444
394
  }
445
395
 
446
396
  plocals->active = Qfalse;
397
+ frame.thread_data->last_plocals = old_parent_locals;
447
398
  return plocals->return_value;
448
399
  }
449
400
 
@@ -468,72 +419,131 @@ module FastRuby
468
419
  }
469
420
 
470
421
  plocals->active = Qfalse;
422
+
423
+ frame.thread_data->last_plocals = old_parent_locals;
471
424
  return ret;
472
425
 
473
426
  }"
474
427
 
475
428
  add_main
476
- ret
429
+ extra_code << ret
477
430
  else
478
431
 
479
- initialize_method_structs(args_tree)
480
-
481
- strargs = if args_tree.size > 1
482
- "VALUE block, VALUE _parent_frame, #{(0..signature.size-1).map{|x| "VALUE arg#{x}"}.join(",")}"
483
- else
484
- "VALUE block, VALUE _parent_frame"
485
- end
432
+ initialize_method_structs(original_args_tree)
486
433
 
487
- is_splat_args = args_tree[1..-1].find{|x| x.to_s.match(/\*/) }
434
+ strargs = "VALUE self, VALUE block, VALUE _parent_frame, int argc, VALUE* argv"
488
435
 
489
- if is_splat_args
436
+ splat_arg = args_tree[1..-1].find{|x| x.to_s.match(/\*/) }
437
+
438
+ maxargnum = args_tree[1..-1].count{ |x|
439
+ if x.instance_of? Symbol
440
+ not x.to_s.match(/\*/) and not x.to_s.match(/\&/)
441
+ else
442
+ false
443
+ end
444
+ }
490
445
 
491
- i = -1
446
+ minargnum = maxargnum
492
447
 
493
- read_arguments_code = args_tree[1..-2].map { |arg|
494
- arg = arg.to_s
495
- i = i + 1
496
- "plocals->#{arg} = arg#{i};\n"
497
- }.join("")
498
-
499
- arguments_array = [(signature.size-1) - (args_tree.size-2)] + (args_tree.size-2..signature.size-1).map{|x| "arg#{x}"}
500
-
501
- read_arguments_code << "
502
- plocals->#{args_tree[-1].to_s.gsub("*","")} = rb_ary_new3(
503
- #{arguments_array.join(",")}
504
- );
505
- "
448
+ args_tree[1..-1].each do |subtree|
449
+ unless subtree.instance_of? Symbol
450
+ if subtree[0] == :block
451
+ minargnum = minargnum - (subtree.size-1)
452
+ end
453
+ end
454
+ end
455
+
456
+ if args_tree[1..-1].find{|x| x.to_s.match(/\*/)}
457
+ maxargnum = 2147483647
458
+ end
459
+
460
+ read_arguments_code = ""
461
+
506
462
 
507
- validate_arguments_code = if signature.size-1 >= args_tree.size-2
463
+ validate_arguments_code = if signature.size-1 < minargnum
508
464
  "
465
+ rb_raise(rb_eArgError, \"wrong number of arguments (#{signature.size-1} for #{minargnum})\");
509
466
  "
510
- else
467
+ elsif signature.size-1 > maxargnum
511
468
  "
512
- rb_raise(rb_eArgError, \"wrong number of arguments (#{signature.size} for #{args_tree.size-2})\");
469
+ rb_raise(rb_eArgError, \"wrong number of arguments (#{signature.size-1} for #{maxargnum})\");
513
470
  "
514
- end
515
-
516
471
  else
472
+
473
+ default_block_tree = args_tree[1..-1].find{|subtree|
474
+ unless subtree.instance_of? Symbol
475
+ if subtree[0] == :block
476
+ next true
477
+ end
478
+ end
479
+
480
+ false
481
+ }
482
+
483
+ i = -1
484
+
485
+ normalargsnum = args_tree[1..-1].count{|subtree|
486
+ if subtree.instance_of? Symbol
487
+ unless subtree.to_s.match(/\*/) or subtree.to_s.match(/\&/)
488
+ next true
489
+ end
490
+ end
491
+
492
+ false
493
+ }
494
+
495
+ read_arguments_code = args_tree[1..-1].map { |arg_|
496
+ arg = arg_.to_s
497
+ i = i + 1
498
+
499
+ if i < normalargsnum
500
+ if i < signature.size-1
501
+ "plocals->#{arg} = argv[#{i}];\n"
502
+ else
503
+
504
+ if default_block_tree
505
+ initialize_tree = default_block_tree[1..-1].find{|subtree| subtree[1] == arg_}
506
+ if initialize_tree
507
+ to_c(initialize_tree) + ";\n"
508
+ else
509
+ ""
510
+ end
511
+ else
512
+ ";\n"
513
+ end
514
+ end
515
+ else
516
+ ""
517
+ end
518
+ }.join("")
519
+
520
+ if splat_arg
521
+ if signature.size-1 < normalargsnum then
522
+ read_arguments_code << "
523
+ plocals->#{splat_arg.to_s.gsub("*","")} = rb_ary_new3(0);
524
+ "
525
+ else
526
+ read_arguments_code << "
527
+ plocals->#{splat_arg.to_s.gsub("*","")} = rb_ary_new4(
528
+ #{(signature.size-1) - (normalargsnum)}, argv+#{normalargsnum}
529
+ );
530
+ "
531
+ end
532
+
533
+ end
517
534
 
518
- i = -1
519
535
 
520
- read_arguments_code = args_tree[1..-1].map { |arg|
521
- arg = arg.to_s
522
- i = i + 1
523
- "plocals->#{arg} = arg#{i};\n"
524
- }.join("")
536
+ ""
537
+ end
525
538
 
526
- validate_arguments_code = if signature.size-1 >= args_tree.size-1
527
- "
528
- "
529
- else
530
- "
531
- rb_raise(rb_eArgError, \"wrong number of arguments (#{signature.size-1} for #{args_tree.size-1})\");
532
- "
533
- end
534
-
539
+ if block_argument
540
+
541
+ proc_reyield_block_tree = s(:iter, s(:call, nil, :proc, s(:arglist)), s(:masgn, s(:array, s(:splat, s(:lasgn, :__xproc_arguments)))), s(:yield, s(:splat, s(:lvar, :__xproc_arguments))))
542
+
543
+ read_arguments_code << "
544
+ plocals->#{block_argument.to_s.gsub("&","")} = #{to_c proc_reyield_block_tree.to_fastruby_sexp};
545
+ "
535
546
  end
536
-
537
547
 
538
548
  ret = "VALUE #{@alt_method_name || method_name}(#{strargs}) {
539
549
  #{validate_arguments_code}
@@ -576,6 +586,11 @@ module FastRuby
576
586
  int previous_stack_position = stack_chunk_get_current_position(stack_chunk);
577
587
 
578
588
  plocals = (typeof(plocals))stack_chunk_alloc(stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
589
+
590
+ plocals->parent_locals = LONG2FIX(frame.thread_data->last_plocals);
591
+ void* old_parent_locals = frame.thread_data->last_plocals;
592
+ frame.thread_data->last_plocals = plocals;
593
+
579
594
  frame.plocals = plocals;
580
595
  plocals->active = Qtrue;
581
596
  plocals->targetted = Qfalse;
@@ -598,10 +613,14 @@ module FastRuby
598
613
  frame.thread_data->rb_stack_chunk = rb_previous_stack_chunk;
599
614
  }
600
615
 
601
- if (plocals->targetted == Qfalse) {
616
+ if (plocals->targetted == Qfalse || aux != FASTRUBY_TAG_RETURN) {
617
+ frame.thread_data->last_plocals = old_parent_locals;
618
+
602
619
  longjmp(((typeof(pframe))_parent_frame)->jmp,aux);
603
620
  }
604
621
 
622
+ frame.thread_data->last_plocals = old_parent_locals;
623
+
605
624
  return plocals->return_value;
606
625
  }
607
626
 
@@ -627,12 +646,21 @@ module FastRuby
627
646
  }
628
647
 
629
648
  plocals->active = Qfalse;
649
+
650
+ frame.thread_data->last_plocals = old_parent_locals;
651
+
630
652
  return __ret;
631
653
  }"
632
654
 
633
655
  add_main
634
- ret
656
+ extra_code << ret
635
657
  end
658
+
659
+ "
660
+ static VALUE dummy_#{method_name}_#{alt_method_name}_#{rand(1000000000000000000000000000000000)}(VALUE a) {
661
+ return Qnil;
662
+ }
663
+ "
636
664
  end
637
665
 
638
666
  def locals_accessor
@@ -646,6 +674,7 @@ module FastRuby
646
674
  @locals = locals
647
675
  @locals_struct = "struct {
648
676
  VALUE return_value;
677
+ VALUE parent_locals;
649
678
  VALUE pframe;
650
679
  VALUE block_function_address;
651
680
  VALUE block_function_param;
@@ -687,16 +716,6 @@ module FastRuby
687
716
  @on_block = old_on_block
688
717
  end
689
718
 
690
- def with_extra_inference(extra_inference)
691
- previous_infer_lvar_map = @infer_lvar_map
692
- begin
693
- @infer_lvar_map = @infer_lvar_map.merge(extra_inference)
694
- yield
695
- ensure
696
- @infer_lvar_map = previous_infer_lvar_map
697
- end
698
- end
699
-
700
719
  def directive(tree)
701
720
  recv = tree[1]
702
721
  mname = tree[2]
@@ -779,14 +798,20 @@ module FastRuby
779
798
  def protected_block(inner_code, always_rescue = false,repass_var = nil, nolocals = false)
780
799
  body = nil
781
800
  rescue_args = nil
782
- if repass_var
801
+
783
802
  body = anonymous_function{ |name| "
784
803
  static VALUE #{name}(VALUE param) {
785
804
 
786
805
  #{@frame_struct} frame;
787
806
 
788
807
  typeof(frame)* pframe;
789
- typeof(frame)* parent_frame = ((typeof(pframe))((void**)param)[0]);
808
+
809
+ #{if repass_var
810
+ "typeof(frame)* parent_frame = ((typeof(pframe))((void**)param)[0]);"
811
+ else
812
+ "typeof(frame)* parent_frame = (typeof(pframe))param;"
813
+ end
814
+ }
790
815
 
791
816
  frame.parent_frame = 0;
792
817
  frame.return_value = Qnil;
@@ -794,6 +819,7 @@ module FastRuby
794
819
  frame.last_error = Qnil;
795
820
  frame.targetted = 0;
796
821
  frame.thread_data = parent_frame->thread_data;
822
+ frame.next_recv = parent_frame->next_recv;
797
823
  if (frame.thread_data == 0) frame.thread_data = rb_current_thread_data();
798
824
 
799
825
  pframe = &frame;
@@ -810,84 +836,69 @@ module FastRuby
810
836
  if (frame.targetted == 1) {
811
837
  return frame.return_value;
812
838
  } else {
813
- rb_jump_tag(aux);
839
+ frb_jump_tag(aux);
814
840
  }
815
841
  }
816
842
 
817
- VALUE #{repass_var} = (VALUE)((void**)param)[1];
843
+ #{if repass_var
844
+ "VALUE #{repass_var} = (VALUE)((void**)param)[1];"
845
+ end
846
+ }
818
847
  return #{inner_code};
819
848
  }
820
849
  "
821
850
  }
822
851
 
852
+ if repass_var
823
853
  rescue_args = ""
824
854
  rescue_args = "(VALUE)(VALUE[]){(VALUE)pframe,(VALUE)#{repass_var}}"
825
855
  else
856
+ rescue_args = "(VALUE)pframe"
857
+ end
826
858
 
827
- body = anonymous_function{ |name| "
828
- static VALUE #{name}(VALUE param) {
829
- #{@frame_struct} frame;
830
-
831
- typeof(frame)* pframe;
832
- typeof(frame)* parent_frame = (typeof(pframe))param;
833
-
834
- frame.parent_frame = 0;
835
- frame.return_value = Qnil;
836
- frame.rescue = 0;
837
- frame.last_error = Qnil;
838
- frame.targetted = 0;
839
- frame.thread_data = parent_frame->thread_data;
840
- if (frame.thread_data == 0) frame.thread_data = rb_current_thread_data();
841
-
842
- pframe = &frame;
843
-
844
- #{
845
- nolocals ? "frame.plocals = 0;" : "#{@locals_struct}* plocals = parent_frame->plocals;
846
- frame.plocals = plocals;
847
- "
848
- }
849
-
850
- int aux = setjmp(frame.jmp);
851
- if (aux != 0) {
852
-
853
- if (frame.targetted == 1) {
854
- return frame.return_value;
855
- } else {
856
- rb_jump_tag(aux);
859
+ wrapper_code = "
860
+ if (str.state >= 0x80) {
861
+ longjmp(pframe->jmp, str.state);
862
+ } else {
863
+ if (str.last_error != Qnil) {
864
+ // raise emulation
865
+ pframe->thread_data->exception = str.last_error;
866
+ longjmp(pframe->jmp, FASTRUBY_TAG_RAISE);
867
+ return Qnil;
857
868
  }
858
869
  }
859
-
860
- return #{inner_code};
861
- }
870
+ "
871
+
872
+ return_err_struct = "struct {
873
+ VALUE last_error;
874
+ int state;
875
+ }
862
876
  "
863
- }
864
-
865
- rescue_args = "(VALUE)pframe"
866
- end
867
-
868
- wrapper_code = " if (state != 0) {
869
- if (state < 0x80) {
870
877
 
871
- if (state == TAG_RAISE) {
872
- // raise emulation
873
- pframe->thread_data->exception = rb_eval_string(\"$!\");
874
- longjmp(pframe->jmp, FASTRUBY_TAG_RAISE);
875
- return Qnil;
878
+ rescue_body = anonymous_function{ |name| "
879
+ static VALUE #{name}(VALUE param, VALUE err) {
880
+ #{return_err_struct} *pstr = (void*)param;
881
+
882
+ if (rb_obj_is_instance_of(err, #{literal_value FastRuby::JumpTagException})) {
883
+ pstr->state = FIX2INT(rb_funcall(err, #{intern_num :state}, 0));
876
884
  } else {
877
- rb_jump_tag(state);
885
+ pstr->last_error = err;
878
886
  }
879
- } else {
880
- longjmp(pframe->jmp, state);
887
+
888
+ return Qnil;
881
889
  }
882
-
883
- }
884
890
  "
891
+ }
885
892
 
886
- rescue_code = "rb_protect(#{body},#{rescue_args},&state)"
893
+ rescue_code = "rb_rescue2(#{body}, #{rescue_args}, #{rescue_body}, (VALUE)&str, rb_eException, (VALUE)0)"
887
894
 
888
895
  if always_rescue
889
896
  inline_block "
890
- int state;
897
+ #{return_err_struct} str;
898
+
899
+ str.state = 0;
900
+ str.last_error = Qnil;
901
+
891
902
  pframe->last_error = Qnil;
892
903
  VALUE result = #{rescue_code};
893
904
 
@@ -898,7 +909,11 @@ module FastRuby
898
909
  else
899
910
  inline_block "
900
911
  VALUE result;
901
- int state;
912
+ #{return_err_struct} str;
913
+
914
+ str.state = 0;
915
+ str.last_error = Qnil;
916
+
902
917
  pframe->last_error = Qnil;
903
918
 
904
919
  if (pframe->rescue) {
@@ -913,42 +928,6 @@ module FastRuby
913
928
  end
914
929
  end
915
930
 
916
- def func_frame
917
- "
918
- #{@locals_struct} *plocals = malloc(sizeof(typeof(*plocals)));
919
- #{@frame_struct} frame;
920
- #{@frame_struct} *pframe;
921
-
922
- frame.plocals = plocals;
923
- frame.parent_frame = (void*)_parent_frame;
924
- frame.return_value = Qnil;
925
- frame.rescue = 0;
926
- frame.targetted = 0;
927
- frame.thread_data = ((typeof(pframe))_parent_frame)->thread_data;
928
- if (frame.thread_data == 0) frame.thread_data = rb_current_thread_data();
929
-
930
- plocals->pframe = LONG2FIX(&frame);
931
- plocals->targetted = Qfalse;
932
-
933
- pframe = (void*)&frame;
934
-
935
- #{@block_struct} *pblock;
936
- VALUE last_expression = Qnil;
937
-
938
- int aux = setjmp(pframe->jmp);
939
- if (aux != 0) {
940
-
941
- if (plocals->targetted == Qfalse) {
942
- longjmp(((typeof(pframe))_parent_frame)->jmp,aux);
943
- }
944
-
945
- return plocals->return_value;
946
- }
947
-
948
- plocals->self = self;
949
- "
950
- end
951
-
952
931
  def c_escape(str)
953
932
  str.inspect
954
933
  end
@@ -1102,7 +1081,7 @@ module FastRuby
1102
1081
  protected_block "rb_funcall(((VALUE*)method_arguments)[0], #{intern_num mname.to_sym}, #{args_tree.size-1}#{inprocstrargs});", false, "method_arguments"
1103
1082
  };
1104
1083
  } else {
1105
- return ( (VALUE(*)(#{value_cast})) (fptr) )(self,(VALUE)block,(VALUE)frame#{inprocstrargs});
1084
+ return ( (VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*)) (fptr) )(self,(VALUE)block,(VALUE)frame,#{args_tree.size-1},method_arguments+1);
1106
1085
  }
1107
1086
  }
1108
1087
  "