[gjs] js: Root throw_invalid_argument() in arg.cpp
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs] js: Root throw_invalid_argument() in arg.cpp
- Date: Fri, 28 Oct 2016 01:12:29 +0000 (UTC)
commit 6864b3ffcafc09eb16124d83ab66417468b0d5dc
Author: Philip Chimento <philip endlessm com>
Date: Thu Oct 27 16:55:48 2016 -0700
js: Root throw_invalid_argument() in arg.cpp
Starting in throw_invalid_argument() and working backwards, we cause
another cascade of GC rooting changes.
This, by necessity, adds a couple of unnecessary roots in
gjs_invoke_c_function() which is quite unfortunate. (Eventually the vp
array comes from a JS::CallArgs somewhere, which is rooted, so we should
not have to re-root any of its values.) In mozjs31, we will be able to
remove these again, because it introduces JS::HandleValueArray for
passing around references to arrays of rooted values.
https://bugzilla.gnome.org/show_bug.cgi?id=742249
gi/arg.cpp | 42 +++++++++++++++++++++---------------------
gi/arg.h | 20 ++++++++++----------
gi/boxed.cpp | 16 ++++++++--------
gi/function.cpp | 31 +++++++++++++++++++------------
4 files changed, 58 insertions(+), 51 deletions(-)
---
diff --git a/gi/arg.cpp b/gi/arg.cpp
index 7f9ed7b..93467d9 100644
--- a/gi/arg.cpp
+++ b/gi/arg.cpp
@@ -263,7 +263,6 @@ gjs_array_to_g_list(JSContext *context,
guint32 i;
GList *list;
GSList *slist;
- JS::Value elem;
list = NULL;
slist = NULL;
@@ -282,11 +281,12 @@ gjs_array_to_g_list(JSContext *context,
transfer = GI_TRANSFER_NOTHING;
}
+ JS::RootedValue elem(context);
for (i = 0; i < length; ++i) {
GArgument elem_arg = { 0 };
elem = JS::UndefinedValue();
- if (!JS_GetElement(context, array_value.toObjectOrNull(), i, &elem)) {
+ if (!JS_GetElement(context, array_value.toObjectOrNull(), i, elem.address())) {
gjs_throw(context,
"Missing array element %u",
i);
@@ -368,13 +368,13 @@ gjs_object_to_g_hash(JSContext *context,
/* Don't use key/value destructor functions here, because we can't
* construct correct ones in general if the value type is complex.
* Rely on the type-aware g_argument_release functions. */
- result = g_hash_table_new(g_str_hash, g_str_equal);
+ result = g_hash_table_new(g_str_hash, g_str_equal);
- while (!JSID_IS_VOID(prop_id)) {
- JS::Value key_js, val_js;
+ JS::RootedValue key_js(context), val_js(context);
+ while (!JSID_IS_VOID(prop_id)) {
GArgument key_arg = { 0 }, val_arg = { 0 };
- if (!JS_IdToValue(context, prop_id, &key_js))
+ if (!JS_IdToValue(context, prop_id, key_js.address()))
goto free_hash_and_fail;
/* Type check key type. */
@@ -385,7 +385,7 @@ gjs_object_to_g_hash(JSContext *context,
&key_arg))
goto free_hash_and_fail;
- if (!JS_GetPropertyById(context, props, prop_id, &val_js))
+ if (!JS_GetPropertyById(context, props, prop_id, val_js.address()))
goto free_hash_and_fail;
/* Type check and convert value to a c type */
@@ -715,20 +715,20 @@ gjs_array_to_ptrarray(JSContext *context,
void **arr_p)
{
unsigned int i;
+ JS::RootedValue elem(context);
/* Always one extra element, to cater for null terminated arrays */
void **array = (void **) g_malloc((length + 1) * sizeof(gpointer));
array[length] = NULL;
for (i = 0; i < length; i++) {
- JS::Value elem;
GIArgument arg;
arg.v_pointer = NULL;
bool success;
elem = JS::UndefinedValue();
- if (!JS_GetElement(context, array_value.toObjectOrNull(), i, &elem)) {
+ if (!JS_GetElement(context, array_value.toObjectOrNull(), i, elem.address())) {
g_free(array);
gjs_throw(context,
"Missing array element %u",
@@ -1068,7 +1068,7 @@ type_tag_to_human_string(GITypeInfo *type_info)
static void
throw_invalid_argument(JSContext *context,
- JS::Value value,
+ JS::HandleValue value,
GITypeInfo *arginfo,
const char *arg_name,
GjsArgumentType arg_type)
@@ -1084,7 +1084,7 @@ throw_invalid_argument(JSContext *context,
static bool
gjs_array_to_explicit_array_internal(JSContext *context,
- JS::Value value,
+ JS::HandleValue value,
GITypeInfo *type_info,
const char *arg_name,
GjsArgumentType arg_type,
@@ -1150,7 +1150,7 @@ gjs_array_to_explicit_array_internal(JSContext *context,
bool
gjs_value_to_g_argument(JSContext *context,
- JS::Value value,
+ JS::HandleValue value,
GITypeInfo *type_info,
const char *arg_name,
GjsArgumentType arg_type,
@@ -1944,10 +1944,10 @@ gjs_g_argument_init_default(JSContext *context,
}
bool
-gjs_value_to_arg(JSContext *context,
- JS::Value value,
- GIArgInfo *arg_info,
- GArgument *arg)
+gjs_value_to_arg(JSContext *context,
+ JS::HandleValue value,
+ GIArgInfo *arg_info,
+ GIArgument *arg)
{
GITypeInfo type_info;
@@ -1964,11 +1964,11 @@ gjs_value_to_arg(JSContext *context,
}
bool
-gjs_value_to_explicit_array (JSContext *context,
- JS::Value value,
- GIArgInfo *arg_info,
- GArgument *arg,
- gsize *length_p)
+gjs_value_to_explicit_array (JSContext *context,
+ JS::HandleValue value,
+ GIArgInfo *arg_info,
+ GIArgument *arg,
+ size_t *length_p)
{
GITypeInfo type_info;
diff --git a/gi/arg.h b/gi/arg.h
index a0ab1b6..7c96c2f 100644
--- a/gi/arg.h
+++ b/gi/arg.h
@@ -43,23 +43,23 @@ typedef enum {
GJS_ARGUMENT_ARRAY_ELEMENT
} GjsArgumentType;
-bool gjs_value_to_arg (JSContext *context,
- JS::Value value,
- GIArgInfo *arg_info,
- GArgument *arg);
+bool gjs_value_to_arg(JSContext *context,
+ JS::HandleValue value,
+ GIArgInfo *arg_info,
+ GIArgument *arg);
-bool gjs_value_to_explicit_array (JSContext *context,
- JS::Value value,
- GIArgInfo *arg_info,
- GArgument *arg,
- gsize *length_p);
+bool gjs_value_to_explicit_array(JSContext *context,
+ JS::HandleValue value,
+ GIArgInfo *arg_info,
+ GIArgument *arg,
+ size_t *length_p);
void gjs_g_argument_init_default (JSContext *context,
GITypeInfo *type_info,
GArgument *arg);
bool gjs_value_to_g_argument (JSContext *context,
- JS::Value value,
+ JS::HandleValue value,
GITypeInfo *type_info,
const char *arg_name,
GjsArgumentType argument_type,
diff --git a/gi/boxed.cpp b/gi/boxed.cpp
index 3e035e1..db4eff3 100644
--- a/gi/boxed.cpp
+++ b/gi/boxed.cpp
@@ -60,10 +60,10 @@ typedef struct {
static bool struct_is_simple(GIStructInfo *info);
-static bool boxed_set_field_from_value(JSContext *context,
- Boxed *priv,
- GIFieldInfo *field_info,
- JS::Value value);
+static bool boxed_set_field_from_value(JSContext *context,
+ Boxed *priv,
+ GIFieldInfo *field_info,
+ JS::HandleValue value);
extern struct JSClass gjs_boxed_class;
@@ -733,10 +733,10 @@ set_nested_interface_object (JSContext *context,
}
static bool
-boxed_set_field_from_value(JSContext *context,
- Boxed *priv,
- GIFieldInfo *field_info,
- JS::Value value)
+boxed_set_field_from_value(JSContext *context,
+ Boxed *priv,
+ GIFieldInfo *field_info,
+ JS::HandleValue value)
{
GITypeInfo *type_info;
GArgument arg;
diff --git a/gi/function.cpp b/gi/function.cpp
index dde7ba3..3dff737 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -182,7 +182,6 @@ gjs_callback_closure(ffi_cif *cif,
JSObject *func_obj;
GjsCallbackTrampoline *trampoline;
int i, n_args, n_jsargs, n_outargs;
- JS::Value rval;
JSObject *this_object;
GITypeInfo ret_type;
bool success = false;
@@ -221,6 +220,7 @@ gjs_callback_closure(ffi_cif *cif,
JS::AutoValueVector jsargs(context);
jsargs.resize(n_args);
JS::Value *args_ptr = jsargs.begin();
+ JS::RootedValue rval(context);
for (i = 0, n_jsargs = 0; i < n_args; i++) {
GIArgInfo arg_info;
@@ -294,7 +294,7 @@ gjs_callback_closure(ffi_cif *cif,
trampoline->js_function,
n_jsargs,
args_ptr,
- &rval)) {
+ rval.address())) {
goto out;
}
@@ -345,7 +345,7 @@ gjs_callback_closure(ffi_cif *cif,
break;
}
} else {
- JS::Value elem;
+ JS::RootedValue elem(context);
gsize elem_idx = 0;
/* more than one of a return value or an out argument.
* Should be an array of output values. */
@@ -353,7 +353,7 @@ gjs_callback_closure(ffi_cif *cif,
if (!ret_type_is_void) {
GIArgument argument;
- if (!JS_GetElement(context, rval.toObjectOrNull(), elem_idx, &elem))
+ if (!JS_GetElement(context, rval.toObjectOrNull(), elem_idx, elem.address()))
goto out;
if (!gjs_value_to_g_argument(context,
@@ -381,7 +381,7 @@ gjs_callback_closure(ffi_cif *cif,
continue;
g_arg_info_load_type(&arg_info, &type_info);
- if (!JS_GetElement(context, rval.toObjectOrNull(), elem_idx, &elem))
+ if (!JS_GetElement(context, rval.toObjectOrNull(), elem_idx, elem.address()))
goto out;
if (!gjs_value_to_g_argument(context,
@@ -903,7 +903,10 @@ gjs_invoke_c_function(JSContext *context,
gint array_length_pos = g_type_info_get_array_length(&ainfo);
gsize length;
- if (!gjs_value_to_explicit_array(context, js_argv[js_arg_pos], &arg_info,
+ /* COMPAT: Avoid this extra root by changing the function's
+ * in parameter to JS::HandleValueArray in mozjs31 */
+ JS::RootedValue v_arg(context, js_argv[js_arg_pos]);
+ if (!gjs_value_to_explicit_array(context, v_arg, &arg_info,
in_value, &length)) {
failed = true;
break;
@@ -912,7 +915,8 @@ gjs_invoke_c_function(JSContext *context,
g_callable_info_load_arg(function->info, array_length_pos, &array_length_arg);
array_length_pos += is_method ? 1 : 0;
- if (!gjs_value_to_arg(context, JS::Int32Value(length), &array_length_arg,
+ JS::RootedValue v_length(context, JS::Int32Value(length));
+ if (!gjs_value_to_arg(context, v_length, &array_length_arg,
in_arg_cvalues + array_length_pos)) {
failed = true;
break;
@@ -934,14 +938,17 @@ gjs_invoke_c_function(JSContext *context,
}
break;
}
- case PARAM_NORMAL:
+ case PARAM_NORMAL: {
/* Ok, now just convert argument normally */
g_assert_cmpuint(js_arg_pos, <, js_argc);
- if (!gjs_value_to_arg(context, js_argv[js_arg_pos], &arg_info,
- in_value)) {
+ /* COMPAT: Avoid this extra root by changing the function's
+ * in parameter to JS::HandleValueArray in mozjs31 */
+ JS::RootedValue v_arg(context, js_argv[js_arg_pos]);
+ if (!gjs_value_to_arg(context, v_arg, &arg_info, in_value))
failed = true;
- break;
- }
+
+ break;
+ }
default:
;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]