[前][次][番号順一覧][スレッド一覧]

ruby-changes:14815

From: tenderlove <ko1@a...>
Date: Tue, 16 Feb 2010 11:06:14 +0900 (JST)
Subject: [ruby-changes:14815] Ruby:r26677 (trunk): * ext/dl/method.c: Adding DL::Method as a superclass for DL::Function

tenderlove	2010-02-16 11:05:46 +0900 (Tue, 16 Feb 2010)

  New Revision: 26677

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=26677

  Log:
    * ext/dl/method.c: Adding DL::Method as a superclass for DL::Function

  Added files:
    trunk/ext/dl/method.c
    trunk/test/dl/test_method.rb
  Removed files:
    trunk/ext/dl/function.c
  Modified files:
    trunk/ChangeLog
    trunk/ext/dl/dl.h
    trunk/ext/dl/lib/dl/func.rb
    trunk/ext/dl/lib/dl/value.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 26676)
+++ ChangeLog	(revision 26677)
@@ -1,3 +1,7 @@
+Tue Feb 16 11:03:19 2010  Aaron Patterson <aaron@t...>
+
+	* ext/dl/method.c: Adding DL::Method as a superclass for DL::Function
+
 Mon Feb 15 23:37:30 2010  Tanaka Akira  <akr@f...>
 
 	* io.c: check lseek error by errno.  NetBSD 4.0.1 may return -1 as
Index: ext/dl/function.c
===================================================================
--- ext/dl/function.c	(revision 26676)
+++ ext/dl/function.c	(revision 26677)
@@ -1,238 +0,0 @@
-/* -*- C -*-
- * $Id$
- */
-
-#include <ruby.h>
-#include <errno.h>
-#include "dl.h"
-#include <dl_conversions.h>
-
-VALUE rb_cDLFunction;
-
-typedef union
-{
-    unsigned char uchar;   /* ffi_type_uchar */
-    signed char   schar;   /* ffi_type_schar */
-    unsigned short ushort; /* ffi_type_sshort */
-    signed short sshort;   /* ffi_type_ushort */
-    unsigned int uint;     /* ffi_type_uint */
-    signed int sint;       /* ffi_type_sint */
-    unsigned long ulong;   /* ffi_type_ulong */
-    signed long slong;     /* ffi_type_slong */
-    float ffloat;          /* ffi_type_float */
-    double ddouble;        /* ffi_type_double */
-#if HAVE_LONG_LONG
-    unsigned LONG_LONG long_long; /* ffi_type_uint64 */
-#endif
-    void * pointer;        /* ffi_type_pointer */
-} dl_generic;
-
-static void
-dlfunction_free(void *p)
-{
-    ffi_cif *ptr = p;
-    if (ptr->arg_types) xfree(ptr->arg_types);
-    xfree(ptr);
-}
-
-static size_t
-dlfunction_memsize(const void *p)
-{
-    /* const */ffi_cif *ptr = (ffi_cif *)p;
-    size_t size = 0;
-
-    if (ptr) {
-	size += sizeof(*ptr);
-	size += ffi_raw_size(ptr);
-    }
-    return size;
-}
-
-const rb_data_type_t dlfunction_data_type = {
-    "dl/function",
-    0, dlfunction_free, dlfunction_memsize,
-};
-
-static VALUE
-rb_dlfunc_allocate(VALUE klass)
-{
-    ffi_cif * cif;
-
-    return TypedData_Make_Struct(klass, ffi_cif, &dlfunction_data_type, cif);
-}
-
-static VALUE
-rb_dlfunction_native_init(VALUE self, VALUE args, VALUE ret_type, VALUE abi)
-{
-    ffi_cif * cif;
-    ffi_type **arg_types;
-    ffi_status result;
-    int i;
-
-    TypedData_Get_Struct(self, ffi_cif, &dlfunction_data_type, cif);
-
-    arg_types = xcalloc(RARRAY_LEN(args) + 1, sizeof(ffi_type *));
-
-    for (i = 0; i < RARRAY_LEN(args); i++) {
-	int type = NUM2INT(RARRAY_PTR(args)[i]);
-	arg_types[i] = DL2FFI_TYPE(type);
-    }
-    arg_types[RARRAY_LEN(args)] = NULL;
-
-    result = ffi_prep_cif (
-	    cif,
-	    NUM2INT(abi),
-	    RARRAY_LEN(args),
-	    DL2FFI_TYPE(NUM2INT(ret_type)),
-	    arg_types);
-
-    if (result)
-	rb_raise(rb_eRuntimeError, "error creating CIF %d", result);
-
-    return self;
-}
-
-static void
-dl2generic(int dl_type, VALUE src, dl_generic * dst)
-{
-    int signed_p = 1;
-
-    if (dl_type < 0) {
-	dl_type = -1 * dl_type;
-	signed_p = 0;
-    }
-
-    switch (dl_type) {
-      case DLTYPE_VOID:
-	break;
-      case DLTYPE_VOIDP:
-	dst->pointer = NUM2PTR(rb_Integer(src));
-	break;
-      case DLTYPE_CHAR:
-      case DLTYPE_SHORT:
-      case DLTYPE_INT:
-	dst->sint = NUM2INT(src);
-	break;
-      case DLTYPE_LONG:
-	if (signed_p)
-	    dst->slong = NUM2LONG(src);
-	else
-	    dst->ulong = NUM2LONG(src);
-	break;
-#if HAVE_LONG_LONG
-      case DLTYPE_LONG_LONG:
-	dst->long_long = rb_big2ull(src);
-	break;
-#endif
-      case DLTYPE_FLOAT:
-	dst->ffloat = (float)NUM2DBL(src);
-	break;
-      case DLTYPE_DOUBLE:
-	dst->ddouble = NUM2DBL(src);
-	break;
-      default:
-	rb_raise(rb_eRuntimeError, "unknown type %d", dl_type);
-    }
-}
-
-static VALUE
-unwrap_ffi(VALUE rettype, dl_generic retval)
-{
-    int signed_p = 1;
-    int dl_type = NUM2INT(rettype);
-
-    if (dl_type < 0) {
-	dl_type = -1 * dl_type;
-	signed_p = 0;
-    }
-
-    switch (dl_type) {
-      case DLTYPE_VOID:
-	return Qnil;
-      case DLTYPE_VOIDP:
-	return rb_dlptr_new((void *)retval.pointer, 0, NULL);
-      case DLTYPE_CHAR:
-      case DLTYPE_SHORT:
-      case DLTYPE_INT:
-	return INT2NUM(retval.sint);
-      case DLTYPE_LONG:
-	if (signed_p) return LONG2NUM(retval.slong);
-	return ULONG2NUM(retval.ulong);
-#if HAVE_LONG_LONG
-      case DLTYPE_LONG_LONG:
-	return rb_ll2inum(retval.long_long);
-	break;
-#endif
-      case DLTYPE_FLOAT:
-	return rb_float_new(retval.ffloat);
-      case DLTYPE_DOUBLE:
-	return rb_float_new(retval.ddouble);
-      default:
-	rb_raise(rb_eRuntimeError, "unknown type %d", dl_type);
-    }
-}
-
-static VALUE
-rb_dlfunction_call(int argc, VALUE argv[], VALUE self)
-{
-    ffi_cif * cif;
-    dl_generic retval;
-    dl_generic *generic_args;
-    void **values;
-    void * fun_ptr;
-    VALUE cfunc, types;
-    int i;
-
-    TypedData_Get_Struct(self, ffi_cif, &dlfunction_data_type, cif);
-
-    values = xcalloc((size_t)argc + 1, (size_t)sizeof(void *));
-    generic_args = xcalloc((size_t)argc, (size_t)sizeof(dl_generic));
-
-    cfunc = rb_iv_get(self, "@cfunc");
-    types = rb_iv_get(self, "@args");
-
-    for (i = 0; i < argc; i++) {
-	VALUE dl_type = RARRAY_PTR(types)[i];
-	VALUE src = rb_funcall(self,
-		rb_intern("ruby2ffi"),
-		2,
-		argv[i],
-		dl_type
-		);
-
-	dl2generic(NUM2INT(dl_type), src, &generic_args[i]);
-	values[i] = (void *)&generic_args[i];
-    }
-    values[argc] = NULL;
-
-    ffi_call(cif, NUM2PTR(rb_Integer(cfunc)), &retval, values);
-
-    rb_dl_set_last_error(self, INT2NUM(errno));
-#if defined(HAVE_WINDOWS_H)
-    rb_dl_set_win32_last_error(self, INT2NUM(GetLastError()));
-#endif
-
-    xfree(values);
-    xfree(generic_args);
-
-    return unwrap_ffi(rb_funcall(cfunc, rb_intern("ctype"), 0), retval);
-}
-
-void
-Init_dlfunction(void)
-{
-    rb_cDLFunction = rb_define_class_under(rb_mDL, "Function", rb_cObject);
-
-    rb_define_const(rb_cDLFunction, "DEFAULT", INT2NUM(FFI_DEFAULT_ABI));
-
-#ifdef FFI_STDCALL
-    rb_define_const(rb_cDLFunction, "STDCALL", INT2NUM(FFI_STDCALL));
-#endif
-
-    rb_define_alloc_func(rb_cDLFunction, rb_dlfunc_allocate);
-
-    rb_define_private_method(rb_cDLFunction, "native_call", rb_dlfunction_call, -1);
-
-    rb_define_private_method(rb_cDLFunction, "native_init", rb_dlfunction_native_init, 3);
-}
-/* vim: set noet sw=4 sts=4 */
Index: ext/dl/method.c
===================================================================
--- ext/dl/method.c	(revision 0)
+++ ext/dl/method.c	(revision 26677)
@@ -0,0 +1,251 @@
+/* -*- C -*-
+ * $Id$
+ */
+
+#include <ruby.h>
+#include <errno.h>
+#include "dl.h"
+#include <dl_conversions.h>
+
+VALUE rb_cDLMethod;
+
+typedef union
+{
+    unsigned char uchar;   /* ffi_type_uchar */
+    signed char   schar;   /* ffi_type_schar */
+    unsigned short ushort; /* ffi_type_sshort */
+    signed short sshort;   /* ffi_type_ushort */
+    unsigned int uint;     /* ffi_type_uint */
+    signed int sint;       /* ffi_type_sint */
+    unsigned long ulong;   /* ffi_type_ulong */
+    signed long slong;     /* ffi_type_slong */
+    float ffloat;          /* ffi_type_float */
+    double ddouble;        /* ffi_type_double */
+#if HAVE_LONG_LONG
+    unsigned LONG_LONG long_long; /* ffi_type_uint64 */
+#endif
+    void * pointer;        /* ffi_type_pointer */
+} dl_generic;
+
+static void
+dlfunction_free(void *p)
+{
+    ffi_cif *ptr = p;
+    if (ptr->arg_types) xfree(ptr->arg_types);
+    xfree(ptr);
+}
+
+static size_t
+dlfunction_memsize(const void *p)
+{
+    /* const */ffi_cif *ptr = (ffi_cif *)p;
+    size_t size = 0;
+
+    if (ptr) {
+	size += sizeof(*ptr);
+	size += ffi_raw_size(ptr);
+    }
+    return size;
+}
+
+const rb_data_type_t dlfunction_data_type = {
+    "dl/method",
+    0, dlfunction_free, dlfunction_memsize,
+};
+
+static VALUE
+rb_dlfunc_allocate(VALUE klass)
+{
+    ffi_cif * cif;
+
+    return TypedData_Make_Struct(klass, ffi_cif, &dlfunction_data_type, cif);
+}
+
+static VALUE
+rb_dlfunction_initialize(int argc, VALUE argv[], VALUE self)
+{
+    ffi_cif * cif;
+    ffi_type **arg_types;
+    ffi_status result;
+    VALUE ptr, args, ret_type, abi;
+    int i;
+
+    rb_scan_args(argc, argv, "31", &ptr, &args, &ret_type, &abi);
+    if(NIL_P(abi)) abi = INT2NUM(FFI_DEFAULT_ABI);
+
+    rb_iv_set(self, "@ptr", ptr);
+    rb_iv_set(self, "@args", args);
+    rb_iv_set(self, "@return_type", ret_type);
+    rb_iv_set(self, "@abi", abi);
+
+    TypedData_Get_Struct(self, ffi_cif, &dlfunction_data_type, cif);
+
+    arg_types = xcalloc(RARRAY_LEN(args) + 1, sizeof(ffi_type *));
+
+    for (i = 0; i < RARRAY_LEN(args); i++) {
+	int type = NUM2INT(RARRAY_PTR(args)[i]);
+	arg_types[i] = DL2FFI_TYPE(type);
+    }
+    arg_types[RARRAY_LEN(args)] = NULL;
+
+    result = ffi_prep_cif (
+	    cif,
+	    NUM2INT(abi),
+	    RARRAY_LEN(args),
+	    DL2FFI_TYPE(NUM2INT(ret_type)),
+	    arg_types);
+
+    if (result)
+	rb_raise(rb_eRuntimeError, "error creating CIF %d", result);
+
+    return self;
+}
+
+static void
+dl2generic(int dl_type, VALUE src, dl_generic * dst)
+{
+    int signed_p = 1;
+
+    if (dl_type < 0) {
+	dl_type = -1 * dl_type;
+	signed_p = 0;
+    }
+
+    switch (dl_type) {
+      case DLTYPE_VOID:
+	break;
+      case DLTYPE_VOIDP:
+	dst->pointer = NUM2PTR(rb_Integer(src));
+	break;
+      case DLTYPE_CHAR:
+      case DLTYPE_SHORT:
+      case DLTYPE_INT:
+	dst->sint = NUM2INT(src);
+	break;
+      case DLTYPE_LONG:
+	if (signed_p)
+	    dst->slong = NUM2LONG(src);
+	else
+	    dst->ulong = NUM2LONG(src);
+	break;
+#if HAVE_LONG_LONG
+      case DLTYPE_LONG_LONG:
+	dst->long_long = rb_big2ull(src);
+	break;
+#endif
+      case DLTYPE_FLOAT:
+	dst->ffloat = (float)NUM2DBL(src);
+	break;
+      case DLTYPE_DOUBLE:
+	dst->ddouble = NUM2DBL(src);
+	break;
+      default:
+	rb_raise(rb_eRuntimeError, "unknown type %d", dl_type);
+    }
+}
+
+static VALUE
+unwrap_ffi(VALUE rettype, dl_generic retval)
+{
+    int signed_p = 1;
+    int dl_type = NUM2INT(rettype);
+
+    if (dl_type < 0) {
+	dl_type = -1 * dl_type;
+	signed_p = 0;
+    }
+
+    switch (dl_type) {
+      case DLTYPE_VOID:
+	return Qnil;
+      case DLTYPE_VOIDP:
+	return rb_dlptr_new((void *)retval.pointer, 0, NULL);
+      case DLTYPE_CHAR:
+      case DLTYPE_SHORT:
+      case DLTYPE_INT:
+	return INT2NUM(retval.sint);
+      case DLTYPE_LONG:
+	if (signed_p) return LONG2NUM(retval.slong);
+	return ULONG2NUM(retval.ulong);
+#if HAVE_LONG_LONG
+      case DLTYPE_LONG_LONG:
+	return rb_ll2inum(retval.long_long);
+	break;
+#endif
+      case DLTYPE_FLOAT:
+	return rb_float_new(retval.ffloat);
+      case DLTYPE_DOUBLE:
+	return rb_float_new(retval.ddouble);
+      default:
+	rb_raise(rb_eRuntimeError, "unknown type %d", dl_type);
+    }
+}
+
+static VALUE
+rb_dlfunction_call(int argc, VALUE argv[], VALUE self)
+{
+    ffi_cif * cif;
+    dl_generic retval;
+    dl_generic *generic_args;
+    void **values;
+    void * fun_ptr;
+    VALUE cfunc, types;
+    int i;
+
+    TypedData_Get_Struct(self, ffi_cif, &dlfunction_data_type, cif);
+
+    values = xcalloc((size_t)argc + 1, (size_t)sizeof(void *));
+    generic_args = xcalloc((size_t)argc, (size_t)sizeof(dl_generic));
+
+    cfunc = rb_iv_get(self, "@ptr");
+    types = rb_iv_get(self, "@args");
+
+    for (i = 0; i < argc; i++) {
+	VALUE dl_type = RARRAY_PTR(types)[i];
+	VALUE src = argv[i];
+
+	if(NUM2INT(dl_type) == DLTYPE_VOIDP) {
+	    if(NIL_P(src)) {
+		src = INT2NUM(0);
+	    } else if(rb_cDLCPtr != CLASS_OF(src)) {
+	        src = rb_funcall(rb_cDLCPtr, rb_intern("[]"), 1, src);
+	    }
+	    src = rb_Integer(src);
+	}
+
+	dl2generic(NUM2INT(dl_type), src, &generic_args[i]);
+	values[i] = (void *)&generic_args[i];
+    }
+    values[argc] = NULL;
+
+    ffi_call(cif, NUM2PTR(rb_Integer(cfunc)), &retval, values);
+
+    rb_dl_set_last_error(self, INT2NUM(errno));
+#if defined(HAVE_WINDOWS_H)
+    rb_dl_set_win32_last_error(self, INT2NUM(GetLastError()));
+#endif
+
+    xfree(values);
+    xfree(generic_args);
+
+    return unwrap_ffi(rb_iv_get(self, "@return_type"), retval);
+}
+
+void
+Init_dlfunction(void)
+{
+    rb_cDLMethod = rb_define_class_under(rb_mDL, "Method", rb_cObject);
+
+    rb_define_const(rb_cDLMethod, "DEFAULT", INT2NUM(FFI_DEFAULT_ABI));
+
+#ifdef FFI_STDCALL
+    rb_define_const(rb_cDLMethod, "STDCALL", INT2NUM(FFI_STDCALL));
+#endif
+
+    rb_define_alloc_func(rb_cDLMethod, rb_dlfunc_allocate);
+
+    rb_define_method(rb_cDLMethod, "call", rb_dlfunction_call, -1);
+
+    rb_define_method(rb_cDLMethod, "initialize", rb_dlfunction_initialize, -1);
+}
+/* vim: set noet sw=4 sts=4 */

Property changes on: ext/dl/method.c
___________________________________________________________________
Name: svn:eol-style
   + LF

Index: ext/dl/dl.h
===================================================================
--- ext/dl/dl.h	(revision 26676)
+++ ext/dl/dl.h	(revision 26677)
@@ -136,6 +136,7 @@
 
 extern VALUE rb_mDL;
 extern VALUE rb_cDLHandle;
+extern VALUE rb_cDLCPtr;
 extern VALUE rb_cDLSymbol;
 extern VALUE rb_eDLError;
 extern VALUE rb_eDLTypeError;
Index: ext/dl/lib/dl/func.rb
===================================================================
--- ext/dl/lib/dl/func.rb	(revision 26676)
+++ ext/dl/lib/dl/func.rb	(revision 26677)
@@ -6,7 +6,7 @@
 require 'thread'
 
 module DL
-  class Function
+  class Function < DL::Method
     include DL
     include ValueUtil
 
@@ -20,7 +20,7 @@
       end
 
       @args   = argtypes
-      native_init(@args.reject { |x| x == TYPE_VOID }, cfunc.ctype, abi)
+      super(@cfunc, @args.reject { |x| x == TYPE_VOID }, cfunc.ctype, abi)
     end
 
     def to_i()
@@ -35,7 +35,7 @@
       if block_given?
         args.find { |a| DL::Function === a }.bind_at_call(&block)
       end
-      native_call(*args)
+      super
     end
 
     def wrap_result(r)
Index: ext/dl/lib/dl/value.rb
===================================================================
--- ext/dl/lib/dl/value.rb	(revision 26676)
+++ ext/dl/lib/dl/value.rb	(revision 26677)
@@ -36,19 +36,6 @@
       end
     end
 
-    def ruby2ffi arg, type
-      return arg unless type == TYPE_VOIDP
-      case arg
-      when nil
-        0
-      when CPtr
-        arg.to_i
-      else
-        CPtr[arg].to_i
-      end
-    end
-    private :ruby2ffi
-
     def wrap_arg(arg, ty, funcs = [], &block)
         funcs ||= []
         case arg
Index: test/dl/test_method.rb
===================================================================
--- test/dl/test_method.rb	(revision 0)
+++ test/dl/test_method.rb	(revision 26677)
@@ -0,0 +1,11 @@
+require_relative 'test_base'
+require 'dl/func'
+
+module DL
+  class TestMethod < TestBase
+    def test_method_call
+      f = Method.new(@libc['sinf'], [TYPE_FLOAT], TYPE_FLOAT)
+      assert_in_delta 1.0, f.call(90 * Math::PI / 180), 0.0001
+    end
+  end
+end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]