fastruby 0.0.20 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
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