fastruby 0.0.16 → 0.0.17
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +17 -1
- data/Rakefile +1 -1
- data/ext/fastruby_base/fastruby_base.inl +81 -3
- data/lib/fastruby/fastruby_sexp.rb +21 -0
- data/lib/fastruby/getlocals.rb +2 -1
- data/lib/fastruby/object.rb +1 -1
- data/lib/fastruby/sexp_extension.rb +189 -0
- data/lib/fastruby/sexp_extension_edges.rb +210 -0
- data/lib/fastruby/translator/modules/block.rb +29 -22
- data/lib/fastruby/translator/modules/call.rb +211 -34
- data/lib/fastruby/translator/modules/defn.rb +64 -29
- data/lib/fastruby/translator/modules/exceptions.rb +1 -1
- data/lib/fastruby/translator/modules/flow.rb +93 -31
- data/lib/fastruby/translator/modules/iter.rb +277 -340
- data/lib/fastruby/translator/modules/literal.rb +97 -20
- data/lib/fastruby/translator/modules/logical.rb +40 -5
- data/lib/fastruby/translator/modules/method_group.rb +41 -19
- data/lib/fastruby/translator/modules/nonlocal.rb +74 -29
- data/lib/fastruby/translator/modules/variable.rb +151 -42
- data/lib/fastruby/translator/scope_mode_helper.rb +161 -0
- data/lib/fastruby/translator/translator.rb +389 -302
- data/lib/fastruby.rb +1 -1
- data/lib/fastruby.rb~ +36 -0
- data/spec/edges_helper.rb +91 -0
- data/spec/graph/base_spec.rb +35 -0
- data/spec/graph/path_spec.rb +48 -0
- data/spec/graph/vertex_spec.rb +58 -0
- data/spec/ruby/block/proc_as_block_spec.rb +214 -0
- data/spec/ruby/block/redo_spec.rb +133 -0
- data/spec/ruby/defn/single_function_spec.rb +50 -0
- data/spec/scope_mode/base_spec.rb +55 -0
- data/spec/scope_mode/block_spec.rb +105 -0
- data/spec/scope_mode/call_spec.rb +24 -0
- data/spec/scope_mode/exception_spec.rb +34 -0
- data/spec/scope_mode/flow_spec.rb +99 -0
- data/spec/scope_mode/optimization_spec.rb +130 -0
- data/spec/sexp2graph/base_spec.rb +36 -0
- data/spec/sexp2graph/exception_spec.rb +172 -0
- data/spec/sexp2graph/flow_spec.rb +67 -0
- data/spec/sexp2graph/logical_spec.rb +21 -0
- data/spec/sexp2graph/variable_spec.rb +26 -0
- metadata +110 -120
- data/lib/fastruby/self +0 -82
- data/lib/len +0 -280
- data/spec/block/proc_as_block_spec.rb +0 -111
- data/spec/block/redo_spec.rb +0 -67
- /data/spec/{base_spec.rb → ruby/base_spec.rb} +0 -0
- /data/spec/{block → ruby/block}/arguments_spec.rb +0 -0
- /data/spec/{block → ruby/block}/block_as_proc_spec.rb +0 -0
- /data/spec/{block → ruby/block}/break_spec.rb +0 -0
- /data/spec/{block → ruby/block}/callcc_spec.rb +0 -0
- /data/spec/{block → ruby/block}/lambda_spec.rb +0 -0
- /data/spec/{block → ruby/block}/next_spec.rb +0 -0
- /data/spec/{block → ruby/block}/proc_spec.rb +0 -0
- /data/spec/{block → ruby/block}/retry_spec.rb +0 -0
- /data/spec/{block_spec.rb → ruby/block_spec.rb} +0 -0
- /data/spec/{call → ruby/call}/base_call_spec.rb +0 -0
- /data/spec/{call → ruby/call}/multiple_args_spec.rb +0 -0
- /data/spec/{control_spec.rb → ruby/control_spec.rb} +0 -0
- /data/spec/{defn → ruby/defn}/default_args_spec.rb +0 -0
- /data/spec/{defn → ruby/defn}/multiple_args_spec.rb +0 -0
- /data/spec/{defn → ruby/defn}/replacement_spec.rb +0 -0
- /data/spec/{exception → ruby/exception}/base_spec.rb +0 -0
- /data/spec/{exception → ruby/exception}/ensure_spec.rb +0 -0
- /data/spec/{exception → ruby/exception}/exc_trap_spec.rb +0 -0
- /data/spec/{exception → ruby/exception}/internal_ex_spec.rb +0 -0
- /data/spec/{exception → ruby/exception}/syntaxis_spec.rb +0 -0
- /data/spec/{expression_spec.rb → ruby/expression_spec.rb} +0 -0
- /data/spec/{flow_control → ruby/flow_control}/case_spec.rb +0 -0
- /data/spec/{flow_control → ruby/flow_control}/for_spec.rb +0 -0
- /data/spec/{integrity_spec.rb → ruby/integrity_spec.rb} +0 -0
- /data/spec/{jump → ruby/jump}/next_spec.rb +0 -0
- /data/spec/{literal_spec.rb → ruby/literal_spec.rb} +0 -0
- /data/spec/{module_spec.rb → ruby/module_spec.rb} +0 -0
- /data/spec/{return_spec.rb → ruby/return_spec.rb} +0 -0
- /data/spec/{singleton_spec.rb → ruby/singleton_spec.rb} +0 -0
- /data/spec/{sugar_spec.rb → ruby/sugar_spec.rb} +0 -0
- /data/spec/{variable_spec.rb → ruby/variable_spec.rb} +0 -0
@@ -25,7 +25,7 @@ require "fastruby/method_extension"
|
|
25
25
|
require "fastruby/set_tree"
|
26
26
|
require "fastruby/exceptions"
|
27
27
|
require "fastruby/translator/translator_modules"
|
28
|
-
|
28
|
+
require "fastruby/translator/scope_mode_helper"
|
29
29
|
|
30
30
|
module FastRuby
|
31
31
|
class Context
|
@@ -65,6 +65,7 @@ module FastRuby
|
|
65
65
|
@block_struct = "struct {
|
66
66
|
void* block_function_address;
|
67
67
|
void* block_function_param;
|
68
|
+
VALUE proc;
|
68
69
|
}"
|
69
70
|
|
70
71
|
extra_code << "
|
@@ -83,6 +84,9 @@ module FastRuby
|
|
83
84
|
#define FASTRUBY_TAG_RETRY 0x85
|
84
85
|
#define TAG_RAISE 0x6
|
85
86
|
|
87
|
+
# define PTR2NUM(x) (ULONG2NUM((unsigned long)(x)))
|
88
|
+
# define NUM2PTR(x) ((void*)(NUM2ULONG(x)))
|
89
|
+
|
86
90
|
#ifndef __INLINE_FASTRUBY_BASE
|
87
91
|
#include \"#{FastRuby.fastruby_load_path}/../ext/fastruby_base/fastruby_base.inl\"
|
88
92
|
#define __INLINE_FASTRUBY_BASE
|
@@ -142,7 +146,7 @@ module FastRuby
|
|
142
146
|
#{@frame_struct}* pframe;
|
143
147
|
pframe = (typeof(pframe))_parent_frame;
|
144
148
|
|
145
|
-
return #{protected_block("rb_yield_splat(*(VALUE*)yield_args_p)",true,"yield_args_p",true)};
|
149
|
+
return #{protected_block("last_expression = rb_yield_splat(*(VALUE*)yield_args_p)",true,"yield_args_p",true)};
|
146
150
|
}"
|
147
151
|
|
148
152
|
extra_code << "static VALUE _rb_ivar_set(VALUE recv,ID idvar, VALUE value) {
|
@@ -179,15 +183,26 @@ module FastRuby
|
|
179
183
|
end
|
180
184
|
end
|
181
185
|
|
182
|
-
def to_c(tree)
|
186
|
+
def to_c(tree, result_variable = nil)
|
183
187
|
return "Qnil" unless tree
|
184
|
-
|
188
|
+
|
189
|
+
mname = "to_c_" + tree[0].to_s
|
190
|
+
|
191
|
+
if result_variable
|
192
|
+
if method(mname).arity == 1
|
193
|
+
"#{result_variable} = #{send(mname, tree)};\n"
|
194
|
+
else
|
195
|
+
send(mname, tree, result_variable)
|
196
|
+
end
|
197
|
+
else
|
198
|
+
send(mname, tree)
|
199
|
+
end
|
185
200
|
end
|
186
201
|
|
187
|
-
def anonymous_function
|
202
|
+
def anonymous_function(*x)
|
188
203
|
|
189
204
|
name = "anonymous" + rand(10000000).to_s
|
190
|
-
extra_code << yield(name)
|
205
|
+
extra_code << yield(name,*x)
|
191
206
|
|
192
207
|
name
|
193
208
|
end
|
@@ -195,10 +210,10 @@ module FastRuby
|
|
195
210
|
def frame_call(inner_code, precode = "", postcode = "")
|
196
211
|
inline_block "
|
197
212
|
|
198
|
-
|
213
|
+
volatile VALUE ret = Qnil;
|
199
214
|
// create a call_frame
|
200
215
|
#{@frame_struct} call_frame;
|
201
|
-
typeof(call_frame)* old_pframe = (void*)pframe;
|
216
|
+
typeof(call_frame)* volatile old_pframe = (void*)pframe;
|
202
217
|
|
203
218
|
pframe = (typeof(pframe))&call_frame;
|
204
219
|
|
@@ -209,8 +224,8 @@ module FastRuby
|
|
209
224
|
call_frame.thread_data = old_pframe->thread_data;
|
210
225
|
if (call_frame.thread_data == 0) call_frame.thread_data = rb_current_thread_data();
|
211
226
|
|
212
|
-
|
213
|
-
plocals->call_frame =
|
227
|
+
void* volatile old_call_frame = plocals->call_frame;
|
228
|
+
plocals->call_frame = &call_frame;
|
214
229
|
|
215
230
|
#{precode}
|
216
231
|
|
@@ -235,7 +250,7 @@ module FastRuby
|
|
235
250
|
}
|
236
251
|
|
237
252
|
|
238
|
-
|
253
|
+
#{inner_code};
|
239
254
|
|
240
255
|
#{postcode}
|
241
256
|
|
@@ -246,14 +261,15 @@ module FastRuby
|
|
246
261
|
|
247
262
|
def initialize_method_structs(args_tree)
|
248
263
|
@locals_struct = "struct {
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
264
|
+
int size;
|
265
|
+
void* call_frame;
|
266
|
+
void* parent_locals;
|
267
|
+
void* pframe;
|
268
|
+
void* block_function_address;
|
269
|
+
void* block_function_param;
|
255
270
|
VALUE active;
|
256
271
|
VALUE targetted;
|
272
|
+
VALUE return_value;
|
257
273
|
#{@locals.map{|l| "VALUE #{l};\n"}.join}
|
258
274
|
}"
|
259
275
|
|
@@ -307,9 +323,9 @@ module FastRuby
|
|
307
323
|
rb_method_hash = rb_funcall(#{literal_value klass}, #{intern_num :method_hash},1,#{literal_value method_name});
|
308
324
|
|
309
325
|
if (rb_method_hash != Qnil) {
|
310
|
-
VALUE tmp = rb_hash_aref(rb_method_hash,
|
326
|
+
VALUE tmp = rb_hash_aref(rb_method_hash, PTR2NUM(id));
|
311
327
|
if (tmp != Qnil) {
|
312
|
-
address = (void*)
|
328
|
+
address = (void*)NUM2PTR(tmp);
|
313
329
|
}
|
314
330
|
}
|
315
331
|
|
@@ -323,8 +339,8 @@ module FastRuby
|
|
323
339
|
#{intern_num :register_method_value},
|
324
340
|
3,
|
325
341
|
#{literal_value method_name},
|
326
|
-
|
327
|
-
|
342
|
+
PTR2NUM(id),
|
343
|
+
PTR2NUM(address)
|
328
344
|
);
|
329
345
|
}
|
330
346
|
"
|
@@ -346,247 +362,173 @@ module FastRuby
|
|
346
362
|
|
347
363
|
args_tree = original_args_tree.select{|x| x.to_s[0] != ?&}
|
348
364
|
|
349
|
-
if (options[:main])
|
350
365
|
initialize_method_structs(original_args_tree)
|
366
|
+
|
367
|
+
if options[:main] then
|
368
|
+
strargs = if args_tree.size > 1
|
369
|
+
"VALUE self, VALUE block, VALUE _parent_frame, #{(0..signature.size-1).map{|x| "VALUE arg#{x}"}.join(",")}"
|
370
|
+
else
|
371
|
+
"VALUE self, VALUE block, VALUE _parent_frame"
|
372
|
+
end
|
351
373
|
|
352
|
-
strargs = if args_tree.size > 1
|
353
|
-
"VALUE self, VALUE block, VALUE _parent_frame, #{(0..signature.size-1).map{|x| "VALUE arg#{x}"}.join(",")}"
|
354
374
|
else
|
355
|
-
"VALUE self, VALUE block, VALUE _parent_frame"
|
356
|
-
end
|
357
|
-
|
358
|
-
ret = "VALUE #{@alt_method_name || method_name}(VALUE self) {
|
359
|
-
|
360
|
-
#{@locals_struct} *plocals;
|
361
|
-
#{@frame_struct} frame;
|
362
|
-
#{@frame_struct} *pframe;
|
363
|
-
|
364
|
-
frame.parent_frame = 0;
|
365
|
-
frame.return_value = Qnil;
|
366
|
-
frame.rescue = 0;
|
367
|
-
frame.targetted = 0;
|
368
|
-
frame.thread_data = rb_current_thread_data();
|
369
|
-
|
370
|
-
|
371
|
-
int stack_chunk_instantiated = 0;
|
372
|
-
VALUE rb_previous_stack_chunk = Qnil;
|
373
|
-
VALUE rb_stack_chunk = frame.thread_data->rb_stack_chunk;
|
374
|
-
struct STACKCHUNK* stack_chunk = 0;
|
375
|
-
|
376
|
-
if (rb_stack_chunk != Qnil) {
|
377
|
-
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
378
|
-
}
|
379
|
-
|
380
|
-
if (stack_chunk == 0 || (stack_chunk == 0 ? 0 : stack_chunk_frozen(stack_chunk)) ) {
|
381
|
-
rb_previous_stack_chunk = rb_stack_chunk;
|
382
|
-
rb_gc_register_address(&rb_stack_chunk);
|
383
|
-
stack_chunk_instantiated = 1;
|
384
|
-
|
385
|
-
rb_stack_chunk = rb_stack_chunk_create(Qnil);
|
386
|
-
frame.thread_data->rb_stack_chunk = rb_stack_chunk;
|
387
|
-
|
388
|
-
rb_ivar_set(rb_stack_chunk, #{intern_num :_parent_stack_chunk}, rb_previous_stack_chunk);
|
389
|
-
|
390
|
-
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
391
|
-
}
|
392
|
-
|
393
|
-
int previous_stack_position = stack_chunk_get_current_position(stack_chunk);
|
394
|
-
|
395
|
-
plocals = (typeof(plocals))stack_chunk_alloc(stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
|
396
375
|
|
397
|
-
|
398
|
-
void* old_parent_locals = frame.thread_data->last_plocals;
|
399
|
-
frame.thread_data->last_plocals = plocals;
|
376
|
+
strargs = "VALUE self, VALUE block, VALUE _parent_frame, int argc, VALUE* argv"
|
400
377
|
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
int aux = setjmp(pframe->jmp);
|
411
|
-
if (aux != 0) {
|
412
|
-
stack_chunk_set_current_position(stack_chunk, previous_stack_position);
|
413
|
-
|
414
|
-
if (stack_chunk_instantiated) {
|
415
|
-
rb_gc_unregister_address(&rb_stack_chunk);
|
416
|
-
frame.thread_data->rb_stack_chunk = rb_previous_stack_chunk;
|
378
|
+
splat_arg = args_tree[1..-1].find{|x| x.to_s.match(/\*/) }
|
379
|
+
|
380
|
+
maxargnum = args_tree[1..-1].count{ |x|
|
381
|
+
if x.instance_of? Symbol
|
382
|
+
not x.to_s.match(/\*/) and not x.to_s.match(/\&/)
|
383
|
+
else
|
384
|
+
false
|
385
|
+
end
|
417
386
|
}
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
#{args_tree[1..-1].map { |arg|
|
427
|
-
arg = arg.to_s
|
428
|
-
arg.gsub!("*","")
|
429
|
-
"plocals->#{arg} = #{arg};\n"
|
430
|
-
}.join("") }
|
431
|
-
|
432
|
-
plocals->block_function_address = LONG2FIX(0);
|
433
|
-
plocals->block_function_param = LONG2FIX(Qnil);
|
434
|
-
plocals->call_frame = LONG2FIX(0);
|
435
|
-
|
436
|
-
VALUE ret = #{to_c impl_tree};
|
437
|
-
stack_chunk_set_current_position(stack_chunk, previous_stack_position);
|
438
|
-
|
439
|
-
if (stack_chunk_instantiated) {
|
440
|
-
rb_gc_unregister_address(&rb_stack_chunk);
|
441
|
-
frame.thread_data->rb_stack_chunk = rb_previous_stack_chunk;
|
442
|
-
}
|
443
|
-
|
444
|
-
plocals->active = Qfalse;
|
445
|
-
|
446
|
-
frame.thread_data->last_plocals = old_parent_locals;
|
447
|
-
return ret;
|
448
|
-
|
449
|
-
}"
|
450
|
-
|
451
|
-
add_main
|
452
|
-
extra_code << ret
|
453
|
-
else
|
454
|
-
|
455
|
-
initialize_method_structs(original_args_tree)
|
456
|
-
|
457
|
-
strargs = "VALUE self, VALUE block, VALUE _parent_frame, int argc, VALUE* argv"
|
458
|
-
|
459
|
-
splat_arg = args_tree[1..-1].find{|x| x.to_s.match(/\*/) }
|
460
|
-
|
461
|
-
maxargnum = args_tree[1..-1].count{ |x|
|
462
|
-
if x.instance_of? Symbol
|
463
|
-
not x.to_s.match(/\*/) and not x.to_s.match(/\&/)
|
464
|
-
else
|
465
|
-
false
|
387
|
+
|
388
|
+
minargnum = maxargnum
|
389
|
+
|
390
|
+
args_tree[1..-1].each do |subtree|
|
391
|
+
unless subtree.instance_of? Symbol
|
392
|
+
if subtree[0] == :block
|
393
|
+
minargnum = minargnum - (subtree.size-1)
|
394
|
+
end
|
466
395
|
end
|
467
|
-
|
468
|
-
|
469
|
-
minargnum = maxargnum
|
396
|
+
end
|
470
397
|
|
471
|
-
|
472
|
-
|
473
|
-
if subtree[0] == :block
|
474
|
-
minargnum = minargnum - (subtree.size-1)
|
475
|
-
end
|
398
|
+
if args_tree[1..-1].find{|x| x.to_s.match(/\*/)}
|
399
|
+
maxargnum = 2147483647
|
476
400
|
end
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
default_block_tree = args_tree[1..-1].find{|subtree|
|
497
|
-
unless subtree.instance_of? Symbol
|
498
|
-
if subtree[0] == :block
|
499
|
-
next true
|
401
|
+
|
402
|
+
read_arguments_code = ""
|
403
|
+
|
404
|
+
|
405
|
+
validate_arguments_code = if signature.size-1 < minargnum
|
406
|
+
"
|
407
|
+
rb_raise(rb_eArgError, \"wrong number of arguments (#{signature.size-1} for #{minargnum})\");
|
408
|
+
"
|
409
|
+
elsif signature.size-1 > maxargnum
|
410
|
+
"
|
411
|
+
rb_raise(rb_eArgError, \"wrong number of arguments (#{signature.size-1} for #{maxargnum})\");
|
412
|
+
"
|
413
|
+
else
|
414
|
+
|
415
|
+
default_block_tree = args_tree[1..-1].find{|subtree|
|
416
|
+
unless subtree.instance_of? Symbol
|
417
|
+
if subtree[0] == :block
|
418
|
+
next true
|
419
|
+
end
|
500
420
|
end
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
421
|
+
|
422
|
+
false
|
423
|
+
}
|
424
|
+
|
425
|
+
i = -1
|
426
|
+
|
427
|
+
normalargsnum = args_tree[1..-1].count{|subtree|
|
428
|
+
if subtree.instance_of? Symbol
|
429
|
+
unless subtree.to_s.match(/\*/) or subtree.to_s.match(/\&/)
|
430
|
+
next true
|
431
|
+
end
|
512
432
|
end
|
513
|
-
end
|
514
|
-
|
515
|
-
false
|
516
|
-
}
|
517
|
-
|
518
|
-
read_arguments_code = args_tree[1..-1].map { |arg_|
|
519
|
-
arg = arg_.to_s
|
520
|
-
i = i + 1
|
521
|
-
|
522
|
-
if i < normalargsnum
|
523
|
-
if i < signature.size-1
|
524
|
-
"plocals->#{arg} = argv[#{i}];\n"
|
525
|
-
else
|
526
433
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
434
|
+
false
|
435
|
+
}
|
436
|
+
|
437
|
+
read_arguments_code = args_tree[1..-1].map { |arg_|
|
438
|
+
arg = arg_.to_s
|
439
|
+
i = i + 1
|
440
|
+
|
441
|
+
if i < normalargsnum
|
442
|
+
if i < signature.size-1
|
443
|
+
"plocals->#{arg} = argv[#{i}];\n"
|
444
|
+
else
|
445
|
+
|
446
|
+
if default_block_tree
|
447
|
+
initialize_tree = default_block_tree[1..-1].find{|subtree| subtree[1] == arg_}
|
448
|
+
if initialize_tree
|
449
|
+
to_c(initialize_tree) + ";\n"
|
450
|
+
else
|
451
|
+
""
|
452
|
+
end
|
531
453
|
else
|
532
|
-
|
454
|
+
";\n"
|
533
455
|
end
|
534
|
-
else
|
535
|
-
";\n"
|
536
456
|
end
|
537
|
-
end
|
538
|
-
else
|
539
|
-
""
|
540
|
-
end
|
541
|
-
}.join("")
|
542
|
-
|
543
|
-
if splat_arg
|
544
|
-
if signature.size-1 < normalargsnum then
|
545
|
-
read_arguments_code << "
|
546
|
-
plocals->#{splat_arg.to_s.gsub("*","")} = rb_ary_new3(0);
|
547
|
-
"
|
548
457
|
else
|
549
|
-
|
550
|
-
plocals->#{splat_arg.to_s.gsub("*","")} = rb_ary_new4(
|
551
|
-
#{(signature.size-1) - (normalargsnum)}, argv+#{normalargsnum}
|
552
|
-
);
|
553
|
-
"
|
458
|
+
""
|
554
459
|
end
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
460
|
+
}.join("")
|
461
|
+
|
462
|
+
if splat_arg
|
463
|
+
if signature.size-1 < normalargsnum then
|
464
|
+
read_arguments_code << "
|
465
|
+
plocals->#{splat_arg.to_s.gsub("*","")} = rb_ary_new3(0);
|
466
|
+
"
|
467
|
+
else
|
468
|
+
read_arguments_code << "
|
469
|
+
plocals->#{splat_arg.to_s.gsub("*","")} = rb_ary_new4(
|
470
|
+
#{(signature.size-1) - (normalargsnum)}, argv+#{normalargsnum}
|
471
|
+
);
|
472
|
+
"
|
473
|
+
end
|
474
|
+
|
475
|
+
end
|
476
|
+
|
477
|
+
|
478
|
+
""
|
479
|
+
end
|
480
|
+
|
481
|
+
if block_argument
|
482
|
+
|
483
|
+
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))))
|
484
|
+
|
485
|
+
require "fastruby/sexp_extension"
|
486
|
+
|
487
|
+
read_arguments_code << "
|
488
|
+
if (pblock ? pblock->proc != Qnil : 0) {
|
489
|
+
plocals->#{block_argument.to_s.gsub("&","")} = pblock->proc;
|
490
|
+
} else {
|
491
|
+
plocals->#{block_argument.to_s.gsub("&","")} = #{to_c FastRuby::FastRubySexp.from_sexp(proc_reyield_block_tree)};
|
492
|
+
}
|
493
|
+
"
|
563
494
|
|
564
|
-
|
495
|
+
read_arguments_code << "
|
496
|
+
if (pblock) {
|
497
|
+
rb_ivar_set(plocals->#{block_argument.to_s.gsub("&","")},
|
498
|
+
#{intern_num "__block_address"}, PTR2NUM(pblock->block_function_address));
|
499
|
+
rb_ivar_set(plocals->#{block_argument.to_s.gsub("&","")},
|
500
|
+
#{intern_num "__block_param"}, PTR2NUM(pblock->block_function_param));
|
501
|
+
}
|
565
502
|
|
566
|
-
|
503
|
+
"
|
504
|
+
end
|
567
505
|
|
568
|
-
read_arguments_code << "
|
569
|
-
plocals->#{block_argument.to_s.gsub("&","")} = #{to_c FastRuby::FastRubySexp.from_sexp(proc_reyield_block_tree)};
|
570
|
-
"
|
571
506
|
end
|
572
507
|
|
573
|
-
|
508
|
+
require "fastruby/sexp_extension"
|
509
|
+
scope_mode = FastRuby::ScopeModeHelper.get_scope_mode(tree)
|
510
|
+
|
511
|
+
ret = "VALUE #{@alt_method_name || method_name}(#{options[:main] ? "VALUE self" : strargs}) {
|
574
512
|
#{validate_arguments_code}
|
575
513
|
|
576
514
|
#{@frame_struct} frame;
|
577
|
-
#{@frame_struct} *pframe;
|
515
|
+
#{@frame_struct} * volatile pframe;
|
578
516
|
|
579
|
-
frame.parent_frame = (void*)_parent_frame;
|
517
|
+
frame.parent_frame = #{options[:main] ? "0" : "(void*)_parent_frame"};
|
580
518
|
frame.return_value = Qnil;
|
581
519
|
frame.rescue = 0;
|
582
520
|
frame.targetted = 0;
|
583
|
-
frame.thread_data = ((typeof(pframe))_parent_frame)->thread_data;
|
521
|
+
frame.thread_data = #{options[:main] ? "0" : "((typeof(pframe))_parent_frame)->thread_data"};
|
584
522
|
if (frame.thread_data == 0) frame.thread_data = rb_current_thread_data();
|
585
523
|
|
586
524
|
int stack_chunk_instantiated = 0;
|
587
|
-
|
525
|
+
|
526
|
+
#{
|
527
|
+
if scope_mode == :dag
|
528
|
+
"
|
529
|
+
volatile VALUE rb_previous_stack_chunk = Qnil;
|
588
530
|
VALUE rb_stack_chunk = frame.thread_data->rb_stack_chunk;
|
589
|
-
struct STACKCHUNK* stack_chunk = 0;
|
531
|
+
struct STACKCHUNK* volatile stack_chunk = 0;
|
590
532
|
|
591
533
|
if (rb_stack_chunk != Qnil) {
|
592
534
|
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
@@ -605,43 +547,66 @@ module FastRuby
|
|
605
547
|
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
606
548
|
}
|
607
549
|
|
550
|
+
#{@locals_struct}* volatile plocals;
|
608
551
|
|
609
|
-
|
610
|
-
|
611
|
-
int previous_stack_position = stack_chunk_get_current_position(stack_chunk);
|
612
|
-
|
552
|
+
volatile int previous_stack_position = stack_chunk_get_current_position(stack_chunk);
|
613
553
|
plocals = (typeof(plocals))stack_chunk_alloc(stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
|
614
554
|
|
615
|
-
|
616
|
-
|
617
|
-
|
555
|
+
"
|
556
|
+
else
|
557
|
+
"
|
558
|
+
#{@locals_struct} locals;
|
559
|
+
typeof(locals) * volatile plocals = &locals;
|
560
|
+
"
|
561
|
+
end
|
562
|
+
}
|
563
|
+
|
564
|
+
plocals->parent_locals = (frame.thread_data->last_plocals);
|
565
|
+
void* volatile old_parent_locals = frame.thread_data->last_plocals;
|
566
|
+
|
567
|
+
#{
|
568
|
+
if scope_mode == :dag
|
569
|
+
"frame.thread_data->last_plocals = plocals;\n"
|
570
|
+
end
|
571
|
+
}
|
618
572
|
|
619
573
|
frame.plocals = plocals;
|
620
574
|
plocals->active = Qtrue;
|
621
575
|
plocals->targetted = Qfalse;
|
622
|
-
plocals->pframe =
|
623
|
-
plocals->call_frame =
|
576
|
+
plocals->pframe = (&frame);
|
577
|
+
plocals->call_frame = (0);
|
624
578
|
|
625
579
|
pframe = (void*)&frame;
|
626
580
|
|
627
|
-
#{@block_struct} *pblock;
|
628
|
-
VALUE last_expression = Qnil;
|
581
|
+
#{@block_struct} * volatile pblock;
|
582
|
+
volatile VALUE last_expression = Qnil;
|
629
583
|
|
630
584
|
int aux = setjmp(pframe->jmp);
|
631
585
|
if (aux != 0) {
|
632
586
|
plocals->active = Qfalse;
|
633
587
|
|
588
|
+
#{
|
589
|
+
if scope_mode == :dag
|
590
|
+
"
|
634
591
|
stack_chunk_set_current_position(stack_chunk, previous_stack_position);
|
635
592
|
|
636
593
|
if (stack_chunk_instantiated) {
|
637
594
|
rb_gc_unregister_address(&rb_stack_chunk);
|
638
595
|
frame.thread_data->rb_stack_chunk = rb_previous_stack_chunk;
|
639
596
|
}
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
597
|
+
"
|
598
|
+
end
|
599
|
+
}
|
600
|
+
#{
|
601
|
+
unless options[:main]
|
602
|
+
"
|
603
|
+
if (plocals->targetted == Qfalse || aux != FASTRUBY_TAG_RETURN) {
|
604
|
+
frame.thread_data->last_plocals = old_parent_locals;
|
605
|
+
|
606
|
+
longjmp(((typeof(pframe))_parent_frame)->jmp,aux);
|
607
|
+
}
|
608
|
+
"
|
609
|
+
end
|
645
610
|
}
|
646
611
|
|
647
612
|
frame.thread_data->last_plocals = old_parent_locals;
|
@@ -651,35 +616,47 @@ module FastRuby
|
|
651
616
|
|
652
617
|
plocals->self = self;
|
653
618
|
|
654
|
-
#{
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
619
|
+
#{
|
620
|
+
unless options[:main]
|
621
|
+
"
|
622
|
+
pblock = (void*)block;
|
623
|
+
if (pblock) {
|
624
|
+
plocals->block_function_address = pblock->block_function_address;
|
625
|
+
plocals->block_function_param = pblock->block_function_param;
|
626
|
+
} else {
|
627
|
+
plocals->block_function_address = (0);
|
628
|
+
plocals->block_function_param = 0;
|
629
|
+
}
|
630
|
+
"
|
631
|
+
end
|
663
632
|
}
|
664
633
|
|
665
|
-
|
634
|
+
#{read_arguments_code}
|
635
|
+
|
636
|
+
#{to_c impl_tree, "last_expression"};
|
637
|
+
|
638
|
+
local_return:
|
639
|
+
#{
|
640
|
+
if scope_mode == :dag
|
641
|
+
"
|
666
642
|
stack_chunk_set_current_position(stack_chunk, previous_stack_position);
|
667
643
|
|
668
644
|
if (stack_chunk_instantiated) {
|
669
645
|
rb_gc_unregister_address(&rb_stack_chunk);
|
670
646
|
frame.thread_data->rb_stack_chunk = rb_previous_stack_chunk;
|
671
647
|
}
|
672
|
-
|
648
|
+
"
|
649
|
+
end
|
650
|
+
}
|
673
651
|
plocals->active = Qfalse;
|
674
652
|
|
675
653
|
frame.thread_data->last_plocals = old_parent_locals;
|
676
654
|
|
677
|
-
return
|
655
|
+
return last_expression;
|
678
656
|
}"
|
679
657
|
|
680
658
|
add_main
|
681
659
|
extra_code << ret
|
682
|
-
end
|
683
660
|
|
684
661
|
"
|
685
662
|
static VALUE dummy_#{method_name}_#{alt_method_name}_#{rand(1000000000000000000000000000000000)}(VALUE a) {
|
@@ -698,14 +675,15 @@ module FastRuby
|
|
698
675
|
|
699
676
|
@locals = locals
|
700
677
|
@locals_struct = "struct {
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
678
|
+
int size;
|
679
|
+
void* call_frame;
|
680
|
+
void* parent_locals;
|
681
|
+
void* pframe;
|
682
|
+
void* block_function_address;
|
683
|
+
void* block_function_param;
|
707
684
|
VALUE active;
|
708
685
|
VALUE targetted;
|
686
|
+
VALUE return_value;
|
709
687
|
#{@locals.map{|l| "VALUE #{l};\n"}.join}
|
710
688
|
}"
|
711
689
|
|
@@ -753,9 +731,9 @@ module FastRuby
|
|
753
731
|
lvar_type = eval(args[2][1].to_s)
|
754
732
|
|
755
733
|
@infer_lvar_map[lvar_name] = lvar_type
|
756
|
-
return ""
|
734
|
+
return "Qnil"
|
757
735
|
elsif mname == :block_given?
|
758
|
-
return "
|
736
|
+
return "plocals->block_function_address == 0 ? Qfalse : Qtrue"
|
759
737
|
elsif mname == :inline_c
|
760
738
|
|
761
739
|
code = args[1][1]
|
@@ -806,12 +784,32 @@ module FastRuby
|
|
806
784
|
def inline_block(code, repass_var = nil, nolocals = false)
|
807
785
|
anonymous_function{ |name| "
|
808
786
|
static VALUE #{name}(VALUE param#{repass_var ? ",void* " + repass_var : "" }) {
|
809
|
-
#{@frame_struct} *pframe = (void*)param;
|
787
|
+
#{@frame_struct} * volatile pframe = (void*)param;
|
810
788
|
|
811
|
-
#{nolocals ? "" : "#{@locals_struct} *plocals = (void*)pframe->plocals;"}
|
812
|
-
VALUE last_expression = Qnil;
|
789
|
+
#{nolocals ? "" : "#{@locals_struct} * volatile plocals = (void*)pframe->plocals;"}
|
790
|
+
volatile VALUE last_expression = Qnil;
|
813
791
|
|
814
792
|
#{code}
|
793
|
+
return Qnil;
|
794
|
+
|
795
|
+
#{unless nolocals
|
796
|
+
"
|
797
|
+
local_return:
|
798
|
+
plocals->return_value = last_expression;
|
799
|
+
plocals->targetted = 1;
|
800
|
+
longjmp(pframe->jmp, FASTRUBY_TAG_RETURN);
|
801
|
+
return last_expression;
|
802
|
+
"
|
803
|
+
end
|
804
|
+
}
|
805
|
+
fastruby_local_redo:
|
806
|
+
longjmp(pframe->jmp,FASTRUBY_TAG_REDO);
|
807
|
+
return Qnil;
|
808
|
+
fastruby_local_next:
|
809
|
+
longjmp(pframe->jmp,FASTRUBY_TAG_NEXT);
|
810
|
+
return Qnil;
|
811
|
+
|
812
|
+
|
815
813
|
}
|
816
814
|
"
|
817
815
|
} + "((VALUE)pframe#{repass_var ? ", " + repass_var : "" })"
|
@@ -830,7 +828,7 @@ module FastRuby
|
|
830
828
|
|
831
829
|
#{@frame_struct} frame;
|
832
830
|
|
833
|
-
typeof(frame)* pframe;
|
831
|
+
typeof(frame)* volatile pframe;
|
834
832
|
|
835
833
|
#{if repass_var
|
836
834
|
"typeof(frame)* parent_frame = ((typeof(pframe))((void**)param)[0]);"
|
@@ -870,7 +868,9 @@ module FastRuby
|
|
870
868
|
"VALUE #{repass_var} = (VALUE)((void**)param)[1];"
|
871
869
|
end
|
872
870
|
}
|
873
|
-
|
871
|
+
volatile VALUE last_expression = Qnil;
|
872
|
+
#{inner_code};
|
873
|
+
return last_expression;
|
874
874
|
}
|
875
875
|
"
|
876
876
|
}
|
@@ -946,7 +946,9 @@ module FastRuby
|
|
946
946
|
result = #{rescue_code};
|
947
947
|
#{wrapper_code}
|
948
948
|
} else {
|
949
|
-
|
949
|
+
VALUE last_expression = Qnil;
|
950
|
+
#{inner_code};
|
951
|
+
return last_expression;
|
950
952
|
}
|
951
953
|
|
952
954
|
return result;
|
@@ -983,14 +985,22 @@ module FastRuby
|
|
983
985
|
elsif value.instance_of? Class
|
984
986
|
container_str = value.to_s.split("::")[0..-2].join("::")
|
985
987
|
|
986
|
-
|
987
|
-
#{name} = rb_define_class_under(
|
988
|
-
#{container_str == "" ? "rb_cObject" : literal_value(eval(container_str))}
|
989
|
-
,\"#{value.to_s.split("::").last}\"
|
990
|
-
,#{value.superclass == Object ? "rb_cObject" : literal_value(value.superclass)});
|
988
|
+
str_class_name = value.to_s.split("::").last
|
991
989
|
|
992
|
-
|
993
|
-
|
990
|
+
if (str_class_name == "Object")
|
991
|
+
init_extra << "
|
992
|
+
#{name} = rb_cObject;
|
993
|
+
"
|
994
|
+
else
|
995
|
+
init_extra << "
|
996
|
+
#{name} = rb_define_class_under(
|
997
|
+
#{container_str == "" ? "rb_cObject" : literal_value(eval(container_str))}
|
998
|
+
,\"#{str_class_name}\"
|
999
|
+
,#{value.superclass == Object ? "rb_cObject" : literal_value(value.superclass)});
|
1000
|
+
|
1001
|
+
rb_funcall(#{name},#{intern_num :gc_register_object},0);
|
1002
|
+
"
|
1003
|
+
end
|
994
1004
|
elsif value.instance_of? Array
|
995
1005
|
init_extra << "
|
996
1006
|
#{name} = rb_ary_new3(#{value.size}, #{value.map{|x| literal_value x}.join(",")} );
|
@@ -1032,7 +1042,7 @@ module FastRuby
|
|
1032
1042
|
cfunc_address_name = self.add_global_name("void**", 0);
|
1033
1043
|
cfunc_real_address_name = self.add_global_name("void*", 0);
|
1034
1044
|
tree_pointer_name = self.add_global_name("VALUE*", 0);
|
1035
|
-
args_tree = call_tree[3]
|
1045
|
+
args_tree = call_tree[3].reject{|st| st.respond_to?(:node_type) ? st[0] == :block_pass : false}
|
1036
1046
|
method_tree = nil
|
1037
1047
|
|
1038
1048
|
begin
|
@@ -1068,7 +1078,7 @@ module FastRuby
|
|
1068
1078
|
VALUE method_arguments[#{args_tree.size}] = {#{toprocstrargs}};
|
1069
1079
|
|
1070
1080
|
return #{
|
1071
|
-
protected_block "rb_funcall(((VALUE*)method_arguments)[0], #{intern_num mname.to_sym}, #{args_tree.size-1}#{inprocstrargs});", false, "method_arguments"
|
1081
|
+
protected_block "last_expression = rb_funcall(((VALUE*)method_arguments)[0], #{intern_num mname.to_sym}, #{args_tree.size-1}#{inprocstrargs});", false, "method_arguments"
|
1072
1082
|
};
|
1073
1083
|
}
|
1074
1084
|
"
|
@@ -1078,7 +1088,7 @@ module FastRuby
|
|
1078
1088
|
static VALUE #{funcname}(VALUE self,void* block,void* frame#{strargs_signature}){
|
1079
1089
|
|
1080
1090
|
#{@frame_struct}* pframe = frame;
|
1081
|
-
VALUE method_arguments[#{args_tree.size}] = {#{toprocstrargs}};
|
1091
|
+
VALUE method_arguments[#{args_tree.size+1}] = {#{toprocstrargs},(VALUE)block};
|
1082
1092
|
|
1083
1093
|
void* fptr = 0;
|
1084
1094
|
|
@@ -1097,12 +1107,12 @@ module FastRuby
|
|
1097
1107
|
fptr = *#{address_name};
|
1098
1108
|
|
1099
1109
|
#{
|
1100
|
-
if args_tree.size < 25
|
1110
|
+
if args_tree.size < 25
|
1101
1111
|
"
|
1102
1112
|
if (fptr == 0) {
|
1103
1113
|
fptr = *#{cfunc_address_name};
|
1104
1114
|
if (fptr != 0) {
|
1105
|
-
VALUE params[2] = {self,
|
1115
|
+
VALUE params[2] = {self,PTR2NUM(#{args_tree.size-1})};
|
1106
1116
|
return ( (VALUE(*)(#{value_cast})) (fptr) )((VALUE)params,(VALUE)block,(VALUE)frame#{inprocstrargs});
|
1107
1117
|
}
|
1108
1118
|
}
|
@@ -1111,9 +1121,64 @@ module FastRuby
|
|
1111
1121
|
}
|
1112
1122
|
|
1113
1123
|
if (fptr == 0) {
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1124
|
+
if (block==0) {
|
1125
|
+
return #{
|
1126
|
+
protected_block "last_expression = rb_funcall(((VALUE*)method_arguments)[0], #{intern_num mname.to_sym}, #{args_tree.size-1}#{inprocstrargs});", false, "method_arguments"
|
1127
|
+
};
|
1128
|
+
|
1129
|
+
} else {
|
1130
|
+
return #{
|
1131
|
+
protected_block "
|
1132
|
+
#{@block_struct} *pblock;
|
1133
|
+
pblock = (typeof(pblock))( ((VALUE*)method_arguments)[#{args_tree.size}] );
|
1134
|
+
last_expression = rb_iterate(
|
1135
|
+
#{anonymous_function{|name|
|
1136
|
+
"
|
1137
|
+
static VALUE #{name} (VALUE data) {
|
1138
|
+
VALUE* method_arguments = (VALUE*)data;
|
1139
|
+
return rb_funcall(
|
1140
|
+
((VALUE*)method_arguments)[0],
|
1141
|
+
#{intern_num mname.to_sym},
|
1142
|
+
#{args_tree.size-1}#{inprocstrargs});
|
1143
|
+
}
|
1144
|
+
"
|
1145
|
+
}},
|
1146
|
+
(VALUE)method_arguments,
|
1147
|
+
|
1148
|
+
#{anonymous_function{|name|
|
1149
|
+
"
|
1150
|
+
static VALUE #{name} (VALUE arg_, VALUE param, int argc, VALUE* argv) {
|
1151
|
+
|
1152
|
+
VALUE arg;
|
1153
|
+
#{
|
1154
|
+
# TODO: access directly to argc and argv for optimal execution
|
1155
|
+
if RUBY_VERSION =~ /^1\.9/
|
1156
|
+
"
|
1157
|
+
if (TYPE(arg_) == T_ARRAY) {
|
1158
|
+
if (_RARRAY_LEN(arg_) <= 1) {
|
1159
|
+
arg = rb_ary_new4(argc,argv);
|
1160
|
+
} else {
|
1161
|
+
arg = arg_;
|
1162
|
+
}
|
1163
|
+
} else {
|
1164
|
+
arg = rb_ary_new4(argc,argv);
|
1165
|
+
}
|
1166
|
+
"
|
1167
|
+
else
|
1168
|
+
"arg = arg_;"
|
1169
|
+
end
|
1170
|
+
}
|
1171
|
+
|
1172
|
+
return rb_proc_call(param, arg);
|
1173
|
+
}
|
1174
|
+
"
|
1175
|
+
}},
|
1176
|
+
pblock->proc
|
1177
|
+
);
|
1178
|
+
", false, "method_arguments"
|
1179
|
+
};
|
1180
|
+
}
|
1181
|
+
|
1117
1182
|
} else {
|
1118
1183
|
return ( (VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*)) (fptr) )(self,(VALUE)block,(VALUE)frame,#{args_tree.size-1},method_arguments+1);
|
1119
1184
|
}
|
@@ -1139,7 +1204,7 @@ module FastRuby
|
|
1139
1204
|
static VALUE #{funcname}(VALUE* params, void* block,void* frame, #{strargs_signature}){
|
1140
1205
|
VALUE self = params[0];
|
1141
1206
|
VALUE method_arguments[26] = {#{toprocstrargs}};
|
1142
|
-
return ( (VALUE(*)(int, VALUE*, VALUE)) (#{cfunc_real_address_name}) )(
|
1207
|
+
return ( (VALUE(*)(int, VALUE*, VALUE)) (#{cfunc_real_address_name}) )(NUM2ULONG(params[1]),method_arguments,self);
|
1143
1208
|
}
|
1144
1209
|
"
|
1145
1210
|
}
|
@@ -1147,7 +1212,7 @@ module FastRuby
|
|
1147
1212
|
cfunc_wrapper_2 = anonymous_function{ |funcname| "
|
1148
1213
|
static VALUE #{funcname}(VALUE* params, void* block,void* frame, #{strargs_signature}){
|
1149
1214
|
VALUE self = params[0];
|
1150
|
-
VALUE args = rb_ary_new3(
|
1215
|
+
VALUE args = rb_ary_new3(NUM2ULONG(params[1]),#{toprocstrargs});
|
1151
1216
|
return ( (VALUE(*)(VALUE,VALUE)) (#{cfunc_real_address_name}) )(self,args);
|
1152
1217
|
}
|
1153
1218
|
"
|
@@ -1171,7 +1236,7 @@ module FastRuby
|
|
1171
1236
|
|
1172
1237
|
|
1173
1238
|
VALUE fastruby_method = rb_funcall(recvtype, #{intern_num :fastruby_method}, 1, mname);
|
1174
|
-
#{tree_pointer_name} = (VALUE*)
|
1239
|
+
#{tree_pointer_name} = (VALUE*)NUM2PTR(fastruby_method_tree_pointer(fastruby_method));
|
1175
1240
|
|
1176
1241
|
ID id;
|
1177
1242
|
ID default_id = rb_intern(\"default\");
|
@@ -1182,14 +1247,14 @@ module FastRuby
|
|
1182
1247
|
rb_method_hash = rb_funcall(recvtype, #{intern_num :method_hash},1,mname);
|
1183
1248
|
|
1184
1249
|
if (rb_method_hash != Qnil) {
|
1185
|
-
VALUE tmp = rb_hash_aref(rb_method_hash,
|
1250
|
+
VALUE tmp = rb_hash_aref(rb_method_hash, PTR2NUM(id));
|
1186
1251
|
if (tmp != Qnil) {
|
1187
|
-
address = (void*)
|
1252
|
+
address = (void*)NUM2PTR(tmp);
|
1188
1253
|
}
|
1189
1254
|
|
1190
|
-
tmp = rb_hash_aref(rb_method_hash,
|
1255
|
+
tmp = rb_hash_aref(rb_method_hash, PTR2NUM(default_id));
|
1191
1256
|
if (tmp != Qnil) {
|
1192
|
-
default_address = (void*)
|
1257
|
+
default_address = (void*)NUM2PTR(tmp);
|
1193
1258
|
}
|
1194
1259
|
}
|
1195
1260
|
|
@@ -1217,6 +1282,25 @@ module FastRuby
|
|
1217
1282
|
}
|
1218
1283
|
}
|
1219
1284
|
#endif
|
1285
|
+
#ifdef RUBY_1_9
|
1286
|
+
rb_method_entry_t* me = rb_method_entry(recvtype,#{intern_num mname});
|
1287
|
+
if (me != 0) {
|
1288
|
+
rb_method_definition_t* def = me->def;
|
1289
|
+
|
1290
|
+
if (def->type == VM_METHOD_TYPE_CFUNC) {
|
1291
|
+
if (def->body.cfunc.argc == #{args_tree.size-1}) {
|
1292
|
+
*default_address = #{cfunc_wrapper};
|
1293
|
+
#{cfunc_real_address_name} = (void*)def->body.cfunc.func;
|
1294
|
+
} else if (def->body.cfunc.argc == -1) {
|
1295
|
+
*default_address = #{cfunc_wrapper_1};
|
1296
|
+
#{cfunc_real_address_name} = (void*)def->body.cfunc.func;
|
1297
|
+
} else if (def->body.cfunc.argc == -2) {
|
1298
|
+
*default_address = #{cfunc_wrapper_2};
|
1299
|
+
#{cfunc_real_address_name} = (void*)def->body.cfunc.func;
|
1300
|
+
}
|
1301
|
+
}
|
1302
|
+
}
|
1303
|
+
#endif
|
1220
1304
|
|
1221
1305
|
if (recvtype != Qnil) {
|
1222
1306
|
rb_funcall(
|
@@ -1224,8 +1308,8 @@ module FastRuby
|
|
1224
1308
|
#{intern_num :register_method_value},
|
1225
1309
|
3,
|
1226
1310
|
#{literal_value mname},
|
1227
|
-
|
1228
|
-
|
1311
|
+
PTR2NUM(default_id),
|
1312
|
+
PTR2NUM(default_address)
|
1229
1313
|
);
|
1230
1314
|
}
|
1231
1315
|
}
|
@@ -1239,8 +1323,8 @@ module FastRuby
|
|
1239
1323
|
#{intern_num :register_method_value},
|
1240
1324
|
3,
|
1241
1325
|
#{literal_value mname},
|
1242
|
-
|
1243
|
-
|
1326
|
+
PTR2NUM(id),
|
1327
|
+
PTR2NUM(address)
|
1244
1328
|
);
|
1245
1329
|
}
|
1246
1330
|
|
@@ -1301,9 +1385,12 @@ module FastRuby
|
|
1301
1385
|
|
1302
1386
|
anonymous_function{ |name| "
|
1303
1387
|
static VALUE #{name}(VALUE param) {
|
1304
|
-
VALUE last_expression = Qnil;
|
1305
|
-
#{@frame_struct} frame
|
1306
|
-
|
1388
|
+
volatile VALUE last_expression = Qnil;
|
1389
|
+
#{@frame_struct} frame;
|
1390
|
+
|
1391
|
+
typeof(frame)* volatile pframe;
|
1392
|
+
typeof(frame)* volatile parent_frame;
|
1393
|
+
#{@locals_struct}* volatile plocals;
|
1307
1394
|
|
1308
1395
|
parent_frame = (void*)param;
|
1309
1396
|
|
@@ -1337,7 +1424,7 @@ module FastRuby
|
|
1337
1424
|
#{code};
|
1338
1425
|
|
1339
1426
|
// restore previous frame
|
1340
|
-
typeof(pframe) original_frame = pframe;
|
1427
|
+
volatile typeof(pframe) original_frame = pframe;
|
1341
1428
|
pframe = parent_frame;
|
1342
1429
|
#{not_jmp_code};
|
1343
1430
|
|