[gjs] function: Use safer access to GjsFunctionCallState elements



commit 69ff99f62255b7c10bfdbe65f61c51790655a6f1
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Tue Oct 27 03:11:01 2020 +0100

    function: Use safer access to GjsFunctionCallState elements
    
    Add functions to access to the call state arguments, so that we can
    match what we do in the Arguments cache and we avoid to use "cryptic"
    negative indexes in function code.

 gi/function.cpp | 30 ++++++++++++++++++++----------
 gi/function.h   |  9 ++++++++-
 2 files changed, 28 insertions(+), 11 deletions(-)
---
diff --git a/gi/function.cpp b/gi/function.cpp
index cae434a8..acbe3a7b 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -842,11 +842,7 @@ bool Function::invoke(JSContext* context, const JS::CallArgs& args,
     // - return_value: The actual return value of the C function, i.e. not an
     //   (out) param
     //
-    // The 3 GIArgument arrays are indexed by the GI argument index, with the
-    // following exceptions:
-    // - [-1] is the return value (which can be nothing/garbage if the function
-    //   function returns void)
-    // - [-2] is the instance parameter, if present
+    // The 3 GIArgument arrays are indexed by the GI argument index.
     // ffi_arg_pointers, on the other hand, represents the actual C arguments,
     // in the way ffi expects them.
 
@@ -864,7 +860,7 @@ bool Function::invoke(JSContext* context, const JS::CallArgs& args,
 
     if (state.is_method) {
         GjsArgumentCache* cache = &m_arguments[-state.first_arg_offset()];
-        GIArgument* in_value = &state.in_cvalue(-state.first_arg_offset());
+        GIArgument* in_value = state.instance();
         JS::RootedValue in_js_value(context, JS::ObjectValue(*obj));
 
         if (!cache->marshallers->in(context, cache, &state, in_value,
@@ -963,7 +959,7 @@ bool Function::invoke(JSContext* context, const JS::CallArgs& args,
 
     if (!m_arguments[-1].skip_out()) {
         gi_type_info_extract_ffi_return_value(
-            &m_arguments[-1].type_info, &return_value, &state.out_cvalue(-1));
+            &m_arguments[-1].type_info, &return_value, state.return_value());
     }
 
     // Process out arguments and return values. This loop is skipped if we fail
@@ -971,7 +967,12 @@ bool Function::invoke(JSContext* context, const JS::CallArgs& args,
     js_arg_pos = 0;
     for (gi_arg_pos = -1; gi_arg_pos < state.gi_argc; gi_arg_pos++) {
         GjsArgumentCache* cache = &m_arguments[gi_arg_pos];
-        GIArgument* out_value = &state.out_cvalue(gi_arg_pos);
+        GIArgument* out_value;
+
+        if (gi_arg_pos == -1)
+            out_value = state.return_value();
+        else
+            out_value = &state.out_cvalue(gi_arg_pos);
 
         gjs_debug_marshal(GJS_DEBUG_GFUNCTION,
                           "Marshalling argument '%s' out, %d/%d GI args",
@@ -1023,8 +1024,17 @@ bool Function::finish_invoke(JSContext* cx, const JS::CallArgs& args,
          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_cvalue(gi_arg_pos);
-        GIArgument* out_value = &state->out_cvalue(gi_arg_pos);
+        GIArgument* in_value = nullptr;
+        GIArgument* out_value = nullptr;
+
+        if (gi_arg_pos == -2) {
+            in_value = state->instance();
+        } else if (gi_arg_pos == -1) {
+            out_value = state->return_value();
+        } else {
+            in_value = &state->in_cvalue(gi_arg_pos);
+            out_value = &state->out_cvalue(gi_arg_pos);
+        }
 
         gjs_debug_marshal(
             GJS_DEBUG_GFUNCTION,
diff --git a/gi/function.h b/gi/function.h
index 40c3561b..a6ca4313 100644
--- a/gi/function.h
+++ b/gi/function.h
@@ -86,7 +86,7 @@ class GjsFunctionCallState {
     JS::RootedValueVector return_values;
     GjsAutoError local_error;
     GICallableInfo* info;
-    int gi_argc = 0;
+    uint8_t gi_argc = 0;
     unsigned processed_c_args = 0;
     bool failed : 1;
     bool can_throw_gerror : 1;
@@ -117,6 +117,13 @@ class GjsFunctionCallState {
 
     constexpr int first_arg_offset() const { return is_method ? 2 : 1; }
 
+    // The list always contains the return value, and the arguments
+    constexpr GIArgument* instance() {
+        return is_method ? &m_in_cvalues[1] : nullptr;
+    }
+
+    constexpr GIArgument* return_value() { return &m_out_cvalues[0]; }
+
     constexpr GIArgument& in_cvalue(int index) const {
         return m_in_cvalues[index + first_arg_offset()];
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]