X-Git-Url: http://cgit.sxemacs.org/?a=blobdiff_plain;f=src%2Feffi.c;h=06bf61b48e2905002bb2756ee1a2bf5d74eded3c;hb=1b59d1cfe7ed5c2742559c44ae8a39d4d5d847af;hp=50cac5eec135d6c1715e82e55341f919d4c55a2c;hpb=086d8b4086119b0a2d84ae08c2b17dd81c5d3312;p=sxemacs
diff --git a/src/effi.c b/src/effi.c
index 50cac5e..06bf61b 100644
--- a/src/effi.c
+++ b/src/effi.c
@@ -25,6 +25,7 @@ along with this program. If not, see . */
#include
#include
#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, /*
@@ -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;
}