Add some prototype to silence silly warnings.
[sxemacs] / src / effi.c
index 761b295..06bf61b 100644 (file)
@@ -25,6 +25,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 #include <dlfcn.h>
 #include <math.h>
 #include "sysdep.h"
+#include "ent/ent.h"
 #include "effi.h"
 
 #include "buffer.h"
@@ -543,6 +544,7 @@ Return FO's type.
 
 DEFUN("ffi-set-object-type", Fffi_set_object_type, 2, 2, 0, /*
 Cast FO to type TYPE and reassign the cast value.
+Return casted foreign object.
 */
       (fo, type))
 {
@@ -551,7 +553,7 @@ Cast FO to type TYPE and reassign the cast value.
        ffi_check_type(type);
        XEFFIO(fo)->type = type;
 
-       return type;
+       return fo;
 }
 
 DEFUN("ffi-object-size", Fffi_object_size, 1, 1, 0, /*
@@ -609,10 +611,10 @@ $LD_LIBRARY_PATH environment variable or the more global ld.so.cache.
        dotpos = strrchr((char *)XSTRING_DATA(libname),'.');
        if ( dotpos == NULL || strncmp(dotpos, EXT, sizeof(EXT))) {
                ssize_t liblen = XSTRING_LENGTH(libname);
-               ssize_t soname_len = liblen + sizeof(EXT);
-               soname = xmalloc( soname_len + 1);
-               strncpy(soname, (char *)XSTRING_DATA(libname), liblen+1);
-               strncat(soname, EXT, sizeof(EXT)+1);
+               ssize_t soname_len = liblen + sizeof(EXT) + 1;
+               soname = xmalloc( soname_len);
+               xstrncpy(soname, (char *)XSTRING_DATA(libname), soname_len);
+               xstrncpy(soname+liblen, EXT, soname_len-liblen);
        }
 
        if ( soname == NULL ) {
@@ -728,6 +730,7 @@ This is like `ffi-bind' but for function objects.
 /*
  * Return alignment policy for struct or union FFI_SU.
  * x86: Return 1, 2 or 4.
+ * x86_64: Return 1, 2, 4 or 8
  * mips: Return 1, 2, 4 or 8.
  */
 static int
@@ -740,12 +743,22 @@ ffi_type_align(Lisp_Object type)
                        return 1;
                if (EQ(type, Qshort) || EQ(type, Qunsigned_short))
                        return 2;
+#ifdef __x86_64__
+                if (EQ(type, Qlong) || EQ(type, Qunsigned_long)
+                    || EQ(type, Qdouble))
+                        return 8;
+#endif  /* __x86_64__ */
+
 #ifdef FFI_MIPS
                if (EQ(type, Qdouble))
                        return 8;
 #endif  /* FFI_MIPS */
                return 4;
                /* NOT REACHED */
+#ifdef __x86_64__
+        } else if (FFI_TPTR(type)) {
+                return 8;
+#endif  /* __x86_64__ */
        } else if (CONSP(type)
                   && (EQ(XCAR(type), Qstruct) || EQ(XCAR(type), Qunion))) {
                int al;
@@ -775,6 +788,8 @@ Return TYPE alignment.
        return make_int(ffi_type_align(type));
 }
 
+#define EFFI_ALIGN_OFF(off, a) (((off) + ((a)-1)) & ~((a)-1))
+
 DEFUN("ffi-slot-offset", Fffi_slot_offset, 2, 2, 0, /*
 Return the offset of SLOT in TYPE.
 SLOT can be either a valid (named) slot in TYPE or `nil'.
@@ -783,7 +798,7 @@ If SLOT is `nil' return the size of the struct.
       (type, slot))
 {
        Lisp_Object slots;
-       int lpad, align, retoff;
+       size_t retoff = 0;
 
        type = ffi_canonicalise_type(type);
        if (!CONSP(type)) {
@@ -795,42 +810,19 @@ If SLOT is `nil' return the size of the struct.
 #endif /* SXEMACS */
        }
 
-       retoff = 0;
-       lpad = align = ffi_type_align(type);
        slots = Fcdr(XCDR(type));
        CHECK_CONS(slots);
        while (!NILP(slots)) {
                Lisp_Object tmp_slot = Fcar(Fcdr(XCAR(slots)));
-               int tmp_align;
-               int tmp_size;
-
-               /*
-                * NOTE:
-                *  - for basic types TMP_ALIGN and TMP_SIZE are equal
-                */
-               tmp_align = ffi_type_align(tmp_slot);
 
+                retoff = EFFI_ALIGN_OFF(retoff, ffi_type_align(tmp_slot));
                if (EQ(XCAR(XCAR(slots)), slot)) {
                        /* SLOT found */
                        /* TODO: add support for :offset keyword in SLOT */
-                       if (lpad < tmp_align) {
-                               retoff += lpad;
-                               lpad = 0;
-                       } else
-                               lpad -= tmp_align;
-                       break;
-               }
-
-               tmp_size = XINT(Fffi_size_of_type(tmp_slot));
-               while (tmp_size > 0) {
-                       if (lpad < tmp_align) {
-                               retoff += lpad;
-                               lpad = align;
-                       }
-                       tmp_size -= tmp_align;
-                       lpad -= tmp_align;
-                       retoff += tmp_align;
+                        break;
+                        /* NOT REACHED */
                }
+                retoff += XINT(Fffi_size_of_type(tmp_slot));
 
                slots = XCDR(slots);
        }
@@ -841,7 +833,7 @@ If SLOT is `nil' return the size of the struct.
                signal_error(Qinternal_error, "FFI: Slot not found", slot);
 #endif /* SXEMACS */
        }
-       return make_int(retoff + lpad);
+       return make_int(retoff);
 }
 
 /*
@@ -1674,6 +1666,8 @@ Return DEVICE display as FFI object.
 /* Callbacks */
 #define FFI_CC_CDECL 0
 
+void* ffi_make_callback_x86(Lisp_Object data, int cc_type);
+
 #if defined __i386__
 static void
 ffi_callback_call_x86(Lisp_Object cbk_info, char *arg_buffer)
@@ -1825,6 +1819,13 @@ Create dynamic callback and return pointer to it.
        ptr = Fmake_ffi_object(Qpointer, Qnil);
 #ifdef __i386__
        XEFFIO(ptr)->fop.ptr = ffi_make_callback_x86(data, XINT(cctype));
+#else
+#ifdef SXEMACS
+        error("FFI Callbacks not supported on this configuration");
+#else
+        signal_ferror(Qinternal_error,
+                      "FFI Callbacks not supported on this configuration");
+#endif /* SXEMACS */
 #endif /* __i386__ */
        return ptr;
 }