Add support for foreign structs
[gnome.gobject-introspection] / girepository / ginfo.c
index 3de0cf5..724109f 100644 (file)
@@ -1,6 +1,7 @@
 /* GObject introspection: Repository implementation
  *
  * Copyright (C) 2005 Matthias Clasen
+ * Copyright (C) 2008,2009 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 #include <glib.h>
 #include <glib-object.h>
 
-#include "girepository.h"
 #include "gtypelib.h"
+#include "ginfo.h"
 
-struct _GIBaseInfo 
+typedef struct _GIRealInfo GIRealInfo;
+
+/**
+ * We just use one structure for all of the info object
+ * types; in general, we should be reading data directly
+ * from the typelib, and not having computed data in
+ * per-type structures.
+ */
+struct _GIRealInfo
 {
-  gint type;
-  gint ref_count;
+  /* Keep this part in sync with GIUnresolvedInfo below */
+  gint32 type;
+  gint32 ref_count;
+  GIRepository *repository;
   GIBaseInfo *container;
 
+  /* Resolved specific */
+
   GTypelib *typelib;
   guint32 offset;
+
+  guint32 type_is_embedded : 1; /* Used by GITypeInfo */
+  guint32 reserved : 31;
+
+  gpointer reserved2[4];
 };
 
 struct _GIUnresolvedInfo
 {
-  gint type;
-  gint ref_count;
+  /* Keep this part in sync with GIBaseInfo above */
+  gint32 type;
+  gint32 ref_count;
+  GIRepository *repository;
   GIBaseInfo *container;
 
+  /* Unresolved specific */
+
   const gchar *name;
   const gchar *namespace;
 };
 
-struct _GICallableInfo
-{
-  GIBaseInfo base;
-};
-
-struct _GIFunctionInfo
-{
-  GICallableInfo callable;
-};
+#define INVALID_REFCOUNT 0x7FFFFFFF
 
-struct _GICallbackInfo
+static void
+g_info_init (GIRealInfo     *info,
+             GIInfoType      type,
+             GIRepository   *repository,
+             GIBaseInfo     *container,
+             GTypelib       *typelib,
+             guint32         offset)
 {
-  GICallableInfo callable;
-};
+  memset (info, 0, sizeof (GIRealInfo));
 
-struct _GIRegisteredTypeInfo
-{
-  GIBaseInfo base;
-};
-
-struct _GIStructInfo
-{
-  GIRegisteredTypeInfo registered;
-};
-
-struct _GIEnumInfo
-{
-  GIRegisteredTypeInfo registered;
-};
-
-struct _GIObjectInfo
-{
-  GIRegisteredTypeInfo registered;
-};
+  /* Invalid refcount used to flag stack-allocated infos */
+  info->ref_count = INVALID_REFCOUNT;
+  info->type = type;
 
-struct _GIInterfaceInfo
-{
-  GIRegisteredTypeInfo registered;
-};
+  info->typelib = typelib;
+  info->offset = offset;
 
-struct _GIConstantInfo
-{
-  GIBaseInfo base;
-};
+  if (container)
+    info->container = container;
 
-struct _GIValueInfo
-{
-  GIBaseInfo base;
-};
+  g_assert (G_IS_IREPOSITORY (repository));
+  info->repository = repository;
+}
 
-struct _GISignalInfo
+/* info creation */
+GIBaseInfo *
+g_info_new_full (GIInfoType     type,
+                 GIRepository  *repository,
+                 GIBaseInfo    *container,
+                 GTypelib      *typelib,
+                 guint32        offset)
 {
-  GICallableInfo callable;
-};
+  GIRealInfo *info;
 
-struct _GIVFuncInfo
-{
-  GICallableInfo callable;
-};
+  g_return_val_if_fail (container != NULL || repository != NULL, NULL);
 
-struct _GIPropertyInfo
-{
-  GIBaseInfo base;
-};
+  info = g_new (GIRealInfo, 1);
 
-struct _GIFieldInfo
-{
-  GIBaseInfo base;
-};
+  g_info_init (info, type, repository, container, typelib, offset);
+  info->ref_count = 1;
 
-struct _GIArgInfo
-{
-  GIBaseInfo base;
-};
+  if (container && ((GIRealInfo *) container)->ref_count != INVALID_REFCOUNT)
+    g_base_info_ref (info->container);
 
-struct _GITypeInfo
-{
-  GIBaseInfo base;
-};
-
-struct _GIUnionInfo
-{
-  GIRegisteredTypeInfo registered;
-};
+  g_object_ref (info->repository);
 
+  return (GIBaseInfo*)info;
+}
 
-/* info creation */
 GIBaseInfo *
 g_info_new (GIInfoType     type,
-           GIBaseInfo    *container,
-           GTypelib     *typelib, 
-           guint32        offset)
+            GIBaseInfo    *container,
+            GTypelib      *typelib,
+            guint32        offset)
 {
-  GIBaseInfo *info;
-
-  info = g_new0 (GIBaseInfo, 1);
-
-  info->ref_count = 1;
-  info->type = type;
-
-  info->typelib = typelib;
-  info->offset = offset;
-
-  if (container)
-    info->container = g_base_info_ref (container);
-
-  return info;
+  return g_info_new_full (type, ((GIRealInfo*)container)->repository, container, typelib, offset);
 }
 
 static GIBaseInfo *
-g_info_from_entry (GTypelib *typelib,
-                  guint16    index)
+g_info_from_entry (GIRepository *repository,
+                   GTypelib     *typelib,
+                   guint16       index)
 {
   GIBaseInfo *result;
   DirEntry *entry = g_typelib_get_dir_entry (typelib, index);
-  
+
   if (entry->local)
-    result = g_info_new (entry->blob_type, NULL, typelib, entry->offset);
-  else 
+    result = g_info_new_full (entry->blob_type, repository, NULL, typelib, entry->offset);
+  else
     {
       const gchar *namespace = g_typelib_get_string (typelib, entry->offset);
       const gchar *name = g_typelib_get_string (typelib, entry->name);
-      
-      GIRepository *repository = g_irepository_get_default ();
-      
+
       result = g_irepository_find_by_name (repository, namespace, name);
       if (result == NULL)
-       {
-         GIUnresolvedInfo *unresolved;
-
-         unresolved = g_new0 (GIUnresolvedInfo, 1);
-         
-         unresolved->type = GI_INFO_TYPE_UNRESOLVED;
-         unresolved->ref_count = 1;
-         unresolved->container = NULL;
-         unresolved->name = name;
-         unresolved->namespace = namespace;
-         
-         return (GIBaseInfo*)unresolved;
-       }
-      return result;
+        {
+          GIUnresolvedInfo *unresolved;
+
+          unresolved = g_new0 (GIUnresolvedInfo, 1);
+
+          unresolved->type = GI_INFO_TYPE_UNRESOLVED;
+          unresolved->ref_count = 1;
+          unresolved->repository = g_object_ref (repository);
+          unresolved->container = NULL;
+          unresolved->name = name;
+          unresolved->namespace = namespace;
+
+          return (GIBaseInfo *)unresolved;
+           }
+      return (GIBaseInfo *)result;
     }
 
-  return result;
+  return (GIBaseInfo *)result;
 }
 
 /* GIBaseInfo functions */
 GIBaseInfo *
 g_base_info_ref (GIBaseInfo *info)
 {
-  info->ref_count++;
+  GIRealInfo *rinfo = (GIRealInfo*)info;
+
+  g_assert (rinfo->ref_count != INVALID_REFCOUNT);
+  ((GIRealInfo*)info)->ref_count++;
 
   return info;
 }
@@ -205,30 +181,36 @@ g_base_info_ref (GIBaseInfo *info)
 void
 g_base_info_unref (GIBaseInfo *info)
 {
-  g_assert (info->ref_count > 0);
-  info->ref_count--;
+  GIRealInfo *rinfo = (GIRealInfo*)info;
 
-  if (!info->ref_count)
+  g_assert (rinfo->ref_count > 0 && rinfo->ref_count != INVALID_REFCOUNT);
+  rinfo->ref_count--;
+
+  if (!rinfo->ref_count)
     {
-      if (info->container)
-       g_base_info_unref (info->container);
+      if (rinfo->container && ((GIRealInfo *) rinfo->container)->ref_count != INVALID_REFCOUNT)
+        g_base_info_unref (rinfo->container);
+
+      if (rinfo->repository)
+        g_object_unref (rinfo->repository);
 
-      g_free (info);
+      g_free (rinfo);
     }
 }
 
 GIInfoType
 g_base_info_get_type (GIBaseInfo *info)
 {
-  
-  return info->type;
+
+  return ((GIRealInfo*)info)->type;
 }
 
 const gchar *
 g_base_info_get_name (GIBaseInfo *info)
 {
-  g_assert (info->ref_count > 0);
-  switch (info->type)
+  GIRealInfo *rinfo = (GIRealInfo*)info;
+  g_assert (rinfo->ref_count > 0);
+  switch (rinfo->type)
     {
     case GI_INFO_TYPE_FUNCTION:
     case GI_INFO_TYPE_CALLBACK:
@@ -242,64 +224,64 @@ g_base_info_get_name (GIBaseInfo *info)
     case GI_INFO_TYPE_ERROR_DOMAIN:
     case GI_INFO_TYPE_UNION:
       {
-       CommonBlob *blob = (CommonBlob *)&info->typelib->data[info->offset];
+        CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
 
-       return g_typelib_get_string (info->typelib, blob->name);
+        return g_typelib_get_string (rinfo->typelib, blob->name);
       }
       break;
 
     case GI_INFO_TYPE_VALUE:
       {
-       ValueBlob *blob = (ValueBlob *)&info->typelib->data[info->offset];
+        ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset];
 
-       return g_typelib_get_string (info->typelib, blob->name);
+        return g_typelib_get_string (rinfo->typelib, blob->name);
       }
       break;
 
     case GI_INFO_TYPE_SIGNAL:
       {
-       SignalBlob *blob = (SignalBlob *)&info->typelib->data[info->offset];
+        SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
 
-       return g_typelib_get_string (info->typelib, blob->name);
+        return g_typelib_get_string (rinfo->typelib, blob->name);
       }
       break;
 
     case GI_INFO_TYPE_PROPERTY:
       {
-       PropertyBlob *blob = (PropertyBlob *)&info->typelib->data[info->offset];
+        PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset];
 
-       return g_typelib_get_string (info->typelib, blob->name);
+        return g_typelib_get_string (rinfo->typelib, blob->name);
       }
       break;
 
     case GI_INFO_TYPE_VFUNC:
       {
-       VFuncBlob *blob = (VFuncBlob *)&info->typelib->data[info->offset];
+        VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
 
-       return g_typelib_get_string (info->typelib, blob->name);
+        return g_typelib_get_string (rinfo->typelib, blob->name);
       }
       break;
 
     case GI_INFO_TYPE_FIELD:
       {
-       FieldBlob *blob = (FieldBlob *)&info->typelib->data[info->offset];
-       
-       return g_typelib_get_string (info->typelib, blob->name);
+        FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
+
+        return g_typelib_get_string (rinfo->typelib, blob->name);
       }
       break;
 
     case GI_INFO_TYPE_ARG:
       {
-       ArgBlob *blob = (ArgBlob *)&info->typelib->data[info->offset];
-       
-       return g_typelib_get_string (info->typelib, blob->name);
+        ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
+
+        return g_typelib_get_string (rinfo->typelib, blob->name);
       }
       break;
     case GI_INFO_TYPE_UNRESOLVED:
       {
-       GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info;
+        GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info;
 
-       return unresolved->name;
+        return unresolved->name;
       }
       break;
     case GI_INFO_TYPE_TYPE:
@@ -314,24 +296,26 @@ g_base_info_get_name (GIBaseInfo *info)
 const gchar *
 g_base_info_get_namespace (GIBaseInfo *info)
 {
-  Header *header = (Header *)info->typelib->data;
+  GIRealInfo *rinfo = (GIRealInfo*) info;
+  Header *header = (Header *)rinfo->typelib->data;
 
-  g_assert (info->ref_count > 0);
+  g_assert (rinfo->ref_count > 0);
 
-  if (info->type == GI_INFO_TYPE_UNRESOLVED)
+  if (rinfo->type == GI_INFO_TYPE_UNRESOLVED)
     {
       GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info;
-      
+
       return unresolved->namespace;
     }
 
-  return g_typelib_get_string (info->typelib, header->namespace);
+  return g_typelib_get_string (rinfo->typelib, header->namespace);
 }
 
-gboolean 
+gboolean
 g_base_info_is_deprecated (GIBaseInfo *info)
 {
-  switch (info->type)
+  GIRealInfo *rinfo = (GIRealInfo*) info;
+  switch (rinfo->type)
     {
     case GI_INFO_TYPE_FUNCTION:
     case GI_INFO_TYPE_CALLBACK:
@@ -344,33 +328,33 @@ g_base_info_is_deprecated (GIBaseInfo *info)
     case GI_INFO_TYPE_CONSTANT:
     case GI_INFO_TYPE_ERROR_DOMAIN:
       {
-       CommonBlob *blob = (CommonBlob *)&info->typelib->data[info->offset];
+        CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
 
-       return blob->deprecated;
+        return blob->deprecated;
       }
       break;
 
     case GI_INFO_TYPE_VALUE:
       {
-       ValueBlob *blob = (ValueBlob *)&info->typelib->data[info->offset];
+        ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset];
 
-       return blob->deprecated;
+        return blob->deprecated;
       }
       break;
 
     case GI_INFO_TYPE_SIGNAL:
       {
-       SignalBlob *blob = (SignalBlob *)&info->typelib->data[info->offset];
+        SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
 
-       return blob->deprecated;
+        return blob->deprecated;
       }
       break;
 
     case GI_INFO_TYPE_PROPERTY:
       {
-       PropertyBlob *blob = (PropertyBlob *)&info->typelib->data[info->offset];
+        PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset];
 
-       return blob->deprecated;
+        return blob->deprecated;
       }
       break;
 
@@ -381,106 +365,193 @@ g_base_info_is_deprecated (GIBaseInfo *info)
     default: ;
       /* no deprecation flag for these */
     }
-  
+
   return FALSE;
 }
 
+/**
+ * g_base_info_get_attribute:
+ * @info: A #GIBaseInfo
+ * @name: A freeform string naming an attribute
+ *
+ * Retrieve an arbitrary attribute associated with this node.
+ *
+ * Return value: The value of the attribute, or %NULL if no such attribute exists
+ */
+const gchar *
+g_base_info_get_attribute (GIBaseInfo   *info,
+                           const gchar  *name)
+{
+  GIAttributeIter iter = { 0, };
+  gchar *curname, *curvalue;
+  while (g_base_info_iterate_attributes (info, &iter, &curname, &curvalue))
+    {
+      if (strcmp (name, curname) == 0)
+        return (const gchar*) curvalue;
+    }
+
+  return NULL;
+}
+
 static int
-cmp_annotation (const void *av,
-               const void *bv)
+cmp_attribute (const void *av,
+                const void *bv)
 {
-  const AnnotationBlob *a = av;
-  const AnnotationBlob *b = bv;
-  if (b->offset < a->offset)
-    return -1;
+  const AttributeBlob *a = av;
+  const AttributeBlob *b = bv;
 
-  if (b->offset > a->offset)
+  if (a->offset < b->offset)
+    return -1;
+  else if (a->offset == b->offset)
+    return 0;
+  else
     return 1;
-  
-  return 0;
 }
 
-const gchar *
-g_base_info_get_annotation (GIBaseInfo   *info,
-                           const gchar *name)
-{
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;
-  AnnotationBlob blob, *first, *after, *res, *next;
-  const gchar *rname;
-
-  blob.offset = base->offset;
-  
-  first = (AnnotationBlob *) &base->typelib->data[header->annotations];
-  after = (AnnotationBlob *) &base->typelib->data[header->annotations + 
-                                            header->n_annotations * header->annotation_blob_size];
-
-  res = bsearch (&blob, first, header->n_annotations,
-                header->annotation_blob_size, cmp_annotation);
-  
+static AttributeBlob *
+find_first_attribute (GIRealInfo *rinfo)
+{
+  Header *header = (Header *)rinfo->typelib->data;
+  AttributeBlob blob, *first, *res, *previous;
+
+  blob.offset = rinfo->offset;
+
+  first = (AttributeBlob *) &rinfo->typelib->data[header->attributes];
+
+  res = bsearch (&blob, first, header->n_attributes,
+                 header->attribute_blob_size, cmp_attribute);
+
   if (res == NULL)
     return NULL;
 
-  next = res;
-  do 
+  previous = res - 1;
+  while (previous >= first && previous->offset == rinfo->offset)
     {
-      res = next;
-      next = res -= header->annotation_blob_size;
+      res = previous;
+      previous = res - 1;
     }
-  while (next >= first && next->offset == base->offset);
-    
-  next = res;
-  do 
-    {
-      res = next;
-      
-      rname = g_typelib_get_string (base->typelib, res->name);
-      if (strcmp (name, rname) == 0)
-       return g_typelib_get_string (base->typelib, res->value);
 
-      next = res += header->annotation_blob_size;
-    }
-  while (next < after && next->offset == base->offset);
+  return res;
+}
 
-  return NULL;
+/**
+ * g_base_info_iterate_attributes:
+ * @info: A #GIBaseInfo
+ * @iter: A #GIAttributeIter structure, must be initialized; see below
+ * @name: (out) (transfer none): Returned name, must not be freed
+ * @value: (out) (transfer none): Returned name, must not be freed
+ *
+ * Iterate over all attributes associated with this node.  The iterator
+ * structure is typically stack allocated, and must have its first
+ * member initialized to %NULL.
+ *
+ * Both the @name and @value should be treated as constants
+ * and must not be freed.
+ *
+ * <example>
+ * <title>Iterating over attributes</title>
+ * <programlisting>
+ * void
+ * print_attributes (GIBaseInfo *info)
+ * {
+ *   GIAttributeIter iter = { 0, };
+ *   char *name;
+ *   char *value;
+ *   while (g_base_info_iterate_attributes (info, &iter, &name, &value))
+ *     {
+ *       g_print ("attribute name: %s value: %s", name, value);
+ *     }
+ * }
+ * </programlisting>
+ * </example>
+ *
+ * Return value: %TRUE if there are more attributes, %FALSE otherwise
+ */
+gboolean
+g_base_info_iterate_attributes (GIBaseInfo       *info,
+                                 GIAttributeIter *iter,
+                                 gchar           **name,
+                                 gchar           **value)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  AttributeBlob *next, *after;
+
+  after = (AttributeBlob *) &rinfo->typelib->data[header->attributes +
+                                                  header->n_attributes * header->attribute_blob_size];
+
+  if (iter->data != NULL)
+    next = (AttributeBlob *) iter->data;
+  else
+    next = find_first_attribute (rinfo);
+
+  if (next == NULL || next->offset != rinfo->offset || next >= after)
+    return FALSE;
+
+  *name = (gchar*) g_typelib_get_string (rinfo->typelib, next->name);
+  *value = (gchar*) g_typelib_get_string (rinfo->typelib, next->value);
+  iter->data = next + 1;
+
+  return TRUE;
 }
 
 GIBaseInfo *
 g_base_info_get_container (GIBaseInfo *info)
 {
-  return info->container;
+  return ((GIRealInfo*)info)->container;
 }
 
 GTypelib *
 g_base_info_get_typelib (GIBaseInfo *info)
 {
-  return info->typelib;
+  return ((GIRealInfo*)info)->typelib;
+}
+
+/*
+ * g_base_info_equal:
+ * @info1: A #GIBaseInfo
+ * @info2: A #GIBaseInfo
+ *
+ * Compare two #GIBaseInfo.
+ *
+ * Using pointer comparison is not practical since many functions return
+ * different instances of #GIBaseInfo that refers to the same part of the
+ * TypeLib; use this function instead to do #GIBaseInfo comparisons.
+ *
+ * Return value: TRUE if and only if @info1 equals @info2.
+ */
+gboolean
+g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2)
+{
+  /* Compare the TypeLib pointers, which are mmapped. */
+  GIRealInfo *rinfo1 = (GIRealInfo*)info1;
+  GIRealInfo *rinfo2 = (GIRealInfo*)info2;
+  return rinfo1->typelib->data + rinfo1->offset == rinfo2->typelib->data + rinfo2->offset;
 }
 
 /* GIFunctionInfo functions */
 const gchar *
 g_function_info_get_symbol (GIFunctionInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  return g_typelib_get_string (base->typelib, blob->symbol);
+  return g_typelib_get_string (rinfo->typelib, blob->symbol);
 }
 
 GIFunctionInfoFlags
 g_function_info_get_flags (GIFunctionInfo *info)
 {
   GIFunctionInfoFlags flags;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset];
+
   flags = 0;
 
   /* Make sure we don't flag Constructors as methods */
-  if (base->container != NULL && !blob->constructor)
+  if (!blob->constructor && !blob->is_static)
     flags = flags | GI_FUNCTION_IS_METHOD;
-    
+
   if (blob->constructor)
     flags = flags | GI_FUNCTION_IS_CONSTRUCTOR;
 
@@ -502,30 +573,31 @@ g_function_info_get_flags (GIFunctionInfo *info)
 GIPropertyInfo *
 g_function_info_get_property (GIFunctionInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset];
-  GIInterfaceInfo *container = (GIInterfaceInfo *)base->container;
-  
-  return g_interface_info_get_property (container, blob->index);  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset];
+  GIInterfaceInfo *container = (GIInterfaceInfo *)rinfo->container;
+
+  return g_interface_info_get_property (container, blob->index);
 }
 
 GIVFuncInfo *
 g_function_info_get_vfunc (GIFunctionInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset];
-  GIInterfaceInfo *container = (GIInterfaceInfo *)base->container;
-  
-  return g_interface_info_get_vfunc (container, blob->index);  
-}
+  GIRealInfo *rinfo = (GIRealInfo*)info;
+  FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset];
+  GIInterfaceInfo *container = (GIInterfaceInfo *)rinfo->container;
 
+  return g_interface_info_get_vfunc (container, blob->index);
+}
 
 /* GICallableInfo functions */
 static guint32
 signature_offset (GICallableInfo *info)
 {
+  GIRealInfo *rinfo = (GIRealInfo*)info;
   int sigoff = -1;
-  switch (info->base.type)
+
+  switch (rinfo->type)
     {
     case GI_INFO_TYPE_FUNCTION:
       sigoff = G_STRUCT_OFFSET (FunctionBlob, signature);
@@ -541,19 +613,32 @@ signature_offset (GICallableInfo *info)
       break;
     }
   if (sigoff >= 0)
-    return *(guint32 *)&info->base.typelib->data[info->base.offset + sigoff];
+    return *(guint32 *)&rinfo->typelib->data[rinfo->offset + sigoff];
   return 0;
 }
 
 GITypeInfo *
 g_type_info_new (GIBaseInfo    *container,
-                GTypelib     *typelib,
+                 GTypelib      *typelib,
                 guint32        offset)
 {
   SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset];
 
-  return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib, 
-                                   (type->reserved == 0 && type->reserved2 == 0) ? offset : type->offset);
+  return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib,
+                                    (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset);
+}
+
+static void
+g_type_info_init (GIBaseInfo *info,
+                  GIBaseInfo *container,
+                  GTypelib   *typelib,
+                  guint32     offset)
+{
+  GIRealInfo *rinfo = (GIRealInfo*)container;
+  SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset];
+
+  g_info_init ((GIRealInfo*)info, GI_INFO_TYPE_TYPE, rinfo->repository, container, typelib,
+               (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset);
 }
 
 /**
@@ -569,12 +654,36 @@ g_type_info_new (GIBaseInfo    *container,
 GITypeInfo *
 g_callable_info_get_return_type (GICallableInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
+  GIRealInfo *rinfo = (GIRealInfo *)info;
   guint32 offset;
 
   offset = signature_offset (info);
 
-  return g_type_info_new (base, base->typelib, offset);
+  return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, offset);
+}
+
+
+/**
+ * g_callable_info_load_return_type:
+ * @info: a #GICallableInfo
+ * @type: (out caller-allocates): Initialized with return type of @info
+ *
+ * Get information about a return value of callable; this
+ * function is a variant of g_callable_info_get_return_type() designed for stack
+ * allocation.
+ *
+ * The initialized @type must not be referenced after @info is deallocated.
+ */
+void
+g_callable_info_load_return_type (GICallableInfo *info,
+                                  GITypeInfo     *type)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  guint32 offset;
+
+  offset = signature_offset (info);
+
+  g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, offset);
 }
 
 /**
@@ -588,8 +697,8 @@ g_callable_info_get_return_type (GICallableInfo *info)
 gboolean
 g_callable_info_may_return_null (GICallableInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SignatureBlob *blob = (SignatureBlob *)&base->typelib->data[signature_offset (info)];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  SignatureBlob *blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)];
 
   return blob->may_return_null;
 }
@@ -606,8 +715,8 @@ g_callable_info_may_return_null (GICallableInfo *info)
 GITransfer
 g_callable_info_get_caller_owns (GICallableInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SignatureBlob *blob = (SignatureBlob *)&base->typelib->data[signature_offset (info)];
+  GIRealInfo *rinfo = (GIRealInfo*) info;
+  SignatureBlob *blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)];
 
   if (blob->caller_owns_return_value)
     return GI_TRANSFER_EVERYTHING;
@@ -625,15 +734,15 @@ g_callable_info_get_caller_owns (GICallableInfo *info)
  *
  * Returns: The number of arguments this callable expects.
  */
-gint 
+gint
 g_callable_info_get_n_args (GICallableInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
+  GIRealInfo *rinfo = (GIRealInfo *)info;
   gint offset;
   SignatureBlob *blob;
 
   offset = signature_offset (info);
-  blob = (SignatureBlob *)&base->typelib->data[offset];
+  blob = (SignatureBlob *)&rinfo->typelib->data[offset];
 
   return blob->n_arguments;
 }
@@ -641,6 +750,7 @@ g_callable_info_get_n_args (GICallableInfo *info)
 /**
  * g_callable_info_get_arg:
  * @info: a #GICallableInfo
+ * @n: the argument index to fetch
  *
  * Get information about a particular argument of this callable.
  *
@@ -650,23 +760,50 @@ GIArgInfo *
 g_callable_info_get_arg (GICallableInfo *info,
                         gint           n)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
   gint offset;
 
   offset = signature_offset (info);
-  
-  return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, base, base->typelib, 
+
+  return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, (GIBaseInfo*)info, rinfo->typelib,
                                   offset + header->signature_blob_size + n * header->arg_blob_size);
 }
 
+/**
+ * g_callable_info_load_arg:
+ * @info: a #GICallableInfo
+ * @n: the argument index to fetch
+ * @arg: (out caller-allocates): Initialize with argument number @n
+ *
+ * Get information about a particular argument of this callable; this
+ * function is a variant of g_callable_info_get_arg() designed for stack
+ * allocation.
+ *
+ * The initialized @arg must not be referenced after @info is deallocated.
+ */
+void
+g_callable_info_load_arg (GICallableInfo *info,
+                          gint            n,
+                          GIArgInfo     *arg)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  gint offset;
+
+  offset = signature_offset (info);
+
+  g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib,
+                          offset + header->signature_blob_size + n * header->arg_blob_size);
+}
+
 /* GIArgInfo function */
 GIDirection
 g_arg_info_get_direction (GIArgInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
+
   if (blob->in && blob->out)
     return GI_DIRECTION_INOUT;
   else if (blob->out)
@@ -678,44 +815,44 @@ g_arg_info_get_direction (GIArgInfo *info)
 gboolean
 g_arg_info_is_return_value (GIArgInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->return_value;
 }
 
 gboolean
 g_arg_info_is_dipper (GIArgInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->dipper;
 }
 
 gboolean
 g_arg_info_is_optional (GIArgInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->optional;
 }
 
 gboolean
 g_arg_info_may_be_null (GIArgInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->allow_none;
 }
 
 GITransfer
 g_arg_info_get_ownership_transfer (GIArgInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
 
   if (blob->transfer_ownership)
     return GI_TRANSFER_EVERYTHING;
@@ -725,27 +862,79 @@ g_arg_info_get_ownership_transfer (GIArgInfo *info)
     return GI_TRANSFER_NOTHING;
 }
 
+GIScopeType
+g_arg_info_get_scope (GIArgInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  return blob->scope;
+}
+
+gint
+g_arg_info_get_closure (GIArgInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  return blob->closure;
+}
+
+gint
+g_arg_info_get_destroy (GIArgInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  return blob->destroy;
+}
+
+/**
+ * g_arg_info_get_type:
+ * @info: A #GIArgInfo
+ *
+ * Returns: (transfer full): Information about the type of argument @info
+ */
 GITypeInfo *
 g_arg_info_get_type (GIArgInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  return g_type_info_new (base, base->typelib, base->offset + 8);
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+
+  return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type));
+}
+
+/**
+ * g_arg_info_load_type:
+ * @info: A #GIArgInfo
+ * @type: (out caller-allocates): Initialized with information about type of @info
+ *
+ * Get information about a the type of given argument @info; this
+ * function is a variant of g_arg_info_get_type() designed for stack
+ * allocation.
+ *
+ * The initialized @type must not be referenced after @info is deallocated.
+ */
+void
+g_arg_info_load_type (GIArgInfo *info,
+                      GITypeInfo *type)
+{
+  GIRealInfo *rinfo = (GIRealInfo*) info;
+  g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type));
 }
 
 /* GITypeInfo functions */
 gboolean
 g_type_info_is_pointer (GITypeInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
-  
-  if (type->reserved == 0 && type->reserved2 == 0)
-    return type->pointer;
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
+    return type->flags.pointer;
   else
     {
-      InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->typelib->data[base->offset];
-      
+      InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
+
       return iface->pointer;
     }
 }
@@ -753,14 +942,16 @@ g_type_info_is_pointer (GITypeInfo *info)
 GITypeTag
 g_type_info_get_tag (GITypeInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  if (type->reserved == 0 && type->reserved2 == 0)
-    return type->tag;
+  if (rinfo->type_is_embedded)
+    return GI_TYPE_TAG_INTERFACE;
+  else if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
+    return type->flags.tag;
   else
     {
-      InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->typelib->data[base->offset];
+      InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
 
       return iface->tag;
     }
@@ -768,43 +959,78 @@ g_type_info_get_tag (GITypeInfo *info)
 
 GITypeInfo *
 g_type_info_get_param_type (GITypeInfo *info,
-                           gint       n)
+                            gint       n)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
-  
-  if (!(type->reserved == 0 && type->reserved2 == 0))
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
     {
-      ParamTypeBlob *param = (ParamTypeBlob *)&base->typelib->data[base->offset];
+      ParamTypeBlob *param = (ParamTypeBlob *)&rinfo->typelib->data[rinfo->offset];
 
       switch (param->tag)
-       {
-       case GI_TYPE_TAG_ARRAY: 
-       case GI_TYPE_TAG_GLIST:
-       case GI_TYPE_TAG_GSLIST:
-       case GI_TYPE_TAG_GHASH:
-         return g_type_info_new (base, base->typelib, base->offset + 4 + 4 * n);
-         break;
-         
-       default: ;
-       }
+        {
+          case GI_TYPE_TAG_ARRAY:
+          case GI_TYPE_TAG_GLIST:
+          case GI_TYPE_TAG_GSLIST:
+          case GI_TYPE_TAG_GHASH:
+            return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib,
+                                    rinfo->offset + sizeof (ParamTypeBlob)
+                                    + sizeof (SimpleTypeBlob) * n);
+            break;
+          default:
+            break;
+        }
     }
-      
+
   return NULL;
 }
 
+/**
+ * g_type_info_get_interface:
+ * @info: A #GITypeInfo
+ *
+ * For types which have #GI_TYPE_TAG_INTERFACE such as GObjects and boxed values,
+ * this function returns full information about the referenced type.  You can then
+ * inspect the type of the returned #GIBaseInfo to further query whether it is
+ * a concrete GObject, a GInterface, a structure, etc. using g_base_info_get_type().
+ */
 GIBaseInfo *
 g_type_info_get_interface (GITypeInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
-  
-  if (!(type->reserved == 0 && type->reserved2 == 0))
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+
+  /* For embedded types, the given offset is a pointer to the actual blob,
+   * after the end of the field.  In that case we know it's a "subclass" of
+   * CommonBlob, so use that to determine the info type.
+   */
+  if (rinfo->type_is_embedded)
+    {
+      CommonBlob *common = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
+      GIInfoType info_type;
+
+      switch (common->blob_type)
+        {
+          case BLOB_TYPE_CALLBACK:
+            info_type = GI_INFO_TYPE_CALLBACK;
+            break;
+          default:
+            g_assert_not_reached ();
+            return NULL;
+        }
+      return (GIBaseInfo *) g_info_new (info_type, (GIBaseInfo*)info, rinfo->typelib,
+                                        rinfo->offset);
+    }
+  else
     {
-      InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->typelib->data[base->offset];
-      
-      if (blob->tag == GI_TYPE_TAG_INTERFACE)
-       return g_info_from_entry (base->typelib, blob->interface);
+      SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
+      if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
+        {
+          InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
+
+          if (blob->tag == GI_TYPE_TAG_INTERFACE)
+            return g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface);
+        }
     }
 
   return NULL;
@@ -813,17 +1039,17 @@ g_type_info_get_interface (GITypeInfo *info)
 gint
 g_type_info_get_array_length (GITypeInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
-  
-  if (!(type->reserved == 0 && type->reserved2 == 0))
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
     {
-      ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset];
+      ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
 
       if (blob->tag == GI_TYPE_TAG_ARRAY)
        {
          if (blob->has_length)
-           return blob->length;
+           return blob->dimensions.length;
        }
     }
 
@@ -833,17 +1059,17 @@ g_type_info_get_array_length (GITypeInfo *info)
 gint
 g_type_info_get_array_fixed_size (GITypeInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
-  
-  if (!(type->reserved == 0 && type->reserved2 == 0))
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
     {
-      ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset];
+      ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
 
       if (blob->tag == GI_TYPE_TAG_ARRAY)
        {
          if (blob->has_size)
-           return blob->size;
+           return blob->dimensions.size;
        }
     }
 
@@ -853,12 +1079,12 @@ g_type_info_get_array_fixed_size (GITypeInfo *info)
 gboolean
 g_type_info_is_zero_terminated (GITypeInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
-  
-  if (!(type->reserved == 0 && type->reserved2 == 0))
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
     {
-      ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset];
+      ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
 
       if (blob->tag == GI_TYPE_TAG_ARRAY)
        return blob->zero_terminated;
@@ -870,12 +1096,12 @@ g_type_info_is_zero_terminated (GITypeInfo *info)
 gint
 g_type_info_get_n_error_domains (GITypeInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
-  
-  if (!(type->reserved == 0 && type->reserved2 == 0))
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
     {
-      ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset];
+      ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset];
 
       if (blob->tag == GI_TYPE_TAG_ERROR)
        return blob->n_domains;
@@ -886,18 +1112,19 @@ g_type_info_get_n_error_domains (GITypeInfo *info)
 
 GIErrorDomainInfo *
 g_type_info_get_error_domain (GITypeInfo *info,
-                             gint       n)
+                              gint        n)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
-  
-  if (!(type->reserved == 0 && type->reserved2 == 0))
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
     {
-      ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset];
+      ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset];
 
       if (blob->tag == GI_TYPE_TAG_ERROR)
-       return (GIErrorDomainInfo *) g_info_from_entry (base->typelib, 
-                                                       blob->domains[n]);
+        return (GIErrorDomainInfo *) g_info_from_entry (rinfo->repository,
+                                                        rinfo->typelib,
+                                                        blob->domains[n]);
     }
 
   return NULL;
@@ -908,28 +1135,29 @@ g_type_info_get_error_domain (GITypeInfo *info,
 const gchar *
 g_error_domain_info_get_quark (GIErrorDomainInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ErrorDomainBlob *blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  return g_typelib_get_string (base->typelib, blob->get_quark);
+  return g_typelib_get_string (rinfo->typelib, blob->get_quark);
 }
 
 GIInterfaceInfo *
 g_error_domain_info_get_codes (GIErrorDomainInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->typelib->data[base->offset];
-  
-  return (GIInterfaceInfo *) g_info_from_entry (base->typelib, blob->error_codes);
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ErrorDomainBlob *blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository,
+                                               rinfo->typelib, blob->error_codes);
 }
 
 
-/* GIValueInfo functions */ 
+/* GIValueInfo functions */
 glong
 g_value_info_get_value (GIValueInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ValueBlob *blob = (ValueBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset];
 
   return (glong)blob->value;
 }
@@ -940,8 +1168,8 @@ g_field_info_get_flags (GIFieldInfo *info)
 {
   GIFieldInfoFlags flags;
 
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
 
   flags = 0;
 
@@ -957,38 +1185,51 @@ g_field_info_get_flags (GIFieldInfo *info)
 gint
 g_field_info_get_size (GIFieldInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->bits;
 }
 
 gint
 g_field_info_get_offset (GIFieldInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->struct_offset;
 }
 
 GITypeInfo *
 g_field_info_get_type (GIFieldInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  
-  return g_type_info_new (base, base->typelib, base->offset + 8);
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
+  GIRealInfo *type_info;
+
+  if (blob->has_embedded_type)
+    {
+      type_info = (GIRealInfo *) g_info_new (GI_INFO_TYPE_TYPE,
+                                                (GIBaseInfo*)info, rinfo->typelib,
+                                                rinfo->offset + header->field_blob_size);
+      type_info->type_is_embedded = TRUE;
+    }
+  else
+    return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (FieldBlob, type));
+
+  return (GIBaseInfo*)type_info;
 }
 
 /* GIRegisteredTypeInfo functions */
 const gchar *
 g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset];
 
   if (blob->gtype_name)
-    return g_typelib_get_string (base->typelib, blob->gtype_name);
+    return g_typelib_get_string (rinfo->typelib, blob->gtype_name);
 
   return NULL;
 }
@@ -996,11 +1237,11 @@ g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info)
 const gchar *
 g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset];
 
   if (blob->gtype_init)
-    return g_typelib_get_string (base->typelib, blob->gtype_init);
+    return g_typelib_get_string (rinfo->typelib, blob->gtype_init);
 
   return NULL;
 }
@@ -1010,18 +1251,21 @@ g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info)
 {
   const char *type_init;
   GType (* get_type_func) (void);
+  GIRealInfo *rinfo = (GIRealInfo*)info;
+
+  type_init = g_registered_type_info_get_type_init (info);
 
-  type_init = g_registered_type_info_get_type_init (info);  
-  
   if (type_init == NULL)
     return G_TYPE_NONE;
-  
+  else if (!strcmp (type_init, "intern"))
+    return G_TYPE_OBJECT;
+
   get_type_func = NULL;
-  if (!g_typelib_symbol (((GIBaseInfo*)info)->typelib,
+  if (!g_typelib_symbol (rinfo->typelib,
                          type_init,
                          (void**) &get_type_func))
     return G_TYPE_NONE;
-  
+
   return (* get_type_func) ();
 }
 
@@ -1029,30 +1273,49 @@ g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info)
 gint
 g_struct_info_get_n_fields (GIStructInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->n_fields;
 }
 
+static gint32
+g_struct_get_field_offset (GIStructInfo *info,
+                          gint         n)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  guint32 offset = rinfo->offset + header->struct_blob_size;
+  gint i;
+  FieldBlob *field_blob;
+
+  for (i = 0; i < n; i++)
+    {
+      field_blob = (FieldBlob *)&rinfo->typelib->data[offset];
+      offset += header->field_blob_size;
+      if (field_blob->has_embedded_type)
+        offset += header->callback_blob_size;
+    }
+
+  return offset;
+}
+
 GIFieldInfo *
 g_struct_info_get_field (GIStructInfo *info,
-                        gint         n)
+                         gint          n)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib, 
-                                    base->offset + header->struct_blob_size + 
-                                    n * header->field_blob_size);
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+
+  return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib,
+                                     g_struct_get_field_offset (info, n));
 }
 
 gint
 g_struct_info_get_n_methods (GIStructInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->n_methods;
 }
 
@@ -1060,40 +1323,39 @@ GIFunctionInfo *
 g_struct_info_get_method (GIStructInfo *info,
                          gint         n)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset];
-  Header *header = (Header *)base->typelib->data;  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
+  Header *header = (Header *)rinfo->typelib->data;
   gint offset;
 
-  offset = base->offset + header->struct_blob_size 
-    + blob->n_fields * header->field_blob_size 
-    + n * header->function_blob_size;
-  return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, 
-                                       base->typelib, offset);
+  offset = g_struct_get_field_offset (info, blob->n_fields) + n * header->function_blob_size;
+  return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
+                                        rinfo->typelib, offset);
 }
 
 static GIFunctionInfo *
 find_method (GIBaseInfo   *base,
-            guint32       offset,
-            gint          n_methods,
-            const gchar  *name)
+             guint32       offset,
+             gint          n_methods,
+             const gchar  *name)
 {
   /* FIXME hash */
-  Header *header = (Header *)base->typelib->data;  
+  GIRealInfo *rinfo = (GIRealInfo*)base;
+  Header *header = (Header *)rinfo->typelib->data;
   gint i;
 
   for (i = 0; i < n_methods; i++)
     {
-      FunctionBlob *fblob = (FunctionBlob *)&base->typelib->data[offset];
-      const gchar *fname = (const gchar *)&base->typelib->data[fblob->name];
+      FunctionBlob *fblob = (FunctionBlob *)&rinfo->typelib->data[offset];
+      const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name];
 
       if (strcmp (name, fname) == 0)
-       return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, 
-                                             base->typelib, offset);  
-      
+        return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base,
+                                             rinfo->typelib, offset);
+
       offset += header->function_blob_size;
     }
-      
+
   return NULL;
 }
 
@@ -1102,21 +1364,67 @@ g_struct_info_find_method (GIStructInfo *info,
                           const gchar  *name)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  offset = base->offset + header->struct_blob_size
+  offset = rinfo->offset + header->struct_blob_size
     + blob->n_fields * header->field_blob_size;
 
-  return find_method (base, offset, blob->n_methods, name);
+  return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
+}
+
+gsize
+g_struct_info_get_size (GIStructInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  return blob->size;
+}
+
+gsize
+g_struct_info_get_alignment (GIStructInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  return blob->alignment;
+}
+
+gboolean
+g_struct_info_is_foreign (GIStructInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  return blob->foreign;
+}
+
+/**
+ * g_struct_info_is_gtype_struct:
+ * @info: GIStructInfo
+ *
+ * Return true if this structure represents the "class structure" for some
+ * #GObject or #GInterface.  This function is mainly useful to hide this kind of structure
+ * from generated public APIs.
+ *
+ * Returns: %TRUE if this is a class struct, %FALSE otherwise
+ */
+gboolean
+g_struct_info_is_gtype_struct (GIStructInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  return blob->is_gtype_struct;
 }
 
 gint
 g_enum_info_get_n_values (GIEnumInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  EnumBlob *blob = (EnumBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  EnumBlob *blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
 
   return blob->n_values;
 }
@@ -1125,24 +1433,47 @@ GIValueInfo *
 g_enum_info_get_value (GIEnumInfo *info,
                       gint            n)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
   gint offset;
 
-  offset = base->offset + header->enum_blob_size 
+  offset = rinfo->offset + header->enum_blob_size
     + n * header->value_blob_size;
-  return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, base, base->typelib, offset);
+  return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, (GIBaseInfo*)info, rinfo->typelib, offset);
+}
+
+/**
+ * g_enum_info_get_storage_type:
+ * @info: GIEnumInfo
+ *
+ * Gets the tag of the type used for the enum in the C ABI. This will
+ * will be a signed or unsigned integral type.
+
+ * Note that in the current implementation the width of the type is
+ * computed correctly, but the signed or unsigned nature of the type
+ * may not match the sign of the type used by the C compiler.
+ *
+ * Return Value: the storage type for the enumeration
+ */
+GITypeTag
+g_enum_info_get_storage_type (GIEnumInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  EnumBlob *blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  return blob->storage_type;
 }
 
 /* GIObjectInfo functions */
 GIObjectInfo *
 g_object_info_get_parent (GIObjectInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
 
   if (blob->parent)
-    return (GIObjectInfo *) g_info_from_entry (base->typelib, blob->parent);
+    return (GIObjectInfo *) g_info_from_entry (rinfo->repository,
+                                              rinfo->typelib, blob->parent);
   else
     return NULL;
 }
@@ -1150,34 +1481,34 @@ g_object_info_get_parent (GIObjectInfo *info)
 gboolean
 g_object_info_get_abstract (GIObjectInfo    *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
   return blob->abstract != 0;
 }
 
 const gchar *
 g_object_info_get_type_name (GIObjectInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  return g_typelib_get_string (base->typelib, blob->gtype_name);
+  return g_typelib_get_string (rinfo->typelib, blob->gtype_name);
 }
 
 const gchar *
 g_object_info_get_type_init (GIObjectInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  return g_typelib_get_string (base->typelib, blob->gtype_init);
+  return g_typelib_get_string (rinfo->typelib, blob->gtype_init);
 }
 
 gint
 g_object_info_get_n_interfaces (GIObjectInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
 
   return blob->n_interfaces;
 }
@@ -1186,17 +1517,18 @@ GIInterfaceInfo *
 g_object_info_get_interface (GIObjectInfo *info,
                             gint          n)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  return (GIInterfaceInfo *) g_info_from_entry (base->typelib, blob->interfaces[n]);
+  return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository,
+                                               rinfo->typelib, blob->interfaces[n]);
 }
 
 gint
 g_object_info_get_n_fields (GIObjectInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
 
   return blob->n_fields;
 }
@@ -1206,24 +1538,24 @@ g_object_info_get_field (GIObjectInfo *info,
                         gint          n)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
-  
-  offset = base->offset + header->object_blob_size
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->object_blob_size
     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     + n * header->field_blob_size;
-  
-  return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib, offset);
+
+  return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset);
 }
 
 gint
 g_object_info_get_n_properties (GIObjectInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  return blob->n_properties;  
+  return blob->n_properties;
 }
 
 GIPropertyInfo *
@@ -1231,24 +1563,24 @@ g_object_info_get_property (GIObjectInfo *info,
                            gint          n)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
-  
-  offset = base->offset + header->object_blob_size
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->object_blob_size
     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     + blob->n_fields * header->field_blob_size
     + n * header->property_blob_size;
 
-  return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, base, 
-                                       base->typelib, offset);
+  return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info,
+                                       rinfo->typelib, offset);
 }
 
 gint
 g_object_info_get_n_methods (GIObjectInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
 
   return blob->n_methods;
 }
@@ -1258,18 +1590,18 @@ g_object_info_get_method (GIObjectInfo *info,
                          gint          n)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
-  
-  offset = base->offset + header->object_blob_size
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->object_blob_size
     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     + blob->n_fields * header->field_blob_size
     + blob->n_properties * header->property_blob_size
     + n * header->function_blob_size;
 
-    return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, 
-                                         base->typelib, offset);  
+    return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
+                                         rinfo->typelib, offset);
 }
 
 GIFunctionInfo *
@@ -1277,23 +1609,23 @@ g_object_info_find_method (GIObjectInfo *info,
                           const gchar  *name)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  offset = base->offset + header->object_blob_size
+  offset = rinfo->offset + header->object_blob_size
     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     + blob->n_fields * header->field_blob_size +
     + blob->n_properties * header->property_blob_size;
 
-  return find_method (base, offset, blob->n_methods, name);
+  return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
 }
 
 gint
 g_object_info_get_n_signals (GIObjectInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
 
   return blob->n_signals;
 }
@@ -1303,27 +1635,27 @@ g_object_info_get_signal (GIObjectInfo *info,
                          gint          n)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
-  
-  offset = base->offset + header->object_blob_size
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->object_blob_size
     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     + blob->n_fields * header->field_blob_size
     + blob->n_properties * header->property_blob_size
-    + blob->n_methods * header->function_blob_size 
+    + blob->n_methods * header->function_blob_size
     + n * header->signal_blob_size;
 
-  return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, base, 
-                                     base->typelib, offset);  
+  return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info,
+                                     rinfo->typelib, offset);
 }
 
 gint
 g_object_info_get_n_vfuncs (GIObjectInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->n_vfuncs;
 }
 
@@ -1332,28 +1664,85 @@ g_object_info_get_vfunc (GIObjectInfo *info,
                         gint          n)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
-  
-  offset = base->offset + header->object_blob_size
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->object_blob_size
     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     + blob->n_fields * header->field_blob_size
     + blob->n_properties * header->property_blob_size
-    + blob->n_methods * header->function_blob_size 
-    + blob->n_signals * header->signal_blob_size 
+    + blob->n_methods * header->function_blob_size
+    + blob->n_signals * header->signal_blob_size
     + n * header->vfunc_blob_size;
 
-  return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, base, 
-                                    base->typelib, offset);  
+  return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info,
+                                    rinfo->typelib, offset);
+}
+
+static GIVFuncInfo *
+find_vfunc (GIRealInfo   *rinfo,
+            guint32       offset,
+            gint          n_vfuncs,
+            const gchar  *name)
+{
+  /* FIXME hash */
+  Header *header = (Header *)rinfo->typelib->data;
+  gint i;
+
+  for (i = 0; i < n_vfuncs; i++)
+    {
+      VFuncBlob *fblob = (VFuncBlob *)&rinfo->typelib->data[offset];
+      const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name];
+
+      if (strcmp (name, fname) == 0)
+        return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*) rinfo,
+                                           rinfo->typelib, offset);
+
+      offset += header->vfunc_blob_size;
+    }
+
+  return NULL;
+}
+
+/**
+ * g_object_info_find_vfunc:
+ * @info: An #GIObjectInfo
+ * @name: The name of a virtual function to find.
+ *
+ * Locate a virtual function slot with name @name.  Note that the namespace
+ * for virtuals is distinct from that of methods; there may or may not be
+ * a concrete method associated for a virtual.  If there is one, it may
+ * be retrieved using #g_vfunc_info_get_invoker.  See the documentation for
+ * that function for more information on invoking virtuals.
+ *
+ * Return value: (transfer full): A #GIVFuncInfo, or %NULL if none with name @name.
+ */
+GIVFuncInfo *
+g_object_info_find_vfunc (GIObjectInfo *info,
+                          const gchar  *name)
+{
+  gint offset;
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->object_blob_size
+    + (blob->n_interfaces + blob->n_interfaces % 2) * 2
+    + blob->n_fields * header->field_blob_size
+    + blob->n_properties * header->property_blob_size
+    + blob->n_methods * header->function_blob_size
+    + blob->n_signals * header->signal_blob_size;
+
+  return find_vfunc (rinfo, offset, blob->n_vfuncs, name);
 }
 
 gint
 g_object_info_get_n_constants (GIObjectInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->n_constants;
 }
 
@@ -1362,30 +1751,51 @@ g_object_info_get_constant (GIObjectInfo *info,
                            gint          n)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
-  
-  offset = base->offset + header->object_blob_size
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->object_blob_size
     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
     + blob->n_fields * header->field_blob_size
     + blob->n_properties * header->property_blob_size
-    + blob->n_methods * header->function_blob_size 
-    + blob->n_signals * header->signal_blob_size 
-    + blob->n_vfuncs * header->vfunc_blob_size 
+    + blob->n_methods * header->function_blob_size
+    + blob->n_signals * header->signal_blob_size
+    + blob->n_vfuncs * header->vfunc_blob_size
     + n * header->constant_blob_size;
 
-  return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, 
-                                       base->typelib, offset);  
+  return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
+                                       rinfo->typelib, offset);
 }
 
+/**
+ * g_object_info_get_class_struct:
+ * @info: A #GIObjectInfo to query
+ *
+ * Every #GObject has two structures; an instance structure and a class
+ * structure.  This function returns the metadata for the class structure.
+ *
+ * Returns: a #GIStructInfo for the class struct or %NULL if none found.
+ */
+GIStructInfo *
+g_object_info_get_class_struct (GIObjectInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  if (blob->gtype_struct)
+    return (GIStructInfo *) g_info_from_entry (rinfo->repository,
+                                               rinfo->typelib, blob->gtype_struct);
+  else
+    return NULL;
+}
 
 /* GIInterfaceInfo functions */
 gint
 g_interface_info_get_n_prerequisites (GIInterfaceInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
 
   return blob->n_prerequisites;
 }
@@ -1394,20 +1804,21 @@ GIBaseInfo *
 g_interface_info_get_prerequisite (GIInterfaceInfo *info,
                                   gint            n)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  return g_info_from_entry (base->typelib, blob->prerequisites[n]);
+  return g_info_from_entry (rinfo->repository,
+                           rinfo->typelib, blob->prerequisites[n]);
 }
 
 
 gint
 g_interface_info_get_n_properties (GIInterfaceInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  return blob->n_properties;  
+  return blob->n_properties;
 }
 
 GIPropertyInfo *
@@ -1415,23 +1826,23 @@ g_interface_info_get_property (GIInterfaceInfo *info,
                               gint            n)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
-  
-  offset = base->offset + header->interface_blob_size
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->interface_blob_size
     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
     + n * header->property_blob_size;
 
-  return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, base, 
-                                       base->typelib, offset);
+  return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info,
+                                       rinfo->typelib, offset);
 }
 
 gint
 g_interface_info_get_n_methods (GIInterfaceInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
 
   return blob->n_methods;
 }
@@ -1441,17 +1852,17 @@ g_interface_info_get_method (GIInterfaceInfo *info,
                             gint            n)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
-  
-  offset = base->offset + header->interface_blob_size
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->interface_blob_size
     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
-    + blob->n_properties * header->property_blob_size 
+    + blob->n_properties * header->property_blob_size
     + n * header->function_blob_size;
-  
-  return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, 
-                                       base->typelib, offset);  
+
+  return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
+                                       rinfo->typelib, offset);
 }
 
 GIFunctionInfo *
@@ -1459,22 +1870,22 @@ g_interface_info_find_method (GIInterfaceInfo *info,
                              const gchar     *name)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  offset = base->offset + header->interface_blob_size
+  offset = rinfo->offset + header->interface_blob_size
     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
     + blob->n_properties * header->property_blob_size;
 
-  return find_method (base, offset, blob->n_methods, name);
+  return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
 }
 
 gint
 g_interface_info_get_n_signals (GIInterfaceInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
 
   return blob->n_signals;
 }
@@ -1484,25 +1895,25 @@ g_interface_info_get_signal (GIInterfaceInfo *info,
                             gint            n)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
-  
-  offset = base->offset + header->interface_blob_size 
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->interface_blob_size
     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
-    + blob->n_properties * header->property_blob_size 
-    + blob->n_methods * header->function_blob_size 
+    + blob->n_properties * header->property_blob_size
+    + blob->n_methods * header->function_blob_size
     + n * header->signal_blob_size;
-  
-  return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, base, 
-                                     base->typelib, offset);  
+
+  return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info,
+                                     rinfo->typelib, offset);
 }
 
 gint
 g_interface_info_get_n_vfuncs (GIInterfaceInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
 
   return blob->n_vfuncs;
 }
@@ -1512,27 +1923,55 @@ g_interface_info_get_vfunc (GIInterfaceInfo *info,
                            gint            n)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
-  
-  offset = base->offset + header->interface_blob_size 
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->interface_blob_size
     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
-    + blob->n_properties * header->property_blob_size 
-    + blob->n_methods * header->function_blob_size 
+    + blob->n_properties * header->property_blob_size
+    + blob->n_methods * header->function_blob_size
     + blob->n_signals * header->signal_blob_size
     + n * header->vfunc_blob_size;
-  
-  return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, base, 
-                                    base->typelib, offset);  
+
+  return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info,
+                                    rinfo->typelib, offset);
+}
+
+/**
+ * g_interface_info_find_vfunc:
+ * @info: An #GIObjectInfo
+ * @name: The name of a virtual function to find.
+ *
+ * Locate a virtual function slot with name @name.  See the documentation
+ * for #g_object_info_find_vfunc for more information on virtuals.
+ *
+ * Return value: (transfer full): A #GIVFuncInfo, or %NULL if none with name @name.
+ */
+GIVFuncInfo *
+g_interface_info_find_vfunc (GIInterfaceInfo *info,
+                             const gchar  *name)
+{
+  gint offset;
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->interface_blob_size
+    + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2
+    + blob->n_properties * header->property_blob_size
+    + blob->n_methods * header->function_blob_size
+    + blob->n_signals * header->signal_blob_size;
+
+  return find_vfunc (rinfo, offset, blob->n_vfuncs, name);
 }
 
 gint
 g_interface_info_get_n_constants (GIInterfaceInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->n_constants;
 }
 
@@ -1541,33 +1980,51 @@ g_interface_info_get_constant (GIInterfaceInfo *info,
                               gint             n)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
-  
-  offset = base->offset + header->interface_blob_size
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  offset = rinfo->offset + header->interface_blob_size
     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
     + blob->n_properties * header->property_blob_size
-    + blob->n_methods * header->function_blob_size 
-    + blob->n_signals * header->signal_blob_size 
-    + blob->n_vfuncs * header->vfunc_blob_size 
+    + blob->n_methods * header->function_blob_size
+    + blob->n_signals * header->signal_blob_size
+    + blob->n_vfuncs * header->vfunc_blob_size
     + n * header->constant_blob_size;
 
-  return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, 
-                                       base->typelib, offset);  
+  return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
+                                       rinfo->typelib, offset);
 }
 
+/**
+ * g_interface_info_get_iface_struct:
+ * @info: A #GIInterfaceInfo to query
+ *
+ * Returns the layout C structure associated with this #GInterface.
+ *
+ * Returns: A #GIStructInfo for the class struct or %NULL if none found.
+ */
+GIStructInfo *
+g_interface_info_get_iface_struct (GIInterfaceInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
 
-
+  if (blob->gtype_struct)
+    return (GIStructInfo *) g_info_from_entry (rinfo->repository,
+                                               rinfo->typelib, blob->gtype_struct);
+  else
+    return NULL;
+}
 
 /* GIPropertyInfo functions */
 GParamFlags
 g_property_info_get_flags (GIPropertyInfo *info)
 {
   GParamFlags flags;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  PropertyBlob *blob = (PropertyBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset];
+
   flags = 0;
 
   if (blob->readable)
@@ -1588,9 +2045,9 @@ g_property_info_get_flags (GIPropertyInfo *info)
 GITypeInfo *
 g_property_info_get_type (GIPropertyInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
+  GIRealInfo *rinfo = (GIRealInfo *)info;
 
-  return g_type_info_new (base, base->typelib, base->offset + 8);  
+  return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type));
 }
 
 
@@ -1600,8 +2057,8 @@ g_signal_info_get_flags (GISignalInfo *info)
 {
   GSignalFlags flags;
 
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SignalBlob *blob = (SignalBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
 
   flags = 0;
 
@@ -1632,11 +2089,11 @@ g_signal_info_get_flags (GISignalInfo *info)
 GIVFuncInfo *
 g_signal_info_get_class_closure (GISignalInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SignalBlob *blob = (SignalBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
 
   if (blob->has_class_closure)
-    return g_interface_info_get_vfunc ((GIInterfaceInfo *)base->container, blob->class_closure);
+    return g_interface_info_get_vfunc ((GIInterfaceInfo *)rinfo->container, blob->class_closure);
 
   return NULL;
 }
@@ -1644,8 +2101,8 @@ g_signal_info_get_class_closure (GISignalInfo *info)
 gboolean
 g_signal_info_true_stops_emit (GISignalInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  SignalBlob *blob = (SignalBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
 
   return blob->true_stops_emit;
 }
@@ -1656,8 +2113,8 @@ g_vfunc_info_get_flags (GIVFuncInfo *info)
 {
   GIVFuncInfoFlags flags;
 
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
 
   flags = 0;
 
@@ -1676,97 +2133,134 @@ g_vfunc_info_get_flags (GIVFuncInfo *info)
 gint
 g_vfunc_info_get_offset (GIVFuncInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->struct_offset;
 }
 
 GISignalInfo *
 g_vfunc_info_get_signal (GIVFuncInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
 
   if (blob->class_closure)
-    return g_interface_info_get_signal ((GIInterfaceInfo *)base->container, blob->signal);
-  
+    return g_interface_info_get_signal ((GIInterfaceInfo *)rinfo->container, blob->signal);
+
   return NULL;
 }
 
+/**
+ * g_vfunc_info_get_invoker:
+ * @info: A #GIVFuncInfo
+ *
+ * If this virtual function has an associated invoker method, this
+ * method will return it.  An invoker method is a C entry point.
+ *
+ * Not all virtuals will have invokers.
+ *
+ * Return value: (transfer full): An invoker function, or %NULL if none known
+ */
+GIFunctionInfo *
+g_vfunc_info_get_invoker (GIVFuncInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
+  GIBaseInfo *container = rinfo->container;
+  GIInfoType parent_type;
+
+  /* 1023 = 0x3ff is the maximum of the 10 bits for invoker index */
+  if (blob->invoker == 1023)
+    return NULL;
+
+  parent_type = g_base_info_get_type (container);
+  if (parent_type == GI_INFO_TYPE_OBJECT)
+    return g_object_info_get_method ((GIObjectInfo*)container, blob->invoker);
+  else if (parent_type == GI_INFO_TYPE_INTERFACE)
+    return g_interface_info_get_method ((GIInterfaceInfo*)container, blob->invoker);
+  else
+    g_assert_not_reached ();
+}
 
 /* GIConstantInfo functions */
 GITypeInfo *
 g_constant_info_get_type (GIConstantInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  
-  return g_type_info_new (base, base->typelib, base->offset + 8);
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+
+  return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 8);
 }
 
 gint
-g_constant_info_get_value (GIConstantInfo *info, 
+g_constant_info_get_value (GIConstantInfo *info,
                           GArgument      *value)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  ConstantBlob *blob = (ConstantBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  ConstantBlob *blob = (ConstantBlob *)&rinfo->typelib->data[rinfo->offset];
 
   /* FIXME non-basic types ? */
-  if (blob->type.reserved == 0 && blob->type.reserved2 == 0)
+  if (blob->type.flags.reserved == 0 && blob->type.flags.reserved2 == 0)
     {
-      if (blob->type.pointer)
-       value->v_pointer = g_memdup (&base->typelib->data[blob->offset], blob->size);
+      if (blob->type.flags.pointer)
+       value->v_pointer = g_memdup (&rinfo->typelib->data[blob->offset], blob->size);
       else
        {
-         switch (blob->type.tag)
+         switch (blob->type.flags.tag)
            {
            case GI_TYPE_TAG_BOOLEAN:
-             value->v_boolean = *(gboolean*)&base->typelib->data[blob->offset];
+             value->v_boolean = *(gboolean*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_INT8:
-             value->v_int8 = *(gint8*)&base->typelib->data[blob->offset];
+             value->v_int8 = *(gint8*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_UINT8:
-             value->v_uint8 = *(guint8*)&base->typelib->data[blob->offset];
+             value->v_uint8 = *(guint8*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_INT16:
-             value->v_int16 = *(gint16*)&base->typelib->data[blob->offset];
+             value->v_int16 = *(gint16*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_UINT16:
-             value->v_uint16 = *(guint16*)&base->typelib->data[blob->offset];
+             value->v_uint16 = *(guint16*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_INT32:
-             value->v_int32 = *(gint32*)&base->typelib->data[blob->offset];
+             value->v_int32 = *(gint32*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_UINT32:
-             value->v_uint32 = *(guint32*)&base->typelib->data[blob->offset];
+             value->v_uint32 = *(guint32*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_INT64:
-             value->v_int64 = *(gint64*)&base->typelib->data[blob->offset];
+             value->v_int64 = *(gint64*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_UINT64:
-             value->v_uint64 = *(guint64*)&base->typelib->data[blob->offset];
+             value->v_uint64 = *(guint64*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_FLOAT:
-             value->v_float = *(gfloat*)&base->typelib->data[blob->offset];
+             value->v_float = *(gfloat*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_DOUBLE:
-             value->v_double = *(gdouble*)&base->typelib->data[blob->offset];
+             value->v_double = *(gdouble*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_TIME_T:
-             value->v_long = *(long*)&base->typelib->data[blob->offset];
+             value->v_long = *(long*)&rinfo->typelib->data[blob->offset];
+             break;
+           case GI_TYPE_TAG_SHORT:
+             value->v_short = *(gshort*)&rinfo->typelib->data[blob->offset];
+             break;
+           case GI_TYPE_TAG_USHORT:
+             value->v_ushort = *(gushort*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_INT:
-             value->v_int = *(gint*)&base->typelib->data[blob->offset];
+             value->v_int = *(gint*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_UINT:
-             value->v_uint = *(guint*)&base->typelib->data[blob->offset];
+             value->v_uint = *(guint*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_LONG:
-             value->v_long = *(glong*)&base->typelib->data[blob->offset];
+             value->v_long = *(glong*)&rinfo->typelib->data[blob->offset];
              break;
            case GI_TYPE_TAG_ULONG:
-             value->v_ulong = *(gulong*)&base->typelib->data[blob->offset];
+             value->v_ulong = *(gulong*)&rinfo->typelib->data[blob->offset];
              break;
            }
        }
@@ -1779,9 +2273,9 @@ g_constant_info_get_value (GIConstantInfo *info,
 gint
 g_union_info_get_n_fields  (GIUnionInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->n_fields;
 }
 
@@ -1789,20 +2283,20 @@ GIFieldInfo *
 g_union_info_get_field (GIUnionInfo *info,
                        gint         n)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;  
-  return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib, 
-                                    base->offset + header->union_blob_size + 
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+
+  return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib,
+                                    rinfo->offset + header->union_blob_size +
                                     n * header->field_blob_size);
 }
 
 gint
 g_union_info_get_n_methods (GIUnionInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->n_functions;
 }
 
@@ -1810,63 +2304,63 @@ GIFunctionInfo *
 g_union_info_get_method (GIUnionInfo *info,
                         gint         n)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
-  Header *header = (Header *)base->typelib->data;  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
+  Header *header = (Header *)rinfo->typelib->data;
   gint offset;
 
-  offset = base->offset + header->union_blob_size 
-    + blob->n_fields * header->field_blob_size 
+  offset = rinfo->offset + header->union_blob_size
+    + blob->n_fields * header->field_blob_size
     + n * header->function_blob_size;
-  return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, 
-                                       base->typelib, offset);
+  return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
+                                       rinfo->typelib, offset);
 }
 
 gboolean
 g_union_info_is_discriminated (GIUnionInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->discriminated;
 }
 
 gint
 g_union_info_get_discriminator_offset (GIUnionInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
+
   return blob->discriminator_offset;
 }
 
 GITypeInfo *
 g_union_info_get_discriminator_type (GIUnionInfo *info)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  return g_type_info_new (base, base->typelib, base->offset + 24);
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+
+  return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 24);
 }
 
 GIConstantInfo *
 g_union_info_get_discriminator (GIUnionInfo *info,
                                gint         n)
 {
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
-  
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
+
   if (blob->discriminated)
     {
-      Header *header = (Header *)base->typelib->data;  
+      Header *header = (Header *)rinfo->typelib->data;
       gint offset;
 
-      offset = base->offset + header->union_blob_size 
-       + blob->n_fields * header->field_blob_size 
+      offset = rinfo->offset + header->union_blob_size
+       + blob->n_fields * header->field_blob_size
        + blob->n_functions * header->function_blob_size
        + n * header->constant_blob_size;
-      
-      return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, 
-                                           base->typelib, offset);  
+
+      return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
+                                           rinfo->typelib, offset);
     }
 
   return NULL;
@@ -1877,13 +2371,30 @@ g_union_info_find_method (GIUnionInfo *info,
                           const gchar *name)
 {
   gint offset;
-  GIBaseInfo *base = (GIBaseInfo *)info;
-  Header *header = (Header *)base->typelib->data;
-  UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  Header *header = (Header *)rinfo->typelib->data;
+  UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
 
-  offset = base->offset + header->union_blob_size
+  offset = rinfo->offset + header->union_blob_size
     + blob->n_fields * header->field_blob_size;
 
-  return find_method (base, offset, blob->n_functions, name);
+  return find_method ((GIBaseInfo*)info, offset, blob->n_functions, name);
+}
+
+gsize
+g_union_info_get_size (GIUnionInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  return blob->size;
 }
 
+gsize
+g_union_info_get_alignment (GIUnionInfo *info)
+{
+  GIRealInfo *rinfo = (GIRealInfo *)info;
+  UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
+
+  return blob->alignment;
+}