summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/dl/cfunc.c42
-rw-r--r--ext/dl/lib/dl/struct.rb23
-rw-r--r--ext/dl/mkcallback.rb4
-rw-r--r--ext/dl/test/test_import.rb15
4 files changed, 50 insertions, 34 deletions
diff --git a/ext/dl/cfunc.c b/ext/dl/cfunc.c
index 6907e43e1c0..739de9659e9 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 01445cf55a7..4272b3960cd 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 b5a6889743b..493f55b1888 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 6df7b9cff67..f0694637ebc 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()