diff options
author | ttate <ttate@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-02-04 13:35:37 +0000 |
---|---|---|
committer | ttate <ttate@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2005-02-04 13:35:37 +0000 |
commit | bda37095ca990568069aaf07dc6b3fa8ceebc327 (patch) | |
tree | 15043d94698579d6ab19544542479a42385cd1b5 /ext/dl/mkcallback.rb | |
parent | 4ae9132605dc7b0297bcda408ca7a2ad7de39d2f (diff) | |
download | ruby-bda37095ca990568069aaf07dc6b3fa8ceebc327.tar.gz |
added new files.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7883 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/dl/mkcallback.rb')
-rw-r--r-- | ext/dl/mkcallback.rb | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/ext/dl/mkcallback.rb b/ext/dl/mkcallback.rb new file mode 100644 index 0000000000..0b071d4caa --- /dev/null +++ b/ext/dl/mkcallback.rb @@ -0,0 +1,190 @@ +$out ||= $stdout +$dl_h = ARGV[0] || "dl.h" + +# import DLSTACK_SIZE, DLSTACK_ARGS and so on +File.open($dl_h){|f| + pre = "" + f.each{|line| + line.chop! + if( line[-1] == ?\ ) + line.chop! + line.concat(" ") + pre += line + next + end + if( pre.size > 0 ) + line = pre + line + pre = "" + end + case line + when /#define\s+DLSTACK_SIZE\s+\(?(\d+)\)?/ + DLSTACK_SIZE = $1.to_i + when /#define\s+DLSTACK_ARGS\s+(.+)/ + DLSTACK_ARGS = $1.to_i + when /#define\s+DLTYPE_([A-Z_]+)\s+\(?(\d+)\)?/ + eval("#{$1} = #{$2}") + when /#define\s+MAX_DLTYPE\s+\(?(\d+)\)?/ + MAX_DLTYPE = $1.to_i + when /#define\s+MAX_CALLBACK\s+\(?(\d+)\)?/ + MAX_CALLBACK = $1.to_i + end + } +} + +CDECL = "cdecl" +STDCALL = "stdcall" + +CALLTYPES = [CDECL, STDCALL] + +DLTYPE = { + VOID => { + :name => 'void', + :type => 'void', + :conv => nil, + }, + CHAR => { + :name => 'char', + :type => 'char', + :conv => 'NUM2CHR(%s)' + }, + SHORT => { + :name => 'short', + :type => 'short', + :conv => 'NUM2INT(%s)', + }, + INT => { + :name => 'int', + :type => 'int', + :conv => 'NUM2INT(%s)', + }, + LONG => { + :name => 'long', + :type => 'long', + :conv => 'NUM2LONG(%s)', + }, + LONG_LONG => { + :name => 'long_long', + :type => 'LONG_LONG', + :conv => 'NUM2LL(%s)', + }, + FLOAT => { + :name => 'float', + :type => 'float', + :conv => 'RFLOAT(%s)->value', + }, + DOUBLE => { + :name => 'double', + :type => 'double', + :conv => 'RFLOAT(%s)->value', + }, + VOIDP => { + :name => 'ptr', + :type => 'void *', + :conv => 'NUM2PTR(%s)', + }, +} + + +def func_name(ty, argc, n, calltype) + "rb_dl_callback_#{DLTYPE[ty][:name]}_#{argc}_#{n}_#{calltype}" +end + +$out << (<<EOS) +VALUE rb_DLCdeclCallbackAddrs, rb_DLCdeclCallbackProcs; +VALUE rb_DLStdcallCallbackAddrs, rb_DLStdcallCallbackProcs; +/*static void *cdecl_callbacks[MAX_DLTYPE][MAX_CALLBACK];*/ +/*static void *stdcall_callbacks[MAX_DLTYPE][MAX_CALLBACK];*/ +static ID cb_call; +EOS + +for calltype in CALLTYPES + case calltype + when CDECL + proc_entry = "rb_DLCdeclCallbackProcs" + when STDCALL + proc_entry = "rb_DLStdcallCallbackProcs" + else + raise "unknown calltype: #{calltype}" + end + for ty in 0..(MAX_DLTYPE-1) + for argc in 0..(DLSTACK_SIZE-1) + for n in 0..(MAX_CALLBACK-1) + $out << (<<-EOS) + +PRE_DECL_#{calltype.upcase} static #{DLTYPE[ty][:type]} +#{func_name(ty,argc,n,calltype)}(#{(0...argc).collect{|i| "DLSTACK_TYPE stack" + i.to_s}.join(", ")}) POST_DECL_#{calltype.upcase} +{ + VALUE args[#{argc}]; + VALUE ret, cb; +#{ + (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, cb_call, #{argc}, args); + return #{DLTYPE[ty][:conv] ? DLTYPE[ty][:conv] % "ret" : ""}; +} + + EOS + end + end + end +end + +$out << (<<EOS) +static void +rb_dl_init_callbacks() +{ + cb_call = rb_intern("call"); + + rb_DLCdeclCallbackProcs = rb_ary_new(); + rb_DLCdeclCallbackAddrs = rb_ary_new(); + rb_DLStdcallCallbackProcs = rb_ary_new(); + rb_DLStdcallCallbackAddrs = rb_ary_new(); + rb_define_const(rb_mDL, "CdeclCallbackProcs", rb_DLCdeclCallbackProcs); + rb_define_const(rb_mDL, "CdeclCallbackAddrs", rb_DLCdeclCallbackAddrs); + rb_define_const(rb_mDL, "StdcallCallbackProcs", rb_DLStdcallCallbackProcs); + rb_define_const(rb_mDL, "StdcallCallbackAddrs", rb_DLStdcallCallbackAddrs); +#{ + (0...MAX_DLTYPE).collect{|ty| + sprintf(" rb_ary_push(rb_DLCdeclCallbackProcs, rb_ary_new3(%d,%s));", + MAX_CALLBACK * DLSTACK_SIZE, + (0...MAX_CALLBACK).collect{ + (0...DLSTACK_SIZE).collect{ "Qnil" }.join(",") + }.join(",")) + }.join("\n") +} +#{ + (0...MAX_DLTYPE).collect{|ty| + sprintf(" rb_ary_push(rb_DLCdeclCallbackAddrs, 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,CDECL) + }.join(",") + }.join(",")) + }.join("\n") +} +#{ + (0...MAX_DLTYPE).collect{|ty| + sprintf(" rb_ary_push(rb_DLStdcallCallbackProcs, rb_ary_new3(%d,%s));", + MAX_CALLBACK * DLSTACK_SIZE, + (0...MAX_CALLBACK).collect{ + (0...DLSTACK_SIZE).collect{ "Qnil" }.join(",") + }.join(",")) + }.join("\n") +} +#{ + (0...MAX_DLTYPE).collect{|ty| + sprintf(" rb_ary_push(rb_DLStdcallCallbackAddrs, 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,STDCALL) + }.join(",") + }.join(",")) + }.join("\n") +} +} +EOS |