From 59e4e93ef7b6b7f1536e3c56374cc6b8d74b5d28 Mon Sep 17 00:00:00 2001 From: naruse Date: Thu, 25 Feb 2010 22:49:20 +0000 Subject: * ext/dl: revert dl with libffi because it can't run on mswin now. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26764 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/dl/callback/depend | 15 +++ ext/dl/callback/extconf.rb | 14 +++ ext/dl/callback/mkcallback.rb | 238 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 267 insertions(+) create mode 100644 ext/dl/callback/depend create mode 100644 ext/dl/callback/extconf.rb create mode 100644 ext/dl/callback/mkcallback.rb (limited to 'ext/dl/callback') diff --git a/ext/dl/callback/depend b/ext/dl/callback/depend new file mode 100644 index 0000000000..7a1dc1ee62 --- /dev/null +++ b/ext/dl/callback/depend @@ -0,0 +1,15 @@ +src: callback.c \ + 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 + +$(OBJS): $(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 + +callback.c: $(srcdir)/mkcallback.rb $(srcdir)/../dl.h + @echo "generating callback.c" + @$(RUBY) $(srcdir)/mkcallback.rb -output=callback $(srcdir)/../dl.h diff --git a/ext/dl/callback/extconf.rb b/ext/dl/callback/extconf.rb new file mode 100644 index 0000000000..6c3387670d --- /dev/null +++ b/ext/dl/callback/extconf.rb @@ -0,0 +1,14 @@ +require 'mkmf' + +if compiled?("dl") + callbacks = (0..8).map{|i| "callback-#{i}"}.unshift("callback") + callback_srcs = callbacks.map{|basename| "#{basename}.c"} + callback_objs = callbacks.map{|basename| "#{basename}.o"} + + $distcleanfiles << '$(SRCS)' + $srcs = callback_srcs + $objs = callback_objs + $INCFLAGS << " -I$(srcdir)/.." + + create_makefile("dl/callback") +end diff --git a/ext/dl/callback/mkcallback.rb b/ext/dl/callback/mkcallback.rb new file mode 100644 index 0000000000..d2f9e3f2e1 --- /dev/null +++ b/ext/dl/callback/mkcallback.rb @@ -0,0 +1,238 @@ +#!ruby -s +$output ||= "callback" +$out = open("#{$output}.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 => '(float)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 << (< 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 = "#{$output}-#{ty}.c" + initname = "rb_dl_init_callbacks_#{ty}" + body = <<-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 body + body << <<-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 + [filename, initname, body] +end + +callbacks = [] +for ty in 0...MAX_DLTYPE + filename, initname, body = 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" + callbacks << [filename, body] +end + +$out << (<