BasicObject
# File dl/mkcallback.rb, line 101
def foreach_proc_entry
for calltype in CALLTYPES
case calltype
when CDECL
proc_entry = "rb_DLCdeclCallbackProcs"
when STDCALL
proc_entry = "rb_DLStdcallCallbackProcs"
else
raise "unknown calltype: #{calltype}"
end
yield calltype, proc_entry
end
end
# File dl/mkcallback.rb, line 89
def func_name(ty, argc, n, calltype)
"rb_dl_callback_#{DLTYPE[ty][:name]}_#{argc}_#{n}_#{calltype}"
end
# File dl/mkcallback.rb, line 153
def gen_callback_file(ty)
filename = "callback-#{ty}.c"
initname = "rb_dl_init_callbacks_#{ty}"
open(filename, "w") {|f|
f.puts <<-EOS
#include "dl.h"
extern VALUE rb_DLCdeclCallbackAddrs, rb_DLCdeclCallbackProcs;
#ifdef FUNC_STDCALL
extern VALUE rb_DLStdcallCallbackAddrs, rb_DLStdcallCallbackProcs;
#endif
extern ID rb_dl_cb_call;
EOS
yield f
f.puts <<-EOS
void
#{initname}()
{
#{gen_push_proc_ary(ty, "rb_DLCdeclCallbackProcs")}
#{gen_push_addr_ary(ty, "rb_DLCdeclCallbackAddrs", CDECL)}
#ifdef FUNC_STDCALL
#{gen_push_proc_ary(ty, "rb_DLStdcallCallbackProcs")}
#{gen_push_addr_ary(ty, "rb_DLStdcallCallbackAddrs", STDCALL)}
#endif
}
EOS
}
initname
end
# File dl/mkcallback.rb, line 143
def gen_push_addr_ary(ty, aryname, calltype)
sprintf(" rb_ary_push(#{aryname}, rb_ary_new3(%d,%s));",
MAX_CALLBACK * DLSTACK_SIZE,
(0...MAX_CALLBACK).collect{|i|
(0...DLSTACK_SIZE).collect{|argc|
"PTR2NUM(%s)" % func_name(ty,argc,i,calltype)
}.join(",")
}.join(","))
end
# File dl/mkcallback.rb, line 135
def gen_push_proc_ary(ty, aryname)
sprintf(" rb_ary_push(#{aryname}, rb_ary_new3(%d,%s));",
MAX_CALLBACK * DLSTACK_SIZE,
(0...MAX_CALLBACK).collect{
(0...DLSTACK_SIZE).collect{ "Qnil" }.join(",")
}.join(","))
end
# File dl/mkcallback.rb, line 115
def gencallback(ty, calltype, proc_entry, argc, n)
<<-EOS
#{calltype == STDCALL ? "\n#ifdef FUNC_STDCALL" : ""}
static #{DLTYPE[ty][:type]}
FUNC_#{calltype.upcase}(#{func_name(ty,argc,n,calltype)})(#{(0...argc).collect{|i| "DLSTACK_TYPE stack" + i.to_s}.join(", ")})
{
VALUE ret, cb#{argc > 0 ? ", args[#{argc}]" : ""};
#{
(0...argc).collect{|i|
" args[%d] = LONG2NUM(stack%d);" % [i,i]
}.join("\n")
}
cb = rb_ary_entry(rb_ary_entry(#{proc_entry}, #{ty}), #{(n * DLSTACK_SIZE) + argc});
ret = rb_funcall2(cb, rb_dl_cb_call, #{argc}, #{argc > 0 ? 'args' : 'NULL'});
return #{DLTYPE[ty][:conv] ? DLTYPE[ty][:conv] % "ret" : ""};
}
#{calltype == STDCALL ? "#endif\n" : ""}
EOS
end