[gjs: 2/4] function: Split finishing function invocation phase to another function
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 2/4] function: Split finishing function invocation phase to another function
- Date: Sun, 31 Jan 2021 05:54:31 +0000 (UTC)
commit 93b724069fd429478d0659a7d0e6ce630e4fc37f
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date: Mon Oct 26 17:18:06 2020 +0100
function: Split finishing function invocation phase to another function
We can now avoid using goto (that for example blocks using const&
references), so that all the values we want to bring around are in the
call state struct (so that also the cache might take advantage of them).
gi/function.cpp | 55 ++++++++++++++++++++++++++++++++-----------------------
1 file changed, 32 insertions(+), 23 deletions(-)
---
diff --git a/gi/function.cpp b/gi/function.cpp
index 0d2933e2..8922332c 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -114,6 +114,11 @@ class Function : public CWrapper<Function> {
GJS_JSAPI_RETURN_CONVENTION
bool to_string_impl(JSContext* cx, JS::MutableHandleValue rval);
+ GJS_JSAPI_RETURN_CONVENTION
+ bool finish_invoke(JSContext* cx, const JS::CallArgs& args,
+ GjsFunctionCallState* state,
+ GIArgument* r_value = nullptr);
+
GJS_JSAPI_RETURN_CONVENTION
static JSObject* inherit_builtin_function(JSContext* cx, JSProtoKey) {
JS::RootedObject builtin_function_proto(
@@ -930,9 +935,8 @@ bool Function::invoke(JSContext* context, const JS::CallArgs& args,
/* Did argument conversion fail? In that case, skip invocation and jump to release
* processing. */
- if (state.failed) {
- goto release;
- }
+ if (state.failed)
+ return finish_invoke(context, args, &state, r_value);
if (state.can_throw_gerror) {
g_assert(ffi_arg_pos < ffi_argc && "GError** argument number mismatch");
@@ -997,35 +1001,39 @@ bool Function::invoke(JSContext* context, const JS::CallArgs& args,
g_assert(state.failed || state.did_throw_gerror() ||
js_arg_pos == m_js_out_argc);
-release:
// If we failed before calling the function, or if the function threw an
// exception, then any GI_TRANSFER_EVERYTHING or GI_TRANSFER_CONTAINER
// in-parameters were not transferred. Treat them as GI_TRANSFER_NOTHING so
// that they are freed.
+ return finish_invoke(context, args, &state, r_value);
+}
+bool Function::finish_invoke(JSContext* cx, const JS::CallArgs& args,
+ GjsFunctionCallState* state,
+ GIArgument* r_value /* = nullptr */) {
// In this loop we use ffi_arg_pos just to ensure we don't release stuff
// we haven't allocated yet, if we failed in type conversion above.
// If we start from -1 (the return value), we need to process 1 more than
// state.processed_c_args.
// If we start from -2 (the instance parameter), we need to process 2 more
- ffi_arg_pos = state.first_arg_offset() - 1;
- unsigned ffi_arg_max = state.processed_c_args + state.first_arg_offset();
+ unsigned ffi_arg_pos = state->first_arg_offset() - 1;
+ unsigned ffi_arg_max = state->processed_c_args + state->first_arg_offset();
bool postinvoke_release_failed = false;
- for (int gi_arg_pos = -(state.first_arg_offset());
- gi_arg_pos < state.gi_argc && ffi_arg_pos < ffi_arg_max;
+ for (int gi_arg_pos = -(state->first_arg_offset());
+ gi_arg_pos < state->gi_argc && ffi_arg_pos < ffi_arg_max;
gi_arg_pos++, ffi_arg_pos++) {
GjsArgumentCache* cache = &m_arguments[gi_arg_pos];
- GIArgument* in_value = &state.in_cvalues[gi_arg_pos];
- GIArgument* out_value = &state.out_cvalues[gi_arg_pos];
+ GIArgument* in_value = &state->in_cvalues[gi_arg_pos];
+ GIArgument* out_value = &state->out_cvalues[gi_arg_pos];
gjs_debug_marshal(
GJS_DEBUG_GFUNCTION,
"Releasing argument '%s', %d/%d GI args, %u/%u C args",
- cache->arg_name, gi_arg_pos, state.gi_argc, ffi_arg_pos,
- state.processed_c_args);
+ cache->arg_name, gi_arg_pos, state->gi_argc, ffi_arg_pos,
+ state->processed_c_args);
// Only process in or inout arguments if we failed, the rest is garbage
- if (state.failed && cache->skip_in())
+ if (state->failed && cache->skip_in())
continue;
// Save the return GIArgument if it was requested
@@ -1034,7 +1042,7 @@ release:
continue;
}
- if (!cache->marshallers->release(context, cache, &state, in_value,
+ if (!cache->marshallers->release(cx, cache, state, in_value,
out_value)) {
postinvoke_release_failed = true;
// continue with the release even if we fail, to avoid leaks
@@ -1042,29 +1050,30 @@ release:
}
if (postinvoke_release_failed)
- state.failed = true;
+ state->failed = true;
- g_assert(ffi_arg_pos == state.processed_c_args + state.first_arg_offset());
+ g_assert(ffi_arg_pos ==
+ state->processed_c_args + state->first_arg_offset());
- if (!r_value && m_js_out_argc > 0 && state.call_completed()) {
+ if (!r_value && m_js_out_argc > 0 && state->call_completed()) {
// If we have one return value or out arg, return that item on its
// own, otherwise return a JavaScript array with [return value,
// out arg 1, out arg 2, ...]
if (m_js_out_argc == 1) {
- args.rval().set(state.return_values[0]);
+ args.rval().set(state->return_values[0]);
} else {
- JSObject* array = JS::NewArrayObject(context, state.return_values);
+ JSObject* array = JS::NewArrayObject(cx, state->return_values);
if (!array) {
- state.failed = true;
+ state->failed = true;
} else {
args.rval().setObject(*array);
}
}
}
- if (!state.failed && state.did_throw_gerror()) {
- return gjs_throw_gerror(context, state.local_error);
- } else if (state.failed) {
+ if (!state->failed && state->did_throw_gerror()) {
+ return gjs_throw_gerror(cx, state->local_error);
+ } else if (state->failed) {
return false;
} else {
return true;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]