Merge branch 'girnode-cleanup' into 'main'

girnode: Document ownership and element types of internal structs

See merge request GNOME/glib!3854
This commit is contained in:
Philip Withnall 2024-01-26 09:59:50 +00:00
commit b613c3ef46
7 changed files with 184 additions and 158 deletions

View File

@ -93,8 +93,10 @@ gtype_interface_cache_free (gpointer data)
g_free (cache); g_free (cache);
} }
struct _GIRepositoryPrivate struct _GIRepository
{ {
GObject parent;
GHashTable *typelibs; /* (string) namespace -> GITypelib */ GHashTable *typelibs; /* (string) namespace -> GITypelib */
GHashTable *lazy_typelibs; /* (string) namespace-version -> GITypelib */ GHashTable *lazy_typelibs; /* (string) namespace-version -> GITypelib */
GHashTable *info_by_gtype; /* GType -> GIBaseInfo */ GHashTable *info_by_gtype; /* GType -> GIBaseInfo */
@ -106,7 +108,7 @@ struct _GIRepositoryPrivate
size_t cached_n_shared_libraries; /* length of @cached_shared_libraries, not including NULL terminator */ size_t cached_n_shared_libraries; /* length of @cached_shared_libraries, not including NULL terminator */
}; };
G_DEFINE_TYPE_WITH_CODE (GIRepository, gi_repository, G_TYPE_OBJECT, G_ADD_PRIVATE (GIRepository)); G_DEFINE_TYPE (GIRepository, gi_repository, G_TYPE_OBJECT);
#ifdef G_PLATFORM_WIN32 #ifdef G_PLATFORM_WIN32
@ -146,28 +148,27 @@ DllMain (HINSTANCE hinstDLL,
static void static void
gi_repository_init (GIRepository *repository) gi_repository_init (GIRepository *repository)
{ {
repository->priv = gi_repository_get_instance_private (repository); repository->typelibs
repository->priv->typelibs
= g_hash_table_new_full (g_str_hash, g_str_equal, = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free, (GDestroyNotify) g_free,
(GDestroyNotify) gi_typelib_free); (GDestroyNotify) gi_typelib_free);
repository->priv->lazy_typelibs repository->lazy_typelibs
= g_hash_table_new_full (g_str_hash, g_str_equal, = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free, (GDestroyNotify) g_free,
(GDestroyNotify) NULL); (GDestroyNotify) NULL);
repository->priv->info_by_gtype repository->info_by_gtype
= g_hash_table_new_full (g_direct_hash, g_direct_equal, = g_hash_table_new_full (g_direct_hash, g_direct_equal,
(GDestroyNotify) NULL, (GDestroyNotify) NULL,
(GDestroyNotify) gi_base_info_unref); (GDestroyNotify) gi_base_info_unref);
repository->priv->info_by_error_domain repository->info_by_error_domain
= g_hash_table_new_full (g_direct_hash, g_direct_equal, = g_hash_table_new_full (g_direct_hash, g_direct_equal,
(GDestroyNotify) NULL, (GDestroyNotify) NULL,
(GDestroyNotify) gi_base_info_unref); (GDestroyNotify) gi_base_info_unref);
repository->priv->interfaces_for_gtype repository->interfaces_for_gtype
= g_hash_table_new_full (g_direct_hash, g_direct_equal, = g_hash_table_new_full (g_direct_hash, g_direct_equal,
(GDestroyNotify) NULL, (GDestroyNotify) NULL,
(GDestroyNotify) gtype_interface_cache_free); (GDestroyNotify) gtype_interface_cache_free);
repository->priv->unknown_gtypes = g_hash_table_new (NULL, NULL); repository->unknown_gtypes = g_hash_table_new (NULL, NULL);
} }
static void static void
@ -175,14 +176,14 @@ gi_repository_finalize (GObject *object)
{ {
GIRepository *repository = GI_REPOSITORY (object); GIRepository *repository = GI_REPOSITORY (object);
g_hash_table_destroy (repository->priv->typelibs); g_hash_table_destroy (repository->typelibs);
g_hash_table_destroy (repository->priv->lazy_typelibs); g_hash_table_destroy (repository->lazy_typelibs);
g_hash_table_destroy (repository->priv->info_by_gtype); g_hash_table_destroy (repository->info_by_gtype);
g_hash_table_destroy (repository->priv->info_by_error_domain); g_hash_table_destroy (repository->info_by_error_domain);
g_hash_table_destroy (repository->priv->interfaces_for_gtype); g_hash_table_destroy (repository->interfaces_for_gtype);
g_hash_table_destroy (repository->priv->unknown_gtypes); g_hash_table_destroy (repository->unknown_gtypes);
g_clear_pointer (&repository->priv->cached_shared_libraries, g_strfreev); g_clear_pointer (&repository->cached_shared_libraries, g_strfreev);
(* G_OBJECT_CLASS (gi_repository_parent_class)->finalize) (G_OBJECT (repository)); (* G_OBJECT_CLASS (gi_repository_parent_class)->finalize) (G_OBJECT (repository));
} }
@ -374,10 +375,10 @@ get_registered_status (GIRepository *repository,
repository = get_repository (repository); repository = get_repository (repository);
if (lazy_status) if (lazy_status)
*lazy_status = FALSE; *lazy_status = FALSE;
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace); typelib = g_hash_table_lookup (repository->typelibs, namespace);
if (typelib) if (typelib)
return check_version_conflict (typelib, namespace, version, version_conflict); return check_version_conflict (typelib, namespace, version, version_conflict);
typelib = g_hash_table_lookup (repository->priv->lazy_typelibs, namespace); typelib = g_hash_table_lookup (repository->lazy_typelibs, namespace);
if (!typelib) if (!typelib)
return NULL; return NULL;
if (lazy_status) if (lazy_status)
@ -453,9 +454,9 @@ register_internal (GIRepository *repository,
if (lazy) if (lazy)
{ {
g_assert (!g_hash_table_lookup (repository->priv->lazy_typelibs, g_assert (!g_hash_table_lookup (repository->lazy_typelibs,
namespace)); namespace));
g_hash_table_insert (repository->priv->lazy_typelibs, g_hash_table_insert (repository->lazy_typelibs,
build_typelib_key (namespace, source), (void *)typelib); build_typelib_key (namespace, source), (void *)typelib);
} }
else else
@ -468,20 +469,20 @@ register_internal (GIRepository *repository,
return NULL; return NULL;
/* Check if we are transitioning from lazily loaded state */ /* Check if we are transitioning from lazily loaded state */
if (g_hash_table_lookup_extended (repository->priv->lazy_typelibs, if (g_hash_table_lookup_extended (repository->lazy_typelibs,
namespace, namespace,
(gpointer)&key, &value)) (gpointer)&key, &value))
g_hash_table_remove (repository->priv->lazy_typelibs, key); g_hash_table_remove (repository->lazy_typelibs, key);
else else
key = build_typelib_key (namespace, source); key = build_typelib_key (namespace, source);
g_hash_table_insert (repository->priv->typelibs, g_hash_table_insert (repository->typelibs,
g_steal_pointer (&key), g_steal_pointer (&key),
(void *)typelib); (void *)typelib);
} }
/* These types might be resolved now, clear the cache */ /* These types might be resolved now, clear the cache */
g_hash_table_remove_all (repository->priv->unknown_gtypes); g_hash_table_remove_all (repository->unknown_gtypes);
return namespace; return namespace;
} }
@ -887,13 +888,13 @@ gi_repository_find_by_gtype (GIRepository *repository,
repository = get_repository (repository); repository = get_repository (repository);
cached = g_hash_table_lookup (repository->priv->info_by_gtype, cached = g_hash_table_lookup (repository->info_by_gtype,
(gpointer)gtype); (gpointer)gtype);
if (cached != NULL) if (cached != NULL)
return gi_base_info_ref (cached); return gi_base_info_ref (cached);
if (g_hash_table_contains (repository->priv->unknown_gtypes, (gpointer)gtype)) if (g_hash_table_contains (repository->unknown_gtypes, (gpointer)gtype))
return NULL; return NULL;
data.gtype_name = g_type_name (gtype); data.gtype_name = g_type_name (gtype);
@ -906,9 +907,9 @@ gi_repository_find_by_gtype (GIRepository *repository,
* target type does not have this typelib's C prefix. Use this * target type does not have this typelib's C prefix. Use this
* assumption as our first attempt at locating the DirEntry. * assumption as our first attempt at locating the DirEntry.
*/ */
entry = find_by_gtype (repository->priv->typelibs, &data, TRUE); entry = find_by_gtype (repository->typelibs, &data, TRUE);
if (entry == NULL) if (entry == NULL)
entry = find_by_gtype (repository->priv->lazy_typelibs, &data, TRUE); entry = find_by_gtype (repository->lazy_typelibs, &data, TRUE);
/* Not ever class library necessarily specifies a correct c_prefix, /* Not ever class library necessarily specifies a correct c_prefix,
* so take a second pass. This time we will try a global lookup, * so take a second pass. This time we will try a global lookup,
@ -916,9 +917,9 @@ gi_repository_find_by_gtype (GIRepository *repository,
* See http://bugzilla.gnome.org/show_bug.cgi?id=564016 * See http://bugzilla.gnome.org/show_bug.cgi?id=564016
*/ */
if (entry == NULL) if (entry == NULL)
entry = find_by_gtype (repository->priv->typelibs, &data, FALSE); entry = find_by_gtype (repository->typelibs, &data, FALSE);
if (entry == NULL) if (entry == NULL)
entry = find_by_gtype (repository->priv->lazy_typelibs, &data, FALSE); entry = find_by_gtype (repository->lazy_typelibs, &data, FALSE);
if (entry != NULL) if (entry != NULL)
{ {
@ -926,14 +927,14 @@ gi_repository_find_by_gtype (GIRepository *repository,
repository, repository,
NULL, data.result_typelib, entry->offset); NULL, data.result_typelib, entry->offset);
g_hash_table_insert (repository->priv->info_by_gtype, g_hash_table_insert (repository->info_by_gtype,
(gpointer) gtype, (gpointer) gtype,
gi_base_info_ref (cached)); gi_base_info_ref (cached));
return cached; return cached;
} }
else else
{ {
g_hash_table_add (repository->priv->unknown_gtypes, (gpointer) gtype); g_hash_table_add (repository->unknown_gtypes, (gpointer) gtype);
return NULL; return NULL;
} }
} }
@ -1027,7 +1028,7 @@ gi_repository_find_by_error_domain (GIRepository *repository,
repository = get_repository (repository); repository = get_repository (repository);
cached = g_hash_table_lookup (repository->priv->info_by_error_domain, cached = g_hash_table_lookup (repository->info_by_error_domain,
GUINT_TO_POINTER (domain)); GUINT_TO_POINTER (domain));
if (cached != NULL) if (cached != NULL)
@ -1038,9 +1039,9 @@ gi_repository_find_by_error_domain (GIRepository *repository,
data.result_typelib = NULL; data.result_typelib = NULL;
data.result = NULL; data.result = NULL;
g_hash_table_foreach (repository->priv->typelibs, find_by_error_domain_foreach, &data); g_hash_table_foreach (repository->typelibs, find_by_error_domain_foreach, &data);
if (data.result == NULL) if (data.result == NULL)
g_hash_table_foreach (repository->priv->lazy_typelibs, find_by_error_domain_foreach, &data); g_hash_table_foreach (repository->lazy_typelibs, find_by_error_domain_foreach, &data);
if (data.result != NULL) if (data.result != NULL)
{ {
@ -1048,7 +1049,7 @@ gi_repository_find_by_error_domain (GIRepository *repository,
repository, repository,
NULL, data.result_typelib, data.result->offset); NULL, data.result_typelib, data.result->offset);
g_hash_table_insert (repository->priv->info_by_error_domain, g_hash_table_insert (repository->info_by_error_domain,
GUINT_TO_POINTER (domain), GUINT_TO_POINTER (domain),
gi_base_info_ref ((GIBaseInfo *) cached)); gi_base_info_ref ((GIBaseInfo *) cached));
return cached; return cached;
@ -1091,7 +1092,7 @@ gi_repository_get_object_gtype_interfaces (GIRepository *repository,
repository = get_repository (repository); repository = get_repository (repository);
cache = g_hash_table_lookup (repository->priv->interfaces_for_gtype, cache = g_hash_table_lookup (repository->interfaces_for_gtype,
(void *) gtype); (void *) gtype);
if (cache == NULL) if (cache == NULL)
{ {
@ -1127,7 +1128,7 @@ gi_repository_get_object_gtype_interfaces (GIRepository *repository,
cache->interfaces[i] = iter->data; cache->interfaces[i] = iter->data;
g_list_free (interface_infos); g_list_free (interface_infos);
g_hash_table_insert (repository->priv->interfaces_for_gtype, (gpointer) gtype, g_hash_table_insert (repository->interfaces_for_gtype, (gpointer) gtype,
cache); cache);
g_free (interfaces); g_free (interfaces);
@ -1167,8 +1168,8 @@ gi_repository_get_loaded_namespaces (GIRepository *repository)
repository = get_repository (repository); repository = get_repository (repository);
g_hash_table_foreach (repository->priv->typelibs, collect_namespaces, &list); g_hash_table_foreach (repository->typelibs, collect_namespaces, &list);
g_hash_table_foreach (repository->priv->lazy_typelibs, collect_namespaces, &list); g_hash_table_foreach (repository->lazy_typelibs, collect_namespaces, &list);
names = g_malloc0 (sizeof (char *) * (g_list_length (list) + 1)); names = g_malloc0 (sizeof (char *) * (g_list_length (list) + 1));
i = 0; i = 0;
@ -1264,21 +1265,21 @@ gi_repository_get_shared_libraries (GIRepository *repository,
} }
/* Populate the cache. */ /* Populate the cache. */
if (repository->priv->cached_shared_libraries == NULL) if (repository->cached_shared_libraries == NULL)
{ {
const char *comma_separated = gi_typelib_get_string (typelib, header->shared_library); const char *comma_separated = gi_typelib_get_string (typelib, header->shared_library);
if (comma_separated != NULL && *comma_separated != '\0') if (comma_separated != NULL && *comma_separated != '\0')
{ {
repository->priv->cached_shared_libraries = g_strsplit (comma_separated, ",", -1); repository->cached_shared_libraries = g_strsplit (comma_separated, ",", -1);
repository->priv->cached_n_shared_libraries = g_strv_length (repository->priv->cached_shared_libraries); repository->cached_n_shared_libraries = g_strv_length (repository->cached_shared_libraries);
} }
} }
if (out_n_elements != NULL) if (out_n_elements != NULL)
*out_n_elements = repository->priv->cached_n_shared_libraries; *out_n_elements = repository->cached_n_shared_libraries;
return (const char * const *) repository->priv->cached_shared_libraries; return (const char * const *) repository->cached_shared_libraries;
} }
/** /**
@ -1346,10 +1347,10 @@ gi_repository_get_typelib_path (GIRepository *repository,
repository = get_repository (repository); repository = get_repository (repository);
if (!g_hash_table_lookup_extended (repository->priv->typelibs, namespace, if (!g_hash_table_lookup_extended (repository->typelibs, namespace,
&orig_key, &value)) &orig_key, &value))
{ {
if (!g_hash_table_lookup_extended (repository->priv->lazy_typelibs, namespace, if (!g_hash_table_lookup_extended (repository->lazy_typelibs, namespace,
&orig_key, &value)) &orig_key, &value))
return NULL; return NULL;

View File

@ -57,29 +57,9 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define GI_TYPE_REPOSITORY (gi_repository_get_type ()) #define GI_TYPE_REPOSITORY (gi_repository_get_type ())
#define GI_REPOSITORY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GI_TYPE_REPOSITORY, GIRepository)) GI_AVAILABLE_IN_ALL
#define GI_REPOSITORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GI_TYPE_REPOSITORY, GIRepositoryClass)) G_DECLARE_FINAL_TYPE (GIRepository, gi_repository, GI, REPOSITORY, GObject)
#define GI_IS_REPOSITORY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GI_TYPE_REPOSITORY))
#define GI_IS_REPOSITORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GI_TYPE_REPOSITORY))
#define GI_REPOSITORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GI_TYPE_REPOSITORY, GIRepositoryClass))
typedef struct _GIRepository GIRepository;
typedef struct _GIRepositoryClass GIRepositoryClass;
typedef struct _GIRepositoryPrivate GIRepositoryPrivate;
struct _GIRepository
{
/*< private >*/
GObject parent;
GIRepositoryPrivate *priv;
};
struct _GIRepositoryClass
{
/*< private >*/
GObjectClass parent;
};
/** /**
* GIRepositoryLoadFlags: * GIRepositoryLoadFlags:
@ -96,9 +76,6 @@ typedef enum
/* Repository */ /* Repository */
GI_AVAILABLE_IN_ALL
GType gi_repository_get_type (void) G_GNUC_CONST;
GI_AVAILABLE_IN_ALL GI_AVAILABLE_IN_ALL
GIRepository *gi_repository_get_default (void); GIRepository *gi_repository_get_default (void);

View File

@ -37,6 +37,15 @@
#define NUM_SECTIONS 2 #define NUM_SECTIONS 2
/*< private >
* gi_ir_module_new:
* @name:
* @version:
* @shared_library: (nullable):
* @c_prefix:
*
* Since: 2.80
*/
GIIrModule * GIIrModule *
gi_ir_module_new (const char *name, gi_ir_module_new (const char *name,
const char *version, const char *version,
@ -49,10 +58,7 @@ gi_ir_module_new (const char *name,
module->name = g_strdup (name); module->name = g_strdup (name);
module->version = g_strdup (version); module->version = g_strdup (version);
if (shared_library) module->shared_library = g_strdup (shared_library);
module->shared_library = g_strdup (shared_library);
else
module->shared_library = NULL;
module->c_prefix = g_strdup (c_prefix); module->c_prefix = g_strdup (c_prefix);
module->dependencies = NULL; module->dependencies = NULL;
module->entries = NULL; module->entries = NULL;

View File

@ -94,19 +94,19 @@ typedef enum
struct _GIIrNode struct _GIIrNode
{ {
GIIrNodeTypeId type; GIIrNodeTypeId type;
char *name; char *name; /* (owned) */
GIIrModule *module; GIIrModule *module; /* (unowned) */
uint32_t offset; /* Assigned as we build the typelib */ uint32_t offset; /* Assigned as we build the typelib */
GHashTable *attributes; GHashTable *attributes; /* (element-type utf8 utf8) (owned) */
}; };
struct _GIIrNodeXRef struct _GIIrNodeXRef
{ {
GIIrNode node; GIIrNode node;
char *namespace; char *namespace; /* (owned) */
}; };
struct _GIIrNodeFunction struct _GIIrNodeFunction
@ -124,11 +124,11 @@ struct _GIIrNodeFunction
uint8_t throws : 1; uint8_t throws : 1;
uint8_t instance_transfer_full : 1; uint8_t instance_transfer_full : 1;
char *symbol; char *symbol; /* (owned) */
char *property; char *property; /* (owned) */
GIIrNodeParam *result; GIIrNodeParam *result; /* (owned) */
GList *parameters; GList *parameters; /* (element-type GIIrNode) (owned) */
}; };
struct _GIIrNodeType struct _GIIrNodeType
@ -145,20 +145,20 @@ struct _GIIrNodeType
uint8_t is_error : 1; uint8_t is_error : 1;
int tag; int tag;
char *unparsed; char *unparsed; /* (owned) */
uint8_t zero_terminated : 1; uint8_t zero_terminated : 1;
uint8_t has_length : 1; uint8_t has_length : 1;
int length; unsigned int length;
uint8_t has_size : 1; uint8_t has_size : 1;
int size; size_t size;
int array_type; GIArrayType array_type;
GIIrNodeType *parameter_type1; GIIrNodeType *parameter_type1; /* (owned) */
GIIrNodeType *parameter_type2; GIIrNodeType *parameter_type2; /* (owned) */
char *giinterface; char *giinterface; /* (owned) */
char **errors; char **errors; /* (array zero-terminated=1) (owned) */
}; };
struct _GIIrNodeParam struct _GIIrNodeParam
@ -179,7 +179,7 @@ struct _GIIrNodeParam
int8_t closure; int8_t closure;
int8_t destroy; int8_t destroy;
GIIrNodeType *type; GIIrNodeType *type; /* (owned) */
}; };
struct _GIIrNodeProperty struct _GIIrNodeProperty
@ -188,7 +188,7 @@ struct _GIIrNodeProperty
uint8_t deprecated : 1; uint8_t deprecated : 1;
char *name; char *name; /* (owned) */
uint8_t readable : 1; uint8_t readable : 1;
uint8_t writable : 1; uint8_t writable : 1;
uint8_t construct : 1; uint8_t construct : 1;
@ -196,10 +196,10 @@ struct _GIIrNodeProperty
uint8_t transfer : 1; uint8_t transfer : 1;
uint8_t shallow_transfer : 1; uint8_t shallow_transfer : 1;
char *setter; char *setter; /* (owned) */
char *getter; char *getter; /* (owned) */
GIIrNodeType *type; GIIrNodeType *type; /* (owned) */
}; };
struct _GIIrNodeSignal struct _GIIrNodeSignal
@ -220,10 +220,10 @@ struct _GIIrNodeSignal
uint8_t has_class_closure : 1; uint8_t has_class_closure : 1;
uint8_t true_stops_emit : 1; uint8_t true_stops_emit : 1;
int class_closure; unsigned int class_closure;
GList *parameters; GList *parameters; /* (element-type GIIrNode) (owned) */
GIIrNodeParam *result; GIIrNodeParam *result; /* (owned) */
}; };
struct _GIIrNodeVFunc struct _GIIrNodeVFunc
@ -238,12 +238,12 @@ struct _GIIrNodeVFunc
uint8_t throws : 1; uint8_t throws : 1;
uint8_t instance_transfer_full : 1; uint8_t instance_transfer_full : 1;
char *invoker; char *invoker; /* (owned) */
GList *parameters; GList *parameters; /* (element-type GIIrNode) (owned) */
GIIrNodeParam *result; GIIrNodeParam *result; /* (owned) */
int offset; size_t offset;
}; };
struct _GIIrNodeField struct _GIIrNodeField
@ -252,11 +252,12 @@ struct _GIIrNodeField
uint8_t readable : 1; uint8_t readable : 1;
uint8_t writable : 1; uint8_t writable : 1;
int bits; unsigned int bits;
int offset; size_t offset;
GIIrNodeFunction *callback; GIIrOffsetsState offset_state;
GIIrNodeFunction *callback; /* (owned) */
GIIrNodeType *type; GIIrNodeType *type; /* (owned) */
}; };
struct _GIIrNodeInterface struct _GIIrNodeInterface
@ -268,25 +269,25 @@ struct _GIIrNodeInterface
uint8_t fundamental : 1; uint8_t fundamental : 1;
uint8_t final_ : 1; uint8_t final_ : 1;
char *gtype_name; char *gtype_name; /* (owned) */
char *gtype_init; char *gtype_init; /* (owned) */
char *ref_func; char *ref_func; /* (owned) */
char *unref_func; char *unref_func; /* (owned) */
char *set_value_func; char *set_value_func; /* (owned) */
char *get_value_func; char *get_value_func; /* (owned) */
char *parent; char *parent; /* (owned) */
char *glib_type_struct; char *glib_type_struct; /* (owned) */
GList *interfaces; GList *interfaces; /* (element-type GIIrNode) (owned) */
GList *prerequisites; GList *prerequisites; /* (element-type utf8) (owned) */
size_t alignment; size_t alignment;
size_t size; size_t size;
GIIrOffsetsState offsets_state; GIIrOffsetsState offsets_state;
GList *members; GList *members; /* (element-type GIIrNode) (owned) */
}; };
struct _GIIrNodeValue struct _GIIrNodeValue
@ -304,9 +305,9 @@ struct _GIIrNodeConstant
uint8_t deprecated : 1; uint8_t deprecated : 1;
GIIrNodeType *type; GIIrNodeType *type; /* (owned) */
char *value; char *value; /* (owned) */
}; };
struct _GIIrNodeEnum struct _GIIrNodeEnum
@ -314,14 +315,14 @@ struct _GIIrNodeEnum
GIIrNode node; GIIrNode node;
uint8_t deprecated : 1; uint8_t deprecated : 1;
int storage_type; GITypeTag storage_type;
char *gtype_name; char *gtype_name; /* (owned) */
char *gtype_init; char *gtype_init; /* (owned) */
char *error_domain; char *error_domain; /* (owned) */
GList *values; GList *values; /* (element-type GIIrNode) (owned) */
GList *methods; GList *methods; /* (element-type GIIrNode) (owned) */
}; };
struct _GIIrNodeBoxed struct _GIIrNodeBoxed
@ -330,14 +331,14 @@ struct _GIIrNodeBoxed
uint8_t deprecated : 1; uint8_t deprecated : 1;
char *gtype_name; char *gtype_name; /* (owned) */
char *gtype_init; char *gtype_init; /* (owned) */
size_t alignment; size_t alignment;
size_t size; size_t size;
GIIrOffsetsState offsets_state; GIIrOffsetsState offsets_state;
GList *members; GList *members; /* (element-type GIIrNode) (owned) */
}; };
struct _GIIrNodeStruct struct _GIIrNodeStruct
@ -351,17 +352,17 @@ struct _GIIrNodeStruct
uint8_t is_gtype_struct : 1; uint8_t is_gtype_struct : 1;
uint8_t foreign : 1; uint8_t foreign : 1;
char *gtype_name; char *gtype_name; /* (owned) */
char *gtype_init; char *gtype_init; /* (owned) */
char *copy_func; char *copy_func; /* (owned) */
char *free_func; char *free_func; /* (owned) */
size_t alignment; size_t alignment;
size_t size; size_t size;
GIIrOffsetsState offsets_state; GIIrOffsetsState offsets_state;
GList *members; GList *members; /* (element-type GIIrNode) (owned) */
}; };
struct _GIIrNodeUnion struct _GIIrNodeUnion
@ -370,21 +371,21 @@ struct _GIIrNodeUnion
uint8_t deprecated : 1; uint8_t deprecated : 1;
GList *members; GList *members; /* (element-type GIIrNode) (owned) */
GList *discriminators; GList *discriminators; /* (element-type GIIrNode) (owned) */
char *gtype_name; char *gtype_name; /* (owned) */
char *gtype_init; char *gtype_init; /* (owned) */
char *copy_func; char *copy_func; /* (owned) */
char *free_func; char *free_func; /* (owned) */
size_t alignment; size_t alignment;
size_t size; size_t size;
GIIrOffsetsState offsets_state; GIIrOffsetsState offsets_state;
int discriminator_offset; size_t discriminator_offset;
GIIrNodeType *discriminator_type; GIIrNodeType *discriminator_type; /* (owned) */
}; };

View File

@ -240,7 +240,7 @@ gi_ir_node_free (GIIrNode *node)
g_free (type->giinterface); g_free (type->giinterface);
g_strfreev (type->errors); g_strfreev (type->errors);
g_free (type->unparsed);
} }
break; break;
@ -320,6 +320,8 @@ gi_ir_node_free (GIIrNode *node)
g_free ((GIIrNode *)l->data); g_free ((GIIrNode *)l->data);
g_list_free (iface->interfaces); g_list_free (iface->interfaces);
g_list_free_full (iface->prerequisites, g_free);
for (l = iface->members; l; l = l->next) for (l = iface->members; l; l = l->next)
gi_ir_node_free ((GIIrNode *)l->data); gi_ir_node_free ((GIIrNode *)l->data);
g_list_free (iface->members); g_list_free (iface->members);
@ -1241,7 +1243,7 @@ serialize_type (GIIrTypelibBuild *build,
if (node->has_length) if (node->has_length)
g_string_append_printf (str, "length=%d", node->length); g_string_append_printf (str, "length=%d", node->length);
else if (node->has_size) else if (node->has_size)
g_string_append_printf (str, "fixed-size=%d", node->size); g_string_append_printf (str, "fixed-size=%" G_GSIZE_FORMAT, node->size);
if (node->zero_terminated) if (node->zero_terminated)
g_string_append_printf (str, "%szero-terminated=1", g_string_append_printf (str, "%szero-terminated=1",
@ -1599,7 +1601,7 @@ gi_ir_node_build_typelib (GIIrNode *node,
blob->writable = field->writable; blob->writable = field->writable;
blob->reserved = 0; blob->reserved = 0;
blob->bits = 0; blob->bits = 0;
if (field->offset >= 0) if (field->offset_state == GI_IR_OFFSETS_COMPUTED)
blob->struct_offset = field->offset; blob->struct_offset = field->offset;
else else
blob->struct_offset = 0xFFFF; /* mark as unknown */ blob->struct_offset = 0xFFFF; /* mark as unknown */

View File

@ -392,6 +392,7 @@ compute_struct_field_offsets (GIIrTypelibBuild *build,
size = GI_ALIGN (size, member_alignment); size = GI_ALIGN (size, member_alignment);
alignment = MAX (alignment, member_alignment); alignment = MAX (alignment, member_alignment);
field->offset = size; field->offset = size;
field->offset_state = GI_IR_OFFSETS_COMPUTED;
size += member_size; size += member_size;
} }
else else
@ -399,7 +400,10 @@ compute_struct_field_offsets (GIIrTypelibBuild *build,
} }
if (have_error) if (have_error)
field->offset = -1; {
field->offset = 0;
field->offset_state = GI_IR_OFFSETS_FAILED;
}
} }
else if (member->type == GI_IR_NODE_CALLBACK) else if (member->type == GI_IR_NODE_CALLBACK)
{ {

View File

@ -1366,6 +1366,7 @@ start_field (GMarkupParseContext *context,
GIIrNodeField *field; GIIrNodeField *field;
ParseState target_state; ParseState target_state;
gboolean introspectable; gboolean introspectable;
guint64 parsed_bits;
switch (ctx->state) switch (ctx->state)
{ {
@ -1428,10 +1429,15 @@ start_field (GMarkupParseContext *context,
field->readable = readable == NULL || strcmp (readable, "0") == 0; field->readable = readable == NULL || strcmp (readable, "0") == 0;
field->writable = writable != NULL && strcmp (writable, "1") == 0; field->writable = writable != NULL && strcmp (writable, "1") == 0;
if (bits) if (bits == NULL)
field->bits = atoi (bits);
else
field->bits = 0; field->bits = 0;
else if (g_ascii_string_to_unsigned (bits, 10, 0, G_MAXUINT, &parsed_bits, error))
field->bits = parsed_bits;
else
{
gi_ir_node_free ((GIIrNode *) field);
return FALSE;
}
switch (CURRENT_NODE (ctx)->type) switch (CURRENT_NODE (ctx)->type)
{ {
@ -2100,15 +2106,33 @@ start_type (GMarkupParseContext *context,
} }
if (typenode->array_type == GI_ARRAY_TYPE_C) { if (typenode->array_type == GI_ARRAY_TYPE_C) {
guint64 parsed_uint;
zero = find_attribute ("zero-terminated", attribute_names, attribute_values); zero = find_attribute ("zero-terminated", attribute_names, attribute_values);
len = find_attribute ("length", attribute_names, attribute_values); len = find_attribute ("length", attribute_names, attribute_values);
size = find_attribute ("fixed-size", attribute_names, attribute_values); size = find_attribute ("fixed-size", attribute_names, attribute_values);
typenode->has_length = len != NULL; typenode->has_length = len != NULL;
typenode->length = typenode->has_length ? atoi (len) : -1; if (!typenode->has_length)
typenode->length = -1;
else if (g_ascii_string_to_unsigned (len, 10, 0, G_MAXUINT, &parsed_uint, error))
typenode->length = parsed_uint;
else
{
gi_ir_node_free ((GIIrNode *) typenode);
return FALSE;
}
typenode->has_size = size != NULL; typenode->has_size = size != NULL;
typenode->size = typenode->has_size ? atoi (size) : -1; if (!typenode->has_size)
typenode->size = -1;
else if (g_ascii_string_to_unsigned (size, 10, 0, G_MAXSIZE, &parsed_uint, error))
typenode->size = parsed_uint;
else
{
gi_ir_node_free ((GIIrNode *) typenode);
return FALSE;
}
if (zero) if (zero)
typenode->zero_terminated = strcmp(zero, "1") == 0; typenode->zero_terminated = strcmp(zero, "1") == 0;
@ -2543,6 +2567,7 @@ start_vfunc (GMarkupParseContext *context,
const char *throws; const char *throws;
GIIrNodeInterface *iface; GIIrNodeInterface *iface;
GIIrNodeVFunc *vfunc; GIIrNodeVFunc *vfunc;
guint64 parsed_offset;
if (!(strcmp (element_name, "virtual-method") == 0 && if (!(strcmp (element_name, "virtual-method") == 0 &&
(ctx->state == STATE_CLASS || (ctx->state == STATE_CLASS ||
@ -2602,10 +2627,15 @@ start_vfunc (GMarkupParseContext *context,
else else
vfunc->throws = FALSE; vfunc->throws = FALSE;
if (offset) if (offset == NULL)
vfunc->offset = atoi (offset);
else
vfunc->offset = 0xFFFF; vfunc->offset = 0xFFFF;
else if (g_ascii_string_to_unsigned (offset, 10, 0, G_MAXSIZE, &parsed_offset, error))
vfunc->offset = parsed_offset;
else
{
gi_ir_node_free ((GIIrNode *) vfunc);
return FALSE;
}
vfunc->invoker = g_strdup (invoker); vfunc->invoker = g_strdup (invoker);
@ -2780,6 +2810,8 @@ start_discriminator (GMarkupParseContext *context,
{ {
const char *type; const char *type;
const char *offset; const char *offset;
guint64 parsed_offset;
if (!(strcmp (element_name, "discriminator") == 0 && if (!(strcmp (element_name, "discriminator") == 0 &&
ctx->state == STATE_UNION)) ctx->state == STATE_UNION))
return FALSE; return FALSE;
@ -2799,8 +2831,11 @@ start_discriminator (GMarkupParseContext *context,
((GIIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type ((GIIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_type
= parse_type (ctx, type); = parse_type (ctx, type);
((GIIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset
= atoi (offset); if (g_ascii_string_to_unsigned (offset, 10, 0, G_MAXSIZE, &parsed_offset, error))
((GIIrNodeUnion *)CURRENT_NODE (ctx))->discriminator_offset = parsed_offset;
else
return FALSE;
return TRUE; return TRUE;
} }