Fix Alignment Errors.
[gnome.gobject-introspection] / girepository / girnode.c
index bd9be68..ede6d3b 100644 (file)
@@ -53,6 +53,13 @@ _g_irnode_dump_stats (void)
   g_message ("%lu types (%lu before sharing)", unique_types_count, types_count);
 }
 
+#define DO_ALIGNED_COPY(dest_addr, value, type) \
+do {                                            \
+       type tmp_var;                           \
+       tmp_var = value;                        \
+       memcpy(dest_addr, &tmp_var, sizeof(type));      \
+} while(0)
+
 #define ALIGN_VALUE(this, boundary) \
   (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
 
@@ -279,6 +286,7 @@ g_ir_node_free (GIrNode *node)
        
        g_free (node->name);
        g_ir_node_free ((GIrNode *)field->type);
+       g_ir_node_free ((GIrNode *)field->callback);
       }
       break;
 
@@ -508,7 +516,13 @@ g_ir_node_get_size (GIrNode *node)
       break;
 
     case G_IR_NODE_FIELD:
-      size = sizeof (FieldBlob);
+      {
+       GIrNodeField *field = (GIrNodeField *)node;
+
+        size = sizeof (FieldBlob);
+        if (field->callback)
+          size += g_ir_node_get_size ((GIrNode *)field->callback);
+      }
       break;
 
     case G_IR_NODE_CONSTANT:
@@ -797,7 +811,10 @@ g_ir_node_get_full_size_internal (GIrNode *parent,
 
        size = sizeof (FieldBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
-       size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type);        
+       if (field->callback)
+          size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->callback);
+       else
+          size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type);
       }
       break;
 
@@ -1080,7 +1097,7 @@ find_entry_node (GIrModule   *module,
       goto out;
     }
 
-  g_warning ("Entry '%s' not found", name);
+  g_ir_module_fatal (module, 0, "Type reference '%s' not found", name);
 
  out:
 
@@ -1229,6 +1246,8 @@ serialize_type (GIrModule    *module,
     "uint32", 
     "int64", 
     "uint64", 
+    "short",
+    "ushort",
     "int",
     "uint",
     "long",
@@ -1237,11 +1256,10 @@ serialize_type (GIrModule    *module,
     "size",
     "float", 
     "double",
+    "time_t",
+    "GType",
     "utf8", 
     "filename",
-    "string",
-    "sequence",
-    "any"
   };
   
   if (node->tag < GI_TYPE_TAG_ARRAY)
@@ -1586,8 +1604,6 @@ g_ir_node_build_typelib (GIrNode         *node,
        FieldBlob *blob;
 
        blob = (FieldBlob *)&data[*offset];
-       /* We handle the size member specially below, so subtract it */
-       *offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob);
 
        blob->name = write_string (node->name, strings, data, offset2);
        blob->readable = field->readable;
@@ -1599,8 +1615,22 @@ g_ir_node_build_typelib (GIrNode         *node,
        else
          blob->struct_offset = 0xFFFF; /* mark as unknown */
 
-        g_ir_node_build_typelib ((GIrNode *)field->type, 
-                                node, build, offset, offset2);
+        if (field->callback)
+          {
+            blob->has_embedded_type = TRUE;
+            blob->type.offset = GI_INFO_TYPE_CALLBACK;
+           *offset += sizeof (FieldBlob);
+            g_ir_node_build_typelib ((GIrNode *)field->callback,
+                                    node, build, offset, offset2);
+          }
+        else
+          {
+            blob->has_embedded_type = FALSE;
+            /* We handle the size member specially below, so subtract it */
+           *offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob);
+            g_ir_node_build_typelib ((GIrNode *)field->type,
+                                    node, build, offset, offset2);
+          }
       }
       break;
 
@@ -2248,11 +2278,11 @@ g_ir_node_build_typelib (GIrNode         *node,
            break;
          case GI_TYPE_TAG_INT64:
            blob->size = 8;
-           *(gint64*)&data[blob->offset] = (gint64) parse_int_value (constant->value);
+           DO_ALIGNED_COPY(&data[blob->offset], parse_int_value (constant->value), gint64);
            break;
          case GI_TYPE_TAG_UINT64:
            blob->size = 8;
-           *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value);
+           DO_ALIGNED_COPY(&data[blob->offset], parse_uint_value (constant->value), guint64);
            break;
          case GI_TYPE_TAG_SHORT:
            blob->size = sizeof (gshort);
@@ -2273,21 +2303,21 @@ g_ir_node_build_typelib (GIrNode         *node,
          case GI_TYPE_TAG_SSIZE: /* FIXME */
          case GI_TYPE_TAG_LONG:
            blob->size = sizeof (glong);
-           *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value);
+           DO_ALIGNED_COPY(&data[blob->offset], parse_int_value (constant->value), glong);
            break;
          case GI_TYPE_TAG_SIZE: /* FIXME */
          case GI_TYPE_TAG_TIME_T: 
          case GI_TYPE_TAG_ULONG:
            blob->size = sizeof (gulong);
-           *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value);
+           DO_ALIGNED_COPY(&data[blob->offset], parse_uint_value (constant->value), gulong);
            break;
          case GI_TYPE_TAG_FLOAT:
            blob->size = sizeof (gfloat);
-           *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value);
+           DO_ALIGNED_COPY(&data[blob->offset], parse_float_value (constant->value), gfloat);
            break;
          case GI_TYPE_TAG_DOUBLE:
            blob->size = sizeof (gdouble);
-           *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value);
+           DO_ALIGNED_COPY(&data[blob->offset], parse_float_value (constant->value), gdouble);
            break;
          case GI_TYPE_TAG_UTF8:
          case GI_TYPE_TAG_FILENAME: