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; }