diff --git a/src/gig_arg_map.c b/src/gig_arg_map.c index fb433464..e1bea85c 100644 --- a/src/gig_arg_map.c +++ b/src/gig_arg_map.c @@ -83,8 +83,8 @@ arg_map_allocate(gsize n) { GigArgMap *amap; - amap = g_new0(GigArgMap, 1); - amap->pdata = g_new0(GigArgMapEntry, n); + amap = xcalloc(1, sizeof(GigArgMap)); + amap->pdata = xcalloc(n, sizeof(GigArgMapEntry)); amap->len = n; for (gsize i = 0; i < n; i++) { arg_map_entry_init(&amap->pdata[i]); diff --git a/src/gig_argument.c b/src/gig_argument.c index 139f3e9c..29d875b2 100644 --- a/src/gig_argument.c +++ b/src/gig_argument.c @@ -580,12 +580,11 @@ scm_to_c_native_boolean_array(S2C_ARG_DECL) scm_wrong_type_arg_msg(subr, argpos, object, "vector of booleans"); *size = scm_c_vector_length(object); if (meta->is_zero_terminated) { - arg->v_pointer = malloc(sizeof(gboolean) * (*size + 1)); - ((gboolean *)arg->v_pointer)[*size] = 0; + arg->v_pointer = xcalloc(*size + 1, sizeof(gboolean)); LATER_FREE(arg->v_pointer); } else { - arg->v_pointer = malloc(sizeof(gboolean) * *size); + arg->v_pointer = xcalloc(*size, sizeof(gboolean)); LATER_FREE(arg->v_pointer); } for (gsize i = 0; i < *size; i++) @@ -602,12 +601,11 @@ scm_to_c_native_unichar_array(S2C_ARG_DECL) scm_wrong_type_arg_msg(subr, argpos, object, "string"); *size = scm_c_string_length(object); if (meta->is_zero_terminated) { - arg->v_pointer = malloc(sizeof(gunichar) * (*size + 1)); - ((gunichar *)arg->v_pointer)[*size] = 0; + arg->v_pointer = xcalloc(*size + 1, sizeof(gunichar)); LATER_FREE(arg->v_pointer); } else { - arg->v_pointer = malloc(sizeof(gunichar) * *size); + arg->v_pointer = xcalloc(*size, sizeof(gunichar)); LATER_FREE(arg->v_pointer); } for (gsize i = 0; i < *size; i++) @@ -630,23 +628,23 @@ scm_to_c_native_immediate_array(S2C_ARG_DECL) *size = SCM_BYTEVECTOR_LENGTH(object) / item_size; if (meta->transfer == GI_TRANSFER_EVERYTHING) { if (meta->is_zero_terminated) { - gsize len = SCM_BYTEVECTOR_LENGTH(object); // Note, null terminated here. - arg->v_pointer = g_malloc0(len + item_size); - memcpy(arg->v_pointer, SCM_BYTEVECTOR_CONTENTS(object), len); + arg->v_pointer = xcalloc(*size + 1, item_size); + memcpy(arg->v_pointer, SCM_BYTEVECTOR_CONTENTS(object), + SCM_BYTEVECTOR_LENGTH(object)); } else { - arg->v_pointer = gig_memdup(SCM_BYTEVECTOR_CONTENTS(object), - SCM_BYTEVECTOR_LENGTH(object)); + arg->v_pointer = xmemdup(SCM_BYTEVECTOR_CONTENTS(object), + SCM_BYTEVECTOR_LENGTH(object)); } } else { if (meta->is_zero_terminated) { - gsize len = SCM_BYTEVECTOR_LENGTH(object); // Adding null terminator element. - arg->v_pointer = g_malloc0(len + item_size); + arg->v_pointer = xcalloc(*size + 1, item_size); LATER_FREE(arg->v_pointer); - memcpy(arg->v_pointer, SCM_BYTEVECTOR_CONTENTS(object), len); + memcpy(arg->v_pointer, SCM_BYTEVECTOR_CONTENTS(object), + SCM_BYTEVECTOR_LENGTH(object)); } else // The fast path @@ -670,7 +668,7 @@ scm_to_c_byte_array(S2C_ARG_DECL) if (meta->transfer == GI_TRANSFER_EVERYTHING) arg->v_pointer = g_byte_array_new_take(contents, len); else - arg->v_pointer = g_byte_array_new_take(gig_memdup(contents, len), len); + arg->v_pointer = g_byte_array_new_take(xmemdup(contents, len), len); } else scm_wrong_type_arg_msg(subr, argpos, object, "bytevector"); @@ -769,12 +767,12 @@ arg_to_c_hash_pointer(GigTypeMeta *meta, GigHashKeyType key_type, GIArgument *ar // GHashTables expect gint64 to be passed by reference, even // if they fit in a pointer. if (meta->gtype == G_TYPE_INT || meta->gtype == G_TYPE_INT64) { - gint64 *p = g_malloc(sizeof(gint64)); + gint64 *p = xmalloc(sizeof(gint64)); *p = arg->v_int64; return p; } else if (meta->gtype == G_TYPE_UINT || meta->gtype == G_TYPE_UINT64) { - guint64 *p = g_malloc(sizeof(guint64)); + guint64 *p = xmalloc(sizeof(guint64)); *p = arg->v_uint64; return p; } @@ -783,12 +781,12 @@ arg_to_c_hash_pointer(GigTypeMeta *meta, GigHashKeyType key_type, GIArgument *ar // GHashTables expect double and float to be passed by // reference, even if they fit in a pointer. if (meta->gtype == G_TYPE_DOUBLE) { - gdouble *p = g_malloc(sizeof(double)); + gdouble *p = xmalloc(sizeof(double)); *p = arg->v_double; return p; } else if (meta->gtype == G_TYPE_FLOAT) { - gfloat *p = g_malloc(sizeof(double)); + gfloat *p = xmalloc(sizeof(float)); *p = arg->v_float; return p; } @@ -938,12 +936,11 @@ scm_to_c_native_gtype_array(S2C_ARG_DECL) scm_wrong_type_arg_msg(subr, argpos, object, "vector of gtype-ables"); *size = scm_c_vector_length(object); if (meta->is_zero_terminated) { - arg->v_pointer = malloc(sizeof(GType) * (*size + 1)); - ((GType *) arg->v_pointer)[*size] = 0; + arg->v_pointer = xcalloc(*size + 1, sizeof(GType)); LATER_FREE(arg->v_pointer); } else { - arg->v_pointer = malloc(sizeof(GType) * *size); + arg->v_pointer = xcalloc(*size, sizeof(GType)); LATER_FREE(arg->v_pointer); } for (gsize i = 0; i < *size; i++) @@ -983,19 +980,16 @@ scm_to_c_native_interface_array(S2C_ARG_DECL) scm_wrong_type_arg_msg(subr, argpos, object, "vector of objects"); *size = scm_c_vector_length(object); if (meta->params[0].is_ptr) { - if (meta->is_zero_terminated) { - arg->v_pointer = malloc(sizeof(gpointer) * (*size + 1)); - ((gpointer *)arg->v_pointer)[*size] = 0; - } - else { - arg->v_pointer = malloc(sizeof(gpointer) * *size); - } + if (meta->is_zero_terminated) + arg->v_pointer = xcalloc(*size + 1, sizeof(gpointer)); + else + arg->v_pointer = xcalloc(*size, sizeof(gpointer)); for (gsize i = 0; i < *size; i++) { gpointer p = gig_type_peek_object(scm_c_vector_ref(object, i)); if (meta->transfer == GI_TRANSFER_EVERYTHING) { if (fundamental_item_type == G_TYPE_BOXED) { ((gpointer *)(arg->v_pointer))[i] = - gig_memdup(p, gig_meta_real_item_size(&meta->params[0])); + xmemdup(p, gig_meta_real_item_size(&meta->params[0])); } else if (fundamental_item_type == G_TYPE_VARIANT) { ((gpointer *)(arg->v_pointer))[i] = p; @@ -1014,14 +1008,14 @@ scm_to_c_native_interface_array(S2C_ARG_DECL) GigTypeMeta *item_meta = &meta->params[0]; gsize real_item_size = gig_meta_real_item_size(item_meta); if (meta->is_zero_terminated) - arg->v_pointer = g_malloc0(real_item_size * (*size + 1)); + arg->v_pointer = xcalloc(*size + 1, real_item_size); else - arg->v_pointer = malloc(real_item_size * *size); + arg->v_pointer = xcalloc(*size, real_item_size); for (gsize i = 0; i < *size; i++) { gpointer p = gig_type_peek_object(scm_c_vector_ref(object, i)); if (meta->transfer == GI_TRANSFER_EVERYTHING) memcpy((char *)(arg->v_pointer) + i * real_item_size, - gig_memdup(p, real_item_size), real_item_size); + xmemdup(p, real_item_size), real_item_size); else memcpy((char *)(arg->v_pointer) + i * real_item_size, p, real_item_size); } @@ -1034,9 +1028,9 @@ scm_to_c_native_interface_array(S2C_ARG_DECL) *size = length; gint *ptr; if (meta->is_zero_terminated) - ptr = g_new0(gint, length + 1); + ptr = xcalloc(length + 1, sizeof(gint)); else - ptr = g_new0(gint, length); + ptr = xcalloc(length, sizeof(gint)); arg->v_pointer = ptr; LATER_FREE(ptr); SCM iter = object; @@ -1078,7 +1072,7 @@ scm_to_c_native_string_array(S2C_ARG_DECL) elt = scm_vector_elements(object, &handle, &len, &inc); *size = len; - gchar **strv = g_new0(gchar *, len + 1); + gchar **strv = xcalloc(len + 1, sizeof(gchar *)); LATER_FREE(strv); for (gsize i = 0; i < len; i++, elt += inc) { @@ -1096,7 +1090,7 @@ scm_to_c_native_string_array(S2C_ARG_DECL) else if (scm_is_list(object)) { gsize len = scm_c_length(object); *size = len; - gchar **strv = g_new0(gchar *, len + 1); + gchar **strv = xcalloc(len + 1, sizeof(gchar *)); LATER_FREE(strv); SCM iter = object; for (gsize i = 0; i < len; i++) { @@ -1425,7 +1419,7 @@ c_native_array_to_scm(C2S_ARG_DECL) else if (meta->transfer == GI_TRANSFER_EVERYTHING) \ *object = scm_take_ ## _short_type ## vector((_type *)(arg->v_pointer), length); \ else \ - *object = scm_take_ ## _short_type ## vector((_type *)gig_memdup(arg->v_pointer, sz), length); \ + *object = scm_take_ ## _short_type ## vector((_type *)xmemdup(arg->v_pointer, sz), length); \ } while(0) GType item_type = meta->params[0].gtype; @@ -1650,7 +1644,7 @@ c_gptrarray_to_scm(C2S_ARG_DECL) // Transfer the contents out of the GPtrArray into a // native C array, and then on to an SCM size = array->len; - _arg.v_pointer = gig_memdup(array->pdata, array->len * sizeof(gpointer)); + _arg.v_pointer = xmemdup(array->pdata, array->len * sizeof(gpointer)); c_native_array_to_scm(subr, argpos, &_meta, &_arg, object, size); // Free the GPtrArray without deleting the contents diff --git a/src/gig_callback.c b/src/gig_callback.c index e2a4f43a..2887945f 100644 --- a/src/gig_callback.c +++ b/src/gig_callback.c @@ -395,7 +395,7 @@ gig_callback_new(const char *name, GICallbackInfo *callback_info, SCM s_func) { g_assert(scm_is_true(scm_procedure_p(s_func))); - GigCallback *gcb = g_new0(GigCallback, 1); + GigCallback *gcb = xcalloc(1, sizeof(GigCallback)); ffi_type **ffi_args = NULL; ffi_type *ffi_ret_type; gint n_args = g_callable_info_get_n_args(callback_info); @@ -427,7 +427,7 @@ gig_callback_new(const char *name, GICallbackInfo *callback_info, SCM s_func) // Initialize the argument info vectors. if (n_args > 0) { - ffi_args = g_new0(ffi_type *, n_args); + ffi_args = xcalloc(n_args, sizeof(ffi_type *)); gcb->atypes = ffi_args; for (gint i = 0; i < n_args; i++) @@ -469,7 +469,7 @@ gig_callback_new_for_callback(GICallbackInfo *info, gpointer c_func) // we only take one arg now, the scm arg list n_args = n_args == 0 ? 0 : 1; - GigCallback *gcb = g_new0(GigCallback, 1); + GigCallback *gcb = xcalloc(1, sizeof(GigCallback)); gcb->name = NULL; @@ -478,7 +478,7 @@ gig_callback_new_for_callback(GICallbackInfo *info, gpointer c_func) gcb->amap = gig_amap_new(gcb->name, gcb->callback_info); if (n_args > 0) { - gcb->atypes = g_new0(ffi_type *, 1); + gcb->atypes = xcalloc(1, sizeof(ffi_type *)); gcb->atypes[0] = &ffi_type_pointer; } diff --git a/src/gig_closure.c b/src/gig_closure.c index eb248b66..9b5a4eb1 100644 --- a/src/gig_closure.c +++ b/src/gig_closure.c @@ -118,8 +118,8 @@ invoke_closure(SCM closure, SCM return_type, SCM inout_mask, SCM args) SCM_ASSERT_TYPE(scm_is_list(args), args, SCM_ARG2, "%invoke-closure", "list"); gsize nargs = scm_c_length(args); - GValue *params = g_new0(GValue, nargs); - GValue *retval = g_new0(GValue, 1); + GValue *params = xcalloc(nargs, sizeof(GValue)); + GValue *retval = xcalloc(1, sizeof(GValue)); SCM ret = SCM_UNDEFINED; SCM iter = args; @@ -154,7 +154,7 @@ invoke_closure(SCM closure, SCM return_type, SCM inout_mask, SCM args) if (bit_count > nargs) scm_misc_error(NULL, "~S returned fewer values than we should unpack", scm_list_1(closure)); - GValue *out = g_new0(GValue, bit_count); + GValue *out = xcalloc(bit_count, sizeof(GValue)); bits = scm_bitvector_elements(inout_mask, &handle, &offset, &length, &inc); pos = offset; diff --git a/src/gig_data_type.c b/src/gig_data_type.c index fd106b93..73047d0e 100644 --- a/src/gig_data_type.c +++ b/src/gig_data_type.c @@ -70,7 +70,7 @@ gig_type_meta_init_from_callable_info(GigTypeMeta *meta, GICallableInfo *ci) static void add_params(GigTypeMeta *meta, gint n) { - meta->params = g_new0(GigTypeMeta, n); + meta->params = xcalloc(n, sizeof(GigTypeMeta)); meta->n_params = n; } diff --git a/src/gig_function.c b/src/gig_function.c index 03bec371..036eed18 100644 --- a/src/gig_function.c +++ b/src/gig_function.c @@ -381,7 +381,7 @@ create_gsubr(GIFunctionInfo *function_info, const gchar *name, SCM self_type, return NULL; } - gfn = g_new0(GigFunction, 1); + gfn = xcalloc(1, sizeof(GigFunction)); gfn->function_info = function_info; gfn->amap = amap; g_free(gfn->name); @@ -412,7 +412,7 @@ create_gsubr(GIFunctionInfo *function_info, const gchar *name, SCM self_type, // Initialize the argument info vectors. gint have_args = 0; if (*required_input_count + *optional_input_count > 0) { - gfn->atypes = g_new0(ffi_type *, 1); + gfn->atypes = xcalloc(1, sizeof(ffi_type *)); gfn->atypes[0] = &ffi_type_pointer; have_args = 1; } @@ -480,7 +480,8 @@ gig_callable_prepare_invoke(GigArgMap *amap, // needed. It is easier than figuring out which output arguments // need allocation. *out_args = (GIArgument *)((*cinvoke_output_arg_array)->data); - *out_boxes = g_new0(GIArgument, (*cinvoke_output_arg_array)->len); + *out_boxes = xcalloc((*cinvoke_output_arg_array)->len, sizeof(GIArgument)); + g_ptr_array_insert(*cinvoke_free_array, 0, *out_boxes); for (guint i = 0; i < (*cinvoke_output_arg_array)->len; i++) if ((*out_args + i)->v_pointer == NULL) @@ -748,7 +749,7 @@ store_argument(gint invoke_in, gint invoke_out, gboolean inout, gboolean inout_f if (invoke_in >= 0) { if (inout) { - gpointer *dup = gig_memdup(arg, sizeof(GIArgument)); + gpointer *dup = xmemdup(arg, sizeof(GIArgument)); parg = &g_array_index(cinvoke_input_arg_array, GIArgument, invoke_in); parg->v_pointer = dup; diff --git a/src/gig_object.c b/src/gig_object.c index b4630930..85680588 100644 --- a/src/gig_object.c +++ b/src/gig_object.c @@ -302,7 +302,7 @@ gig_user_object_init(GTypeInstance *instance, gpointer class_ptr) g_type_query(parent_type, &query); properties = g_object_class_list_properties(class_ptr, &n_properties); - GValue *instance_properties = g_new0(GValue, n_properties); + GValue *instance_properties = xcalloc(n_properties, sizeof(GValue)); g_object_set_qdata(G_OBJECT(instance), gig_user_object_properties, instance_properties); for (guint i = 0; i < n_properties; i++) { @@ -325,7 +325,7 @@ gig_user_object_define(const gchar *type_name, memset(&type_info, 0, sizeof(type_info)); /* This data will needed when the class is dynamically instantiated. */ - class_init_info = g_new0(GigUserObjectInitInfo, 1); + class_init_info = xcalloc(1, sizeof(GigUserObjectInitInfo)); class_init_info->properties = properties; class_init_info->signals = signals; @@ -483,7 +483,7 @@ gig_i_scm_emit(SCM self, SCM signal, SCM s_detail, SCM args) scm_list_4(self, signal, scm_from_uint32(query_info.n_params), scm_length(args))); - values = g_new0(GValue, query_info.n_params + 1); + values = xcalloc(query_info.n_params + 1, sizeof(GValue)); g_value_init(values, G_OBJECT_TYPE(obj)); gig_value_from_scm_with_error(values, self, "%emit", SCM_ARG1); SCM iter = args; diff --git a/src/gig_signal.c b/src/gig_signal.c index 9a69f95b..5bf3c72d 100644 --- a/src/gig_signal.c +++ b/src/gig_signal.c @@ -88,7 +88,7 @@ gig_signalspec_from_obj(SCM obj) SCM_ASSERT_TYPE(SCM_IS_A_P(obj, gig_signal_type), obj, SCM_ARG1, "%scm->signalspec", "signal"); scm_dynwind_begin(0); - spec = g_new0(GigSignalSpec, 1); + spec = xcalloc(1, sizeof(GigSignalSpec)); scm_dynwind_unwind_handler((handler_func) gig_free_signalspec, spec, 0); spec->return_type = scm_to_gtype(gig_signal_ref(obj, GIG_SIGNAL_SLOT_RETURN_TYPE)); if (spec->return_type == G_TYPE_INVALID) @@ -99,7 +99,7 @@ gig_signalspec_from_obj(SCM obj) sparams = gig_signal_ref(obj, GIG_SIGNAL_SLOT_PARAM_TYPES); saccu = gig_signal_ref(obj, GIG_SIGNAL_SLOT_ACCUMULATOR); n_params = scm_c_length(sparams); - params = g_new0(GType, n_params); + params = xcalloc(n_params, sizeof(GType)); for (guint i = 0; i < n_params; i++, sparams = scm_cdr(sparams)) params[i] = scm_to_gtype(scm_car(sparams)); diff --git a/src/gig_type.c b/src/gig_type.c index a4469b32..7c429d5f 100644 --- a/src/gig_type.c +++ b/src/gig_type.c @@ -1,4 +1,4 @@ -// Copyright (C) 2018, 2019, 2020, 2021 Michael L. Gran +// Copyright (C) 2018, 2019, 2020, 2021, 2022 Michael L. Gran // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -790,7 +790,7 @@ scm_allocate_boxed(SCM boxed_type) if (size == 0) scm_out_of_range("%allocate-boxed", s_size); - gpointer boxed = g_malloc0(size); + gpointer boxed = xcalloc(1, size); GigTypeUnrefFunction unref; unref = (GigTypeUnrefFunction)scm_to_pointer(scm_class_ref(boxed_type, sym_unref)); SCM pointer = scm_from_pointer(boxed, unref); diff --git a/src/gig_util.c b/src/gig_util.c index 274f9cdf..eaa7760c 100644 --- a/src/gig_util.c +++ b/src/gig_util.c @@ -25,6 +25,56 @@ static gboolean is_predicate(GIFunctionInfo *info); static void count_args(GICallableInfo *info, gint *in, gint *out); +void * +xcalloc(size_t nmemb, size_t siz) +{ + void *x; + if (nmemb == 0 || siz == 0) + return NULL; + x = calloc(nmemb, siz); + if (x == 0) { + fprintf(stderr, "Out of memory\n"); + exit(1); + } + return x; +} + +void * +xmalloc(size_t siz) +{ + void *x; + if (siz == 0) { + fprintf(stderr, "malloc zero size error\n"); + exit(1); + } + x = malloc(siz); + if (x == NULL) { + fprintf(stderr, "Out of memory\n"); + exit(1); + } + return x; +} + +void * +xmemdup(const void *mem, size_t len) +{ + void *new_mem; + + if (mem == NULL || len == 0) { + fprintf(stderr, "memdup zero size error\n"); + exit(1); + } + new_mem = malloc(len); + if (new_mem == NULL) { + fprintf(stderr, "Out of memory\n"); + exit(1); + } + memcpy(new_mem, mem, len); + + return new_mem; +} + + char * xstrdup(const char *S) { @@ -262,21 +312,6 @@ gig_gname_to_scm_name(const gchar *gname) return g_string_free(str, FALSE); } -void * -gig_memdup(const void *mem, size_t len) -{ - void *new_mem; - - if (mem && len != 0) { - new_mem = g_malloc(len); - memcpy(new_mem, mem, len); - } - else - new_mem = NULL; - - return new_mem; -} - SCM scm_c_list_ref(SCM list, gsize k) { diff --git a/src/gig_util.h b/src/gig_util.h index 82ff70f3..353790e9 100644 --- a/src/gig_util.h +++ b/src/gig_util.h @@ -24,13 +24,16 @@ G_BEGIN_DECLS // *INDENT-ON* +#define MALLOC __attribute__((malloc)) +MALLOC void *xcalloc(size_t nmemb, size_t siz); +MALLOC void *xmalloc(size_t siz); char *xstrdup(const char *S); char *xstrndup(const char *S, size_t siz); +void *xmemdup(const void *mem, size_t len); -G_GNUC_MALLOC gchar *gig_callable_info_make_name(GICallableInfo *info, const gchar *prefix); +MALLOC gchar *gig_callable_info_make_name(GICallableInfo *info, const gchar *prefix); const gchar *gig_constant_strip_prefix(const gchar *name, const gchar *strip_prefix); gchar *gig_gname_to_scm_name(const gchar *gname); -void *gig_memdup(const void *mem, size_t len); SCM scm_c_list_ref(SCM list, gsize k); gboolean scm_is_list(SCM obj); gsize scm_c_length(SCM list); diff --git a/src/gig_value.c b/src/gig_value.c index 53f6765c..c963faa1 100644 --- a/src/gig_value.c +++ b/src/gig_value.c @@ -488,7 +488,7 @@ SCM gig_value_transform(SCM val, SCM type) { GValue *old_val = gig_type_peek_typed_object(val, gig_value_type); - GValue *new_val = g_new0(GValue, 1); + GValue *new_val = xcalloc(1, sizeof(GValue)); g_value_init(new_val, scm_to_gtype(type)); if (g_value_transform(old_val, new_val)) return gig_type_transfer_object(G_TYPE_VALUE, new_val, GI_TRANSFER_EVERYTHING);