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))
{
ffi_check_type(type);
XEFFIO(fo)->type = type;
- return type;
+ return fo;
}
DEFUN("ffi-object-size", Fffi_object_size, 1, 1, 0, /*
/*
* 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
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;
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'.
(type, slot))
{
Lisp_Object slots;
- int lpad, align, retoff;
+ size_t retoff = 0;
type = ffi_canonicalise_type(type);
if (!CONSP(type)) {
#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);
}
signal_error(Qinternal_error, "FFI: Slot not found", slot);
#endif /* SXEMACS */
}
- return make_int(retoff + lpad);
+ return make_int(retoff);
}
/*
/* 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)
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;
}