diff --git a/ChangeLog b/ChangeLog index fd4e086281..0cd5e555af 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Sat Feb 25 14:46:54 2012 Nobuyoshi Nakada + + * ext/dl/dl.c (Init_dl): support intrinsic types, size_t, ptrdiff_t + and intptr_t. [ruby-core:42460][Feature #5992] + + * ext/fiddle/fiddle.c (Init_fiddle): ditto. + + * ext/dl/lib/dl/cparser.rb (DL::CParser#parse_ctype): ditto. + Sat Feb 25 11:08:28 2012 Tanaka Akira * ext/curses/curses.c (Init_curses): use rb_define_const once for diff --git a/ext/dl/dl.c b/ext/dl/dl.c index 200c1d6dab..cd4e0c1030 100644 --- a/ext/dl/dl.c +++ b/ext/dl/dl.c @@ -17,6 +17,38 @@ VALUE rb_eDLTypeError; ID rbdl_id_cdecl; ID rbdl_id_stdcall; +#ifndef DLTYPE_SSIZE_T +# if SIZEOF_SIZE_T == SIZEOF_INT +# define DLTYPE_SSIZE_T DLTYPE_INT +# elif SIZEOF_SIZE_T == SIZEOF_LONG +# define DLTYPE_SSIZE_T DLTYPE_LONG +# elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG +# define DLTYPE_SSIZE_T DLTYPE_LONG_LONG +# endif +#endif +#define DLTYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*DLTYPE_SSIZE_T) + +#ifndef DLTYPE_PTRDIFF_T +# if SIZEOF_PTRDIFF_T == SIZEOF_INT +# define DLTYPE_PTRDIFF_T DLTYPE_INT +# elif SIZEOF_PTRDIFF_T == SIZEOF_LONG +# define DLTYPE_PTRDIFF_T DLTYPE_LONG +# elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG +# define DLTYPE_PTRDIFF_T DLTYPE_LONG_LONG +# endif +#endif + +#ifndef DLTYPE_INTPTR_T +# if SIZEOF_INTPTR_T == SIZEOF_INT +# define DLTYPE_INTPTR_T DLTYPE_INT +# elif SIZEOF_INTPTR_T == SIZEOF_LONG +# define DLTYPE_INTPTR_T DLTYPE_LONG +# elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG +# define DLTYPE_INTPTR_T DLTYPE_LONG_LONG +# endif +#endif +#define DLTYPE_UINTPTR_T (-DLTYPE_INTPTR_T) + VALUE rb_dl_dlopen(int argc, VALUE argv[], VALUE self) { @@ -271,6 +303,36 @@ Init_dl(void) */ rb_define_const(rb_mDL, "TYPE_DOUBLE", INT2NUM(DLTYPE_DOUBLE)); + /* Document-const: TYPE_SIZE_T + * + * DL::CFunc type - size_t + */ + rb_define_const(rb_mDL, "TYPE_SIZE_T", INT2NUM(DLTYPE_SIZE_T)); + + /* Document-const: TYPE_SSIZE_T + * + * DL::CFunc type - ssize_t + */ + rb_define_const(rb_mDL, "TYPE_SSIZE_T", INT2NUM(DLTYPE_SSIZE_T)); + + /* Document-const: TYPE_PTRDIFF_T + * + * DL::CFunc type - ptrdiff_t + */ + rb_define_const(rb_mDL, "TYPE_PTRDIFF_T", INT2NUM(DLTYPE_PTRDIFF_T)); + + /* Document-const: TYPE_INTPTR_T + * + * DL::CFunc type - intptr_t + */ + rb_define_const(rb_mDL, "TYPE_INTPTR_T", INT2NUM(DLTYPE_INTPTR_T)); + + /* Document-const: TYPE_UINTPTR_T + * + * DL::CFunc type - uintptr_t + */ + rb_define_const(rb_mDL, "TYPE_UINTPTR_T", INT2NUM(DLTYPE_UINTPTR_T)); + /* Document-const: ALIGN_VOIDP * * The alignment size of a void* @@ -321,6 +383,36 @@ Init_dl(void) */ rb_define_const(rb_mDL, "ALIGN_DOUBLE",INT2NUM(ALIGN_DOUBLE)); + /* Document-const: ALIGN_SIZE_T + * + * The alignment size of a size_t + */ + rb_define_const(rb_mDL, "ALIGN_SIZE_T", INT2NUM(ALIGN_OF(size_t))); + + /* Document-const: ALIGN_SSIZE_T + * + * The alignment size of a ssize_t + */ + rb_define_const(rb_mDL, "ALIGN_SSIZE_T", INT2NUM(ALIGN_OF(size_t))); /* same as size_t */ + + /* Document-const: ALIGN_PTRDIFF_T + * + * The alignment size of a ptrdiff_t + */ + rb_define_const(rb_mDL, "ALIGN_PTRDIFF_T", INT2NUM(ALIGN_OF(ptrdiff_t))); + + /* Document-const: ALIGN_INTPTR_T + * + * The alignment size of a intptr_t + */ + rb_define_const(rb_mDL, "ALIGN_INTPTR_T", INT2NUM(ALIGN_OF(intptr_t))); + + /* Document-const: ALIGN_UINTPTR_T + * + * The alignment size of a uintptr_t + */ + rb_define_const(rb_mDL, "ALIGN_UINTPTR_T", INT2NUM(ALIGN_OF(uintptr_t))); + /* Document-const: SIZEOF_VOIDP * * size of a void* @@ -371,6 +463,36 @@ Init_dl(void) */ rb_define_const(rb_mDL, "SIZEOF_DOUBLE",INT2NUM(sizeof(double))); + /* Document-const: SIZEOF_SIZE_T + * + * size of a size_t + */ + rb_define_const(rb_mDL, "SIZEOF_SIZE_T", INT2NUM(sizeof(size_t))); + + /* Document-const: SIZEOF_SSIZE_T + * + * size of a ssize_t + */ + rb_define_const(rb_mDL, "SIZEOF_SSIZE_T", INT2NUM(sizeof(size_t))); /* same as size_t */ + + /* Document-const: SIZEOF_PTRDIFF_T + * + * size of a ptrdiff_t + */ + rb_define_const(rb_mDL, "SIZEOF_PTRDIFF_T", INT2NUM(sizeof(ptrdiff_t))); + + /* Document-const: SIZEOF_INTPTR_T + * + * size of a intptr_t + */ + rb_define_const(rb_mDL, "SIZEOF_INTPTR_T", INT2NUM(sizeof(intptr_t))); + + /* Document-const: SIZEOF_UINTPTR_T + * + * size of a intptr_t + */ + rb_define_const(rb_mDL, "SIZEOF_UINTPTR_T", INT2NUM(sizeof(uintptr_t))); + rb_define_module_function(rb_mDL, "dlwrap", rb_dl_value2ptr, 1); rb_define_module_function(rb_mDL, "dlunwrap", rb_dl_ptr2value, 1); diff --git a/ext/dl/extconf.rb b/ext/dl/extconf.rb index 6d4d6c5d51..4ef46f85fb 100644 --- a/ext/dl/extconf.rb +++ b/ext/dl/extconf.rb @@ -25,6 +25,19 @@ else end if check + config = File.read(RbConfig.expand(File.join($arch_hdrdir, "ruby/config.h"))) + types = {"SIZE_T"=>"SSIZE_T", "PTRDIFF_T"=>nil, "INTPTR_T"=>nil} + types.each do |type, signed| + if /^\#define\s+SIZEOF_#{type}\s+(SIZEOF_(.+)|\d+)/ =~ config + if size = $2 and size != 'VOIDP' + size = types.fetch(size) {size} + $defs << format("-DDLTYPE_%s=DLTYPE_%s", signed||type, size) + end + if signed + check_signedness(type.downcase, "stddef.h") + end + end + end $defs << %[-DRUBY_VERSION=\\"#{RUBY_VERSION}\\"] create_makefile("dl") end diff --git a/ext/dl/lib/dl/cparser.rb b/ext/dl/lib/dl/cparser.rb index 210f953471..7aae9ea4eb 100644 --- a/ext/dl/lib/dl/cparser.rb +++ b/ext/dl/lib/dl/cparser.rb @@ -95,6 +95,16 @@ module DL return TYPE_FLOAT when "double" return TYPE_DOUBLE + when "size_t" + return TYPE_SIZE_T + when "ssize_t" + return TYPE_SSIZE_T + when "ptrdiff_t" + return TYPE_PTRDIFF_T + when "intptr_t" + return TYPE_INTPTR_T + when "uintptr_t" + return TYPE_UINTPTR_T when /\*/, /\[\s*\]/ return TYPE_VOIDP else diff --git a/ext/dl/lib/dl/types.rb b/ext/dl/lib/dl/types.rb index 3dfa40807a..d5724e407b 100644 --- a/ext/dl/lib/dl/types.rb +++ b/ext/dl/lib/dl/types.rb @@ -40,11 +40,7 @@ module DL typealias "UINT", "unsigned int" typealias "ULONG", "unsigned long" typealias "UCHAR", "unsigned char" - if [nil].pack('p').bytesize == 8 - typealias "HANDLE", "unsigned long long" - else - typealias "HANDLE", "unsigned long" - end + typealias "HANDLE", "uintptr_t" typealias "PHANDLE", "void*" typealias "PVOID", "void*" typealias "LPCSTR", "char*" diff --git a/ext/fiddle/extconf.rb b/ext/fiddle/extconf.rb index 03b0ac2765..95589028d0 100644 --- a/ext/fiddle/extconf.rb +++ b/ext/fiddle/extconf.rb @@ -19,6 +19,20 @@ end have_header 'sys/mman.h' +config = File.read(RbConfig.expand(File.join($arch_hdrdir, "ruby/config.h"))) +types = {"SIZE_T"=>"SSIZE_T", "PTRDIFF_T"=>nil, "INTPTR_T"=>nil} +types.each do |type, signed| + if /^\#define\s+SIZEOF_#{type}\s+(SIZEOF_(.+)|\d+)/ =~ config + if size = $2 and size != 'VOIDP' + size = types.fetch(size) {size} + $defs << format("-DTYPE_%s=TYPE_%s", signed||type, size) + end + if signed + check_signedness(type.downcase, "stddef.h") + end + end +end + create_makefile 'fiddle' # :startdoc: diff --git a/ext/fiddle/fiddle.c b/ext/fiddle/fiddle.c index 83c0bb5e1e..3006bbeb77 100644 --- a/ext/fiddle/fiddle.c +++ b/ext/fiddle/fiddle.c @@ -2,6 +2,38 @@ VALUE mFiddle; +#ifndef TYPE_SSIZE_T +# if SIZEOF_SIZE_T == SIZEOF_INT +# define TYPE_SSIZE_T TYPE_INT +# elif SIZEOF_SIZE_T == SIZEOF_LONG +# define TYPE_SSIZE_T TYPE_LONG +# elif defined HAVE_LONG_LONG && SIZEOF_SIZE_T == SIZEOF_LONG_LONG +# define TYPE_SSIZE_T TYPE_LONG_LONG +# endif +#endif +#define TYPE_SIZE_T (-1*SIGNEDNESS_OF_SIZE_T*TYPE_SSIZE_T) + +#ifndef TYPE_PTRDIFF_T +# if SIZEOF_PTRDIFF_T == SIZEOF_INT +# define TYPE_PTRDIFF_T TYPE_INT +# elif SIZEOF_PTRDIFF_T == SIZEOF_LONG +# define TYPE_PTRDIFF_T TYPE_LONG +# elif defined HAVE_LONG_LONG && SIZEOF_PTRDIFF_T == SIZEOF_LONG_LONG +# define TYPE_PTRDIFF_T TYPE_LONG_LONG +# endif +#endif + +#ifndef TYPE_INTPTR_T +# if SIZEOF_INTPTR_T == SIZEOF_INT +# define TYPE_INTPTR_T TYPE_INT +# elif SIZEOF_INTPTR_T == SIZEOF_LONG +# define TYPE_INTPTR_T TYPE_LONG +# elif defined HAVE_LONG_LONG && SIZEOF_INTPTR_T == SIZEOF_LONG_LONG +# define TYPE_INTPTR_T TYPE_LONG_LONG +# endif +#endif +#define TYPE_UINTPTR_T (-TYPE_INTPTR_T) + void Init_fiddle(void) { @@ -71,6 +103,36 @@ Init_fiddle(void) */ rb_define_const(mFiddle, "TYPE_DOUBLE", INT2NUM(TYPE_DOUBLE)); + /* Document-const: TYPE_SIZE_T + * + * C type - size_t + */ + rb_define_const(mFiddle, "TYPE_SIZE_T", INT2NUM(TYPE_SIZE_T)); + + /* Document-const: TYPE_SSIZE_T + * + * C type - ssize_t + */ + rb_define_const(mFiddle, "TYPE_SSIZE_T", INT2NUM(TYPE_SSIZE_T)); + + /* Document-const: TYPE_PTRDIFF_T + * + * C type - ptrdiff_t + */ + rb_define_const(mFiddle, "TYPE_PTRDIFF_T", INT2NUM(TYPE_PTRDIFF_T)); + + /* Document-const: TYPE_INTPTR_T + * + * C type - intptr_t + */ + rb_define_const(mFiddle, "TYPE_INTPTR_T", INT2NUM(TYPE_INTPTR_T)); + + /* Document-const: TYPE_UINTPTR_T + * + * C type - uintptr_t + */ + rb_define_const(mFiddle, "TYPE_UINTPTR_T", INT2NUM(TYPE_UINTPTR_T)); + /* Document-const: WINDOWS * * Returns a boolean regarding whether the host is WIN32 diff --git a/test/dl/test_cparser.rb b/test/dl/test_cparser.rb index 3be727a759..cea9ac73b0 100644 --- a/test/dl/test_cparser.rb +++ b/test/dl/test_cparser.rb @@ -9,5 +9,25 @@ module DL def test_uint_ctype assert_equal(-DL::TYPE_INT, parse_ctype('uint')) end + + def test_size_t_ctype + assert_equal(DL::TYPE_SIZE_T, parse_ctype("size_t")) + end + + def test_ssize_t_ctype + assert_equal(DL::TYPE_SSIZE_T, parse_ctype("ssize_t")) + end + + def test_ptrdiff_t_ctype + assert_equal(DL::TYPE_PTRDIFF_T, parse_ctype("ptrdiff_t")) + end + + def test_intptr_t_ctype + assert_equal(DL::TYPE_INTPTR_T, parse_ctype("intptr_t")) + end + + def test_uintptr_t_ctype + assert_equal(DL::TYPE_UINTPTR_T, parse_ctype("uintptr_t")) + end end end diff --git a/test/dl/test_dl2.rb b/test/dl/test_dl2.rb index 1d6e39114f..8f4275fb65 100644 --- a/test/dl/test_dl2.rb +++ b/test/dl/test_dl2.rb @@ -151,5 +151,17 @@ class TestDL < TestBase ary2 = dlunwrap(addr) assert_equal(ary, ary2) end + + def test_type_size_t + assert_equal(DL::TYPE_SSIZE_T, DL::TYPE_SIZE_T.abs) + end + + def test_type_uintptr_t + assert_equal(-DL::TYPE_INTPTR_T, DL::TYPE_UINTPTR_T) + end + + def test_sizeof_uintptr_t + assert_equal(DL::SIZEOF_VOIDP, DL::SIZEOF_INTPTR_T) + end end end # module DL diff --git a/test/fiddle/test_fiddle.rb b/test/fiddle/test_fiddle.rb index 21609933d2..f910978af5 100644 --- a/test/fiddle/test_fiddle.rb +++ b/test/fiddle/test_fiddle.rb @@ -15,8 +15,13 @@ class TestFiddle < Fiddle::TestCase :TYPE_LONG_LONG, :TYPE_FLOAT, :TYPE_DOUBLE, + :TYPE_SIZE_T, + :TYPE_SSIZE_T, + :TYPE_PTRDIFF_T, + :TYPE_INTPTR_T, + :TYPE_UINTPTR_T, ].each do |name| - assert_equal(DL.const_get(name), Fiddle.const_get(name)) + assert_equal(DL.const_get(name), Fiddle.const_get(name), "Fiddle::#{name}") end end diff --git a/test/ruby/memory_status.rb b/test/ruby/memory_status.rb index cd4a62c1c0..3694e619ef 100644 --- a/test/ruby/memory_status.rb +++ b/test/ruby/memory_status.rb @@ -22,11 +22,7 @@ module Memory extend DL::Importer dlload "kernel32.dll", "psapi.dll" include DL::Win32Types - if [nil].pack('p').bytesize == 8 - typealias "SIZE_T", "DWORD64" - else - typealias "SIZE_T", "DWORD32" - end + typealias "SIZE_T", "size_t" PROCESS_MEMORY_COUNTERS = struct [ "DWORD cb",