ruby-changes:11122
From: nobu <ko1@a...>
Date: Tue, 3 Mar 2009 15:40:51 +0900 (JST)
Subject: [ruby-changes:11122] Ruby:r22722 (trunk): * ext/dl/dl.c (rb_dl_init_callbacks): autoloads callbacks.
nobu 2009-03-03 15:40:40 +0900 (Tue, 03 Mar 2009) New Revision: 22722 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=22722 Log: * ext/dl/dl.c (rb_dl_init_callbacks): autoloads callbacks. * ext/dl/callback: split from dl. Added directories: trunk/ext/dl/callback/ Added files: trunk/ext/dl/callback/depend trunk/ext/dl/callback/extconf.rb trunk/ext/dl/callback/mkcallback.rb Removed files: trunk/ext/dl/mkcallback.rb Modified files: trunk/ChangeLog trunk/ext/dl/depend trunk/ext/dl/dl.c trunk/ext/dl/extconf.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 22721) +++ ChangeLog (revision 22722) @@ -1,5 +1,9 @@ -Tue Mar 3 15:09:12 2009 Nobuyoshi Nakada <nobu@r...> +Tue Mar 3 15:40:38 2009 Nobuyoshi Nakada <nobu@r...> + * ext/dl/dl.c (rb_dl_init_callbacks): autoloads callbacks. + + * ext/dl/callback: split from dl. + * ext/dl/lib/dl/cparser.rb (DL::CParser::parse_signature): fixed variable name. Index: ext/dl/mkcallback.rb =================================================================== --- ext/dl/mkcallback.rb (revision 22721) +++ ext/dl/mkcallback.rb (revision 22722) @@ -1,222 +0,0 @@ -$out = open("callback.h", "w") - -$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_VALUE(%s)', - }, - DOUBLE => { - :name => 'double', - :type => 'double', - :conv => 'RFLOAT_VALUE(%s)', - }, - 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];*/ -ID rb_dl_cb_call; -EOS - -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 - -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 - -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 - -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 - -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 - -for ty in 0...MAX_DLTYPE - initname = gen_callback_file(ty) {|f| - foreach_proc_entry do |calltype, proc_entry| - for argc in 0...DLSTACK_SIZE - for n in 0...MAX_CALLBACK - f << gencallback(ty, calltype, proc_entry, argc, n) - end - end - end - } - $out << "void #{initname}();\n" -end - -$out << (<<EOS) -static void -rb_dl_init_callbacks() -{ - VALUE tmp; - rb_dl_cb_call = rb_intern("call"); - - tmp = rb_DLCdeclCallbackProcs = rb_ary_new(); - rb_define_const(rb_mDL, "CdeclCallbackProcs", tmp); - - tmp = rb_DLCdeclCallbackAddrs = rb_ary_new(); - rb_define_const(rb_mDL, "CdeclCallbackAddrs", tmp); - -#ifdef FUNC_STDCALL - tmp = rb_DLStdcallCallbackProcs = rb_ary_new(); - rb_define_const(rb_mDL, "StdcallCallbackProcs", tmp); - - tmp = rb_DLStdcallCallbackAddrs = rb_ary_new(); - rb_define_const(rb_mDL, "StdcallCallbackAddrs", tmp); -#endif - -#{ - (0...MAX_DLTYPE).collect{|ty| - " rb_dl_init_callbacks_#{ty}();\n" - }.join("") -} -} -EOS Index: ext/dl/depend =================================================================== --- ext/dl/depend (revision 22721) +++ ext/dl/depend (revision 22722) @@ -4,21 +4,4 @@ handle.o: handle.c dl.h $(hdrdir)/ruby.h -dl.o: dl.c dl.h callback.h $(hdrdir)/ruby.h $(hdrdir)/io.h - -callback-0.o: callback-0.c $(hdrdir)/ruby.h -callback-1.o: callback-1.c $(hdrdir)/ruby.h -callback-2.o: callback-2.c $(hdrdir)/ruby.h -callback-3.o: callback-3.c $(hdrdir)/ruby.h -callback-4.o: callback-4.c $(hdrdir)/ruby.h -callback-5.o: callback-5.c $(hdrdir)/ruby.h -callback-6.o: callback-6.c $(hdrdir)/ruby.h -callback-7.o: callback-7.c $(hdrdir)/ruby.h -callback-8.o: callback-8.c $(hdrdir)/ruby.h - -callback-0.c callback-1.c callback-2.c \ -callback-3.c callback-4.c callback-5.c \ -callback-6.c callback-7.c callback-8.c \ -callback.h: $(srcdir)/mkcallback.rb dl.h - @echo "generating callback.h" - @$(RUBY) $(srcdir)/mkcallback.rb $(srcdir)/dl.h +dl.o: dl.c dl.h $(hdrdir)/ruby.h $(hdrdir)/io.h Index: ext/dl/dl.c =================================================================== --- ext/dl/dl.c (revision 22721) +++ ext/dl/dl.c (revision 22722) @@ -60,8 +60,19 @@ return PTR2NUM((void*)val); } -#include "callback.h" +static void +rb_dl_init_callbacks(VALUE dl) +{ + static const char cb[] = "dl/callback.so"; + rb_autoload(dl, rb_intern_const("CdeclCallbackAddrs"), cb); + rb_autoload(dl, rb_intern_const("CdeclCallbackProcs"), cb); +#ifdef FUNC_STDCALL + rb_autoload(dl, rb_intern_const("StdcallCallbackAddrs"), cb); + rb_autoload(dl, rb_intern_const("StdcallCallbackProcs"), cb); +#endif +} + void Init_dl() { @@ -69,8 +80,8 @@ void Init_dlcfunc(); void Init_dlptr(); - rbdl_id_cdecl = rb_intern("cdecl"); - rbdl_id_stdcall = rb_intern("stdcall"); + rbdl_id_cdecl = rb_intern_const("cdecl"); + rbdl_id_stdcall = rb_intern_const("stdcall"); rb_mDL = rb_define_module("DL"); rb_eDLError = rb_define_class_under(rb_mDL, "DLError", rb_eStandardError); @@ -79,7 +90,7 @@ rb_define_const(rb_mDL, "MAX_CALLBACK", INT2NUM(MAX_CALLBACK)); rb_define_const(rb_mDL, "DLSTACK_SIZE", INT2NUM(DLSTACK_SIZE)); - rb_dl_init_callbacks(); + rb_dl_init_callbacks(rb_mDL); rb_define_const(rb_mDL, "RTLD_GLOBAL", INT2NUM(RTLD_GLOBAL)); rb_define_const(rb_mDL, "RTLD_LAZY", INT2NUM(RTLD_LAZY)); Index: ext/dl/extconf.rb =================================================================== --- ext/dl/extconf.rb (revision 22721) +++ ext/dl/extconf.rb (revision 22722) @@ -4,16 +4,10 @@ $CFLAGS << " -fno-defer-pop -fno-omit-frame-pointer" end -CALLBACKS = (0..8).map{|i| "callback-#{i}"} -CALLBACK_SRCS = CALLBACKS.map{|basename| "#{basename}.c"} -CALLBACK_OBJS = CALLBACKS.map{|basename| "#{basename}.o"} - $INSTALLFILES = [ ["dl.h", "$(HDRDIR)"], ] -$distcleanfiles += [ "callback.h", *CALLBACK_SRCS ] - check = true if( have_header("dlfcn.h") ) have_library("dl") @@ -29,8 +23,6 @@ check = false end -$objs = %w[ cfunc.o dl.o cptr.o handle.o ] + CALLBACK_OBJS - if check $defs << %[-DRUBY_VERSION=\\"#{RUBY_VERSION}\\"] create_makefile("dl") Index: ext/dl/callback/depend =================================================================== --- ext/dl/callback/depend (revision 0) +++ ext/dl/callback/depend (revision 22722) @@ -0,0 +1,18 @@ +callback.o: $(hdrdir)/ruby.h $(hdrdir)/io.h + +callback-0.o: callback-0.c $(hdrdir)/ruby.h +callback-1.o: callback-1.c $(hdrdir)/ruby.h +callback-2.o: callback-2.c $(hdrdir)/ruby.h +callback-3.o: callback-3.c $(hdrdir)/ruby.h +callback-4.o: callback-4.c $(hdrdir)/ruby.h +callback-5.o: callback-5.c $(hdrdir)/ruby.h +callback-6.o: callback-6.c $(hdrdir)/ruby.h +callback-7.o: callback-7.c $(hdrdir)/ruby.h +callback-8.o: callback-8.c $(hdrdir)/ruby.h + +callback-0.c callback-1.c callback-2.c \ +callback-3.c callback-4.c callback-5.c \ +callback-6.c callback-7.c callback-8.c \ +callback.c: $(srcdir)/mkcallback.rb $(srcdir)/../dl.h + @echo "generating callback.h" + @$(RUBY) $(srcdir)/mkcallback.rb $(srcdir)/../dl.h Property changes on: ext/dl/callback/depend ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + LF Index: ext/dl/callback/mkcallback.rb =================================================================== --- ext/dl/callback/mkcallback.rb (revision 0) +++ ext/dl/callback/mkcallback.rb (revision 22722) @@ -0,0 +1,231 @@ +$out = open("callback.c", "w") + +$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_VALUE(%s)', + }, + DOUBLE => { + :name => 'double', + :type => 'double', + :conv => 'RFLOAT_VALUE(%s)', + }, + 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) +#include "ruby.h" + +VALUE rb_DLCdeclCallbackAddrs, rb_DLCdeclCallbackProcs; +#ifdef FUNC_STDCALL +VALUE rb_DLStdcallCallbackAddrs, rb_DLStdcallCallbackProcs; +#endif +/*static void *cdecl_callbacks[MAX_DLTYPE][MAX_CALLBACK];*/ +#ifdef FUNC_STDCALL +/*static void *stdcall_callbacks[MAX_DLTYPE][MAX_CALLBACK];*/ +#endif +ID rb_dl_cb_call; +EOS + +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 + +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 + +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 + +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 + +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 + +for ty in 0...MAX_DLTYPE + initname = gen_callback_file(ty) {|f| + foreach_proc_entry do |calltype, proc_entry| + for argc in 0...DLSTACK_SIZE + for n in 0...MAX_CALLBACK + f << gencallback(ty, calltype, proc_entry, argc, n) + end + end + end + } + $out << "void #{initname}();\n" +end + +$out << (<<EOS) +void +Init_callback(void) +{ + VALUE tmp; + VALUE rb_mDL = rb_path2class("DL"); + + rb_dl_cb_call = rb_intern("call"); + + tmp = rb_DLCdeclCallbackProcs = rb_ary_new(); + rb_define_const(rb_mDL, "CdeclCallbackProcs", tmp); + + tmp = rb_DLCdeclCallbackAddrs = rb_ary_new(); + rb_define_const(rb_mDL, "CdeclCallbackAddrs", tmp); + +#ifdef FUNC_STDCALL + tmp = rb_DLStdcallCallbackProcs = rb_ary_new(); + rb_define_const(rb_mDL, "StdcallCallbackProcs", tmp); + + tmp = rb_DLStdcallCallbackAddrs = rb_ary_new(); + rb_define_const(rb_mDL, "StdcallCallbackAddrs", tmp); +#endif + +#{ + (0...MAX_DLTYPE).collect{|ty| + " rb_dl_init_callbacks_#{ty}();" + }.join("\n") +} +} +EOS Property changes on: ext/dl/callback/mkcallback.rb ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + LF Index: ext/dl/callback/extconf.rb =================================================================== --- ext/dl/callback/extconf.rb (revision 0) +++ ext/dl/callback/extconf.rb (revision 22722) @@ -0,0 +1,15 @@ +require 'mkmf' + +if compiled?("dl") + CALLBACKS = (0..8).map{|i| "callback-#{i}"} + CALLBACK_SRCS = CALLBACKS.map{|basename| "#{basename}.c"} + CALLBACK_OBJS = CALLBACKS.map{|basename| "#{basename}.o"} + + $distcleanfiles += [ "callback.h", *CALLBACK_SRCS ] + + $objs = %w[ callback.o ] + CALLBACK_OBJS + + $INCFLAGS << " -I$(srcdir)/.." + + create_makefile("dl/callback") +end Property changes on: ext/dl/callback/extconf.rb ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + LF -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/