fastruby 0.0.20 → 0.0.21

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.
Files changed (42) hide show
  1. data/Rakefile +1 -1
  2. data/lib/fastruby/builder.rb~ +5 -1
  3. data/lib/fastruby/corelib/fixnum.rb +1 -1
  4. data/lib/fastruby/corelib/fixnum.rb~ +0 -71
  5. data/lib/fastruby/corelib.rb~ +1 -1
  6. data/lib/fastruby/modules/inliner/call.rb~ +3 -1
  7. data/lib/fastruby/modules/translator/call.rb +1 -1
  8. data/lib/fastruby/modules/translator/call.rb~ +1 -1
  9. data/lib/fastruby/object.rb~ +0 -6
  10. data/lib/fastruby.rb +1 -1
  11. data/lib/fastruby.rb~ +1 -1
  12. data/spec/corelib/numeric/fixnum_spec.rb +1 -1
  13. data/spec/corelib/numeric/fixnum_spec.rb~ +7 -1
  14. metadata +12 -40
  15. data/lib/fastruby/builder/inference_updater.rb~ +0 -76
  16. data/lib/fastruby/builder/inliner.rb~ +0 -60
  17. data/lib/fastruby/builder/lvar_type.rb~ +0 -44
  18. data/lib/fastruby/builder/pipeline.rb~ +0 -43
  19. data/lib/fastruby/builder/reductor.rb~ +0 -42
  20. data/lib/fastruby/corelib/integer.rb~ +0 -96
  21. data/lib/fastruby/modules/inliner/defn.rb~ +0 -29
  22. data/lib/fastruby/modules/inliner/recursive.rb~ +0 -40
  23. data/lib/fastruby/modules/lvar_type/call.rb~ +0 -36
  24. data/lib/fastruby/modules/lvar_type/defn.rb~ +0 -42
  25. data/lib/fastruby/modules/lvar_type/lasgn.rb~ +0 -42
  26. data/lib/fastruby/modules/lvar_type/recursive.rb~ +0 -33
  27. data/lib/fastruby/modules/reductor/nontree.rb~ +0 -32
  28. data/lib/fastruby/modules/reductor/recursive.rb~ +0 -31
  29. data/lib/fastruby/modules/translator/defn.rb~ +0 -267
  30. data/lib/fastruby/modules/translator/directive.rb~ +0 -44
  31. data/lib/fastruby/modules/translator/exceptions.rb~ +0 -120
  32. data/lib/fastruby/modules/translator/iter.rb~ +0 -745
  33. data/lib/fastruby/modules/translator/literal.rb~ +0 -150
  34. data/lib/fastruby/modules/translator/nonlocal.rb~ +0 -298
  35. data/lib/fastruby/modules/translator/static.rb~ +0 -291
  36. data/lib/fastruby/modules/translator/variable.rb~ +0 -280
  37. data/lib/fastruby/set_tree.rb~ +0 -71
  38. data/lib/fastruby/sexp_extension.rb~ +0 -262
  39. data/lib/fastruby/translator/scope_mode_helper.rb~ +0 -138
  40. data/lib/fastruby/translator/translator.rb~ +0 -1600
  41. data/lib/fastruby/translator/translator_modules.rb~ +0 -53
  42. data/lib/fastruby_only/base.rb +0 -1
@@ -1,745 +0,0 @@
1
- =begin
2
-
3
- This file is part of the fastruby project, http://github.com/tario/fastruby
4
-
5
- Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
-
7
- fastruby is free software: you can redistribute it and/or modify
8
- it under the terms of the gnu general public license as published by
9
- the free software foundation, either version 3 of the license, or
10
- (at your option) any later version.
11
-
12
- fastruby is distributed in the hope that it will be useful,
13
- but without any warranty; without even the implied warranty of
14
- merchantability or fitness for a particular purpose. see the
15
- gnu general public license for more details.
16
-
17
- you should have received a copy of the gnu general public license
18
- along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
-
20
- =end
21
- module FastRuby
22
- class Context
23
-
24
- define_translator_for(:iter, :method => :to_c_iter)
25
- def to_c_iter(tree, result_var = nil)
26
-
27
- call_tree = tree[1]
28
- args_tree = tree[2]
29
- recv_tree = call_tree[1]
30
-
31
- directive_code = directive(call_tree)
32
- if directive_code
33
- if result_var
34
- return "#{result_var} = #{directive_code};\n"
35
- else
36
- return directive_code
37
- end
38
- end
39
-
40
- other_call_tree = call_tree.dup
41
- other_call_tree[1] = s(:lvar, :arg)
42
-
43
- mname = call_tree[2]
44
-
45
- call_args_tree = call_tree[3]
46
-
47
- caller_code = nil
48
-
49
- recvtype = infer_type(recv_tree || s(:self))
50
-
51
- address = nil
52
- mobject = nil
53
- len = nil
54
-
55
- if recvtype
56
-
57
- inference_complete = true
58
- signature = [recvtype]
59
-
60
- call_args_tree[1..-1].each do |arg|
61
- argtype = infer_type(arg)
62
- if argtype
63
- signature << argtype
64
- else
65
- inference_complete = false
66
- end
67
- end
68
- end
69
-
70
- anonymous_impl = tree[3]
71
-
72
- str_lvar_initialization = "#{@frame_struct} *pframe;
73
- #{@locals_struct} *plocals;
74
-
75
- "
76
-
77
- str_arg_initialization = ""
78
-
79
- str_impl = ""
80
- on_block do
81
- str_impl = to_c(anonymous_impl, "last_expression")
82
- end
83
-
84
- if not args_tree
85
- elsif args_tree.first == :lasgn
86
- if RUBY_VERSION =~ /^1\.8/
87
- str_arg_initialization << "plocals->#{args_tree[1]} = arg;"
88
- elsif RUBY_VERSION =~ /^1\.9/
89
- str_arg_initialization << "
90
- if (TYPE(arg) != T_ARRAY) {
91
- plocals->#{args_tree[1]} = arg;
92
- } else {
93
- plocals->#{args_tree[1]} = rb_ary_entry(arg,0);
94
- }
95
- "
96
- end
97
- elsif args_tree.first == :masgn
98
-
99
- if RUBY_VERSION =~ /^1\.8/
100
- str_arg_initialization << "
101
- {
102
- if (TYPE(arg) != T_ARRAY) {
103
- if (arg != Qnil) {
104
- arg = rb_ary_new4(1,&arg);
105
- } else {
106
- arg = rb_ary_new2(0);
107
- }
108
- } else if (_RARRAY_LEN(arg) <= 1) {
109
- arg = rb_ary_new4(1,&arg);
110
- }
111
- }
112
- "
113
- elsif RUBY_VERSION =~ /^1\.9/
114
- str_arg_initialization << "
115
- {
116
- }
117
- "
118
- end
119
-
120
- arguments = args_tree[1][1..-1]
121
-
122
- (0..arguments.size-1).each do |i|
123
- arg = arguments[i]
124
- if arg[0] == :lasgn
125
- str_arg_initialization << "plocals->#{arguments[i].last} = rb_ary_entry(arg,#{i});\n"
126
- elsif arg[0] == :splat
127
- str_arg_initialization << "plocals->#{arg.last.last} = rb_ary_new2(_RARRAY_LEN(arg)-#{i});\n
128
-
129
- int i;
130
- for (i=#{i};i<_RARRAY_LEN(arg);i++){
131
- rb_ary_store(plocals->#{arg.last.last},i-#{i},rb_ary_entry(arg,i));
132
- }
133
- "
134
- end
135
- end
136
- end
137
- str_recv = "pframe->next_recv"
138
- str_recv = "plocals->self" unless recv_tree
139
-
140
- strargs = if call_args_tree.size > 1
141
- "," + (0..call_args_tree.size-2).map{|i| "arg#{i}"}.join(",")
142
- else
143
- ""
144
- end
145
-
146
- str_evaluate_args = ""
147
-
148
- rb_funcall_caller_code = proc { |name, call_type| "
149
- static VALUE #{name}(VALUE param) {
150
- // call to #{call_tree[2]}
151
- VALUE last_expression = Qnil;
152
- VALUE* args_array = (VALUE*)param;
153
-
154
- #{str_lvar_initialization}
155
- pframe = (void*)args_array[0];
156
- plocals = (void*)pframe->plocals;
157
- #{str_evaluate_args};
158
-
159
- VALUE ret = rb_funcall(#{str_recv}, #{intern_num call_tree[2]}, #{call_args_tree.size-1} #{strargs});
160
- #{
161
- if call_type == :lambda
162
- "
163
-
164
- // freeze all stacks
165
- struct FASTRUBYTHREADDATA* thread_data = rb_current_thread_data();
166
-
167
- if (thread_data != 0) {
168
- VALUE rb_stack_chunk = thread_data->rb_stack_chunk;
169
-
170
- // add reference to stack chunk to lambda object
171
- rb_ivar_set(ret,#{intern_num :_fastruby_stack_chunk},rb_stack_chunk);
172
-
173
- // freeze the complete chain of stack chunks
174
- while (rb_stack_chunk != Qnil) {
175
- struct STACKCHUNK* stack_chunk;
176
- Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
177
-
178
- stack_chunk_freeze(stack_chunk);
179
-
180
- rb_stack_chunk = rb_ivar_get(rb_stack_chunk,#{intern_num :_parent_stack_chunk});
181
- }
182
- }
183
- "
184
- end
185
- }
186
- return ret;
187
- }
188
- "
189
- }
190
-
191
-
192
- if call_args_tree.size > 1
193
- if call_args_tree.last[0] == :splat
194
- rb_funcall_caller_code = proc { |name,call_type| "
195
- static VALUE #{name}(VALUE param) {
196
- // call to #{call_tree[2]}
197
-
198
- VALUE* args_array = (VALUE*)param;
199
- int argc = args_array[1];
200
- VALUE* argv = args_array[2];
201
-
202
- VALUE last_expression = Qnil;
203
- #{str_lvar_initialization}
204
-
205
- pframe = (void*)args_array[0];
206
- plocals = (void*)pframe->plocals;
207
-
208
- return rb_funcall2(#{str_recv}, #{intern_num call_tree[2]}, argc, argv);
209
- }
210
- "
211
- }
212
- else
213
- str_evaluate_args = "
214
- #{
215
- (0..call_args_tree.size-2).map{|i|
216
- "VALUE arg#{i} = args_array[#{i+1}];"
217
- }.join("\n")
218
- }
219
-
220
- "
221
- end
222
- end
223
-
224
- argument_array_read = "
225
- VALUE arg;
226
- #{
227
- # TODO: access directly to argc and argv for optimal execution
228
- if RUBY_VERSION =~ /^1\.9/
229
- "
230
- if (TYPE(arg_) == T_ARRAY) {
231
- if (_RARRAY_LEN(arg_) <= 1) {
232
- arg = rb_ary_new4(argc,argv);
233
- } else {
234
- arg = arg_;
235
- }
236
- } else {
237
- arg = rb_ary_new4(argc,argv);
238
- }
239
- "
240
- else
241
- "arg = arg_;"
242
- end
243
- }
244
- "
245
-
246
- rb_funcall_block_code = proc { |name,call_type| "
247
- static VALUE #{name}(VALUE arg_, VALUE _plocals, int argc, VALUE* argv) {
248
- // block for call to #{call_tree[2]}
249
- #{argument_array_read}
250
-
251
- volatile VALUE last_expression = Qnil;
252
-
253
- #{@frame_struct} frame;
254
- #{@frame_struct} * volatile pframe = (void*)&frame;
255
- #{@locals_struct} * volatile plocals = (void*)_plocals;
256
-
257
- frame.plocals = plocals;
258
- frame.parent_frame = 0;
259
- frame.return_value = Qnil;
260
- frame.rescue = 0;
261
- frame.targetted = 0;
262
- frame.thread_data = rb_current_thread_data();
263
-
264
- #{str_arg_initialization}
265
-
266
- #{
267
- if call_type == :lambda or call_type == :proc_new
268
- "
269
- void* volatile old_call_frame = ((typeof(plocals))(pframe->plocals))->call_frame;
270
- ((typeof(plocals))(pframe->plocals))->call_frame = pframe;
271
- "
272
- end
273
- }
274
-
275
- int aux = setjmp(frame.jmp);
276
- if (aux != 0) {
277
-
278
- if (aux == FASTRUBY_TAG_NEXT) {
279
- last_expression = pframe->thread_data->accumulator;
280
- goto fastruby_local_next;
281
- } else if (aux == FASTRUBY_TAG_REDO) {
282
- // do nothing and let execute the block again
283
- #{
284
- if call_type == :lambda
285
- "
286
-
287
- } else if (aux == FASTRUBY_TAG_BREAK) {
288
- last_expression = frame.return_value;
289
- typeof(pframe) target_frame_ = (void*)plocals->call_frame;
290
-
291
- if (target_frame_ == 0) {
292
- goto fastruby_local_next;
293
- } else {
294
- if (target_frame_->targetted == 1) {
295
- goto fastruby_local_next;
296
- } else {
297
- #{_raise("rb_eLocalJumpError","illegal break")};
298
- }
299
- }
300
- "
301
- end
302
- }
303
- #{
304
- if call_type == :lambda or call_type == :proc_new
305
- "
306
- } else if (aux == FASTRUBY_TAG_RAISE) {
307
- rb_funcall(((typeof(plocals))(pframe->plocals))->self, #{intern_num :raise}, 1, frame.thread_data->exception);
308
- return Qnil;
309
- "
310
- end
311
- }
312
- } else {
313
- #{
314
- case call_type
315
- when :proc_new
316
- "
317
- _local_return:
318
- if (plocals->targetted == 1) {
319
- if (plocals->active == Qfalse) {
320
- rb_raise(rb_eLocalJumpError,\"return from proc-closure\");
321
- } else {
322
- ((typeof(plocals))(pframe->plocals))->call_frame = old_call_frame;
323
- frb_jump_tag(aux);
324
- }
325
- } else {
326
- rb_raise(rb_eLocalJumpError, \"unexpected return\");
327
- }
328
- "
329
- when :lambda
330
- "
331
- if (aux == FASTRUBY_TAG_RETURN) {
332
- if (plocals->targetted == 1) {
333
- last_expression = ((typeof(plocals))(pframe->plocals))->return_value;
334
- goto fastruby_local_next;
335
-
336
- } else {
337
- rb_raise(rb_eLocalJumpError, \"unexpected return\");
338
- }
339
- } else {
340
- rb_raise(rb_eLocalJumpError, \"unexpected return\");
341
- }
342
- "
343
- else
344
- "
345
- frb_jump_tag(aux);
346
- return frame.return_value;
347
- "
348
- end
349
- }
350
-
351
- }
352
- }
353
-
354
- #{
355
- if call_type == :callcc
356
- "
357
- if (rb_obj_is_kind_of(arg, rb_const_get(rb_cObject, #{intern_num :Continuation}))) {
358
- struct FASTRUBYTHREADDATA* thread_data = frame.thread_data;
359
- rb_ivar_set(arg,#{intern_num :__stack_chunk},thread_data->rb_stack_chunk);
360
- }
361
- "
362
- end
363
- }
364
-
365
- fastruby_local_redo:
366
- #{str_impl};
367
-
368
- #{
369
- case call_type
370
- when :proc_new
371
- "
372
- return last_expression;
373
- local_return:
374
- aux = FASTRUBY_TAG_RETURN;
375
- plocals->return_value = last_expression;
376
- plocals->targetted = 1;
377
- goto _local_return;
378
- "
379
- when :lambda
380
- "
381
- local_return:
382
- "
383
- else
384
- "
385
- return last_expression;
386
- local_return:
387
- plocals->return_value = last_expression;
388
- plocals->targetted = 1;
389
- frb_jump_tag(FASTRUBY_TAG_RETURN);
390
- "
391
- end
392
- }
393
-
394
-
395
- fastruby_local_next:
396
- #{
397
- if call_type == :proc_new or call_type == :lambda
398
- "
399
- ((typeof(plocals))(pframe->plocals))->call_frame = old_call_frame;
400
- "
401
- end
402
- }
403
- return last_expression;
404
- }
405
- "
406
- }
407
-
408
- fastruby_str_arg_initialization = ""
409
-
410
- if not args_tree
411
- fastruby_str_arg_initialization = ""
412
- elsif args_tree.first == :lasgn
413
- fastruby_str_arg_initialization = "plocals->#{args_tree[1]} = argv[0];"
414
- elsif args_tree.first == :masgn
415
- arguments = args_tree[1][1..-1]
416
-
417
- (0..arguments.size-1).each do |i|
418
- arg = arguments[i]
419
- if arg[0] == :lasgn
420
- fastruby_str_arg_initialization << "plocals->#{arg.last} = #{i} < argc ? argv[#{i}] : Qnil;\n"
421
- elsif arg[0] == :splat
422
- fastruby_str_arg_initialization << "plocals->#{arg.last.last} = rb_ary_new2(#{arguments.size-1-i});\n
423
- {
424
- int i;
425
- for (i=#{i};i<argc;i++){
426
- rb_ary_store(plocals->#{arg.last.last},i-#{i},argv[i]);
427
- }
428
- }
429
- "
430
- end
431
- end
432
- end
433
-
434
- block_code = proc { |name| "
435
- static VALUE #{name}(int argc, VALUE* argv, VALUE _locals, VALUE _parent_frame) {
436
- // block for call to #{call_tree[2]}
437
- volatile VALUE last_expression = Qnil;
438
- #{@frame_struct} frame;
439
- #{@frame_struct} * volatile pframe = (void*)&frame;
440
- #{@frame_struct} * volatile parent_frame = (void*)_parent_frame;
441
- #{@locals_struct} * volatile plocals;
442
-
443
- frame.plocals = (void*)_locals;
444
- frame.parent_frame = parent_frame;
445
- frame.return_value = Qnil;
446
- frame.rescue = 0;
447
- frame.targetted = 0;
448
- frame.thread_data = parent_frame->thread_data;
449
- if (frame.thread_data == 0) frame.thread_data = rb_current_thread_data();
450
-
451
- plocals = frame.plocals;
452
-
453
- #{fastruby_str_arg_initialization}
454
-
455
- int aux = setjmp(frame.jmp);
456
- if (aux != 0) {
457
- if (pframe->targetted == 0) {
458
- if (aux == FASTRUBY_TAG_NEXT) {
459
- return pframe->thread_data->accumulator;
460
- } else if (aux == FASTRUBY_TAG_REDO) {
461
- // do nothing and let execute the block again
462
- } else {
463
- longjmp(((typeof(pframe))_parent_frame)->jmp,aux);
464
- }
465
- }
466
-
467
- }
468
-
469
- fastruby_local_redo:
470
- #{str_impl};
471
-
472
- return last_expression;
473
- local_return:
474
- plocals->return_value = last_expression;
475
- plocals->targetted = 1;
476
- longjmp(pframe->jmp, FASTRUBY_TAG_RETURN);
477
- fastruby_local_next:
478
- return last_expression; }
479
- "
480
- }
481
-
482
- caller_code = nil
483
- convention_global_name = add_global_name("int",0)
484
-
485
- precode = "
486
- struct FASTRUBYTHREADDATA* thread_data = 0;
487
- VALUE saved_rb_stack_chunk = Qnil;
488
-
489
- VALUE next_recv = plocals->self;
490
-
491
- #{
492
- if recv_tree
493
- to_c recv_tree, "next_recv"
494
- end
495
- };
496
-
497
- pframe->next_recv = next_recv;
498
- #ifdef RUBY_1_8
499
- NODE* node = rb_method_node(CLASS_OF(pframe->next_recv), #{intern_num mname});
500
- #endif
501
- #ifdef RUBY_1_9
502
- void* node = rb_method_entry(CLASS_OF(pframe->next_recv), #{intern_num mname});
503
- #endif
504
-
505
- if (node == #{@callcc_node_gvar}) {
506
-
507
- // freeze all stacks
508
- thread_data = rb_current_thread_data();
509
-
510
- if (thread_data != 0) {
511
- VALUE rb_stack_chunk = thread_data->rb_stack_chunk;
512
- saved_rb_stack_chunk = rb_stack_chunk;
513
-
514
- // freeze the complete chain of stack chunks
515
- while (rb_stack_chunk != Qnil) {
516
- struct STACKCHUNK* stack_chunk;
517
- Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
518
-
519
- stack_chunk_freeze(stack_chunk);
520
-
521
- rb_stack_chunk = rb_ivar_get(rb_stack_chunk,#{intern_num :_parent_stack_chunk});
522
- }
523
- }
524
- }
525
- "
526
-
527
- postcode = "
528
- if (node == #{@callcc_node_gvar}) {
529
- thread_data->rb_stack_chunk = saved_rb_stack_chunk;
530
- }
531
- "
532
-
533
-
534
- funcall_call_code = "
535
- #{
536
- frame_call(
537
- "ret = " + protected_block("
538
-
539
- void* caller_func;
540
- void* block_func;
541
- typeof(plocals) current_plocals;
542
-
543
- if (pframe->thread_data == 0) pframe->thread_data = rb_current_thread_data();
544
- void* last_plocals = pframe->thread_data->last_plocals;
545
-
546
- #ifdef RUBY_1_8
547
- NODE* node = rb_method_node(CLASS_OF(pframe->next_recv), #{intern_num mname});
548
- #endif
549
- #ifdef RUBY_1_9
550
- void* node = rb_method_entry(CLASS_OF(pframe->next_recv), #{intern_num mname});
551
- #endif
552
-
553
- if (
554
- node == #{@proc_node_gvar} ||
555
- node == #{@lambda_node_gvar}
556
- ) {
557
-
558
- caller_func = #{anonymous_function(:lambda,&rb_funcall_caller_code)};
559
- block_func = #{anonymous_function(:lambda,&rb_funcall_block_code)};
560
- } else if (node == #{@procnew_node_gvar} && pframe->next_recv == rb_cProc) {
561
- caller_func = #{anonymous_function(:lambda,&rb_funcall_caller_code)};
562
- block_func = #{anonymous_function(:proc_new,&rb_funcall_block_code)};
563
- } else if (node == #{@callcc_node_gvar}) {
564
- caller_func = #{anonymous_function(:normal,&rb_funcall_caller_code)};
565
- block_func = #{anonymous_function(:callcc,&rb_funcall_block_code)};
566
- } else {
567
- caller_func = #{anonymous_function(:normal,&rb_funcall_caller_code)};
568
- block_func = #{anonymous_function(:normal,&rb_funcall_block_code)};
569
- }
570
-
571
-
572
- #{if call_args_tree.size > 1 and call_args_tree.last[0] == :splat
573
- "
574
- VALUE args_array[3];
575
- VALUE array = Qnil;
576
-
577
- #{to_c call_args_tree.last[1], "array"};
578
-
579
- if (TYPE(array) != T_ARRAY) {
580
- array = rb_ary_new4(1,&array);
581
- }
582
-
583
- int argc = #{call_args_tree.size-2};
584
- VALUE argv[#{call_args_tree.size} + _RARRAY_LEN(array)];
585
-
586
- VALUE aux_ = Qnil;;
587
- #{
588
- i = -1
589
- call_args_tree[1..-2].map {|arg|
590
- i = i + 1
591
- "
592
- #{to_c arg, "aux_"};
593
- argv[#{i}] = aux_;
594
- "
595
- }.join(";\n")
596
- };
597
-
598
- int array_len = _RARRAY_LEN(array);
599
-
600
- int i;
601
- for (i=0; i<array_len;i++) {
602
- argv[argc] = rb_ary_entry(array,i);
603
- argc++;
604
- }
605
-
606
- args_array[0] = (VALUE)pframe;
607
- args_array[1] = (VALUE)argc;
608
- args_array[2] = (VALUE)argv;
609
-
610
- last_expression = rb_iterate(
611
- caller_func,
612
- (VALUE)args_array,
613
- block_func,
614
- (VALUE)plocals);
615
-
616
- "
617
- else
618
- "
619
-
620
- VALUE args_array[#{call_args_tree.size+2}];
621
- VALUE aux___ = Qnil;
622
- args_array[0] = (VALUE)pframe;
623
-
624
- #{
625
- (0..call_args_tree.size-2).map{|i|
626
- to_c(call_args_tree[i+1], "aux___")+";"+
627
- "args_array[#{i+1}] = aux___;"
628
- }.join("\n")
629
- }
630
-
631
- last_expression = rb_iterate(
632
- caller_func,
633
- (VALUE)args_array,
634
- block_func,
635
- (VALUE)plocals);
636
- "
637
- end
638
- }
639
- if (node == #{@callcc_node_gvar}) {
640
-
641
- // remove active flags of abandoned stack
642
- current_plocals = pframe->thread_data->last_plocals;
643
- while (current_plocals) {
644
- current_plocals->active = Qfalse;
645
- current_plocals = (typeof(current_plocals))(current_plocals->parent_locals);
646
- }
647
-
648
- // restore last_plocals
649
- pframe->thread_data->last_plocals = last_plocals;
650
-
651
- // mark all scopes as active
652
- current_plocals = last_plocals;
653
-
654
- while (current_plocals) {
655
- current_plocals->active = Qtrue;
656
- current_plocals = (typeof(current_plocals))(current_plocals->parent_locals);
657
- }
658
- }
659
- ", true), precode, postcode
660
- )
661
- };
662
- "
663
-
664
- recvtype = nil if call_args_tree.size > 1 ? call_args_tree.last[0] == :splat : false
665
- unless recvtype
666
- if result_var
667
- "#{result_var} = #{funcall_call_code};"
668
- else
669
- funcall_call_code
670
- end
671
- else
672
- encoded_address = encode_address(recvtype,signature,mname,call_tree,inference_complete,convention_global_name, true)
673
-
674
- if call_args_tree.size > 1
675
- strargs = (0..call_args_tree.size-2).map{|i| "arg#{i}"}.join(",")
676
- else
677
- strargs = ""
678
- end
679
-
680
- fastruby_call_code = "
681
- // call to #{call_tree[2]}
682
- #{
683
- if call_args_tree.size > 1
684
- " #{
685
- (0..call_args_tree.size-2).map{|i|
686
- "VALUE arg#{i} = Qnil;"
687
- }.join("\n")
688
- }
689
-
690
- #{
691
- (0..call_args_tree.size-2).map{|i|
692
- to_c(call_args_tree[i+1], "arg#{i}")+";"
693
- }.join("\n")
694
- }
695
- "
696
- end
697
- };
698
-
699
- VALUE recv = plocals->self;
700
-
701
- #{
702
- if recv_tree
703
- to_c recv_tree, "recv"
704
- end
705
- }
706
-
707
- ret = ((VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*))#{encoded_address})(recv, (VALUE)&block, (VALUE)&call_frame, #{call_args_tree.size-1}, (VALUE[]){#{strargs}});
708
- "
709
-
710
- code = "
711
- if (#{@last_address_name} == 0) {
712
- return #{funcall_call_code};
713
- } else {
714
- #{if recvtype and inference_complete
715
- "if (*#{@last_address_name} == 0) {
716
- rb_funcall(#{literal_value recvtype},#{intern_num :build}, 2, #{literal_value signature}, #{literal_value mname});
717
- }
718
- "
719
- end
720
- }
721
- if (*#{@last_address_name} == 0) {
722
- return #{funcall_call_code};
723
- } else {
724
- #{fastruby_call_code}
725
- }
726
- }
727
- "
728
-
729
- fastruby_precode = " #{@block_struct} block;
730
-
731
- block.block_function_address = ((void*)#{anonymous_function(&block_code)});
732
- block.block_function_param = ((void*)plocals);
733
- block.proc = Qnil;
734
- "
735
-
736
- if result_var
737
- "#{result_var} = #{frame_call(code,fastruby_precode,"")}"
738
- else
739
- frame_call(code,fastruby_precode,"")
740
- end
741
-
742
- end
743
- end
744
- end
745
- end