The word-alignment bugs are now fixed in lua-gtk CVS Upstream's diffs to the source are attached, but it doesn't apply cleanly to the 0.8 - among other things, there are new source files, and unrelated extra "const" declarations.
lua-gtk version 0.9 was released on 25 August 2008 - is that in time for lenny or should I derive and test an alignment patch for 0.8-2008* ?
diff -ru lua-gtk-0.9/src/boxed.c /home/luagnome/build/lua-gtk-0.9/src/boxed.c --- lua-gtk-0.9/src/boxed.c 2008-07-22 16:28:11.000000000 +0100 +++ /home/luagnome/build/lua-gtk-0.9/src/boxed.c 2008-09-01 12:48:07.000000000 +0100 @@ -171,7 +171,7 @@ * A boxed value should now be used to fill a gtk_arg_types. */ void luagtk_boxed_to_ffi(lua_State *L, int index, union gtk_arg_types *dest, - ffi_type **argtype) + const ffi_type **argtype) { struct boxed_lua_value *b = (struct boxed_lua_value*) lua_topointer(L, index); diff -ru lua-gtk-0.9/src/call.c /home/luagnome/build/lua-gtk-0.9/src/call.c --- lua-gtk-0.9/src/call.c 2008-07-23 12:16:44.000000000 +0100 +++ /home/luagnome/build/lua-gtk-0.9/src/call.c 2008-09-01 12:50:21.000000000 +0100 @@ -24,7 +24,7 @@ #include <string.h> // memset, strcmp, memcpy #include <stdarg.h> // va_start etc. -#include "luagtk_ffi.h" // LUAGTK_FFI_TYPE() macro +// #include "luagtk_ffi.h" // LUAGTK_FFI_TYPE() macro /* extra arguments that have to be allocated are kept in this list. */ @@ -203,7 +203,7 @@ #define ALLOC_MORE(p, type) p = (type*) g_realloc(p, n * sizeof(*p)); \ memset(p + old_n, 0, sizeof(*p) * (n - old_n)) ALLOC_MORE(ci->args, struct call_arg); - ALLOC_MORE(ci->argtypes, ffi_type*); + ALLOC_MORE(ci->argtypes, const ffi_type*); ALLOC_MORE(ci->argvalues, void*); #undef ALLOC_MORE @@ -496,7 +496,8 @@ /* call the function */ if (_call_build_parameters(L, index, ci)) { if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, ci->arg_count, - ci->argtypes[0], ci->argtypes + 1) == FFI_OK) { + (ffi_type*) ci->argtypes[0], + (ffi_type**) ci->argtypes + 1) == FFI_OK) { // A trace function displaying the argument values could be called // from here. This doesn't exist yet. diff -ru lua-gtk-0.9/src/closure.c /home/luagnome/build/lua-gtk-0.9/src/closure.c --- lua-gtk-0.9/src/closure.c 2008-07-23 12:18:58.000000000 +0100 +++ /home/luagnome/build/lua-gtk-0.9/src/closure.c 2008-09-01 12:50:06.000000000 +0100 @@ -13,7 +13,7 @@ #include "luagtk.h" #include <lauxlib.h> // luaL_check*, luaL_ref/unref -#include "luagtk_ffi.h" +// #include "luagtk_ffi.h" #include <string.h> // memset #include <stdlib.h> // exit @@ -29,7 +29,7 @@ void *code; // points to somewhere in closure ffi_closure *closure; // closure allocated by FFI ffi_cif *cif; // cif - spec of retval/args types - ffi_type **arg_types; // allocated array + const ffi_type **arg_types; // allocated array int is_automatic; // true if allocated automatically }; @@ -39,7 +39,7 @@ struct closure_keeper *next; ffi_closure *closure; ffi_cif *cif; - ffi_type **arg_types; + const ffi_type **arg_types; }; static struct closure_keeper *unused = NULL; @@ -254,7 +254,7 @@ * * The first byte is the length of the following data. */ -static int set_ffi_types(const unsigned char *sig, ffi_type **arg_types) +static int set_ffi_types(const unsigned char *sig, const ffi_type **arg_types) { int type_idx, arg_nr=0; const unsigned char *sig_end = sig + 1 + *sig; @@ -275,7 +275,7 @@ // really free all memory of the closure. static void _free_closure(ffi_closure *closure, ffi_cif *cif, - ffi_type **arg_types) + const ffi_type **arg_types) { ffi_closure_free(closure); @@ -459,10 +459,10 @@ luaL_error(L, "luagtk_make_closure: invalid signature"); // allocate and fill arg_types, then ffi_cif - cl->arg_types = (ffi_type**) g_malloc(sizeof(ffi_type*) * arg_count); + cl->arg_types = (const ffi_type**) g_malloc(sizeof(ffi_type*) * arg_count); set_ffi_types(sig, cl->arg_types); - ffi_prep_cif(cl->cif, FFI_DEFAULT_ABI, arg_count-1, cl->arg_types[0], - cl->arg_types+1); + ffi_prep_cif(cl->cif, FFI_DEFAULT_ABI, arg_count-1, + (ffi_type*) cl->arg_types[0], (ffi_type**) cl->arg_types+1); ffi_prep_closure_loc(cl->closure, cl->cif, closure_handler, (void*) cl, cl->code); } diff -ru lua-gtk-0.9/src/hash-cmph.c /home/luagnome/build/lua-gtk-0.9/src/hash-cmph.c --- lua-gtk-0.9/src/hash-cmph.c 2008-06-23 13:09:00.000000000 +0100 +++ /home/luagnome/build/lua-gtk-0.9/src/hash-cmph.c 2008-09-01 11:07:05.000000000 +0100 @@ -14,6 +14,68 @@ #include <endian.h> #endif +#ifdef __ARMEL__ + +#if 0 +// access bytewise, which is not as efficient I guess. Well, optimization +// shouldn't be done but I couldn't resist in this case. +static int _get_bytes_simple(const void *p, int n) +{ + unsigned int val = 0, shift = 0; + + while (n-- > 0) { + val |= (*(unsigned char*) p) << shift; + p ++; + shift += 8; + } + + return val; +} +#endif + +/** + * The architecture ARMEL demands that memory accesses are aligned by the + * data type size. Therefore, when using "int" (4 bytes), align by 4 bytes. + * Note that "n" will typically be 2, but could be anything from 1 to 4. + */ +static int _get_bytes(const void *p, int n) +{ + unsigned int ofs = ((size_t)p) & 3; + p = (void*) (((size_t)p) & ~3); + + // get the first word and shift + unsigned int val = (((unsigned int*)p)[0] >> (ofs<<3)); + + // all of it in the first word - mask and return + if (ofs + n <= 4) + return val & ((1 << (n<<3))-1); + + // need to access next word, too. armel is little endian + unsigned int val2 = ((unsigned int*)p)[1] >> ((8 - n - ofs)<<3); + val2 <<= (4 - ofs)<<3; + return val | val2; +} + +#elif (__BYTE_ORDER == __BIG_ENDIAN) + +static int _get_bytes(const void *p, int n) +{ + unsigned int val = * (unsigned int *) p; + unsigned int shift = (sizeof(unsigned int) - n) << 3; + return val >> shift; +} + +#else + +static int _get_bytes(const void *p, int n) +{ + unsigned int val = * (unsigned int *) p; + unsigned int mask = (1 << (n << 3)) - 1; + return val & mask; +} + +#endif + /** * Hash table lookup. The key is used to calculate a bucket number. The * hash value stored there is verified; if it matches, then an entry has @@ -29,7 +91,7 @@ { int bucket_nr, bucket_size = hi->offset_size + hi->hash_size; const unsigned char *bucket; - unsigned int hash_value, data_offset, data_offset2, mask; + unsigned int hash_value, val, mask, data_offset, data_offset2; /* determine the bucket number, and the bucket address */ bucket_nr = CMPH_ALGORITHM(hi, (const unsigned char*) key, keylen, @@ -37,32 +99,20 @@ bucket = hi->index + bucket_nr * bucket_size; /* check hash value - but just the first "hash_size" bytes. */ + val = _get_bytes(bucket, hi->hash_size); mask = (1 << (hi->hash_size << 3)) - 1; - unsigned int val = * (unsigned int*) bucket; - -#if (__BYTE_ORDER == __BIG_ENDIAN) - /* Correct for Big Endianness */ - unsigned int shift = (sizeof(unsigned int) - hi->hash_size) << 3; - val >>= shift; -#endif if ((hash_value ^ val) & mask) return NULL; /* found! get the data address */ bucket += hi->hash_size; - data_offset = * (unsigned int*) bucket; + data_offset = _get_bytes(bucket, hi->offset_size); /* get next bucket to determine the length of the data entry */ bucket += bucket_size; - data_offset2 = * (unsigned int*)bucket; - mask = (1 << (hi->offset_size << 3)) - 1; - -#if (__BYTE_ORDER == __BIG_ENDIAN) - data_offset >>= shift; - data_offset2 >>= shift; -#endif + data_offset2 = _get_bytes(bucket, hi->offset_size); - *datalen = (data_offset2 & mask) - (data_offset & mask); - return hi->data + (data_offset & mask); + *datalen = data_offset2 - data_offset; + return hi->data + data_offset; } diff -ru lua-gtk-0.9/src/luagtk.h /home/luagnome/build/lua-gtk-0.9/src/luagtk.h --- lua-gtk-0.9/src/luagtk.h 2008-07-23 16:38:50.000000000 +0100 +++ /home/luagnome/build/lua-gtk-0.9/src/luagtk.h 2008-09-01 12:57:47.000000000 +0100 @@ -183,6 +183,34 @@ #define FFI_CHAR_PTR_CONST 1 // flags: for char_ptr: don't free this retval +#define LUAGTK_FFI_TYPE(nr) ffi_array[nr] +extern const ffi_type *ffi_array[]; + +#define LUAGTK_FFI_TYPE_VOID 1 +#define LUAGTK_FFI_TYPE_UCHAR 2 +#define LUAGTK_FFI_TYPE_SCHAR 3 +#define LUAGTK_FFI_TYPE_USHORT 4 +#define LUAGTK_FFI_TYPE_SSHORT 5 +#define LUAGTK_FFI_TYPE_UINT 6 +#define LUAGTK_FFI_TYPE_SINT 7 +#define LUAGTK_FFI_TYPE_ULONG 8 +#define LUAGTK_FFI_TYPE_SLONG 9 +#define LUAGTK_FFI_TYPE_UINT64 10 +#define LUAGTK_FFI_TYPE_SINT64 11 +#define LUAGTK_FFI_TYPE_POINTER 12 +#define LUAGTK_FFI_TYPE_FLOAT 13 +#define LUAGTK_FFI_TYPE_DOUBLE 14 +#define LUAGTK_FFI_TYPE_LONGDOUBLE 15 + +/* not used +#define LUAGTK_FFI_TYPE_UINT8 2 +#define LUAGTK_FFI_TYPE_SINT8 3 +#define LUAGTK_FFI_TYPE_UINT16 4 +#define LUAGTK_FFI_TYPE_SINT16 5 +#define LUAGTK_FFI_TYPE_UINT32 6 +#define LUAGTK_FFI_TYPE_SINT32 7 +*/ + // in types.c unsigned long int luagtk_get_bits(const unsigned char *ptr, int bitofs, int bitlen); @@ -195,7 +223,7 @@ int lua2ffi_void_ptr(struct argconv_t *ar); int luagtk_is_vwrapper(void *p); void luagtk_userdata_to_ffi(lua_State *L, int index, union gtk_arg_types *dest, - ffi_type **argtype, int only_ptr); + const ffi_type **argtype, int only_ptr); int luagtk_vwrapper_get(lua_State *L, struct value_wrapper *p); // in enum.c @@ -328,7 +356,7 @@ int arg_alloc; /* number of slots allocated in args */ /* arguments. [0] is for the return value */ - ffi_type **argtypes; + const ffi_type **argtypes; void **argvalues; /* [0] not used */ struct call_arg *args; @@ -425,7 +453,7 @@ void *luagtk_make_boxed_value(lua_State *L, int index); int luagtk_get_boxed_value(lua_State *L, const void *p); void luagtk_boxed_to_ffi(lua_State *L, int index, union gtk_arg_types *dest, - ffi_type **argtype); + const ffi_type **argtype); // in call.c enum luagtk_msg_level { LUAGTK_DEBUG=0, LUAGTK_INFO, LUAGTK_WARNING, diff -ru lua-gtk-0.9/src/types.c /home/luagnome/build/lua-gtk-0.9/src/types.c --- lua-gtk-0.9/src/types.c 2008-07-23 16:41:51.000000000 +0100 +++ /home/luagnome/build/lua-gtk-0.9/src/types.c 2008-09-01 13:32:14.000000000 +0100 @@ -15,13 +15,37 @@ * ffi_type_names */ #include "luagtk.h" -#include "luagtk_ffi.h" #include <lauxlib.h> #include <string.h> // strcmp #include <stdlib.h> // strtol #include <math.h> // floor +// map the LUAGTK_FFI_TYPE_xxx constants to the actual structures. I +// previously had the constants be generated at compile time so that +// they could be used as index starting at the ffi_type with the lowest +// address, but at least on architecture armel the relative offets between +// the different ffi_type_xxx structures isn't dependable. +const ffi_type *ffi_array[] = { + NULL, + + &ffi_type_void, + &ffi_type_uchar, + &ffi_type_schar, + &ffi_type_ushort, + &ffi_type_sshort, + &ffi_type_uint, + &ffi_type_sint, + &ffi_type_ulong, + &ffi_type_slong, + &ffi_type_uint64, + &ffi_type_sint64, + &ffi_type_pointer, + &ffi_type_float, + &ffi_type_double, + &ffi_type_longdouble, +}; + // The order in these ENUMs must match the function pointer arrays at the // end of this file. enum { LUA2FFI_BOOL=1, LUA2FFI_LONG, LUA2FFI_ENUM, LUA2FFI_LONGLONG, @@ -66,8 +90,8 @@ unsigned long int val; if (bitlen && bitlen <= BITS_PER_INT) { - ptr += bitofs >> 3; - bitofs = bitofs & 7; + ptr += (bitofs >> 3) & ~(BITS_PER_INT/8-1); + bitofs = bitofs & (BITS_PER_INT-1); val = (* (unsigned long*) ptr) >> bitofs; if (bitlen < BITS_PER_INT) val &= (1L << bitlen) - 1; @@ -79,7 +103,7 @@ luaL_error(L, "%s access to attribute of size %d not supported", msgprefix, bitlen); } -#undef BITS_PER_INT + /** * Retrieve an arbitrarily long memory block, which must be byte aligned @@ -117,9 +141,9 @@ { unsigned long int v, mask; - /* do byte aligned accesses */ - ptr += bitofs / 8; - bitofs = bitofs % 8; + /* do 32 bit aligned accesses */ + ptr += (bitofs >> 3) & ~(BITS_PER_INT/8-1); + bitofs = bitofs & (BITS_PER_INT-1); if (bitlen == 0 || bitlen+bitofs > sizeof(v)*8) { printf("%s write to attribute of size %d not supported\n", @@ -127,7 +151,7 @@ return; } - mask = (bitlen < sizeof(mask)*8) ? ((1L << bitlen) - 1) : -1L; + mask = (bitlen < BITS_PER_INT) ? ((1L << bitlen) - 1) : -1L; mask <<= bitofs; // fetch the old value, replace bits with new value, write back. @@ -136,6 +160,8 @@ v |= (val << bitofs) & mask; * (unsigned long int*) ptr = v; } +#undef BITS_PER_INT + static inline void set_bits_long(lua_State *L, unsigned char *dest, int bitofs, int bitlen, const char *src) @@ -1421,7 +1447,7 @@ const struct struct_elem *se, unsigned char *ptr, int index) { union gtk_arg_types dest; - ffi_type *argtype; + const ffi_type *argtype; luagtk_userdata_to_ffi(L, index, &dest, &argtype, 1); set_bits_long(L, ptr, se->bit_offset, se->bit_length, (char*) &dest.p); return 1; diff -ru lua-gtk-0.9/src/voidptr.c /home/luagnome/build/lua-gtk-0.9/src/voidptr.c --- lua-gtk-0.9/src/voidptr.c 2008-07-21 14:28:27.000000000 +0100 +++ /home/luagnome/build/lua-gtk-0.9/src/voidptr.c 2008-09-01 12:48:32.000000000 +0100 @@ -57,7 +57,7 @@ * @param only_ptr Only accept a pointer type; otherwise, ENUM (integer) is OK */ void luagtk_userdata_to_ffi(lua_State *L, int index, union gtk_arg_types *dest, - ffi_type **argtype, int only_ptr) + const ffi_type **argtype, int only_ptr) { void *p = (void*) lua_topointer(L, index); @@ -271,7 +271,7 @@ break; case LUA_TUSERDATA:; - ffi_type *argtype; + const ffi_type *argtype; luagtk_userdata_to_ffi(L, ar->index, ar->arg, &argtype, 1); break;