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;
 	

Reply via email to