[gjs/gnome-3-38] function: Early-initialize arguments cache or we won't ever release them
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/gnome-3-38] function: Early-initialize arguments cache or we won't ever release them
- Date: Sat, 12 Sep 2020 19:43:42 +0000 (UTC)
commit e85fb9059d45c43ea621e036986e6488ef3f30e2
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Mon Sep 7 19:42:49 2020 +0200
function: Early-initialize arguments cache or we won't ever release them
If we throw during the arguments cache creation as we fail during an early
stage of init_cached_function_data, we don't save the function GICallableInfo
or the already allocated parameters, but we'd just return loosing
track of allocated data.
This is not just a potential leak, but also wrong as if a method
introspection is malformed or not fully supported by gjs, we'd just
assert crashing badly during function unallocation because no function
info is set, instead of just throwing as expected.
As per this, let's save the function private informations (such as the
callable info and the arguments cache) as soon as we allocate them,
and update the number of initialized arguments in real time, so that
we can partially de-allocate the arguments cache in case of errors.
This also implies that during function de-init we must ensure that
we don't overflow using the marshallers pointer to check if we've ever
initialized such argument cache and to figure out how many we've allocated
other than of the total number of the introspected function arguments.
gi/function.cpp | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
---
diff --git a/gi/function.cpp b/gi/function.cpp
index 1b065b598..68919a597 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -1066,8 +1066,15 @@ uninit_cached_function_data (Function *function)
// Careful! function->arguments is offset by one or two elements inside
// the allocated space, so we have to free index -1 or -2.
int start_index = g_callable_info_is_method(function->info) ? -2 : -1;
- int gi_argc = g_callable_info_get_n_args(function->info);
- for (int ix = start_index; ix < gi_argc; ix++) {
+ int gi_argc = MIN(g_callable_info_get_n_args(function->info),
+ function->js_in_argc + function->js_out_argc);
+
+ for (int i = 0; i < gi_argc; i++) {
+ int ix = start_index + i;
+
+ if (!function->arguments[ix].marshallers)
+ break;
+
if (function->arguments[ix].marshallers->free)
function->arguments[ix].marshallers->free(
&function->arguments[ix]);
@@ -1242,6 +1249,11 @@ init_cached_function_data (JSContext *context,
GjsArgumentCache* arguments =
g_new0(GjsArgumentCache, n_args + offset) + offset;
+ function->arguments = arguments;
+ function->info = g_base_info_ref(info);
+ function->js_in_argc = 0;
+ function->js_out_argc = 0;
+
if (is_method &&
!gjs_arg_cache_build_instance(context, &arguments[-2], info))
return false;
@@ -1251,8 +1263,7 @@ init_cached_function_data (JSContext *context,
&inc_counter))
return false;
- int out_argc = inc_counter ? 1 : 0;
- int in_argc = 0;
+ function->js_out_argc = inc_counter ? 1 : 0;
for (i = 0; i < n_args; i++) {
GIDirection direction;
@@ -1271,13 +1282,13 @@ init_cached_function_data (JSContext *context,
if (inc_counter) {
switch (direction) {
case GI_DIRECTION_INOUT:
- out_argc++;
+ function->js_out_argc++;
[[fallthrough]];
case GI_DIRECTION_IN:
- in_argc++;
+ function->js_in_argc++;
break;
case GI_DIRECTION_OUT:
- out_argc++;
+ function->js_out_argc++;
break;
default:
g_assert_not_reached();
@@ -1285,14 +1296,6 @@ init_cached_function_data (JSContext *context,
}
}
- function->arguments = arguments;
-
- function->js_in_argc = in_argc;
- function->js_out_argc = out_argc;
- function->info = info;
-
- g_base_info_ref((GIBaseInfo*) function->info);
-
return true;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]