diff options
Diffstat (limited to 'ext/fiddle')
-rw-r--r-- | ext/fiddle/closure.c | 165 | ||||
-rw-r--r-- | ext/fiddle/conversions.c | 77 | ||||
-rw-r--r-- | ext/fiddle/conversions.h | 2 | ||||
-rw-r--r-- | ext/fiddle/depend | 32 | ||||
-rw-r--r-- | ext/fiddle/extconf.rb | 35 | ||||
-rw-r--r-- | ext/fiddle/extlibs | 13 | ||||
-rw-r--r-- | ext/fiddle/fiddle.c | 268 | ||||
-rw-r--r-- | ext/fiddle/fiddle.gemspec | 8 | ||||
-rw-r--r-- | ext/fiddle/fiddle.h | 40 | ||||
-rw-r--r-- | ext/fiddle/function.c | 10 | ||||
-rw-r--r-- | ext/fiddle/handle.c | 70 | ||||
-rw-r--r-- | ext/fiddle/lib/fiddle.rb | 35 | ||||
-rw-r--r-- | ext/fiddle/lib/fiddle/closure.rb | 25 | ||||
-rw-r--r-- | ext/fiddle/lib/fiddle/cparser.rb | 42 | ||||
-rw-r--r-- | ext/fiddle/lib/fiddle/import.rb | 2 | ||||
-rw-r--r-- | ext/fiddle/lib/fiddle/pack.rb | 47 | ||||
-rw-r--r-- | ext/fiddle/lib/fiddle/value.rb | 28 | ||||
-rw-r--r-- | ext/fiddle/lib/fiddle/version.rb | 2 | ||||
-rw-r--r-- | ext/fiddle/pointer.c | 50 | ||||
-rw-r--r-- | ext/fiddle/win32/fficonfig.h | 29 | ||||
-rw-r--r-- | ext/fiddle/win32/libffi-3.2.1-mswin.patch | 191 | ||||
-rwxr-xr-x | ext/fiddle/win32/libffi-config.rb | 48 | ||||
-rw-r--r-- | ext/fiddle/win32/libffi.mk.tmpl | 96 |
23 files changed, 720 insertions, 595 deletions
diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c index 3679e5c9ad..7aa9407619 100644 --- a/ext/fiddle/closure.c +++ b/ext/fiddle/closure.c @@ -1,4 +1,5 @@ #include <fiddle.h> +#include <stdbool.h> #include <ruby/thread.h> int ruby_thread_has_gvl_p(void); /* from internal.h */ @@ -54,8 +55,13 @@ closure_memsize(const void * ptr) } const rb_data_type_t closure_data_type = { - "fiddle/closure", - {0, dealloc, closure_memsize,}, + .wrap_struct_name = "fiddle/closure", + .function = { + .dmark = 0, + .dfree = dealloc, + .dsize = closure_memsize + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; struct callback_args { @@ -90,7 +96,7 @@ with_gvl_callback(void *ptr) case TYPE_INT: rb_ary_push(params, INT2NUM(*(int *)x->args[i])); break; - case -TYPE_INT: + case TYPE_UINT: rb_ary_push(params, UINT2NUM(*(unsigned int *)x->args[i])); break; case TYPE_VOIDP: @@ -101,19 +107,19 @@ with_gvl_callback(void *ptr) case TYPE_LONG: rb_ary_push(params, LONG2NUM(*(long *)x->args[i])); break; - case -TYPE_LONG: + case TYPE_ULONG: rb_ary_push(params, ULONG2NUM(*(unsigned long *)x->args[i])); break; case TYPE_CHAR: rb_ary_push(params, INT2NUM(*(signed char *)x->args[i])); break; - case -TYPE_CHAR: + case TYPE_UCHAR: rb_ary_push(params, UINT2NUM(*(unsigned char *)x->args[i])); break; case TYPE_SHORT: rb_ary_push(params, INT2NUM(*(signed short *)x->args[i])); break; - case -TYPE_SHORT: + case TYPE_USHORT: rb_ary_push(params, UINT2NUM(*(unsigned short *)x->args[i])); break; case TYPE_DOUBLE: @@ -126,7 +132,7 @@ with_gvl_callback(void *ptr) case TYPE_LONG_LONG: rb_ary_push(params, LL2NUM(*(LONG_LONG *)x->args[i])); break; - case -TYPE_LONG_LONG: + case TYPE_ULONG_LONG: rb_ary_push(params, ULL2NUM(*(unsigned LONG_LONG *)x->args[i])); break; #endif @@ -134,6 +140,20 @@ with_gvl_callback(void *ptr) rb_ary_push(params, rb_str_new_cstr(*((const char **)(x->args[i])))); break; + case TYPE_BOOL: + if (sizeof(bool) == sizeof(char)) { + rb_ary_push(params, CBOOL2RBBOOL(*(unsigned char *)x->args[i])); + } else if (sizeof(bool) == sizeof(short)) { + rb_ary_push(params, CBOOL2RBBOOL(*(unsigned short *)x->args[i])); + } else if (sizeof(bool) == sizeof(int)) { + rb_ary_push(params, CBOOL2RBBOOL(*(unsigned int *)x->args[i])); + } else if (sizeof(bool) == sizeof(long)) { + rb_ary_push(params, CBOOL2RBBOOL(*(unsigned long *)x->args[i])); + } else { + rb_raise(rb_eNotImpError, "bool isn't supported: %u", + (unsigned int)sizeof(bool)); + } + break; default: rb_raise(rb_eRuntimeError, "closure args: %d", type); } @@ -149,7 +169,7 @@ with_gvl_callback(void *ptr) case TYPE_LONG: *(long *)x->resp = NUM2LONG(ret); break; - case -TYPE_LONG: + case TYPE_ULONG: *(unsigned long *)x->resp = NUM2ULONG(ret); break; case TYPE_CHAR: @@ -157,9 +177,9 @@ with_gvl_callback(void *ptr) case TYPE_INT: *(ffi_sarg *)x->resp = NUM2INT(ret); break; - case -TYPE_CHAR: - case -TYPE_SHORT: - case -TYPE_INT: + case TYPE_UCHAR: + case TYPE_USHORT: + case TYPE_UINT: *(ffi_arg *)x->resp = NUM2UINT(ret); break; case TYPE_VOIDP: @@ -175,7 +195,7 @@ with_gvl_callback(void *ptr) case TYPE_LONG_LONG: *(LONG_LONG *)x->resp = NUM2LL(ret); break; - case -TYPE_LONG_LONG: + case TYPE_ULONG_LONG: *(unsigned LONG_LONG *)x->resp = NUM2ULL(ret); break; #endif @@ -183,6 +203,13 @@ with_gvl_callback(void *ptr) /* Dangerous. Callback must keep reference of the String. */ *((const char **)(x->resp)) = StringValueCStr(ret); break; + case TYPE_BOOL: + if (sizeof(bool) == sizeof(long)) { + *(unsigned long *)x->resp = RB_TEST(ret); + } else { + *(ffi_arg *)x->resp = RB_TEST(ret); + } + break; default: rb_raise(rb_eRuntimeError, "closure retval: %d", type); } @@ -224,9 +251,27 @@ allocate(VALUE klass) return i; } +static fiddle_closure * +get_raw(VALUE self) +{ + fiddle_closure *closure; + TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, closure); + if (!closure) { + rb_raise(rb_eArgError, "already freed: %+"PRIsVALUE, self); + } + return closure; +} + +typedef struct { + VALUE self; + int argc; + VALUE *argv; +} initialize_data; + static VALUE -initialize(int rbargc, VALUE argv[], VALUE self) +initialize_body(VALUE user_data) { + initialize_data *data = (initialize_data *)user_data; VALUE ret; VALUE args; VALUE normalized_args; @@ -237,14 +282,14 @@ initialize(int rbargc, VALUE argv[], VALUE self) ffi_status result; int i, argc; - if (2 == rb_scan_args(rbargc, argv, "21", &ret, &args, &abi)) - abi = INT2NUM(FFI_DEFAULT_ABI); + if (2 == rb_scan_args(data->argc, data->argv, "21", &ret, &args, &abi)) + abi = INT2NUM(FFI_DEFAULT_ABI); Check_Type(args, T_ARRAY); argc = RARRAY_LENINT(args); - TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl); + TypedData_Get_Struct(data->self, fiddle_closure, &closure_data_type, cl); cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *)); @@ -257,8 +302,8 @@ initialize(int rbargc, VALUE argv[], VALUE self) cl->argv[argc] = NULL; ret = rb_fiddle_type_ensure(ret); - rb_iv_set(self, "@ctype", ret); - rb_iv_set(self, "@args", normalized_args); + rb_iv_set(data->self, "@ctype", ret); + rb_iv_set(data->self, "@args", normalized_args); cif = &cl->cif; pcl = cl->pcl; @@ -269,38 +314,75 @@ initialize(int rbargc, VALUE argv[], VALUE self) rb_fiddle_int_to_ffi_type(NUM2INT(ret)), cl->argv); - if (FFI_OK != result) - rb_raise(rb_eRuntimeError, "error prepping CIF %d", result); + if (FFI_OK != result) { + rb_raise(rb_eRuntimeError, "error prepping CIF %d", result); + } #if USE_FFI_CLOSURE_ALLOC result = ffi_prep_closure_loc(pcl, cif, callback, - (void *)self, cl->code); + (void *)(data->self), cl->code); #else - result = ffi_prep_closure(pcl, cif, callback, (void *)self); + result = ffi_prep_closure(pcl, cif, callback, (void *)(data->self)); cl->code = (void *)pcl; i = mprotect(pcl, sizeof(*pcl), PROT_READ | PROT_EXEC); if (i) { - rb_sys_fail("mprotect"); + rb_sys_fail("mprotect"); } #endif - if (FFI_OK != result) - rb_raise(rb_eRuntimeError, "error prepping closure %d", result); + if (FFI_OK != result) { + rb_raise(rb_eRuntimeError, "error prepping closure %d", result); + } - return self; + return data->self; } static VALUE -to_i(VALUE self) +initialize_rescue(VALUE user_data, VALUE exception) { - fiddle_closure * cl; - void *code; + initialize_data *data = (initialize_data *)user_data; + dealloc(RTYPEDDATA_DATA(data->self)); + RTYPEDDATA_DATA(data->self) = NULL; + rb_exc_raise(exception); + return data->self; +} + +static VALUE +initialize(int argc, VALUE *argv, VALUE self) +{ + initialize_data data; + data.self = self; + data.argc = argc; + data.argv = argv; + return rb_rescue(initialize_body, (VALUE)&data, + initialize_rescue, (VALUE)&data); +} - TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl); +static VALUE +to_i(VALUE self) +{ + fiddle_closure *closure = get_raw(self); + return PTR2NUM(closure->code); +} - code = cl->code; +static VALUE +closure_free(VALUE self) +{ + fiddle_closure *closure; + TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, closure); + if (closure) { + dealloc(closure); + RTYPEDDATA_DATA(self) = NULL; + } + return RUBY_Qnil; +} - return PTR2NUM(code); +static VALUE +closure_freed_p(VALUE self) +{ + fiddle_closure *closure; + TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, closure); + return closure ? RUBY_Qfalse : RUBY_Qtrue; } void @@ -353,8 +435,23 @@ Init_fiddle_closure(void) /* * Document-method: to_i * - * Returns the memory address for this closure + * Returns the memory address for this closure. */ rb_define_method(cFiddleClosure, "to_i", to_i, 0); + + /* + * Document-method: free + * + * Free this closure explicitly. You can't use this closure anymore. + * + * If this closure is already freed, this does nothing. + */ + rb_define_method(cFiddleClosure, "free", closure_free, 0); + + /* + * Document-method: freed? + * + * Whether this closure was freed explicitly. + */ + rb_define_method(cFiddleClosure, "freed?", closure_freed_p, 0); } -/* vim: set noet sw=4 sts=4 */ diff --git a/ext/fiddle/conversions.c b/ext/fiddle/conversions.c index 6e0ce36378..298ed9775a 100644 --- a/ext/fiddle/conversions.c +++ b/ext/fiddle/conversions.c @@ -1,3 +1,5 @@ +#include <stdbool.h> + #include <fiddle.h> VALUE @@ -44,6 +46,7 @@ rb_fiddle_type_ensure(VALUE type) ID ptrdiff_t_id; ID intptr_t_id; ID uintptr_t_id; + ID bool_id; RUBY_CONST_ID(void_id, "void"); RUBY_CONST_ID(voidp_id, "voidp"); RUBY_CONST_ID(char_id, "char"); @@ -74,6 +77,7 @@ rb_fiddle_type_ensure(VALUE type) RUBY_CONST_ID(ptrdiff_t_id, "ptrdiff_t"); RUBY_CONST_ID(intptr_t_id, "intptr_t"); RUBY_CONST_ID(uintptr_t_id, "uintptr_t"); + RUBY_CONST_ID(bool_id, "bool"); if (type_id == void_id) { return INT2NUM(TYPE_VOID); } @@ -144,6 +148,9 @@ rb_fiddle_type_ensure(VALUE type) else if (type_id == uintptr_t_id) { return INT2NUM(TYPE_UINTPTR_T); } + else if (type_id == bool_id) { + return INT2NUM(TYPE_BOOL); + } else { type = original_type; } @@ -187,6 +194,20 @@ rb_fiddle_int_to_ffi_type(int type) return &ffi_type_double; case TYPE_CONST_STRING: return &ffi_type_pointer; + case TYPE_BOOL: + signed_p = 0; + if (sizeof(bool) == sizeof(char)) { + return rb_ffi_type_of(char); + } else if (sizeof(bool) == sizeof(short)) { + return rb_ffi_type_of(short); + } else if (sizeof(bool) == sizeof(int)) { + return rb_ffi_type_of(int); + } else if (sizeof(bool) == sizeof(long)) { + return rb_ffi_type_of(long); + } else { + rb_raise(rb_eNotImpError, "bool isn't supported: %u", + (unsigned int)sizeof(bool)); + } default: rb_raise(rb_eRuntimeError, "unknown type %d", type); } @@ -209,34 +230,38 @@ rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst) dst->pointer = NUM2PTR(rb_Integer(*src)); break; case TYPE_CHAR: - dst->schar = (signed char)NUM2INT(*src); + if (RB_TYPE_P(*src, RUBY_T_STRING) && RSTRING_LEN(*src) == 1) { + dst->schar = RSTRING_PTR(*src)[0]; + } else { + dst->schar = (signed char)NUM2INT(*src); + } break; - case -TYPE_CHAR: + case TYPE_UCHAR: dst->uchar = (unsigned char)NUM2UINT(*src); break; case TYPE_SHORT: dst->sshort = (unsigned short)NUM2INT(*src); break; - case -TYPE_SHORT: + case TYPE_USHORT: dst->sshort = (signed short)NUM2UINT(*src); break; case TYPE_INT: dst->sint = NUM2INT(*src); break; - case -TYPE_INT: + case TYPE_UINT: dst->uint = NUM2UINT(*src); break; case TYPE_LONG: dst->slong = NUM2LONG(*src); break; - case -TYPE_LONG: + case TYPE_ULONG: dst->ulong = NUM2ULONG(*src); break; #if HAVE_LONG_LONG case TYPE_LONG_LONG: dst->slong_long = NUM2LL(*src); break; - case -TYPE_LONG_LONG: + case TYPE_ULONG_LONG: dst->ulong_long = NUM2ULL(*src); break; #endif @@ -254,8 +279,23 @@ rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst) dst->pointer = rb_string_value_cstr(src); } break; + case TYPE_BOOL: + if (sizeof(bool) == sizeof(char)) { + dst->uchar = RB_TEST(*src); + } else if (sizeof(bool) == sizeof(short)) { + dst->ushort = RB_TEST(*src); + } else if (sizeof(bool) == sizeof(int)) { + dst->uint = RB_TEST(*src); + } else if (sizeof(bool) == sizeof(long)) { + dst->ulong = RB_TEST(*src); + } else { + rb_raise(rb_eNotImpError, "bool isn't supported: %u", + (unsigned int)sizeof(bool)); + } + break; default: rb_raise(rb_eRuntimeError, "unknown type %d", type); + break; } } @@ -283,24 +323,24 @@ rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval) PTR2NUM((void *)retval.pointer)); case TYPE_CHAR: return INT2NUM((signed char)retval.fffi_sarg); - case -TYPE_CHAR: + case TYPE_UCHAR: return INT2NUM((unsigned char)retval.fffi_arg); case TYPE_SHORT: return INT2NUM((signed short)retval.fffi_sarg); - case -TYPE_SHORT: + case TYPE_USHORT: return INT2NUM((unsigned short)retval.fffi_arg); case TYPE_INT: return INT2NUM((signed int)retval.fffi_sarg); - case -TYPE_INT: + case TYPE_UINT: return UINT2NUM((unsigned int)retval.fffi_arg); case TYPE_LONG: return LONG2NUM(retval.slong); - case -TYPE_LONG: + case TYPE_ULONG: return ULONG2NUM(retval.ulong); #if HAVE_LONG_LONG case TYPE_LONG_LONG: return LL2NUM(retval.slong_long); - case -TYPE_LONG_LONG: + case TYPE_ULONG_LONG: return ULL2NUM(retval.ulong_long); #endif case TYPE_FLOAT: @@ -314,6 +354,19 @@ rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval) else { return Qnil; } + case TYPE_BOOL: + if (sizeof(bool) == sizeof(char)) { + return CBOOL2RBBOOL((unsigned char)retval.fffi_arg); + } else if (sizeof(bool) == sizeof(short)) { + return CBOOL2RBBOOL((unsigned short)retval.fffi_arg); + } else if (sizeof(bool) == sizeof(int)) { + return CBOOL2RBBOOL((unsigned int)retval.fffi_arg); + } else if (sizeof(bool) == sizeof(long)) { + return CBOOL2RBBOOL(retval.ulong); + } else { + rb_raise(rb_eNotImpError, "bool isn't supported: %u", + (unsigned int)sizeof(bool)); + } default: rb_raise(rb_eRuntimeError, "unknown type %d", type); } @@ -326,5 +379,3 @@ generic_to_value(VALUE rettype, fiddle_generic retval) { return rb_fiddle_generic_to_value(rettype, retval); } - -/* vim: set noet sw=4 sts=4 */ diff --git a/ext/fiddle/conversions.h b/ext/fiddle/conversions.h index c7c12a9234..7a1e928d56 100644 --- a/ext/fiddle/conversions.h +++ b/ext/fiddle/conversions.h @@ -50,4 +50,6 @@ VALUE generic_to_value(VALUE rettype, fiddle_generic retval); # define NUM2PTR(x) ((void*)(NUM2ULL(x))) #endif +#define CBOOL2RBBOOL(cbool) ((cbool) ? RUBY_Qtrue : RUBY_Qfalse) + #endif diff --git a/ext/fiddle/depend b/ext/fiddle/depend index d6a053f05b..43b11ca780 100644 --- a/ext/fiddle/depend +++ b/ext/fiddle/depend @@ -105,6 +105,7 @@ closure.o: $(hdrdir)/ruby/internal/attr/noexcept.h closure.o: $(hdrdir)/ruby/internal/attr/noinline.h closure.o: $(hdrdir)/ruby/internal/attr/nonnull.h closure.o: $(hdrdir)/ruby/internal/attr/noreturn.h +closure.o: $(hdrdir)/ruby/internal/attr/packed_struct.h closure.o: $(hdrdir)/ruby/internal/attr/pure.h closure.o: $(hdrdir)/ruby/internal/attr/restrict.h closure.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -164,7 +165,6 @@ closure.o: $(hdrdir)/ruby/internal/intern/enumerator.h closure.o: $(hdrdir)/ruby/internal/intern/error.h closure.o: $(hdrdir)/ruby/internal/intern/eval.h closure.o: $(hdrdir)/ruby/internal/intern/file.h -closure.o: $(hdrdir)/ruby/internal/intern/gc.h closure.o: $(hdrdir)/ruby/internal/intern/hash.h closure.o: $(hdrdir)/ruby/internal/intern/io.h closure.o: $(hdrdir)/ruby/internal/intern/load.h @@ -195,12 +195,12 @@ closure.o: $(hdrdir)/ruby/internal/memory.h closure.o: $(hdrdir)/ruby/internal/method.h closure.o: $(hdrdir)/ruby/internal/module.h closure.o: $(hdrdir)/ruby/internal/newobj.h -closure.o: $(hdrdir)/ruby/internal/rgengc.h closure.o: $(hdrdir)/ruby/internal/scan_args.h closure.o: $(hdrdir)/ruby/internal/special_consts.h closure.o: $(hdrdir)/ruby/internal/static_assert.h closure.o: $(hdrdir)/ruby/internal/stdalign.h closure.o: $(hdrdir)/ruby/internal/stdbool.h +closure.o: $(hdrdir)/ruby/internal/stdckdint.h closure.o: $(hdrdir)/ruby/internal/symbol.h closure.o: $(hdrdir)/ruby/internal/value.h closure.o: $(hdrdir)/ruby/internal/value_type.h @@ -270,6 +270,7 @@ conversions.o: $(hdrdir)/ruby/internal/attr/noexcept.h conversions.o: $(hdrdir)/ruby/internal/attr/noinline.h conversions.o: $(hdrdir)/ruby/internal/attr/nonnull.h conversions.o: $(hdrdir)/ruby/internal/attr/noreturn.h +conversions.o: $(hdrdir)/ruby/internal/attr/packed_struct.h conversions.o: $(hdrdir)/ruby/internal/attr/pure.h conversions.o: $(hdrdir)/ruby/internal/attr/restrict.h conversions.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -329,7 +330,6 @@ conversions.o: $(hdrdir)/ruby/internal/intern/enumerator.h conversions.o: $(hdrdir)/ruby/internal/intern/error.h conversions.o: $(hdrdir)/ruby/internal/intern/eval.h conversions.o: $(hdrdir)/ruby/internal/intern/file.h -conversions.o: $(hdrdir)/ruby/internal/intern/gc.h conversions.o: $(hdrdir)/ruby/internal/intern/hash.h conversions.o: $(hdrdir)/ruby/internal/intern/io.h conversions.o: $(hdrdir)/ruby/internal/intern/load.h @@ -360,12 +360,12 @@ conversions.o: $(hdrdir)/ruby/internal/memory.h conversions.o: $(hdrdir)/ruby/internal/method.h conversions.o: $(hdrdir)/ruby/internal/module.h conversions.o: $(hdrdir)/ruby/internal/newobj.h -conversions.o: $(hdrdir)/ruby/internal/rgengc.h conversions.o: $(hdrdir)/ruby/internal/scan_args.h conversions.o: $(hdrdir)/ruby/internal/special_consts.h conversions.o: $(hdrdir)/ruby/internal/static_assert.h conversions.o: $(hdrdir)/ruby/internal/stdalign.h conversions.o: $(hdrdir)/ruby/internal/stdbool.h +conversions.o: $(hdrdir)/ruby/internal/stdckdint.h conversions.o: $(hdrdir)/ruby/internal/symbol.h conversions.o: $(hdrdir)/ruby/internal/value.h conversions.o: $(hdrdir)/ruby/internal/value_type.h @@ -434,6 +434,7 @@ fiddle.o: $(hdrdir)/ruby/internal/attr/noexcept.h fiddle.o: $(hdrdir)/ruby/internal/attr/noinline.h fiddle.o: $(hdrdir)/ruby/internal/attr/nonnull.h fiddle.o: $(hdrdir)/ruby/internal/attr/noreturn.h +fiddle.o: $(hdrdir)/ruby/internal/attr/packed_struct.h fiddle.o: $(hdrdir)/ruby/internal/attr/pure.h fiddle.o: $(hdrdir)/ruby/internal/attr/restrict.h fiddle.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -493,7 +494,6 @@ fiddle.o: $(hdrdir)/ruby/internal/intern/enumerator.h fiddle.o: $(hdrdir)/ruby/internal/intern/error.h fiddle.o: $(hdrdir)/ruby/internal/intern/eval.h fiddle.o: $(hdrdir)/ruby/internal/intern/file.h -fiddle.o: $(hdrdir)/ruby/internal/intern/gc.h fiddle.o: $(hdrdir)/ruby/internal/intern/hash.h fiddle.o: $(hdrdir)/ruby/internal/intern/io.h fiddle.o: $(hdrdir)/ruby/internal/intern/load.h @@ -524,12 +524,12 @@ fiddle.o: $(hdrdir)/ruby/internal/memory.h fiddle.o: $(hdrdir)/ruby/internal/method.h fiddle.o: $(hdrdir)/ruby/internal/module.h fiddle.o: $(hdrdir)/ruby/internal/newobj.h -fiddle.o: $(hdrdir)/ruby/internal/rgengc.h fiddle.o: $(hdrdir)/ruby/internal/scan_args.h fiddle.o: $(hdrdir)/ruby/internal/special_consts.h fiddle.o: $(hdrdir)/ruby/internal/static_assert.h fiddle.o: $(hdrdir)/ruby/internal/stdalign.h fiddle.o: $(hdrdir)/ruby/internal/stdbool.h +fiddle.o: $(hdrdir)/ruby/internal/stdckdint.h fiddle.o: $(hdrdir)/ruby/internal/symbol.h fiddle.o: $(hdrdir)/ruby/internal/value.h fiddle.o: $(hdrdir)/ruby/internal/value_type.h @@ -598,6 +598,7 @@ function.o: $(hdrdir)/ruby/internal/attr/noexcept.h function.o: $(hdrdir)/ruby/internal/attr/noinline.h function.o: $(hdrdir)/ruby/internal/attr/nonnull.h function.o: $(hdrdir)/ruby/internal/attr/noreturn.h +function.o: $(hdrdir)/ruby/internal/attr/packed_struct.h function.o: $(hdrdir)/ruby/internal/attr/pure.h function.o: $(hdrdir)/ruby/internal/attr/restrict.h function.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -657,7 +658,6 @@ function.o: $(hdrdir)/ruby/internal/intern/enumerator.h function.o: $(hdrdir)/ruby/internal/intern/error.h function.o: $(hdrdir)/ruby/internal/intern/eval.h function.o: $(hdrdir)/ruby/internal/intern/file.h -function.o: $(hdrdir)/ruby/internal/intern/gc.h function.o: $(hdrdir)/ruby/internal/intern/hash.h function.o: $(hdrdir)/ruby/internal/intern/io.h function.o: $(hdrdir)/ruby/internal/intern/load.h @@ -688,12 +688,12 @@ function.o: $(hdrdir)/ruby/internal/memory.h function.o: $(hdrdir)/ruby/internal/method.h function.o: $(hdrdir)/ruby/internal/module.h function.o: $(hdrdir)/ruby/internal/newobj.h -function.o: $(hdrdir)/ruby/internal/rgengc.h function.o: $(hdrdir)/ruby/internal/scan_args.h function.o: $(hdrdir)/ruby/internal/special_consts.h function.o: $(hdrdir)/ruby/internal/static_assert.h function.o: $(hdrdir)/ruby/internal/stdalign.h function.o: $(hdrdir)/ruby/internal/stdbool.h +function.o: $(hdrdir)/ruby/internal/stdckdint.h function.o: $(hdrdir)/ruby/internal/symbol.h function.o: $(hdrdir)/ruby/internal/value.h function.o: $(hdrdir)/ruby/internal/value_type.h @@ -763,6 +763,7 @@ handle.o: $(hdrdir)/ruby/internal/attr/noexcept.h handle.o: $(hdrdir)/ruby/internal/attr/noinline.h handle.o: $(hdrdir)/ruby/internal/attr/nonnull.h handle.o: $(hdrdir)/ruby/internal/attr/noreturn.h +handle.o: $(hdrdir)/ruby/internal/attr/packed_struct.h handle.o: $(hdrdir)/ruby/internal/attr/pure.h handle.o: $(hdrdir)/ruby/internal/attr/restrict.h handle.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -822,7 +823,6 @@ handle.o: $(hdrdir)/ruby/internal/intern/enumerator.h handle.o: $(hdrdir)/ruby/internal/intern/error.h handle.o: $(hdrdir)/ruby/internal/intern/eval.h handle.o: $(hdrdir)/ruby/internal/intern/file.h -handle.o: $(hdrdir)/ruby/internal/intern/gc.h handle.o: $(hdrdir)/ruby/internal/intern/hash.h handle.o: $(hdrdir)/ruby/internal/intern/io.h handle.o: $(hdrdir)/ruby/internal/intern/load.h @@ -853,12 +853,12 @@ handle.o: $(hdrdir)/ruby/internal/memory.h handle.o: $(hdrdir)/ruby/internal/method.h handle.o: $(hdrdir)/ruby/internal/module.h handle.o: $(hdrdir)/ruby/internal/newobj.h -handle.o: $(hdrdir)/ruby/internal/rgengc.h handle.o: $(hdrdir)/ruby/internal/scan_args.h handle.o: $(hdrdir)/ruby/internal/special_consts.h handle.o: $(hdrdir)/ruby/internal/static_assert.h handle.o: $(hdrdir)/ruby/internal/stdalign.h handle.o: $(hdrdir)/ruby/internal/stdbool.h +handle.o: $(hdrdir)/ruby/internal/stdckdint.h handle.o: $(hdrdir)/ruby/internal/symbol.h handle.o: $(hdrdir)/ruby/internal/value.h handle.o: $(hdrdir)/ruby/internal/value_type.h @@ -928,6 +928,7 @@ memory_view.o: $(hdrdir)/ruby/internal/attr/noexcept.h memory_view.o: $(hdrdir)/ruby/internal/attr/noinline.h memory_view.o: $(hdrdir)/ruby/internal/attr/nonnull.h memory_view.o: $(hdrdir)/ruby/internal/attr/noreturn.h +memory_view.o: $(hdrdir)/ruby/internal/attr/packed_struct.h memory_view.o: $(hdrdir)/ruby/internal/attr/pure.h memory_view.o: $(hdrdir)/ruby/internal/attr/restrict.h memory_view.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -996,7 +997,6 @@ memory_view.o: $(hdrdir)/ruby/internal/intern/enumerator.h memory_view.o: $(hdrdir)/ruby/internal/intern/error.h memory_view.o: $(hdrdir)/ruby/internal/intern/eval.h memory_view.o: $(hdrdir)/ruby/internal/intern/file.h -memory_view.o: $(hdrdir)/ruby/internal/intern/gc.h memory_view.o: $(hdrdir)/ruby/internal/intern/hash.h memory_view.o: $(hdrdir)/ruby/internal/intern/io.h memory_view.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1027,12 +1027,12 @@ memory_view.o: $(hdrdir)/ruby/internal/memory.h memory_view.o: $(hdrdir)/ruby/internal/method.h memory_view.o: $(hdrdir)/ruby/internal/module.h memory_view.o: $(hdrdir)/ruby/internal/newobj.h -memory_view.o: $(hdrdir)/ruby/internal/rgengc.h memory_view.o: $(hdrdir)/ruby/internal/scan_args.h memory_view.o: $(hdrdir)/ruby/internal/special_consts.h memory_view.o: $(hdrdir)/ruby/internal/static_assert.h memory_view.o: $(hdrdir)/ruby/internal/stdalign.h memory_view.o: $(hdrdir)/ruby/internal/stdbool.h +memory_view.o: $(hdrdir)/ruby/internal/stdckdint.h memory_view.o: $(hdrdir)/ruby/internal/symbol.h memory_view.o: $(hdrdir)/ruby/internal/value.h memory_view.o: $(hdrdir)/ruby/internal/value_type.h @@ -1104,6 +1104,7 @@ pinned.o: $(hdrdir)/ruby/internal/attr/noexcept.h pinned.o: $(hdrdir)/ruby/internal/attr/noinline.h pinned.o: $(hdrdir)/ruby/internal/attr/nonnull.h pinned.o: $(hdrdir)/ruby/internal/attr/noreturn.h +pinned.o: $(hdrdir)/ruby/internal/attr/packed_struct.h pinned.o: $(hdrdir)/ruby/internal/attr/pure.h pinned.o: $(hdrdir)/ruby/internal/attr/restrict.h pinned.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1163,7 +1164,6 @@ pinned.o: $(hdrdir)/ruby/internal/intern/enumerator.h pinned.o: $(hdrdir)/ruby/internal/intern/error.h pinned.o: $(hdrdir)/ruby/internal/intern/eval.h pinned.o: $(hdrdir)/ruby/internal/intern/file.h -pinned.o: $(hdrdir)/ruby/internal/intern/gc.h pinned.o: $(hdrdir)/ruby/internal/intern/hash.h pinned.o: $(hdrdir)/ruby/internal/intern/io.h pinned.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1194,12 +1194,12 @@ pinned.o: $(hdrdir)/ruby/internal/memory.h pinned.o: $(hdrdir)/ruby/internal/method.h pinned.o: $(hdrdir)/ruby/internal/module.h pinned.o: $(hdrdir)/ruby/internal/newobj.h -pinned.o: $(hdrdir)/ruby/internal/rgengc.h pinned.o: $(hdrdir)/ruby/internal/scan_args.h pinned.o: $(hdrdir)/ruby/internal/special_consts.h pinned.o: $(hdrdir)/ruby/internal/static_assert.h pinned.o: $(hdrdir)/ruby/internal/stdalign.h pinned.o: $(hdrdir)/ruby/internal/stdbool.h +pinned.o: $(hdrdir)/ruby/internal/stdckdint.h pinned.o: $(hdrdir)/ruby/internal/symbol.h pinned.o: $(hdrdir)/ruby/internal/value.h pinned.o: $(hdrdir)/ruby/internal/value_type.h @@ -1269,6 +1269,7 @@ pointer.o: $(hdrdir)/ruby/internal/attr/noexcept.h pointer.o: $(hdrdir)/ruby/internal/attr/noinline.h pointer.o: $(hdrdir)/ruby/internal/attr/nonnull.h pointer.o: $(hdrdir)/ruby/internal/attr/noreturn.h +pointer.o: $(hdrdir)/ruby/internal/attr/packed_struct.h pointer.o: $(hdrdir)/ruby/internal/attr/pure.h pointer.o: $(hdrdir)/ruby/internal/attr/restrict.h pointer.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h @@ -1337,7 +1338,6 @@ pointer.o: $(hdrdir)/ruby/internal/intern/enumerator.h pointer.o: $(hdrdir)/ruby/internal/intern/error.h pointer.o: $(hdrdir)/ruby/internal/intern/eval.h pointer.o: $(hdrdir)/ruby/internal/intern/file.h -pointer.o: $(hdrdir)/ruby/internal/intern/gc.h pointer.o: $(hdrdir)/ruby/internal/intern/hash.h pointer.o: $(hdrdir)/ruby/internal/intern/io.h pointer.o: $(hdrdir)/ruby/internal/intern/load.h @@ -1368,12 +1368,12 @@ pointer.o: $(hdrdir)/ruby/internal/memory.h pointer.o: $(hdrdir)/ruby/internal/method.h pointer.o: $(hdrdir)/ruby/internal/module.h pointer.o: $(hdrdir)/ruby/internal/newobj.h -pointer.o: $(hdrdir)/ruby/internal/rgengc.h pointer.o: $(hdrdir)/ruby/internal/scan_args.h pointer.o: $(hdrdir)/ruby/internal/special_consts.h pointer.o: $(hdrdir)/ruby/internal/static_assert.h pointer.o: $(hdrdir)/ruby/internal/stdalign.h pointer.o: $(hdrdir)/ruby/internal/stdbool.h +pointer.o: $(hdrdir)/ruby/internal/stdckdint.h pointer.o: $(hdrdir)/ruby/internal/symbol.h pointer.o: $(hdrdir)/ruby/internal/value.h pointer.o: $(hdrdir)/ruby/internal/value_type.h diff --git a/ext/fiddle/extconf.rb b/ext/fiddle/extconf.rb index 93b4f9d4fa..2d85b3eea5 100644 --- a/ext/fiddle/extconf.rb +++ b/ext/fiddle/extconf.rb @@ -46,7 +46,7 @@ end libffi_version = nil have_libffi = false -bundle = enable_config('bundled-libffi') +bundle = with_config("libffi-source-dir") unless bundle dir_config 'libffi' @@ -63,31 +63,20 @@ unless bundle end if have_ffi_header && (have_library('ffi') || have_library('libffi')) have_libffi = true + checking_for("undefined FFI_GO_CLOSURES is used") do + if egrep_cpp(/warning: 'FFI_GO_CLOSURES' is not defined/, cpp_include(ffi_header), "2>&1") + $defs.push('-DFFI_GO_CLOSURES=0') + end + end end end unless have_libffi - # for https://github.com/ruby/fiddle - extlibs_rb = File.expand_path("../../bin/extlibs.rb", $srcdir) - if bundle && File.exist?(extlibs_rb) - require "fileutils" - require_relative "../../bin/extlibs" - extlibs = ExtLibs.new - cache_dir = File.expand_path("../../tmp/.download_cache", $srcdir) - ext_dir = File.expand_path("../../ext", $srcdir) - Dir.glob("#{$srcdir}/libffi-*/").each{|dir| FileUtils.rm_rf(dir)} - extlibs.run(["--cache=#{cache_dir}", ext_dir]) - end - if bundle != false - libffi_package_name = Dir.glob("#{$srcdir}/libffi-*/") - .map {|n| File.basename(n)} - .max_by {|n| n.scan(/\d+/).map(&:to_i)} - end - unless libffi_package_name - raise "missing libffi. Please install libffi." + if bundle + libffi_srcdir = libffi_package_name = bundle + else + raise "missing libffi. Please install libffi or use --with-libffi-source-dir with libffi source location." end - - libffi_srcdir = "#{$srcdir}/#{libffi_package_name}" ffi_header = 'ffi.h' libffi = Struct.new(*%I[dir srcdir builddir include lib a cflags ldflags opt arch]).new libffi.dir = libffi_package_name @@ -167,7 +156,7 @@ if libffi_version libffi_version = libffi_version.gsub(/-rc\d+/, '') libffi_version = (libffi_version.split('.').map(&:to_i) + [0,0])[0,3] $defs.push(%{-DRUBY_LIBFFI_MODVERSION=#{ '%d%03d%03d' % libffi_version }}) - puts "libffi_version: #{libffi_version.join('.')}" + warn "libffi_version: #{libffi_version.join('.')}" end case @@ -226,7 +215,7 @@ types.each do |type, signed| end if libffi - $LOCAL_LIBS.prepend("./#{libffi.a} ").strip! # to exts.mk + $LOCAL_LIBS.prepend("#{libffi.a} ").strip! # to exts.mk $INCFLAGS.gsub!(/-I#{libffi.dir}/, '-I$(LIBFFI_DIR)') end create_makefile 'fiddle' do |conf| diff --git a/ext/fiddle/extlibs b/ext/fiddle/extlibs deleted file mode 100644 index 68dac46a95..0000000000 --- a/ext/fiddle/extlibs +++ /dev/null @@ -1,13 +0,0 @@ -ver = 3.2.1 -pkg = libffi-$(ver) - -https://ftp.osuosl.org/pub/blfs/conglomeration/libffi/$(pkg).tar.gz \ - md5:83b89587607e3eb65c70d361f13bab43 \ - sha512:980ca30a8d76f963fca722432b1fe5af77d7a4e4d2eac5144fbc5374d4c596609a293440573f4294207e1bdd9fda80ad1e1cafb2ffb543df5a275bc3bd546483 \ - # - win32/$(pkg)-mswin.patch -p0 - -$(pkg)/config.guess -> /tool/config.guess -$(pkg)/config.sub -> /tool/config.sub - -! chdir: $(pkg)| autoconf || exit 0 diff --git a/ext/fiddle/fiddle.c b/ext/fiddle/fiddle.c index a8b5123269..91a998813a 100644 --- a/ext/fiddle/fiddle.c +++ b/ext/fiddle/fiddle.c @@ -1,3 +1,5 @@ +#include <stdbool.h> + #include <fiddle.h> VALUE mFiddle; @@ -58,18 +60,16 @@ rb_fiddle_free(VALUE self, VALUE addr) /* * call-seq: Fiddle.dlunwrap(addr) * - * Returns the hexadecimal representation of a memory pointer address +addr+ + * Returns the Ruby object stored at the memory address +addr+ * * Example: * - * lib = Fiddle.dlopen('/lib64/libc-2.15.so') - * => #<Fiddle::Handle:0x00000001342460> - * - * lib['strcpy'].to_s(16) - * => "7f59de6dd240" - * - * Fiddle.dlunwrap(Fiddle.dlwrap(lib['strcpy'].to_s(16))) - * => "7f59de6dd240" + * x = Object.new + * # => #<Object:0x0000000107c7d870> + * Fiddle.dlwrap(x) + * # => 4425504880 + * Fiddle.dlunwrap(_) + * # => #<Object:0x0000000107c7d870> */ VALUE rb_fiddle_ptr2value(VALUE self, VALUE addr) @@ -80,15 +80,22 @@ rb_fiddle_ptr2value(VALUE self, VALUE addr) /* * call-seq: Fiddle.dlwrap(val) * - * Returns a memory pointer of a function's hexadecimal address location +val+ + * Returns the memory address of the Ruby object stored at +val+ * * Example: * - * lib = Fiddle.dlopen('/lib64/libc-2.15.so') - * => #<Fiddle::Handle:0x00000001342460> + * x = Object.new + * # => #<Object:0x0000000107c7d870> + * Fiddle.dlwrap(x) + * # => 4425504880 + * + * In the case +val+ is not a heap allocated object, this method will return + * the tagged pointer value. + * + * Example: * - * Fiddle.dlwrap(lib['strcpy'].to_s(16)) - * => 25522520 + * Fiddle.dlwrap(123) + * # => 247 */ static VALUE rb_fiddle_value2ptr(VALUE self, VALUE val) @@ -164,137 +171,199 @@ Init_fiddle(void) */ rb_eFiddleDLError = rb_define_class_under(mFiddle, "DLError", rb_eFiddleError); - /* Document-const: TYPE_VOID + VALUE mFiddleTypes = rb_define_module_under(mFiddle, "Types"); + + /* Document-const: Fiddle::Types::VOID * * C type - void */ - rb_define_const(mFiddle, "TYPE_VOID", INT2NUM(TYPE_VOID)); + rb_define_const(mFiddleTypes, "VOID", INT2NUM(TYPE_VOID)); - /* Document-const: TYPE_VOIDP + /* Document-const: Fiddle::Types::VOIDP * * C type - void* */ - rb_define_const(mFiddle, "TYPE_VOIDP", INT2NUM(TYPE_VOIDP)); + rb_define_const(mFiddleTypes, "VOIDP", INT2NUM(TYPE_VOIDP)); - /* Document-const: TYPE_CHAR + /* Document-const: Fiddle::Types::CHAR * * C type - char */ - rb_define_const(mFiddle, "TYPE_CHAR", INT2NUM(TYPE_CHAR)); + rb_define_const(mFiddleTypes, "CHAR", INT2NUM(TYPE_CHAR)); - /* Document-const: TYPE_SHORT + /* Document-const: Fiddle::Types::UCHAR + * + * C type - unsigned char + */ + rb_define_const(mFiddleTypes, "UCHAR", INT2NUM(TYPE_UCHAR)); + + /* Document-const: Fiddle::Types::SHORT * * C type - short */ - rb_define_const(mFiddle, "TYPE_SHORT", INT2NUM(TYPE_SHORT)); + rb_define_const(mFiddleTypes, "SHORT", INT2NUM(TYPE_SHORT)); - /* Document-const: TYPE_INT + /* Document-const: Fiddle::Types::USHORT + * + * C type - unsigned short + */ + rb_define_const(mFiddleTypes, "USHORT", INT2NUM(TYPE_USHORT)); + + /* Document-const: Fiddle::Types::INT * * C type - int */ - rb_define_const(mFiddle, "TYPE_INT", INT2NUM(TYPE_INT)); + rb_define_const(mFiddleTypes, "INT", INT2NUM(TYPE_INT)); + + /* Document-const: Fiddle::Types::UINT + * + * C type - unsigned int + */ + rb_define_const(mFiddleTypes, "UINT", INT2NUM(TYPE_UINT)); - /* Document-const: TYPE_LONG + /* Document-const: Fiddle::Types::LONG * * C type - long */ - rb_define_const(mFiddle, "TYPE_LONG", INT2NUM(TYPE_LONG)); + rb_define_const(mFiddleTypes, "LONG", INT2NUM(TYPE_LONG)); + + /* Document-const: Fiddle::Types::ULONG + * + * C type - long + */ + rb_define_const(mFiddleTypes, "ULONG", INT2NUM(TYPE_ULONG)); #if HAVE_LONG_LONG - /* Document-const: TYPE_LONG_LONG + /* Document-const: Fiddle::Types::LONG_LONG + * + * C type - long long + */ + rb_define_const(mFiddleTypes, "LONG_LONG", INT2NUM(TYPE_LONG_LONG)); + + /* Document-const: Fiddle::Types::ULONG_LONG * * C type - long long */ - rb_define_const(mFiddle, "TYPE_LONG_LONG", INT2NUM(TYPE_LONG_LONG)); + rb_define_const(mFiddleTypes, "ULONG_LONG", INT2NUM(TYPE_ULONG_LONG)); #endif #ifdef TYPE_INT8_T - /* Document-const: TYPE_INT8_T + /* Document-const: Fiddle::Types::INT8_T * * C type - int8_t */ - rb_define_const(mFiddle, "TYPE_INT8_T", INT2NUM(TYPE_INT8_T)); + rb_define_const(mFiddleTypes, "INT8_T", INT2NUM(TYPE_INT8_T)); + + /* Document-const: Fiddle::Types::UINT8_T + * + * C type - uint8_t + */ + rb_define_const(mFiddleTypes, "UINT8_T", INT2NUM(TYPE_UINT8_T)); #endif #ifdef TYPE_INT16_T - /* Document-const: TYPE_INT16_T + /* Document-const: Fiddle::Types::INT16_T * * C type - int16_t */ - rb_define_const(mFiddle, "TYPE_INT16_T", INT2NUM(TYPE_INT16_T)); + rb_define_const(mFiddleTypes, "INT16_T", INT2NUM(TYPE_INT16_T)); + + /* Document-const: Fiddle::Types::UINT16_T + * + * C type - uint16_t + */ + rb_define_const(mFiddleTypes, "UINT16_T", INT2NUM(TYPE_UINT16_T)); #endif #ifdef TYPE_INT32_T - /* Document-const: TYPE_INT32_T + /* Document-const: Fiddle::Types::INT32_T * * C type - int32_t */ - rb_define_const(mFiddle, "TYPE_INT32_T", INT2NUM(TYPE_INT32_T)); + rb_define_const(mFiddleTypes, "INT32_T", INT2NUM(TYPE_INT32_T)); + + /* Document-const: Fiddle::Types::UINT32_T + * + * C type - uint32_t + */ + rb_define_const(mFiddleTypes, "UINT32_T", INT2NUM(TYPE_UINT32_T)); #endif #ifdef TYPE_INT64_T - /* Document-const: TYPE_INT64_T + /* Document-const: Fiddle::Types::INT64_T * * C type - int64_t */ - rb_define_const(mFiddle, "TYPE_INT64_T", INT2NUM(TYPE_INT64_T)); + rb_define_const(mFiddleTypes, "INT64_T", INT2NUM(TYPE_INT64_T)); + + /* Document-const: Fiddle::Types::UINT64_T + * + * C type - uint64_t + */ + rb_define_const(mFiddleTypes, "UINT64_T", INT2NUM(TYPE_UINT64_T)); #endif - /* Document-const: TYPE_FLOAT + /* Document-const: Fiddle::Types::FLOAT * * C type - float */ - rb_define_const(mFiddle, "TYPE_FLOAT", INT2NUM(TYPE_FLOAT)); + rb_define_const(mFiddleTypes, "FLOAT", INT2NUM(TYPE_FLOAT)); - /* Document-const: TYPE_DOUBLE + /* Document-const: Fiddle::Types::DOUBLE * * C type - double */ - rb_define_const(mFiddle, "TYPE_DOUBLE", INT2NUM(TYPE_DOUBLE)); + rb_define_const(mFiddleTypes, "DOUBLE", INT2NUM(TYPE_DOUBLE)); #ifdef HAVE_FFI_PREP_CIF_VAR - /* Document-const: TYPE_VARIADIC + /* Document-const: Fiddle::Types::VARIADIC * * C type - ... */ - rb_define_const(mFiddle, "TYPE_VARIADIC", INT2NUM(TYPE_VARIADIC)); + rb_define_const(mFiddleTypes, "VARIADIC", INT2NUM(TYPE_VARIADIC)); #endif - /* Document-const: TYPE_CONST_STRING + /* Document-const: Fiddle::Types::CONST_STRING * * C type - const char* ('\0' terminated const char*) */ - rb_define_const(mFiddle, "TYPE_CONST_STRING", INT2NUM(TYPE_CONST_STRING)); + rb_define_const(mFiddleTypes, "CONST_STRING", INT2NUM(TYPE_CONST_STRING)); - /* Document-const: TYPE_SIZE_T + /* Document-const: Fiddle::Types::SIZE_T * * C type - size_t */ - rb_define_const(mFiddle, "TYPE_SIZE_T", INT2NUM(TYPE_SIZE_T)); + rb_define_const(mFiddleTypes, "SIZE_T", INT2NUM(TYPE_SIZE_T)); - /* Document-const: TYPE_SSIZE_T + /* Document-const: Fiddle::Types::SSIZE_T * * C type - ssize_t */ - rb_define_const(mFiddle, "TYPE_SSIZE_T", INT2NUM(TYPE_SSIZE_T)); + rb_define_const(mFiddleTypes, "SSIZE_T", INT2NUM(TYPE_SSIZE_T)); - /* Document-const: TYPE_PTRDIFF_T + /* Document-const: Fiddle::Types::PTRDIFF_T * * C type - ptrdiff_t */ - rb_define_const(mFiddle, "TYPE_PTRDIFF_T", INT2NUM(TYPE_PTRDIFF_T)); + rb_define_const(mFiddleTypes, "PTRDIFF_T", INT2NUM(TYPE_PTRDIFF_T)); - /* Document-const: TYPE_INTPTR_T + /* Document-const: Fiddle::Types::INTPTR_T * * C type - intptr_t */ - rb_define_const(mFiddle, "TYPE_INTPTR_T", INT2NUM(TYPE_INTPTR_T)); + rb_define_const(mFiddleTypes, "INTPTR_T", INT2NUM(TYPE_INTPTR_T)); - /* Document-const: TYPE_UINTPTR_T + /* Document-const: Fiddle::Types::UINTPTR_T * * C type - uintptr_t */ - rb_define_const(mFiddle, "TYPE_UINTPTR_T", INT2NUM(TYPE_UINTPTR_T)); + rb_define_const(mFiddleTypes, "UINTPTR_T", INT2NUM(TYPE_UINTPTR_T)); + + /* Document-const: Fiddle::Types::BOOL + * + * C type - bool + */ + rb_define_const(mFiddleTypes, "BOOL" , INT2NUM(TYPE_BOOL)); /* Document-const: ALIGN_VOIDP * @@ -400,6 +469,12 @@ Init_fiddle(void) */ rb_define_const(mFiddle, "ALIGN_UINTPTR_T", INT2NUM(ALIGN_OF(uintptr_t))); + /* Document-const: ALIGN_BOOL + * + * The alignment size of a bool + */ + rb_define_const(mFiddle, "ALIGN_BOOL", INT2NUM(ALIGN_OF(bool))); + /* Document-const: WINDOWS * * Returns a boolean regarding whether the host is WIN32 @@ -422,30 +497,60 @@ Init_fiddle(void) */ rb_define_const(mFiddle, "SIZEOF_CHAR", INT2NUM(sizeof(char))); + /* Document-const: SIZEOF_UCHAR + * + * size of a unsigned char + */ + rb_define_const(mFiddle, "SIZEOF_UCHAR", INT2NUM(sizeof(unsigned char))); + /* Document-const: SIZEOF_SHORT * * size of a short */ rb_define_const(mFiddle, "SIZEOF_SHORT", INT2NUM(sizeof(short))); + /* Document-const: SIZEOF_USHORT + * + * size of a unsigned short + */ + rb_define_const(mFiddle, "SIZEOF_USHORT", INT2NUM(sizeof(unsigned short))); + /* Document-const: SIZEOF_INT * * size of an int */ rb_define_const(mFiddle, "SIZEOF_INT", INT2NUM(sizeof(int))); + /* Document-const: SIZEOF_UINT + * + * size of an unsigned int + */ + rb_define_const(mFiddle, "SIZEOF_UINT", INT2NUM(sizeof(unsigned int))); + /* Document-const: SIZEOF_LONG * * size of a long */ rb_define_const(mFiddle, "SIZEOF_LONG", INT2NUM(sizeof(long))); + /* Document-const: SIZEOF_ULONG + * + * size of a unsigned long + */ + rb_define_const(mFiddle, "SIZEOF_ULONG", INT2NUM(sizeof(unsigned long))); + #if HAVE_LONG_LONG /* Document-const: SIZEOF_LONG_LONG * * size of a long long */ rb_define_const(mFiddle, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG))); + + /* Document-const: SIZEOF_ULONG_LONG + * + * size of a unsigned long long + */ + rb_define_const(mFiddle, "SIZEOF_ULONG_LONG", INT2NUM(sizeof(unsigned LONG_LONG))); #endif /* Document-const: SIZEOF_INT8_T @@ -454,24 +559,48 @@ Init_fiddle(void) */ rb_define_const(mFiddle, "SIZEOF_INT8_T", INT2NUM(sizeof(int8_t))); + /* Document-const: SIZEOF_UINT8_T + * + * size of a uint8_t + */ + rb_define_const(mFiddle, "SIZEOF_UINT8_T", INT2NUM(sizeof(uint8_t))); + /* Document-const: SIZEOF_INT16_T * * size of a int16_t */ rb_define_const(mFiddle, "SIZEOF_INT16_T", INT2NUM(sizeof(int16_t))); + /* Document-const: SIZEOF_UINT16_T + * + * size of a uint16_t + */ + rb_define_const(mFiddle, "SIZEOF_UINT16_T", INT2NUM(sizeof(uint16_t))); + /* Document-const: SIZEOF_INT32_T * * size of a int32_t */ rb_define_const(mFiddle, "SIZEOF_INT32_T", INT2NUM(sizeof(int32_t))); + /* Document-const: SIZEOF_UINT32_T + * + * size of a uint32_t + */ + rb_define_const(mFiddle, "SIZEOF_UINT32_T", INT2NUM(sizeof(uint32_t))); + /* Document-const: SIZEOF_INT64_T * * size of a int64_t */ rb_define_const(mFiddle, "SIZEOF_INT64_T", INT2NUM(sizeof(int64_t))); + /* Document-const: SIZEOF_UINT64_T + * + * size of a uint64_t + */ + rb_define_const(mFiddle, "SIZEOF_UINT64_T", INT2NUM(sizeof(uint64_t))); + /* Document-const: SIZEOF_FLOAT * * size of a float @@ -520,6 +649,12 @@ Init_fiddle(void) */ rb_define_const(mFiddle, "SIZEOF_CONST_STRING", INT2NUM(sizeof(const char*))); + /* Document-const: SIZEOF_BOOL + * + * size of a bool + */ + rb_define_const(mFiddle, "SIZEOF_BOOL", INT2NUM(sizeof(bool))); + /* Document-const: RUBY_FREE * * Address of the ruby_xfree() function @@ -540,6 +675,30 @@ Init_fiddle(void) rb_define_module_function(mFiddle, "realloc", rb_fiddle_realloc, 2); rb_define_module_function(mFiddle, "free", rb_fiddle_free, 1); + /* Document-const: Qtrue + * + * The value of Qtrue + */ + rb_define_const(mFiddle, "Qtrue", INT2NUM(Qtrue)); + + /* Document-const: Qfalse + * + * The value of Qfalse + */ + rb_define_const(mFiddle, "Qfalse", INT2NUM(Qfalse)); + + /* Document-const: Qnil + * + * The value of Qnil + */ + rb_define_const(mFiddle, "Qnil", INT2NUM(Qnil)); + + /* Document-const: Qundef + * + * The value of Qundef + */ + rb_define_const(mFiddle, "Qundef", INT2NUM(Qundef)); + Init_fiddle_function(); Init_fiddle_closure(); Init_fiddle_handle(); @@ -550,4 +709,3 @@ Init_fiddle(void) Init_fiddle_memory_view(); #endif } -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/fiddle/fiddle.gemspec b/ext/fiddle/fiddle.gemspec index a9c0ec4026..fc3cbfabc7 100644 --- a/ext/fiddle/fiddle.gemspec +++ b/ext/fiddle/fiddle.gemspec @@ -20,15 +20,12 @@ Gem::Specification.new do |spec| "LICENSE.txt", "README.md", "Rakefile", - "bin/downloader.rb", - "bin/extlibs.rb", "ext/fiddle/closure.c", "ext/fiddle/closure.h", "ext/fiddle/conversions.c", "ext/fiddle/conversions.h", "ext/fiddle/depend", "ext/fiddle/extconf.rb", - "ext/fiddle/extlibs", "ext/fiddle/fiddle.c", "ext/fiddle/fiddle.h", "ext/fiddle/function.c", @@ -37,10 +34,6 @@ Gem::Specification.new do |spec| "ext/fiddle/memory_view.c", "ext/fiddle/pinned.c", "ext/fiddle/pointer.c", - "ext/fiddle/win32/fficonfig.h", - "ext/fiddle/win32/libffi-3.2.1-mswin.patch", - "ext/fiddle/win32/libffi-config.rb", - "ext/fiddle/win32/libffi.mk.tmpl", "fiddle.gemspec", "lib/fiddle.rb", "lib/fiddle/closure.rb", @@ -59,4 +52,5 @@ Gem::Specification.new do |spec| spec.required_ruby_version = ">= 2.5.0" spec.metadata["msys2_mingw_dependencies"] = "libffi" + spec.metadata["changelog_uri"] = "https://github.com/ruby/fiddle/releases" end diff --git a/ext/fiddle/fiddle.h b/ext/fiddle/fiddle.h index 9de62a58cc..54391b95f5 100644 --- a/ext/fiddle/fiddle.h +++ b/ext/fiddle/fiddle.h @@ -111,23 +111,36 @@ #define TYPE_VOID 0 #define TYPE_VOIDP 1 #define TYPE_CHAR 2 +#define TYPE_UCHAR -TYPE_CHAR #define TYPE_SHORT 3 +#define TYPE_USHORT -TYPE_SHORT #define TYPE_INT 4 +#define TYPE_UINT -TYPE_INT #define TYPE_LONG 5 -#if HAVE_LONG_LONG +#define TYPE_ULONG -TYPE_LONG +#ifdef HAVE_LONG_LONG #define TYPE_LONG_LONG 6 +#define TYPE_ULONG_LONG -TYPE_LONG_LONG #endif #define TYPE_FLOAT 7 #define TYPE_DOUBLE 8 #define TYPE_VARIADIC 9 #define TYPE_CONST_STRING 10 +#define TYPE_BOOL 11 #define TYPE_INT8_T TYPE_CHAR +#define TYPE_UINT8_T -TYPE_INT8_T + #if SIZEOF_SHORT == 2 # define TYPE_INT16_T TYPE_SHORT #elif SIZEOF_INT == 2 # define TYPE_INT16_T TYPE_INT #endif + +#ifdef TYPE_INT16_T +# define TYPE_UINT16_T -TYPE_INT16_T +#endif + #if SIZEOF_SHORT == 4 # define TYPE_INT32_T TYPE_SHORT #elif SIZEOF_INT == 4 @@ -135,6 +148,11 @@ #elif SIZEOF_LONG == 4 # define TYPE_INT32_T TYPE_LONG #endif + +#ifdef TYPE_INT32_T +#define TYPE_UINT32_T -TYPE_INT32_T +#endif + #if SIZEOF_INT == 8 # define TYPE_INT64_T TYPE_INT #elif SIZEOF_LONG == 8 @@ -143,6 +161,10 @@ # define TYPE_INT64_T TYPE_LONG_LONG #endif +#ifdef TYPE_INT64_T +#define TYPE_UINT64_T -TYPE_INT64_T +#endif + #ifndef TYPE_SSIZE_T # if SIZEOF_SIZE_T == SIZEOF_INT # define TYPE_SSIZE_T TYPE_INT @@ -175,7 +197,20 @@ #endif #define TYPE_UINTPTR_T (-TYPE_INTPTR_T) -#define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x) +/* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023 + <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>. + clang versions < 8.0.0 have the same bug. */ +#if defined(HAVE__ALIGNOF) +# /* Autoconf detected availability of a sane `_Alignof()`. */ +# define ALIGN_OF(type) RB_GNUC_EXTENSION(_Alignof(type)) +#elif (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112 \ + || (defined(__GNUC__) && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \ + && !defined(__clang__)) \ + || (defined(__clang__) && __clang_major__ < 8)) +# define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x) +#else +# define ALIGN_OF(type) _Alignof(type) +#endif #define ALIGN_VOIDP ALIGN_OF(void*) #define ALIGN_CHAR ALIGN_OF(char) @@ -202,4 +237,3 @@ typedef void (*rb_fiddle_freefunc_t)(void*); VALUE rb_fiddle_ptr_new_wrap(void *ptr, long size, rb_fiddle_freefunc_t func, VALUE wrap0, VALUE wrap1); #endif -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/fiddle/function.c b/ext/fiddle/function.c index 274d181d17..b6a105abe1 100644 --- a/ext/fiddle/function.c +++ b/ext/fiddle/function.c @@ -53,8 +53,13 @@ function_memsize(const void *p) } const rb_data_type_t function_data_type = { - "fiddle/function", - {0, deallocate, function_memsize,}, + .wrap_struct_name = "fiddle/function", + .function = { + .dmark = 0, + .dfree = deallocate, + .dsize = function_memsize + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -488,4 +493,3 @@ Init_fiddle_function(void) */ rb_define_method(cFiddleFunction, "initialize", initialize, -1); } -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/fiddle/handle.c b/ext/fiddle/handle.c index 76b90909d3..558d6d4551 100644 --- a/ext/fiddle/handle.c +++ b/ext/fiddle/handle.c @@ -50,8 +50,13 @@ fiddle_handle_memsize(const void *ptr) } static const rb_data_type_t fiddle_handle_data_type = { - "fiddle/handle", - {0, fiddle_handle_free, fiddle_handle_memsize,}, + .wrap_struct_name = "fiddle/handle", + .function = { + .dmark = 0, + .dfree = fiddle_handle_free, + .dsize = fiddle_handle_memsize + }, + .flags = RUBY_TYPED_WB_PROTECTED, }; /* @@ -321,8 +326,10 @@ rb_fiddle_handle_s_sym(VALUE self, VALUE sym) return fiddle_handle_sym(RTLD_NEXT, sym); } -static VALUE -fiddle_handle_sym(void *handle, VALUE symbol) +typedef void (*fiddle_void_func)(void); + +static fiddle_void_func +fiddle_handle_find_func(void *handle, VALUE symbol) { #if defined(HAVE_DLERROR) const char *err; @@ -330,13 +337,13 @@ fiddle_handle_sym(void *handle, VALUE symbol) #else # define CHECK_DLERROR #endif - void (*func)(); + fiddle_void_func func; const char *name = StringValueCStr(symbol); #ifdef HAVE_DLERROR dlerror(); #endif - func = (void (*)())(VALUE)dlsym(handle, name); + func = (fiddle_void_func)(VALUE)dlsym(handle, name); CHECK_DLERROR; #if defined(FUNC_STDCALL) if( !func ){ @@ -379,6 +386,53 @@ fiddle_handle_sym(void *handle, VALUE symbol) xfree(name_n); } #endif + + return func; +} + +static VALUE +rb_fiddle_handle_s_sym_defined(VALUE self, VALUE sym) +{ + fiddle_void_func func; + + func = fiddle_handle_find_func(RTLD_NEXT, sym); + + if( func ) { + return PTR2NUM(func); + } + else { + return Qnil; + } +} + +static VALUE +rb_fiddle_handle_sym_defined(VALUE self, VALUE sym) +{ + struct dl_handle *fiddle_handle; + fiddle_void_func func; + + TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle); + if( ! fiddle_handle->open ){ + rb_raise(rb_eFiddleDLError, "closed handle"); + } + + func = fiddle_handle_find_func(fiddle_handle->ptr, sym); + + if( func ) { + return PTR2NUM(func); + } + else { + return Qnil; + } +} + +static VALUE +fiddle_handle_sym(void *handle, VALUE symbol) +{ + fiddle_void_func func; + + func = fiddle_handle_find_func(handle, symbol); + if( !func ){ rb_raise(rb_eFiddleDLError, "unknown symbol \"%"PRIsVALUE"\"", symbol); } @@ -468,6 +522,7 @@ Init_fiddle_handle(void) rb_cHandle = rb_define_class_under(mFiddle, "Handle", rb_cObject); rb_define_alloc_func(rb_cHandle, rb_fiddle_handle_s_allocate); rb_define_singleton_method(rb_cHandle, "sym", rb_fiddle_handle_s_sym, 1); + rb_define_singleton_method(rb_cHandle, "sym_defined?", rb_fiddle_handle_s_sym_defined, 1); rb_define_singleton_method(rb_cHandle, "[]", rb_fiddle_handle_s_sym, 1); /* Document-const: NEXT @@ -526,10 +581,9 @@ Init_fiddle_handle(void) rb_define_method(rb_cHandle, "close", rb_fiddle_handle_close, 0); rb_define_method(rb_cHandle, "sym", rb_fiddle_handle_sym, 1); rb_define_method(rb_cHandle, "[]", rb_fiddle_handle_sym, 1); + rb_define_method(rb_cHandle, "sym_defined?", rb_fiddle_handle_sym_defined, 1); rb_define_method(rb_cHandle, "file_name", rb_fiddle_handle_file_name, 0); rb_define_method(rb_cHandle, "disable_close", rb_fiddle_handle_disable_close, 0); rb_define_method(rb_cHandle, "enable_close", rb_fiddle_handle_enable_close, 0); rb_define_method(rb_cHandle, "close_enabled?", rb_fiddle_handle_close_enabled_p, 0); } - -/* vim: set noet sws=4 sw=4: */ diff --git a/ext/fiddle/lib/fiddle.rb b/ext/fiddle/lib/fiddle.rb index 4512989310..6137c487c6 100644 --- a/ext/fiddle/lib/fiddle.rb +++ b/ext/fiddle/lib/fiddle.rb @@ -58,7 +58,36 @@ module Fiddle # # See Fiddle::Handle.new for more. def dlopen library - Fiddle::Handle.new library + begin + Fiddle::Handle.new(library) + rescue DLError => error + case RUBY_PLATFORM + when /linux/ + case error.message + when /\A(\/.+?): (?:invalid ELF header|file too short)/ + # This may be a linker script: + # https://sourceware.org/binutils/docs/ld.html#Scripts + path = $1 + else + raise + end + else + raise + end + + File.open(path) do |input| + input.each_line do |line| + case line + when /\A\s*(?:INPUT|GROUP)\s*\(\s*([^\s,\)]+)/ + # TODO: Should we support multiple files? + return dlopen($1) + end + end + end + + # Not found + raise + end end module_function :dlopen @@ -67,4 +96,8 @@ module Fiddle RTLD_GLOBAL = Handle::RTLD_GLOBAL # :nodoc: RTLD_LAZY = Handle::RTLD_LAZY # :nodoc: RTLD_NOW = Handle::RTLD_NOW # :nodoc: + + Fiddle::Types.constants.each do |type| + const_set "TYPE_#{type}", Fiddle::Types.const_get(type) + end end diff --git a/ext/fiddle/lib/fiddle/closure.rb b/ext/fiddle/lib/fiddle/closure.rb index c865a63c20..7e0077ea52 100644 --- a/ext/fiddle/lib/fiddle/closure.rb +++ b/ext/fiddle/lib/fiddle/closure.rb @@ -1,6 +1,31 @@ # frozen_string_literal: true module Fiddle class Closure + class << self + # Create a new closure. If a block is given, the created closure + # is automatically freed after the given block is executed. + # + # The all given arguments are passed to Fiddle::Closure.new. So + # using this method without block equals to Fiddle::Closure.new. + # + # == Example + # + # Fiddle::Closure.create(TYPE_INT, [TYPE_INT]) do |closure| + # # closure is freed automatically when this block is finished. + # end + def create(*args) + if block_given? + closure = new(*args) + begin + yield(closure) + ensure + closure.free + end + else + new(*args) + end + end + end # the C type of the return of the FFI closure attr_reader :ctype diff --git a/ext/fiddle/lib/fiddle/cparser.rb b/ext/fiddle/lib/fiddle/cparser.rb index 93a05513c9..264ca166dd 100644 --- a/ext/fiddle/lib/fiddle/cparser.rb +++ b/ext/fiddle/lib/fiddle/cparser.rb @@ -164,23 +164,35 @@ module Fiddle unless Fiddle.const_defined?(:TYPE_LONG_LONG) raise(RuntimeError, "unsupported type: #{ty}") end - return -TYPE_LONG_LONG - when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/ + return TYPE_ULONG_LONG + when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/, + /\Aunsigned\s+int\s+long(?:\s+\w+)?\z/, + /\Along(?:\s+int)?\s+unsigned(?:\s+\w+)?\z/, + /\Aint\s+unsigned\s+long(?:\s+\w+)?\z/, + /\A(?:int\s+)?long\s+unsigned(?:\s+\w+)?\z/ + return TYPE_ULONG + when /\A(?:signed\s+)?long(?:\s+int\s+)?(?:\s+\w+)?\z/, + /\A(?:signed\s+)?int\s+long(?:\s+\w+)?\z/, + /\Along(?:\s+int)?\s+signed(?:\s+\w+)?\z/ return TYPE_LONG - when /\Aunsigned\s+long(?:\s+int\s+)?(?:\s+\w+)?\z/ - return -TYPE_LONG + when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/, + /\Aunsigned\s+int\s+short(?:\s+\w+)?\z/, + /\Ashort(?:\s+int)?\s+unsigned(?:\s+\w+)?\z/, + /\Aint\s+unsigned\s+short(?:\s+\w+)?\z/, + /\A(?:int\s+)?short\s+unsigned(?:\s+\w+)?\z/ + return TYPE_USHORT + when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/, + /\A(?:signed\s+)?int\s+short(?:\s+\w+)?\z/, + /\Aint\s+(?:signed\s+)?short(?:\s+\w+)?\z/ + return TYPE_SHORT when /\A(?:signed\s+)?int(?:\s+\w+)?\z/ return TYPE_INT when /\A(?:unsigned\s+int|uint)(?:\s+\w+)?\z/ - return -TYPE_INT - when /\A(?:signed\s+)?short(?:\s+int\s+)?(?:\s+\w+)?\z/ - return TYPE_SHORT - when /\Aunsigned\s+short(?:\s+int\s+)?(?:\s+\w+)?\z/ - return -TYPE_SHORT + return TYPE_UINT when /\A(?:signed\s+)?char(?:\s+\w+)?\z/ return TYPE_CHAR when /\Aunsigned\s+char(?:\s+\w+)?\z/ - return -TYPE_CHAR + return TYPE_UCHAR when /\Aint8_t(?:\s+\w+)?\z/ unless Fiddle.const_defined?(:TYPE_INT8_T) raise(RuntimeError, "unsupported type: #{ty}") @@ -190,7 +202,7 @@ module Fiddle unless Fiddle.const_defined?(:TYPE_INT8_T) raise(RuntimeError, "unsupported type: #{ty}") end - return -TYPE_INT8_T + return TYPE_UINT8_T when /\Aint16_t(?:\s+\w+)?\z/ unless Fiddle.const_defined?(:TYPE_INT16_T) raise(RuntimeError, "unsupported type: #{ty}") @@ -200,7 +212,7 @@ module Fiddle unless Fiddle.const_defined?(:TYPE_INT16_T) raise(RuntimeError, "unsupported type: #{ty}") end - return -TYPE_INT16_T + return TYPE_UINT16_T when /\Aint32_t(?:\s+\w+)?\z/ unless Fiddle.const_defined?(:TYPE_INT32_T) raise(RuntimeError, "unsupported type: #{ty}") @@ -210,7 +222,7 @@ module Fiddle unless Fiddle.const_defined?(:TYPE_INT32_T) raise(RuntimeError, "unsupported type: #{ty}") end - return -TYPE_INT32_T + return TYPE_UINT32_T when /\Aint64_t(?:\s+\w+)?\z/ unless Fiddle.const_defined?(:TYPE_INT64_T) raise(RuntimeError, "unsupported type: #{ty}") @@ -220,7 +232,7 @@ module Fiddle unless Fiddle.const_defined?(:TYPE_INT64_T) raise(RuntimeError, "unsupported type: #{ty}") end - return -TYPE_INT64_T + return TYPE_UINT64_T when /\Afloat(?:\s+\w+)?\z/ return TYPE_FLOAT when /\Adouble(?:\s+\w+)?\z/ @@ -235,6 +247,8 @@ module Fiddle return TYPE_INTPTR_T when /\Auintptr_t(?:\s+\w+)?\z/ return TYPE_UINTPTR_T + when "bool" + return TYPE_BOOL when /\*/, /\[[\s\d]*\]/ return TYPE_VOIDP when "..." diff --git a/ext/fiddle/lib/fiddle/import.rb b/ext/fiddle/lib/fiddle/import.rb index 09ffcef544..050708fb96 100644 --- a/ext/fiddle/lib/fiddle/import.rb +++ b/ext/fiddle/lib/fiddle/import.rb @@ -119,6 +119,8 @@ module Fiddle return SIZEOF_VOIDP when TYPE_CONST_STRING return SIZEOF_CONST_STRING + when TYPE_BOOL + return SIZEOF_BOOL else if defined?(TYPE_LONG_LONG) and ty == TYPE_LONG_LONG diff --git a/ext/fiddle/lib/fiddle/pack.rb b/ext/fiddle/lib/fiddle/pack.rb index 22eccedb76..81088f402b 100644 --- a/ext/fiddle/lib/fiddle/pack.rb +++ b/ext/fiddle/lib/fiddle/pack.rb @@ -11,25 +11,36 @@ module Fiddle TYPE_LONG => ALIGN_LONG, TYPE_FLOAT => ALIGN_FLOAT, TYPE_DOUBLE => ALIGN_DOUBLE, - -TYPE_CHAR => ALIGN_CHAR, - -TYPE_SHORT => ALIGN_SHORT, - -TYPE_INT => ALIGN_INT, - -TYPE_LONG => ALIGN_LONG, + TYPE_UCHAR => ALIGN_CHAR, + TYPE_USHORT => ALIGN_SHORT, + TYPE_UINT => ALIGN_INT, + TYPE_ULONG => ALIGN_LONG, + TYPE_BOOL => ALIGN_BOOL, } PACK_MAP = { - TYPE_VOIDP => "l!", + TYPE_VOIDP => "L!", TYPE_CHAR => "c", TYPE_SHORT => "s!", TYPE_INT => "i!", TYPE_LONG => "l!", TYPE_FLOAT => "f", TYPE_DOUBLE => "d", - -TYPE_CHAR => "c", - -TYPE_SHORT => "s!", - -TYPE_INT => "i!", - -TYPE_LONG => "l!", + TYPE_UCHAR => "C", + TYPE_USHORT => "S!", + TYPE_UINT => "I!", + TYPE_ULONG => "L!", } + case SIZEOF_BOOL + when SIZEOF_CHAR + PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_UCHAR] + when SIZEOF_SHORT + PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_USHORT] + when SIZEOF_INT + PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_UINT] + when SIZEOF_LONG + PACK_MAP[TYPE_BOOL] = PACK_MAP[TYPE_ULONG] + end SIZE_MAP = { TYPE_VOIDP => SIZEOF_VOIDP, @@ -39,16 +50,18 @@ module Fiddle TYPE_LONG => SIZEOF_LONG, TYPE_FLOAT => SIZEOF_FLOAT, TYPE_DOUBLE => SIZEOF_DOUBLE, - -TYPE_CHAR => SIZEOF_CHAR, - -TYPE_SHORT => SIZEOF_SHORT, - -TYPE_INT => SIZEOF_INT, - -TYPE_LONG => SIZEOF_LONG, + TYPE_UCHAR => SIZEOF_CHAR, + TYPE_USHORT => SIZEOF_SHORT, + TYPE_UINT => SIZEOF_INT, + TYPE_ULONG => SIZEOF_LONG, + TYPE_BOOL => SIZEOF_BOOL, } if defined?(TYPE_LONG_LONG) - ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[-TYPE_LONG_LONG] = ALIGN_LONG_LONG - PACK_MAP[TYPE_LONG_LONG] = PACK_MAP[-TYPE_LONG_LONG] = "q" - SIZE_MAP[TYPE_LONG_LONG] = SIZE_MAP[-TYPE_LONG_LONG] = SIZEOF_LONG_LONG - PACK_MAP[TYPE_VOIDP] = "q" if SIZEOF_LONG_LONG == SIZEOF_VOIDP + ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_MAP[TYPE_ULONG_LONG] = ALIGN_LONG_LONG + PACK_MAP[TYPE_LONG_LONG] = "q" + PACK_MAP[TYPE_ULONG_LONG] = "Q" + SIZE_MAP[TYPE_LONG_LONG] = SIZE_MAP[TYPE_ULONG_LONG] = SIZEOF_LONG_LONG + PACK_MAP[TYPE_VOIDP] = "Q" if SIZEOF_LONG_LONG == SIZEOF_VOIDP end def align(addr, align) diff --git a/ext/fiddle/lib/fiddle/value.rb b/ext/fiddle/lib/fiddle/value.rb index 01fec1c206..5f0b2e951e 100644 --- a/ext/fiddle/lib/fiddle/value.rb +++ b/ext/fiddle/lib/fiddle/value.rb @@ -6,17 +6,17 @@ module Fiddle def unsigned_value(val, ty) case ty.abs when TYPE_CHAR - [val].pack("c").unpack("C")[0] + [val].pack("c").unpack1("C") when TYPE_SHORT - [val].pack("s!").unpack("S!")[0] + [val].pack("s!").unpack1("S!") when TYPE_INT - [val].pack("i!").unpack("I!")[0] + [val].pack("i!").unpack1("I!") when TYPE_LONG - [val].pack("l!").unpack("L!")[0] + [val].pack("l!").unpack1("L!") else if defined?(TYPE_LONG_LONG) and ty.abs == TYPE_LONG_LONG - [val].pack("q").unpack("Q")[0] + [val].pack("q").unpack1("Q") else val end @@ -26,17 +26,17 @@ module Fiddle def signed_value(val, ty) case ty.abs when TYPE_CHAR - [val].pack("C").unpack("c")[0] + [val].pack("C").unpack1("c") when TYPE_SHORT - [val].pack("S!").unpack("s!")[0] + [val].pack("S!").unpack1("s!") when TYPE_INT - [val].pack("I!").unpack("i!")[0] + [val].pack("I!").unpack1("i!") when TYPE_LONG - [val].pack("L!").unpack("l!")[0] + [val].pack("L!").unpack1("l!") else if defined?(TYPE_LONG_LONG) and ty.abs == TYPE_LONG_LONG - [val].pack("Q").unpack("q")[0] + [val].pack("Q").unpack1("q") else val end @@ -80,11 +80,11 @@ module Fiddle else case SIZEOF_VOIDP when SIZEOF_LONG - return [arg].pack("p").unpack("l!")[0] + return [arg].pack("p").unpack1("l!") else if defined?(SIZEOF_LONG_LONG) and SIZEOF_VOIDP == SIZEOF_LONG_LONG - return [arg].pack("p").unpack("q")[0] + return [arg].pack("p").unpack1("q") else raise(RuntimeError, "sizeof(void*)?") end @@ -102,10 +102,8 @@ module Fiddle return val.unpack('C*') end end - return arg - else - return arg end + return arg else if( arg.respond_to?(:to_ptr) ) return arg.to_ptr.to_i diff --git a/ext/fiddle/lib/fiddle/version.rb b/ext/fiddle/lib/fiddle/version.rb index db6504b650..3444e24f92 100644 --- a/ext/fiddle/lib/fiddle/version.rb +++ b/ext/fiddle/lib/fiddle/version.rb @@ -1,3 +1,3 @@ module Fiddle - VERSION = "1.1.0" + VERSION = "1.1.3.dev" end diff --git a/ext/fiddle/pointer.c b/ext/fiddle/pointer.c index 15107e3862..1b7d7a69f6 100644 --- a/ext/fiddle/pointer.c +++ b/ext/fiddle/pointer.c @@ -88,8 +88,13 @@ fiddle_ptr_memsize(const void *ptr) } static const rb_data_type_t fiddle_ptr_data_type = { - "fiddle/pointer", - {fiddle_ptr_mark, fiddle_ptr_free, fiddle_ptr_memsize,}, + .wrap_struct_name = "fiddle/pointer", + .function = { + .dmark = fiddle_ptr_mark, + .dfree = fiddle_ptr_free, + .dsize = fiddle_ptr_memsize, + }, + .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED }; #ifdef HAVE_RUBY_MEMORY_VIEW_H @@ -135,8 +140,8 @@ rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func, VALUE wra data->free = func; data->freed = false; data->size = size; - data->wrap[0] = wrap0; - data->wrap[1] = wrap1; + RB_OBJ_WRITE(val, &data->wrap[0], wrap0); + RB_OBJ_WRITE(val, &data->wrap[1], wrap1); return val; } @@ -235,8 +240,8 @@ rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self) /* Free previous memory. Use of inappropriate initialize may cause SEGV. */ (*(data->free))(data->ptr); } - data->wrap[0] = wrap; - data->wrap[1] = funcwrap; + RB_OBJ_WRITE(self, &data->wrap[0], wrap); + RB_OBJ_WRITE(self, &data->wrap[1], funcwrap); data->ptr = p; data->size = s; data->free = f; @@ -314,7 +319,7 @@ rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass) } obj = rb_fiddle_ptr_malloc(klass, s,f); - if (wrap) RPTR_DATA(obj)->wrap[1] = wrap; + if (wrap) RB_OBJ_WRITE(obj, &RPTR_DATA(obj)->wrap[1], wrap); if (rb_block_given_p()) { if (!f) { @@ -795,10 +800,37 @@ rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val) if (num == val) wrap = 0; ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL); } - if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap; + if (wrap) RB_OBJ_WRITE(ptr, &RPTR_DATA(ptr)->wrap[0], wrap); return ptr; } +/* + * call-seq: + * Fiddle::Pointer.read(address, len) => string + * + * Or read the memory at address +address+ with length +len+ and return a + * string with that memory + */ + +static VALUE +rb_fiddle_ptr_read_mem(VALUE klass, VALUE address, VALUE len) +{ + return rb_str_new((char *)NUM2PTR(address), NUM2ULONG(len)); +} + +/* + * call-seq: + * Fiddle::Pointer.write(address, str) + * + * Write bytes in +str+ to the location pointed to by +address+. + */ +static VALUE +rb_fiddle_ptr_write_mem(VALUE klass, VALUE addr, VALUE str) +{ + memcpy(NUM2PTR(addr), StringValuePtr(str), RSTRING_LEN(str)); + return str; +} + void Init_fiddle_pointer(void) { @@ -815,6 +847,8 @@ Init_fiddle_pointer(void) rb_define_singleton_method(rb_cPointer, "malloc", rb_fiddle_ptr_s_malloc, -1); rb_define_singleton_method(rb_cPointer, "to_ptr", rb_fiddle_ptr_s_to_ptr, 1); rb_define_singleton_method(rb_cPointer, "[]", rb_fiddle_ptr_s_to_ptr, 1); + rb_define_singleton_method(rb_cPointer, "read", rb_fiddle_ptr_read_mem, 2); + rb_define_singleton_method(rb_cPointer, "write", rb_fiddle_ptr_write_mem, 2); rb_define_method(rb_cPointer, "initialize", rb_fiddle_ptr_initialize, -1); rb_define_method(rb_cPointer, "free=", rb_fiddle_ptr_free_set, 1); rb_define_method(rb_cPointer, "free", rb_fiddle_ptr_free_get, 0); diff --git a/ext/fiddle/win32/fficonfig.h b/ext/fiddle/win32/fficonfig.h deleted file mode 100644 index 776808159c..0000000000 --- a/ext/fiddle/win32/fficonfig.h +++ /dev/null @@ -1,29 +0,0 @@ -#define HAVE_ALLOCA 1 -#define HAVE_MEMCPY 1 -#define HAVE_MEMORY_H 1 -#define HAVE_STDLIB_H 1 -#define HAVE_STRING_H 1 -#define HAVE_SYS_STAT_H 1 -#define HAVE_SYS_TYPES_H 1 -#if _MSC_VER >= 1600 -#define HAVE_INTTYPES_H 1 -#define HAVE_STDINT_H 1 -#endif - -#define SIZEOF_DOUBLE 8 -#if defined(X86_WIN64) -#define SIZEOF_SIZE_T 8 -#else -#define SIZEOF_SIZE_T 4 -#endif - -#define STACK_DIRECTION -1 - -#define STDC_HEADERS 1 - -#ifdef LIBFFI_ASM -#define FFI_HIDDEN(name) -#else -#define FFI_HIDDEN -#endif - diff --git a/ext/fiddle/win32/libffi-3.2.1-mswin.patch b/ext/fiddle/win32/libffi-3.2.1-mswin.patch deleted file mode 100644 index f9100e703d..0000000000 --- a/ext/fiddle/win32/libffi-3.2.1-mswin.patch +++ /dev/null @@ -1,191 +0,0 @@ -diff -ru libffi-3.2.1/src/x86/ffi.c libffi-3.2.1/src/x86/ffi.c ---- libffi-3.2.1/src/x86/ffi.c 2014-11-08 21:47:24.000000000 +0900 -+++ libffi-3.2.1/src/x86/ffi.c 2014-12-25 18:46:14.806761900 +0900 -@@ -99,11 +99,13 @@ - i != 0; - i--, p_arg += dir, p_argv += dir) - { -+ size_t z; -+ - /* Align if necessary */ - if ((sizeof(void*) - 1) & (size_t) argp) - argp = (char *) ALIGN(argp, sizeof(void*)); - -- size_t z = (*p_arg)->size; -+ z = (*p_arg)->size; - - #ifdef X86_WIN64 - if (z > FFI_SIZEOF_ARG -@@ -202,6 +204,7 @@ - on top of stack, so that those can be moved to registers by call-handler. */ - if (stack_args_count > 0) - { -+ int i; - if (dir < 0 && stack_args_count > 1) - { - /* Reverse order if iterating arguments backwards */ -@@ -210,7 +213,6 @@ - *(ffi_arg*) p_stack_data[stack_args_count - 1] = tmp; - } - -- int i; - for (i = 0; i < stack_args_count; i++) - { - if (p_stack_data[i] != argp2) -@@ -569,11 +571,12 @@ - i < cif->nargs && passed_regs < max_stack_count; - i++, p_arg++) - { -+ size_t sz; - if ((*p_arg)->type == FFI_TYPE_FLOAT - || (*p_arg)->type == FFI_TYPE_STRUCT) - continue; - -- size_t sz = (*p_arg)->size; -+ sz = (*p_arg)->size; - if(sz == 0 || sz > FFI_SIZEOF_ARG) - continue; - -@@ -599,11 +602,13 @@ - i != 0; - i--, p_arg += dir, p_argv += dir) - { -+ size_t z; -+ - /* Align if necessary */ - if ((sizeof(void*) - 1) & (size_t) argp) - argp = (char *) ALIGN(argp, sizeof(void*)); - -- size_t z = (*p_arg)->size; -+ z = (*p_arg)->size; - - #ifdef X86_WIN64 - if (z > FFI_SIZEOF_ARG -@@ -642,7 +647,7 @@ - #endif - } - -- return (size_t)argp - (size_t)stack; -+ return (int)((size_t)argp - (size_t)stack); - } - - #define FFI_INIT_TRAMPOLINE_WIN64(TRAMP,FUN,CTX,MASK) \ -@@ -855,11 +860,12 @@ - - for (i = 0; i < cif->nargs && passed_regs <= max_regs; i++) - { -+ size_t sz; - if (cif->arg_types[i]->type == FFI_TYPE_FLOAT - || cif->arg_types[i]->type == FFI_TYPE_STRUCT) - continue; - -- size_t sz = cif->arg_types[i]->size; -+ sz = cif->arg_types[i]->size; - if (sz == 0 || sz > FFI_SIZEOF_ARG) - continue; - -diff -ru libffi-3.2.1/src/x86/ffitarget.h libffi-3.2.1/src/x86/ffitarget.h ---- libffi-3.2.1/src/x86/ffitarget.h 2014-11-08 21:47:24.000000000 +0900 -+++ libffi-3.2.1/src/x86/ffitarget.h 2014-12-22 15:45:54.000000000 +0900 -@@ -50,7 +50,9 @@ - #endif - - #define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION -+#ifndef _MSC_VER - #define FFI_TARGET_HAS_COMPLEX_TYPE -+#endif - - /* ---- Generic type definitions ----------------------------------------- */ - -diff -ru libffi-3.2.1/src/x86/win64.S libffi-3.2.1/src/x86/win64.S ---- libffi-3.2.1/src/x86/win64.S 2014-11-08 21:47:24.000000000 +0900 -+++ libffi-3.2.1/src/x86/win64.S 2014-12-22 16:14:40.000000000 +0900 -@@ -127,7 +127,7 @@ - - mov rcx, QWORD PTR RVALUE[rbp] - mov DWORD PTR [rcx], eax -- jmp ret_void$ -+ jmp SHORT ret_void$ - - ret_struct2b$: - cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_2B -@@ -135,7 +135,7 @@ - - mov rcx, QWORD PTR RVALUE[rbp] - mov WORD PTR [rcx], ax -- jmp ret_void$ -+ jmp SHORT ret_void$ - - ret_struct1b$: - cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SMALL_STRUCT_1B -@@ -143,7 +143,7 @@ - - mov rcx, QWORD PTR RVALUE[rbp] - mov BYTE PTR [rcx], al -- jmp ret_void$ -+ jmp SHORT ret_void$ - - ret_uint8$: - cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT8 -@@ -152,7 +152,7 @@ - mov rcx, QWORD PTR RVALUE[rbp] - movzx rax, al - mov QWORD PTR [rcx], rax -- jmp ret_void$ -+ jmp SHORT ret_void$ - - ret_sint8$: - cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT8 -@@ -161,7 +161,7 @@ - mov rcx, QWORD PTR RVALUE[rbp] - movsx rax, al - mov QWORD PTR [rcx], rax -- jmp ret_void$ -+ jmp SHORT ret_void$ - - ret_uint16$: - cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_UINT16 -@@ -188,7 +188,13 @@ - mov rcx, QWORD PTR RVALUE[rbp] - mov eax, eax - mov QWORD PTR [rcx], rax -- jmp SHORT ret_void$ -+ -+ret_void$: -+ xor rax, rax -+ -+ lea rsp, QWORD PTR [rbp+16] -+ pop rbp -+ ret 0 - - ret_sint32$: - cmp DWORD PTR CIF_FLAGS[rbp], FFI_TYPE_SINT32 -@@ -247,13 +253,6 @@ - cdqe - mov QWORD PTR [rcx], rax - jmp SHORT ret_void$ -- --ret_void$: -- xor rax, rax -- -- lea rsp, QWORD PTR [rbp+16] -- pop rbp -- ret 0 - ffi_call_win64 ENDP - _TEXT ENDS - END -diff -ru libffi-3.2.1/include/ffi.h.in libffi-3.2.1/include/ffi.h.in ---- libffi-3.2.1/include/ffi.h.in 2014-11-08 21:47:24.000000000 +0900 -+++ libffi-3.2.1/include/ffi.h.in 2015-01-11 12:35:30.000000000 +0900 -@@ -103,6 +103,11 @@ - # undef FFI_64_BIT_MAX - # define FFI_64_BIT_MAX 9223372036854775807LL - # endif -+# ifdef _MSC_VER -+# define FFI_LONG_LONG_MAX _I64_MAX -+# undef FFI_64_BIT_MAX -+# define FFI_64_BIT_MAX 9223372036854775807I64 -+# endif - # endif - #endif - diff --git a/ext/fiddle/win32/libffi-config.rb b/ext/fiddle/win32/libffi-config.rb deleted file mode 100755 index 985fc29d36..0000000000 --- a/ext/fiddle/win32/libffi-config.rb +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/ruby -# frozen_string_literal: true -require 'fileutils' - -basedir = File.dirname(__FILE__) -conf = {} -enable = {} -until ARGV.empty? - arg = ARGV.shift - case arg - when '-C' - # ignore - when /\A--srcdir=(.*)/ - conf['SRCDIR'] = srcdir = $1 - when /\A(CC|CFLAGS|CXX|CXXFLAGS|LD|LDFLAGS)=(.*)/ - conf[$1] = $2 - when /\A--host=(.*)/ - host = $1 - when /\A--enable-([^=]+)(?:=(.*))?/ - enable[$1] = $2 || true - when /\A--disable-([^=]+)/ - enable[$1] = false - end -end - -IO.foreach("#{srcdir}/configure.ac") do |line| - if /^AC_INIT\((.*)\)/ =~ line - version = $1.split(/,\s*/)[1] - version.gsub!(/\A\[|\]\z/, '') - conf['VERSION'] = version - break - end -end - -builddir = srcdir == "." ? (enable['builddir'] || ".") : "." -conf['TARGET'] = /^x64/ =~ host ? "X86_WIN64" : "X86_WIN32" - -FileUtils.mkdir_p([builddir, "#{builddir}/include", "#{builddir}/src/x86"]) -FileUtils.cp("#{basedir}/fficonfig.h", ".", preserve: true) - -hdr = IO.binread("#{srcdir}/include/ffi.h.in") -hdr.gsub!(/@(\w+)@/) {conf[$1] || $&} -hdr.gsub!(/^(#if\s+)@\w+@/, '\10') -IO.binwrite("#{builddir}/include/ffi.h", hdr) - -mk = IO.binread("#{basedir}/libffi.mk.tmpl") -mk.gsub!(/@(\w+)@/) {conf[$1] || $&} -IO.binwrite("Makefile", mk) diff --git a/ext/fiddle/win32/libffi.mk.tmpl b/ext/fiddle/win32/libffi.mk.tmpl deleted file mode 100644 index 2a16e8efec..0000000000 --- a/ext/fiddle/win32/libffi.mk.tmpl +++ /dev/null @@ -1,96 +0,0 @@ -# -*- makefile -*- -# ==================================================================== -# -# libffi Windows Makefile -# -# -# ==================================================================== -# -NAME = ffi -TARGET = @TARGET@ -CC = cl -!if "$(TARGET)" == "X86_WIN64" -AS = ml64 -!else -AS = ml -!endif -AR = link -DLEXT = dll -OBJEXT = obj -LIBEXT = lib -TOPDIR = @SRCDIR@ -CPP = $(CC) -EP -CFLAGS = @CFLAGS@ -ARFLAGS = -lib -ASFLAGS = -coff -W3 -Cx -INCLUDES= -I. -I./include -I./src/x86 \ - -I$(TOPDIR)/include -I$(TOPDIR)/include/src/x86 - -SRCDIR = $(TOPDIR)/src -WORKDIR = ./.libs -BUILDDIR= ./src -LIBNAME = lib$(NAME) -STATICLIB= $(WORKDIR)/$(LIBNAME)_convenience.$(LIBEXT) - -HEADERS = \ - ./fficonfig.h -FFI_HEADERS = \ - ./include/ffi.h \ - ./include/ffitarget.h - -!if "$(TARGET)" == "X86_WIN32" -OSSRC = win32 -!else if "$(TARGET)" == "X86_WIN64" -OSSRC = win64 -!else -! error unknown target: $(TARGET) -!endif - -OBJECTS = \ - $(BUILDDIR)/closures.$(OBJEXT) \ - $(BUILDDIR)/debug.$(OBJEXT) \ - $(BUILDDIR)/java_raw_api.$(OBJEXT) \ - $(BUILDDIR)/prep_cif.$(OBJEXT) \ - $(BUILDDIR)/raw_api.$(OBJEXT) \ - $(BUILDDIR)/types.$(OBJEXT) \ - $(BUILDDIR)/x86/ffi.$(OBJEXT) \ - $(BUILDDIR)/x86/$(OSSRC).$(OBJEXT) -ASMSRCS = \ - $(BUILDDIR)/x86/$(OSSRC).asm - -.SUFFIXES : .S .asm - -all: $(WORKDIR) $(STATICLIB) - -{$(SRCDIR)}.c{$(BUILDDIR)}.$(OBJEXT): - $(CC) -c $(CFLAGS) $(INCLUDES) -Fo$(@:\=/) -Fd$(WORKDIR)/$(NAME)-src $(<:\=/) - -{$(SRCDIR)/x86}.c{$(BUILDDIR)/x86}.$(OBJEXT): - $(CC) -c $(CFLAGS) $(INCLUDES) -Fo$(@:\=/) -Fd$(WORKDIR)/$(NAME)-src $(<:\=/) - -{$(SRCDIR)/x86}.S{$(BUILDDIR)/x86}.asm: - $(CPP) $(CFLAGS) $(INCLUDES) $(<:\=/) >$(@:\=/) - -{$(BUILDDIR)/x86}.asm{$(BUILDDIR)/x86}.$(OBJEXT): - cd $(@D) && $(AS) -c $(ASFLAGS) -Fo $(@F) $(<F) - -$(BUILDDIR)/x86/$(OSSRC).asm: $(SRCDIR)/x86/$(OSSRC).S - -$(OBJECTS): $(FFI_HEADERS) $(HEADERS) - -$(WORKDIR): - -@if not exist "$(WORKDIR:/=\)\$(NULL)" mkdir $(WORKDIR:/=\) - -$(STATICLIB): $(WORKDIR) $(OBJECTS) - $(AR) $(ARFLAGS) -out:$(STATICLIB) @<< - $(OBJECTS) -<< - -clean: - -@del /Q $(OBJECTS:/=\) 2>NUL - -@del /Q $(ASMSRCS:/=\) 2>NUL - -@del /Q /S $(WORKDIR:/=\) 2>NUL - -distclean: clean - -@del /Q $(HEADERS:/=\) $(FFI_HEADERS:/=\) 2>NUL - -@del /Q Makefile 2>NUL |