MCPcopy Create free account
hub / github.com/GNOME/gjs / finish_invoke

Method finish_invoke

gi/function.cpp:1104–1185  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1102}
1103
1104bool Function::finish_invoke(JSContext* cx, const JS::CallArgs& args,
1105 GjsFunctionCallState* state,
1106 GIArgument* r_value /* = nullptr */) {
1107 // In this loop we use ffi_arg_pos just to ensure we don't release stuff
1108 // we haven't allocated yet, if we failed in type conversion above.
1109 // If we start from -1 (the return value), we need to process 1 more than
1110 // state.processed_c_args.
1111 // If we start from -2 (the instance parameter), we need to process 2 more
1112 unsigned ffi_arg_pos = state->first_arg_offset() - 1;
1113 unsigned ffi_arg_max = state->last_processed_index();
1114 bool postinvoke_release_failed = false;
1115 for (int gi_arg_pos = -(state->first_arg_offset());
1116 gi_arg_pos < state->gi_argc && ffi_arg_pos < ffi_arg_max;
1117 gi_arg_pos++, ffi_arg_pos++) {
1118 Maybe<Argument*> gjs_arg;
1119 GIArgument* in_value = nullptr;
1120 GIArgument* out_value = nullptr;
1121
1122 if (gi_arg_pos == -2) {
1123 in_value = state->instance();
1124 gjs_arg = m_arguments.instance();
1125 } else if (gi_arg_pos == -1) {
1126 out_value = state->return_value();
1127 gjs_arg = m_arguments.return_value();
1128 } else {
1129 in_value = &state->in_cvalue(gi_arg_pos);
1130 out_value = &state->out_cvalue(gi_arg_pos);
1131 gjs_arg = Some(m_arguments.argument(gi_arg_pos));
1132 }
1133
1134 if (!gjs_arg)
1135 continue;
1136
1137 gjs_debug_marshal(
1138 GJS_DEBUG_GFUNCTION,
1139 "Releasing argument '%s', %d/%d GI args, %u/%u C args",
1140 (*gjs_arg)->arg_name(), gi_arg_pos, state->gi_argc, ffi_arg_pos,
1141 state->processed_c_args);
1142
1143 // Only process in or inout arguments if we failed, the rest is garbage
1144 if (state->failed && (*gjs_arg)->skip_in())
1145 continue;
1146
1147 // Save the return GIArgument if it was requested
1148 if (r_value && gi_arg_pos == -1) {
1149 *r_value = *out_value;
1150 continue;
1151 }
1152
1153 if (!(*gjs_arg)->release(cx, state, in_value, out_value)) {
1154 postinvoke_release_failed = true;
1155 // continue with the release even if we fail, to avoid leaks
1156 }
1157 }
1158
1159 if (postinvoke_release_failed || state->failed)
1160 return false;
1161 if (state->did_throw_gerror())

Callers

nothing calls this directly

Calls 11

gjs_throw_gerrorFunction · 0.85
first_arg_offsetMethod · 0.80
last_processed_indexMethod · 0.80
argumentMethod · 0.80
arg_nameMethod · 0.80
skip_inMethod · 0.80
did_throw_gerrorMethod · 0.80
setMethod · 0.80
instanceMethod · 0.45
return_valueMethod · 0.45
releaseMethod · 0.45

Tested by

no test coverage detected