fastruby 0.0.16 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +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
|
|