This function can be called in two different ways. You can either use it to create JavaScript objects by calling it without @r_value, or you can decide to keep the return values in GIArgument format by providing a @r_value argument.
| 862 | // to keep the return values in GIArgument format by providing a @r_value |
| 863 | // argument. |
| 864 | bool Function::invoke(JSContext* cx, const JS::CallArgs& args, |
| 865 | JS::HandleObject this_obj /* = nullptr */, |
| 866 | GIArgument* r_value /* = nullptr */) { |
| 867 | g_assert((args.isConstructing() || !this_obj) && |
| 868 | "If not a constructor, then pass the 'this' object via CallArgs"); |
| 869 | |
| 870 | GIFFIReturnValue return_value; |
| 871 | |
| 872 | unsigned ffi_argc = m_invoker.cif.nargs; |
| 873 | GjsFunctionCallState state{cx, m_info}; |
| 874 | |
| 875 | if (state.gi_argc > Argument::MAX_ARGS) { |
| 876 | gjs_throw(cx, "Function %s has too many arguments", |
| 877 | format_name().c_str()); |
| 878 | return false; |
| 879 | } |
| 880 | |
| 881 | // ffi_argc is the number of arguments that the underlying C function takes. |
| 882 | // state.gi_argc is the number of arguments the GICallableInfo describes |
| 883 | // (which does not include "this" or GError**). m_js_in_argc is the number |
| 884 | // of arguments we expect the JS function to take (which does not include |
| 885 | // PARAM_SKIPPED args). |
| 886 | // args.length() is the number of arguments that were actually passed. |
| 887 | if (args.length() > m_js_in_argc) { |
| 888 | if (!JS::WarnUTF8(cx, "Too many arguments to %s: expected %u, got %u", |
| 889 | format_name().c_str(), m_js_in_argc, args.length())) |
| 890 | return false; |
| 891 | } else if (args.length() < m_js_in_argc) { |
| 892 | JS::CallArgs::reportMoreArgsNeeded(cx, format_name().c_str(), |
| 893 | m_js_in_argc, args.length()); |
| 894 | return false; |
| 895 | } |
| 896 | |
| 897 | // These arrays hold argument pointers. |
| 898 | // - state.in_cvalue(): C values which are passed on input (in or inout) |
| 899 | // - state.out_cvalue(): C values which are returned as arguments (out or |
| 900 | // inout) |
| 901 | // - state.inout_original_cvalue(): For the special case of (inout) args, |
| 902 | // we need to keep track of the original values we passed into the |
| 903 | // function, in case we need to free it. |
| 904 | // - ffi_arg_pointers: For passing data to FFI, we need to create another |
| 905 | // layer of indirection; this array is a pointer to an element in |
| 906 | // state.in_cvalue() or state.out_cvalue(). |
| 907 | // - return_value: The actual return value of the C function, i.e. not an |
| 908 | // (out) param |
| 909 | // |
| 910 | // The 3 GIArgument arrays are indexed by the GI argument index. |
| 911 | // ffi_arg_pointers, on the other hand, represents the actual C arguments, |
| 912 | // in the way ffi expects them. |
| 913 | |
| 914 | Gjs::InlineArray<void*, 8> ffi_arg_pointers; |
| 915 | ffi_arg_pointers.allocate(ffi_argc); |
| 916 | |
| 917 | int gi_arg_pos = 0; // index into GIArgument array |
| 918 | unsigned ffi_arg_pos = 0; // index into ffi_arg_pointers |
| 919 | unsigned js_arg_pos = 0; // index into args |
| 920 | |
| 921 | JS::RootedObject obj{cx, this_obj}; |
no test coverage detected