[gjs/generalised-array-args] Generalise array input arguments
- From: Chris Lord <chrisl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/generalised-array-args] Generalise array input arguments
- Date: Tue, 16 Feb 2010 08:47:39 +0000 (UTC)
commit 8101b9281ddb8869954e3eb4d21522d2370156ed
Author: Chris Lord <chris linux intel com>
Date: Tue Feb 16 08:44:49 2010 +0000
Generalise array input arguments
Patch by Johan Dahlin <johan gnome org>
Generalise array input arguments instead of special casing particular
array types. Based on a patch by Johan, updated to apply against trunk
and work with arrays of GValue.
gi/arg.c | 397 +++++++++++++++++++++++++++++++--------------------------
gi/arg.h | 15 ++-
gi/boxed.c | 3 +-
gi/function.c | 4 +
gi/value.c | 10 +-
5 files changed, 237 insertions(+), 192 deletions(-)
---
diff --git a/gi/arg.c b/gi/arg.c
index 7772392..517f829 100644
--- a/gi/arg.c
+++ b/gi/arg.c
@@ -29,6 +29,7 @@
#include "union.h"
#include "value.h"
#include <gjs/gjs.h>
+#include <girffi.h>
#include <util/log.h>
@@ -255,6 +256,7 @@ gjs_array_to_g_list(JSContext *context,
if (!gjs_value_to_g_argument(context,
elem,
param_info,
+ g_type_info_get_tag (param_info),
NULL,
GJS_ARGUMENT_LIST_ELEMENT,
transfer,
@@ -333,7 +335,8 @@ gjs_object_to_g_hash(JSContext *context,
goto free_hash_and_fail;
/* Type check key type. */
- if (!gjs_value_to_g_argument(context, key_js, key_param_info, NULL,
+ if (!gjs_value_to_g_argument(context, key_js, key_param_info,
+ g_type_info_get_tag (key_param_info), NULL,
GJS_ARGUMENT_HASH_ELEMENT,
transfer,
FALSE /* don't allow null */,
@@ -349,7 +352,8 @@ gjs_object_to_g_hash(JSContext *context,
#endif
/* Type check and convert value to a c type */
- if (!gjs_value_to_g_argument(context, val_js, val_param_info, NULL,
+ if (!gjs_value_to_g_argument(context, val_js, val_param_info,
+ g_type_info_get_tag (val_param_info), NULL,
GJS_ARGUMENT_HASH_ELEMENT,
transfer,
TRUE /* allow null */,
@@ -371,47 +375,6 @@ gjs_object_to_g_hash(JSContext *context,
return JS_FALSE;
}
-JSBool
-gjs_array_to_strv(JSContext *context,
- jsval array_value,
- unsigned int length,
- void **arr_p)
-{
- char **result;
- guint32 i;
-
- result = g_new0(char *, length+1);
-
- for (i = 0; i < length; ++i) {
- jsval elem;
-
- elem = JSVAL_VOID;
- if (!JS_GetElement(context, JSVAL_TO_OBJECT(array_value),
- i, &elem)) {
- g_free(result);
- gjs_throw(context,
- "Missing array element %u",
- i);
- return JS_FALSE;
- }
-
- if (!JSVAL_IS_STRING(elem)) {
- gjs_throw(context,
- "Invalid element in string array");
- g_strfreev(result);
- return JS_FALSE;
- }
- if (!gjs_string_to_utf8(context, elem, (char **)&(result[i]))) {
- g_strfreev(result);
- return JS_FALSE;
- }
- }
-
- *arr_p = result;
-
- return JS_TRUE;
-}
-
static JSBool
gjs_string_to_intarray(JSContext *context,
jsval string_val,
@@ -451,103 +414,138 @@ gjs_string_to_intarray(JSContext *context,
}
}
-static JSBool
-gjs_array_to_intarray(JSContext *context,
- jsval array_value,
- unsigned int length,
- void **arr_p,
- unsigned intsize,
- gboolean is_signed)
+static GType
+gjs_interface_get_gvalue (GIBaseInfo *interface_info)
{
- /* nasty union types in an attempt to unify the various int types */
- union { guint32 u; gint32 i; } intval;
- union { guint8 u8[0]; guint16 u16[0]; guint32 u32[0]; } *result;
- unsigned i;
+ GType gtype;
+ GIInfoType interface_type;
+
+ interface_type = g_base_info_get_type(interface_info);
+
+ switch(interface_type) {
+
+ case GI_INFO_TYPE_STRUCT:
+ case GI_INFO_TYPE_ENUM:
+ case GI_INFO_TYPE_OBJECT:
+ case GI_INFO_TYPE_INTERFACE:
+ case GI_INFO_TYPE_UNION:
+ case GI_INFO_TYPE_BOXED:
+ /* These are subtypes of GIRegisteredTypeInfo for which the
+ * cast is safe */
+ gtype = g_registered_type_info_get_g_type
+ ((GIRegisteredTypeInfo*)interface_info);
+ break;
- result = g_malloc0(length * intsize);
+ case GI_INFO_TYPE_VALUE:
+ /* Special case for GValues */
+ gtype = G_TYPE_VALUE;
+ break;
- for (i = 0; i < length; ++i) {
- jsval elem;
- JSBool success;
+ default:
+ /* Everything else */
+ gtype = G_TYPE_NONE;
+ break;
+ }
- elem = JSVAL_VOID;
- if (!JS_GetElement(context, JSVAL_TO_OBJECT(array_value),
- i, &elem)) {
- g_free(result);
- gjs_throw(context,
- "Missing array element %u",
- i);
- return JS_FALSE;
- }
+ return gtype;
+}
- /* do whatever sign extension is appropriate */
- success = (is_signed) ?
- JS_ValueToECMAInt32(context, elem, &(intval.i)) :
- JS_ValueToECMAUint32(context, elem, &(intval.u));
+JSBool
+gjs_array_to_array(JSContext *context,
+ jsval array_value,
+ unsigned int length,
+ GITypeTag param_type_tag,
+ GITypeInfo *param_info,
+ gboolean zero_terminated,
+ void **arguments_p)
+{
+ guint32 alloc_size, i, j, type_size;
+ jsval elem;
+ void *tmp;
+ gboolean copy_back = FALSE;
+ gboolean failed = FALSE;
+ JSObject *array;
+ ffi_type *ftype;
- if (!success) {
- g_free(result);
- gjs_throw(context,
- "Invalid element in string array");
- return JS_FALSE;
- }
- /* Note that this is truncating assignment. */
- switch (intsize) {
- case 1:
- result->u8[i] = (gint8) intval.u; break;
- case 2:
- result->u16[i] = (gint16) intval.u; break;
- case 4:
- result->u32[i] = (gint32) intval.u; break;
- default:
- g_assert_not_reached();
+ ftype = g_ir_ffi_get_ffi_type (param_type_tag);
+ array = JSVAL_TO_OBJECT(array_value);
+
+ alloc_size = length;
+ if (zero_terminated)
+ alloc_size += 1;
+
+ type_size = ftype->size;
+
+ /* Special case GValue - note, this might need to be done for other
+ * types that are marked as interfaces (e.g. structs), but this needs
+ * some investigation.
+ */
+ if (param_type_tag == GI_TYPE_TAG_INTERFACE) {
+ GType gtype;
+ GIBaseInfo *interface_info = g_type_info_get_interface(param_info);
+
+ g_assert(interface_info != NULL);
+
+ gtype = gjs_interface_get_gvalue (interface_info);
+
+ if (gtype == G_TYPE_VALUE) {
+ type_size = sizeof (GValue);
+ copy_back = TRUE;
}
}
- *arr_p = result;
+ tmp = g_malloc0(alloc_size * type_size);
- return JS_TRUE;
-}
+ for (i = 0; i < length; ++i) {
+ elem = JSVAL_VOID;
+ if (!JS_GetElement(context, array, i, &elem)) {
+ gjs_throw(context, "Missing array element %u", i);
+ failed = TRUE;
+ break;
+ }
-static JSBool
-gjs_array_to_array(JSContext *context,
- jsval array_value,
- unsigned int length,
- GITypeInfo *param_info,
- void **arr_p)
-{
- enum { UNSIGNED=FALSE, SIGNED=TRUE };
- GITypeTag element_type;
+ if (!gjs_value_to_g_argument(context,
+ elem,
+ param_info,
+ param_type_tag,
+ "element argument",
+ GJS_ARGUMENT_ARGUMENT,
+ FALSE,
+ TRUE,
+ (void*)((guchar*)tmp + i * type_size))) {
+ /* exception already set */
+ failed = TRUE;
+ break;
+ } else if (copy_back) {
+ GArgument *arg = (GArgument *)((guchar *)tmp + i * type_size);
+ GValue *gvalue = arg->v_pointer;
+ GValue gvalue_copy = *gvalue;
- element_type = g_type_info_get_tag(param_info);
- element_type = normalize_int_types(element_type);
+ /* FIXME: This kind of relies on the knowledge that the GValue
+ * boxed type copy func uses g_new...?
+ */
+ g_free (arg->v_pointer);
- switch (element_type) {
- case GI_TYPE_TAG_UTF8:
- return gjs_array_to_strv (context, array_value, length, arr_p);
- case GI_TYPE_TAG_UINT8:
- return gjs_array_to_intarray
- (context, array_value, length, arr_p, 1, UNSIGNED);
- case GI_TYPE_TAG_INT8:
- return gjs_array_to_intarray
- (context, array_value, length, arr_p, 1, SIGNED);
- case GI_TYPE_TAG_UINT16:
- return gjs_array_to_intarray
- (context, array_value, length, arr_p, 2, UNSIGNED);
- case GI_TYPE_TAG_INT16:
- return gjs_array_to_intarray
- (context, array_value, length, arr_p, 2, SIGNED);
- case GI_TYPE_TAG_UINT32:
- return gjs_array_to_intarray
- (context, array_value, length, arr_p, 4, UNSIGNED);
- case GI_TYPE_TAG_INT32:
- return gjs_array_to_intarray
- (context, array_value, length, arr_p, 4, SIGNED);
- default:
- gjs_throw(context,
- "Unhandled array element type %d", element_type);
+ gvalue = (GValue *)arg;
+ *((GValue *)arg) = gvalue_copy;
+ }
+ }
+
+ if (failed) {
+ for (j = 0; j < i; ++j) {
+ gjs_g_argument_release(context,
+ 0, /* FIXME, JS_GetElement */
+ GI_TRANSFER_EVERYTHING,
+ param_info,
+ (void*)((guchar*)tmp + i * type_size));
+ }
+ g_free(tmp);
return JS_FALSE;
}
+
+ *arguments_p = tmp;
+
+ return JS_TRUE;
}
static gchar *
@@ -574,19 +572,18 @@ JSBool
gjs_value_to_g_argument(JSContext *context,
jsval value,
GITypeInfo *type_info,
+ GITypeTag type_tag,
const char *arg_name,
GjsArgumentType arg_type,
GITransfer transfer,
gboolean may_be_null,
GArgument *arg)
{
- GITypeTag type_tag;
gboolean wrong;
gboolean out_of_range;
gboolean report_type_mismatch;
gboolean nullable_type;
- type_tag = g_type_info_get_tag( (GITypeInfo*) type_info);
if (type_tag != GI_TYPE_TAG_TIME_T) // we handle time_t as a non-int type
type_tag = normalize_int_types(type_tag);
@@ -747,35 +744,12 @@ gjs_value_to_g_argument(JSContext *context,
GIInfoType interface_type;
GType gtype;
+ g_assert (type_info != NULL);
interface_info = g_type_info_get_interface(type_info);
g_assert(interface_info != NULL);
interface_type = g_base_info_get_type(interface_info);
-
- switch(interface_type) {
-
- case GI_INFO_TYPE_STRUCT:
- case GI_INFO_TYPE_ENUM:
- case GI_INFO_TYPE_OBJECT:
- case GI_INFO_TYPE_INTERFACE:
- case GI_INFO_TYPE_UNION:
- case GI_INFO_TYPE_BOXED:
- /* These are subtypes of GIRegisteredTypeInfo for which the
- * cast is safe */
- gtype = g_registered_type_info_get_g_type
- ((GIRegisteredTypeInfo*)interface_info);
- break;
-
- case GI_INFO_TYPE_VALUE:
- /* Special case for GValues */
- gtype = G_TYPE_VALUE;
- break;
-
- default:
- /* Everything else */
- gtype = G_TYPE_NONE;
- break;
- }
+ gtype = gjs_interface_get_gvalue (interface_info);
if (gtype != G_TYPE_NONE)
gjs_debug_marshal(GJS_DEBUG_GFUNCTION,
@@ -942,6 +916,7 @@ gjs_value_to_g_argument(JSContext *context,
GSList *slist;
GITypeInfo *param_info;
+ g_assert(type_info != NULL);
param_info = g_type_info_get_param_type(type_info, 0);
g_assert(param_info != NULL);
@@ -1043,11 +1018,16 @@ gjs_value_to_g_argument(JSContext *context,
wrong = TRUE;
} else {
GITypeInfo *param_info;
-
+ gboolean zero_terminated;
+
+ g_assert(type_info != NULL);
param_info = g_type_info_get_param_type(type_info, 0);
g_assert(param_info != NULL);
-
- if (!gjs_array_to_array (context, value, length, param_info, &arg->v_pointer))
+ zero_terminated = g_type_info_is_zero_terminated(type_info);
+ if (!gjs_array_to_array (context, value, length,
+ g_type_info_get_tag (param_info),
+ param_info, zero_terminated,
+ &arg->v_pointer))
wrong = TRUE;
g_base_info_unref((GIBaseInfo*) param_info);
@@ -1127,6 +1107,7 @@ gjs_value_to_arg(JSContext *context,
result =
gjs_value_to_g_argument(context, value,
type_info,
+ g_type_info_get_tag (type_info),
g_base_info_get_name( (GIBaseInfo*) arg_info),
(g_arg_info_is_return_value(arg_info) ?
GJS_ARGUMENT_RETURN_VALUE : GJS_ARGUMENT_ARGUMENT),
@@ -1591,6 +1572,7 @@ gjs_value_from_g_argument (JSContext *context,
}
static JSBool gjs_g_arg_release_internal(JSContext *context,
+ jsval value,
GITransfer transfer,
GITypeInfo *type_info,
GITypeTag type_tag,
@@ -1609,13 +1591,14 @@ gjs_ghr_helper(gpointer key, gpointer val, gpointer user_data) {
GArgument key_arg, val_arg;
key_arg.v_pointer = key;
val_arg.v_pointer = val;
- if (!gjs_g_arg_release_internal(c->context, c->transfer,
+ /* FIXME: Should values be zero here? */
+ if (!gjs_g_arg_release_internal(c->context, 0, c->transfer,
c->key_param_info,
g_type_info_get_tag(c->key_param_info),
&key_arg))
c->failed = JS_TRUE;
- if (!gjs_g_arg_release_internal(c->context, c->transfer,
+ if (!gjs_g_arg_release_internal(c->context, 0, c->transfer,
c->val_param_info,
g_type_info_get_tag(c->val_param_info),
&val_arg))
@@ -1631,6 +1614,7 @@ gjs_ghr_helper(gpointer key, gpointer val, gpointer user_data) {
static JSBool
gjs_g_arg_release_internal(JSContext *context,
+ jsval value,
GITransfer transfer,
GITypeInfo *type_info,
GITypeTag type_tag,
@@ -1706,10 +1690,10 @@ gjs_g_arg_release_internal(JSContext *context,
g_closure_unref(arg->v_pointer);
} else if (g_type_is_a(gtype, G_TYPE_VALUE)) {
/* G_TYPE_VALUE is-a G_TYPE_BOXED, but we special case it */
- g_boxed_free(gtype, arg->v_pointer);
+ /*g_boxed_free(gtype, arg->v_pointer);*/
} else if (g_type_is_a(gtype, G_TYPE_BOXED)) {
- if (transfer != TRANSFER_IN_NOTHING)
- g_boxed_free(gtype, arg->v_pointer);
+ /*if (transfer != TRANSFER_IN_NOTHING)
+ g_boxed_free(gtype, arg->v_pointer);*/
} else if (gtype == G_TYPE_NONE) {
if (transfer != TRANSFER_IN_NOTHING) {
gjs_throw(context, "Don't know how to release GArgument: not an object or boxed type");
@@ -1741,6 +1725,7 @@ gjs_g_arg_release_internal(JSContext *context,
elem.v_pointer = list->data;
if (!gjs_g_arg_release_internal(context,
+ 0, /* FIXME: JS_Getelement */
transfer,
param_info,
g_type_info_get_tag(param_info),
@@ -1760,35 +1745,78 @@ gjs_g_arg_release_internal(JSContext *context,
/* OK */
} else {
GITypeInfo *param_info;
- GITypeTag element_type;
+ void *arguments = arg->v_pointer;
+ GITypeTag param_type_tag;
+ ffi_type *ftype;
+ jsval length_value;
+ guint32 length;
+ unsigned int i;
+ gboolean zero_terminated;
param_info = g_type_info_get_param_type(type_info, 0);
- element_type = g_type_info_get_tag(param_info);
- element_type = normalize_int_types(element_type);
-
- switch (element_type) {
- case GI_TYPE_TAG_UTF8:
- case GI_TYPE_TAG_FILENAME:
- if (transfer == GI_TRANSFER_CONTAINER)
- g_free(arg->v_pointer);
- else if (transfer == GI_TRANSFER_EVERYTHING)
- g_strfreev (arg->v_pointer);
- break;
+ param_type_tag = g_type_info_get_tag(param_info);
+
+ if (param_type_tag == GI_TYPE_TAG_UTF8 ||
+ param_type_tag == GI_TYPE_TAG_FILENAME)
+ gjs_debug_marshal(GJS_DEBUG_MEMORY,
+ "Releasing memory for string arrays is "
+ "not properly implement. Leaking.");
- case GI_TYPE_TAG_UINT8:
- case GI_TYPE_TAG_UINT16:
- case GI_TYPE_TAG_UINT32:
- case GI_TYPE_TAG_INT8:
- case GI_TYPE_TAG_INT16:
- case GI_TYPE_TAG_INT32:
- g_free (arg->v_pointer);
+ ftype = g_type_info_get_ffi_type (param_info);
+
+ if (!gjs_object_require_property(context,
+ JSVAL_TO_OBJECT(value), NULL,
+ "length",
+ &length_value) ||
+ !JS_ValueToECMAUint32(context, length_value, &length)) {
+ g_error("Failed to release list element");
break;
+ }
- default:
- g_assert_not_reached ();
+ /* FIXME: Special case GValue (see gjs_array_to_array) - may need
+ * to do this for other types too, not sure.
+ */
+ if (param_type_tag == GI_TYPE_TAG_INTERFACE) {
+ GType gtype;
+ GIBaseInfo *interface_info = g_type_info_get_interface(param_info);
+
+ g_assert(interface_info != NULL);
+
+ gtype = gjs_interface_get_gvalue (interface_info);
+
+ if (gtype == G_TYPE_VALUE) {
+ for (i = 0; i < length; ++i) {
+ GValue *gvalue = (GValue *)
+ (((guchar*)arguments) + i * sizeof (GValue));
+ g_value_unset (gvalue);
+ }
+ g_free (arguments);
+ break;
+ }
}
+ zero_terminated = g_type_info_is_zero_terminated(type_info);
+ if (zero_terminated)
+ length += 1;
+
+ for (i = 0; i < length; ++i) {
+ /* FIXME: Special case GValue for now - see
+ * gjs_array_to_array
+ */
+ if (!gjs_g_argument_release(context,
+ 0, /* FIXME, JS_GetElement */
+ GI_TRANSFER_EVERYTHING,
+ param_info,
+ (void*)(((guchar*)arguments) + i * ftype->size))) {
+ /* no way to recover here, and errors should
+ * not be possible.
+ */
+ g_error("Failed to release list element");
+ break;
+ }
+ }
g_base_info_unref((GIBaseInfo*) param_info);
+ g_free (arguments);
}
break;
@@ -1807,6 +1835,7 @@ gjs_g_arg_release_internal(JSContext *context,
elem.v_pointer = slist->data;
if (!gjs_g_arg_release_internal(context,
+ 0, /* FIXME: JS_GetElement */
transfer,
param_info,
g_type_info_get_tag(param_info),
@@ -1862,6 +1891,7 @@ gjs_g_arg_release_internal(JSContext *context,
JSBool
gjs_g_argument_release(JSContext *context,
+ jsval value,
GITransfer transfer,
GITypeInfo *type_info,
GArgument *arg)
@@ -1877,11 +1907,12 @@ gjs_g_argument_release(JSContext *context,
"Releasing GArgument %s out param or return value",
g_type_tag_to_string(type_tag));
- return gjs_g_arg_release_internal(context, transfer, type_info, type_tag, arg);
+ return gjs_g_arg_release_internal(context, value, transfer, type_info, type_tag, arg);
}
JSBool
gjs_g_argument_release_in_arg(JSContext *context,
+ jsval value,
GITransfer transfer,
GITypeInfo *type_info,
GArgument *arg)
@@ -1904,7 +1935,7 @@ gjs_g_argument_release_in_arg(JSContext *context,
g_type_tag_to_string(type_tag));
if (type_needs_release (type_info, type_tag))
- return gjs_g_arg_release_internal(context, TRANSFER_IN_NOTHING,
+ return gjs_g_arg_release_internal(context, value, TRANSFER_IN_NOTHING,
type_info, type_tag, arg);
return JS_TRUE;
diff --git a/gi/arg.h b/gi/arg.h
index 28619f3..4a0bd33 100644
--- a/gi/arg.h
+++ b/gi/arg.h
@@ -49,6 +49,7 @@ JSBool gjs_value_to_arg (JSContext *context,
JSBool gjs_value_to_g_argument (JSContext *context,
jsval value,
GITypeInfo *type_info,
+ GITypeTag type_tag,
const char *arg_name,
GjsArgumentType argument_type,
GITransfer transfer,
@@ -60,10 +61,12 @@ JSBool gjs_value_from_g_argument (JSContext *context,
GITypeInfo *type_info,
GArgument *arg);
JSBool gjs_g_argument_release (JSContext *context,
+ jsval value,
GITransfer transfer,
GITypeInfo *type_info,
GArgument *arg);
JSBool gjs_g_argument_release_in_arg (JSContext *context,
+ jsval value,
GITransfer transfer,
GITypeInfo *type_info,
GArgument *arg);
@@ -72,11 +75,13 @@ JSBool _gjs_flags_value_is_valid (JSContext *context,
GType gtype,
guint value);
-
-JSBool gjs_array_to_strv (JSContext *context,
- jsval array_value,
- unsigned int length,
- void **arr_p);
+JSBool gjs_array_to_array (JSContext *context,
+ jsval array_value,
+ unsigned int length,
+ GITypeTag param_type_tag,
+ GITypeInfo *param_info,
+ gboolean zero_terminated,
+ void **arguments);
G_END_DECLS
diff --git a/gi/boxed.c b/gi/boxed.c
index f1cdbf8..8d5984c 100644
--- a/gi/boxed.c
+++ b/gi/boxed.c
@@ -808,6 +808,7 @@ boxed_set_field_from_value(JSContext *context,
if (!gjs_value_to_g_argument(context, value,
type_info,
+ g_type_info_get_tag (type_info),
g_base_info_get_name ((GIBaseInfo *)field_info),
GJS_ARGUMENT_FIELD,
GI_TRANSFER_NOTHING,
@@ -827,7 +828,7 @@ boxed_set_field_from_value(JSContext *context,
out:
if (need_release)
- gjs_g_argument_release (context, GI_TRANSFER_NOTHING,
+ gjs_g_argument_release (context, value, GI_TRANSFER_NOTHING,
type_info,
&arg);
diff --git a/gi/function.c b/gi/function.c
index 09bb09f..2bacfde 100644
--- a/gi/function.c
+++ b/gi/function.c
@@ -208,6 +208,7 @@ gjs_callback_closure(ffi_cif *cif,
if (!gjs_value_to_g_argument(invoke_info->context,
rval,
ret_type,
+ g_type_info_get_tag (ret_type),
"callback",
GJS_ARGUMENT_RETURN_VALUE,
FALSE,
@@ -721,6 +722,7 @@ gjs_invoke_c_function(JSContext *context,
/* Free GArgument, the jsval should have ref'd or copied it */
if (invoke_ok &&
!gjs_g_argument_release(context,
+ return_values[next_rval],
g_callable_info_get_caller_owns((GICallableInfo*) info),
return_info,
&return_arg))
@@ -750,6 +752,7 @@ gjs_invoke_c_function(JSContext *context,
g_assert(in_args_pos < expected_in_argc + destroy_notify_argc);
if (!gjs_g_argument_release_in_arg(context,
+ argv[i],
g_arg_info_get_ownership_transfer(arg_info),
arg_type_info,
&in_args[in_args_pos]))
@@ -774,6 +777,7 @@ gjs_invoke_c_function(JSContext *context,
/* Free GArgument, the jsval should have ref'd or copied it */
if (invoke_ok &&
!gjs_g_argument_release(context,
+ argv[i],
g_arg_info_get_ownership_transfer(arg_info),
arg_type_info,
out_args[out_args_pos].v_pointer))
diff --git a/gi/value.c b/gi/value.c
index ab80ac9..d014e5b 100644
--- a/gi/value.c
+++ b/gi/value.c
@@ -355,9 +355,13 @@ gjs_value_to_g_value_internal(JSContext *context,
void *result;
char **strv;
- if (!gjs_array_to_strv (context,
- value,
- length, &result))
+ if (!gjs_array_to_array (context,
+ value,
+ length,
+ GI_TYPE_TAG_UTF8,
+ NULL,
+ TRUE,
+ (void **)&strv))
return JS_FALSE;
/* cast to strv in a separate step to avoid type-punning */
strv = result;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]