From e587cf273099ee1e0dbaafdc47f220ea8b81e2e9 Mon Sep 17 00:00:00 2001 From: ttate Date: Fri, 30 Jun 2006 18:05:40 +0000 Subject: fixed the alignment problems discussed in [ruby-dev:28667]. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10440 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/dl/cfunc.c | 42 ++++++++++++++++++++++-------------------- ext/dl/lib/dl/struct.rb | 23 +++++++++++++++++------ ext/dl/mkcallback.rb | 4 ++-- ext/dl/test/test_import.rb | 15 +++++++++------ 4 files changed, 50 insertions(+), 34 deletions(-) (limited to 'ext') diff --git a/ext/dl/cfunc.c b/ext/dl/cfunc.c index 6907e43e1c..739de9659e 100644 --- a/ext/dl/cfunc.c +++ b/ext/dl/cfunc.c @@ -223,10 +223,12 @@ rb_dlcfunc_inspect(VALUE self) } #if defined(__GNUC__) -# define DECL_FUNC(f,ret,args,calltype) ret (__attribute__((calltype)) *f)(args) +# define DECL_FUNC_CDECL(f,ret,args) FUNC_CDECL(ret (*f)(args)) +# define DECL_FUNC_STDCALL(f,ret,args) FUNC_STDCALL(ret (*f)(args)) /* # define DECL_FUNC(f,ret,args,calltype) ret (*f)(args) */ #elif defined(_MSC_VER) || defined(__BORLANDC__) -# define DECL_FUNC(f,ret,args,calltype) ret (__##calltype *f)(args) +# define DECL_FUNC_CDECL(f,ret,args) ret (__cdecl *f)(args) +# define DECL_FUNC_STDCALL(f,ret,args) ret (__stdcall *f)(args) #else # error "unsupported compiler." #endif @@ -273,7 +275,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) switch( cfunc->type ){ case DLTYPE_VOID: #define CASE(n) case n: { \ - DECL_FUNC(f,void,DLSTACK_PROTO##n,cdecl) = cfunc->ptr; \ + DECL_FUNC_CDECL(f,void,DLSTACK_PROTO##n) = cfunc->ptr; \ f(DLSTACK_ARGS##n(stack)); \ result = Qnil; \ } @@ -282,7 +284,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) break; case DLTYPE_VOIDP: #define CASE(n) case n: { \ - DECL_FUNC(f,void*,DLSTACK_PROTO##n,cdecl) = cfunc->ptr; \ + DECL_FUNC_CDECL(f,void*,DLSTACK_PROTO##n) = cfunc->ptr; \ void * ret; \ ret = f(DLSTACK_ARGS##n(stack)); \ result = PTR2NUM(ret); \ @@ -292,7 +294,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) break; case DLTYPE_CHAR: #define CASE(n) case n: { \ - DECL_FUNC(f,char,DLSTACK_PROTO##n,cdecl) = cfunc->ptr; \ + DECL_FUNC_CDECL(f,char,DLSTACK_PROTO##n) = cfunc->ptr; \ char ret; \ ret = f(DLSTACK_ARGS##n(stack)); \ result = CHR2FIX(ret); \ @@ -302,7 +304,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) break; case DLTYPE_SHORT: #define CASE(n) case n: { \ - DECL_FUNC(f,short,DLSTACK_PROTO##n,cdecl) = cfunc->ptr; \ + DECL_FUNC_CDECL(f,short,DLSTACK_PROTO##n) = cfunc->ptr; \ short ret; \ ret = f(DLSTACK_ARGS##n(stack)); \ result = INT2NUM((int)ret); \ @@ -312,7 +314,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) break; case DLTYPE_INT: #define CASE(n) case n: { \ - DECL_FUNC(f,int,DLSTACK_PROTO##n,cdecl) = cfunc->ptr; \ + DECL_FUNC_CDECL(f,int,DLSTACK_PROTO##n) = cfunc->ptr; \ int ret; \ ret = f(DLSTACK_ARGS##n(stack)); \ result = INT2NUM(ret); \ @@ -322,7 +324,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) break; case DLTYPE_LONG: #define CASE(n) case n: { \ - DECL_FUNC(f,long,DLSTACK_PROTO##n,cdecl) = cfunc->ptr; \ + DECL_FUNC_CDECL(f,long,DLSTACK_PROTO##n) = cfunc->ptr; \ long ret; \ ret = f(DLSTACK_ARGS##n(stack)); \ result = LONG2NUM(ret); \ @@ -333,7 +335,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) #if HAVE_LONG_LONG /* used in ruby.h */ case DLTYPE_LONG_LONG: #define CASE(n) case n: { \ - DECL_FUNC(f,LONG_LONG,DLSTACK_PROTO,cdecl) = cfunc->ptr; \ + DECL_FUNC_CDECL(f,LONG_LONG,DLSTACK_PROTO) = cfunc->ptr; \ LONG_LONG ret; \ ret = f(DLSTACK_ARGS(stack)); \ result = LL2NUM(ret); \ @@ -344,7 +346,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) #endif case DLTYPE_FLOAT: #define CASE(n) case n: { \ - DECL_FUNC(f,float,DLSTACK_PROTO,cdecl) = cfunc->ptr; \ + DECL_FUNC_CDECL(f,float,DLSTACK_PROTO) = cfunc->ptr; \ float ret; \ ret = f(DLSTACK_ARGS(stack)); \ result = rb_float_new(ret); \ @@ -354,7 +356,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) break; case DLTYPE_DOUBLE: #define CASE(n) case n: { \ - DECL_FUNC(f,double,DLSTACK_PROTO,cdecl) = cfunc->ptr; \ + DECL_FUNC_CDECL(f,double,DLSTACK_PROTO) = cfunc->ptr; \ double ret; \ ret = f(DLSTACK_ARGS(stack)); \ result = rb_float_new(ret); \ @@ -371,7 +373,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) switch( cfunc->type ){ case DLTYPE_VOID: #define CASE(n) case n: { \ - DECL_FUNC(f,void,DLSTACK_PROTO##n,stdcall) = cfunc->ptr; \ + DECL_FUNC_STDCALL(f,void,DLSTACK_PROTO##n) = cfunc->ptr; \ f(DLSTACK_ARGS##n(stack)); \ result = Qnil; \ } @@ -380,7 +382,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) break; case DLTYPE_VOIDP: #define CASE(n) case n: { \ - DECL_FUNC(f,void*,DLSTACK_PROTO##n,stdcall) = cfunc->ptr; \ + DECL_FUNC_STDCALL(f,void*,DLSTACK_PROTO##n) = cfunc->ptr; \ void * ret; \ ret = f(DLSTACK_ARGS##n(stack)); \ result = PTR2NUM(ret); \ @@ -390,7 +392,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) break; case DLTYPE_CHAR: #define CASE(n) case n: { \ - DECL_FUNC(f,char,DLSTACK_PROTO##n,stdcall) = cfunc->ptr; \ + DECL_FUNC_STDCALL(f,char,DLSTACK_PROTO##n) = cfunc->ptr; \ char ret; \ ret = f(DLSTACK_ARGS##n(stack)); \ result = CHR2FIX(ret); \ @@ -400,7 +402,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) break; case DLTYPE_SHORT: #define CASE(n) case n: { \ - DECL_FUNC(f,short,DLSTACK_PROTO##n,stdcall) = cfunc->ptr; \ + DECL_FUNC_STDCALL(f,short,DLSTACK_PROTO##n) = cfunc->ptr; \ short ret; \ ret = f(DLSTACK_ARGS##n(stack)); \ result = INT2NUM((int)ret); \ @@ -410,7 +412,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) break; case DLTYPE_INT: #define CASE(n) case n: { \ - DECL_FUNC(f,int,DLSTACK_PROTO##n,stdcall) = cfunc->ptr; \ + DECL_FUNC_STDCALL(f,int,DLSTACK_PROTO##n) = cfunc->ptr; \ int ret; \ ret = f(DLSTACK_ARGS##n(stack)); \ result = INT2NUM(ret); \ @@ -420,7 +422,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) break; case DLTYPE_LONG: #define CASE(n) case n: { \ - DECL_FUNC(f,long,DLSTACK_PROTO##n,stdcall) = cfunc->ptr; \ + DECL_FUNC_STDCALL(f,long,DLSTACK_PROTO##n) = cfunc->ptr; \ long ret; \ ret = f(DLSTACK_ARGS##n(stack)); \ result = LONG2NUM(ret); \ @@ -431,7 +433,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) #if HAVE_LONG_LONG /* used in ruby.h */ case DLTYPE_LONG_LONG: #define CASE(n) case n: { \ - DECL_FUNC(f,LONG_LONG,DLSTACK_PROTO,stdcall) = cfunc->ptr; \ + DECL_FUNC_STDCALL(f,LONG_LONG,DLSTACK_PROTO) = cfunc->ptr; \ LONG_LONG ret; \ ret = f(DLSTACK_ARGS(stack)); \ result = LL2NUM(ret); \ @@ -442,7 +444,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) #endif case DLTYPE_FLOAT: #define CASE(n) case n: { \ - DECL_FUNC(f,float,DLSTACK_PROTO,stdcall) = cfunc->ptr; \ + DECL_FUNC_STDCALL(f,float,DLSTACK_PROTO) = cfunc->ptr; \ float ret; \ ret = f(DLSTACK_ARGS(stack)); \ result = rb_float_new(ret); \ @@ -452,7 +454,7 @@ rb_dlcfunc_call(VALUE self, VALUE ary) break; case DLTYPE_DOUBLE: #define CASE(n) case n: { \ - DECL_FUNC(f,double,DLSTACK_PROTO,stdcall) = cfunc->ptr; \ + DECL_FUNC_STDCALL(f,double,DLSTACK_PROTO) = cfunc->ptr; \ double ret; \ ret = f(DLSTACK_ARGS(stack)); \ result = rb_float_new(ret); \ diff --git a/ext/dl/lib/dl/struct.rb b/ext/dl/lib/dl/struct.rb index 01445cf55a..4272b3960c 100644 --- a/ext/dl/lib/dl/struct.rb +++ b/ext/dl/lib/dl/struct.rb @@ -54,19 +54,25 @@ module DL def CStructEntity.size(types) offset = 0 + max_align = 0 types.each_with_index{|t,i| orig_offset = offset if( t.is_a?(Array) ) - offset = PackInfo.align(orig_offset, PackInfo::ALIGN_MAP[TYPE_VOIDP]) + align = PackInfo::ALIGN_MAP[t[0]] + offset = PackInfo.align(orig_offset, align) size = offset - orig_offset offset += (PackInfo::SIZE_MAP[t[0]] * t[1]) else - offset = PackInfo.align(orig_offset, PackInfo::ALIGN_MAP[t]) + align = PackInfo::ALIGN_MAP[t] + offset = PackInfo.align(orig_offset, align) size = offset - orig_offset offset += PackInfo::SIZE_MAP[t] end + if (max_align < align) + max_align = align + end } - offset = PackInfo.align(offset, PackInfo::ALIGN_MAP[TYPE_VOIDP]) + offset = PackInfo.align(offset, max_align) offset end @@ -83,13 +89,15 @@ module DL @ctypes = types @offset = [] offset = 0 + max_align = 0 types.each_with_index{|t,i| orig_offset = offset if( t.is_a?(Array) ) - offset = align(orig_offset, ALIGN_MAP[TYPE_VOIDP]) + align = ALIGN_MAP[t[0]] else - offset = align(orig_offset, ALIGN_MAP[t]) + align = ALIGN_MAP[t] end + offset = PackInfo.align(orig_offset, align) size = offset - orig_offset @offset[i] = offset if( t.is_a?(Array) ) @@ -97,8 +105,11 @@ module DL else offset += SIZE_MAP[t] end + if (max_align < align) + max_align = align + end } - offset = align(offset, ALIGN_MAP[TYPE_VOIDP]) + offset = PackInfo.align(offset, max_align) @size = offset end diff --git a/ext/dl/mkcallback.rb b/ext/dl/mkcallback.rb index b5a6889743..493f55b188 100644 --- a/ext/dl/mkcallback.rb +++ b/ext/dl/mkcallback.rb @@ -111,8 +111,8 @@ for calltype in CALLTYPES for n in 0..(MAX_CALLBACK-1) $out << (<<-EOS) -PRE_DECL_#{calltype.upcase} static #{DLTYPE[ty][:type]} MIDST_DECL_#{calltype.upcase} -#{func_name(ty,argc,n,calltype)}(#{(0...argc).collect{|i| "DLSTACK_TYPE stack" + i.to_s}.join(", ")}) POST_DECL_#{calltype.upcase} +FUNC_#{calltype.upcase}(static #{DLTYPE[ty][:type]} +#{func_name(ty,argc,n,calltype)}(#{(0...argc).collect{|i| "DLSTACK_TYPE stack" + i.to_s}.join(", ")})) { VALUE ret, cb#{argc > 0 ? ", args[#{argc}]" : ""}; #{ diff --git a/ext/dl/test/test_import.rb b/ext/dl/test/test_import.rb index 6df7b9cff6..f0694637eb 100644 --- a/ext/dl/test/test_import.rb +++ b/ext/dl/test/test_import.rb @@ -28,8 +28,9 @@ module DL "int tz_dsttime", ] MyStruct = struct [ - "int num[10]", - "unsigned char buff[8]", + "short num[5]", + "char c", + "unsigned char buff[7]", ] CallCallback = bind("void call_callback(void*, void*)"){|ptr1, ptr2| @@ -93,10 +94,12 @@ module DL def test_struct() s = LIBC::MyStruct.malloc() - s.num = [0,1,2,3,4,5,6,7,8,9] - s.buff = "0123456\377" - assert_equal([0,1,2,3,4,5,6,7,8,9], s.num) - assert_equal([?0,?1,?2,?3,?4,?5,?6,?\377], s.buff) + s.num = [0,1,2,3,4] + s.c = ?a + s.buff = "012345\377" + assert_equal([0,1,2,3,4], s.num) + assert_equal(?a, s.c) + assert_equal([?0,?1,?2,?3,?4,?5,?\377], s.buff) end def test_gettimeofday() -- cgit v1.2.3