[gjs: 3/5] arg-cache: Use more flags to store argument flags




commit b5a9deadde3a9d6d457a8fd6f68b21ec750feb35
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Tue Sep 8 06:56:38 2020 +0200

    arg-cache: Use more flags to store argument flags

 gi/arg-cache.cpp | 19 ++++++++++---------
 gi/arg-cache.h   | 18 ++++++++++--------
 gi/arg.h         |  4 ++++
 gi/function.cpp  | 14 +++++++-------
 4 files changed, 31 insertions(+), 24 deletions(-)
---
diff --git a/gi/arg-cache.cpp b/gi/arg-cache.cpp
index 1f294797..ffa9b7cf 100644
--- a/gi/arg-cache.cpp
+++ b/gi/arg-cache.cpp
@@ -266,7 +266,7 @@ static bool gjs_marshal_callback_in(JSContext* cx, GjsArgumentCache* self,
     GjsCallbackTrampoline* trampoline;
     ffi_closure* closure;
 
-    if (value.isNull() && !!(self->flags & GjsArgumentFlags::MAY_BE_NULL)) {
+    if (value.isNull() && (self->flags & GjsArgumentFlags::MAY_BE_NULL)) {
         closure = nullptr;
         trampoline = nullptr;
     } else {
@@ -463,7 +463,7 @@ static bool gjs_marshal_string_in_in(JSContext* cx, GjsArgumentCache* self,
         return report_typeof_mismatch(cx, self->arg_name, value,
                                       ExpectedType::STRING);
 
-    if (self->contents.string_is_filename) {
+    if (self->flags & GjsArgumentFlags::FILENAME) {
         GjsAutoChar str;
         if (!gjs_string_to_filename(cx, value, &str))
             return false;
@@ -1245,7 +1245,7 @@ static const GjsArgumentMarshallers caller_allocates_out_marshallers = {
 
 static inline void gjs_arg_cache_set_skip_all(GjsArgumentCache* self) {
     self->marshallers = &skip_all_marshallers;
-    self->skip_in = self->skip_out = true;
+    self->flags = (GjsArgumentFlags::SKIP_IN | GjsArgumentFlags::SKIP_OUT);
 }
 
 bool gjs_arg_cache_build_return(JSContext*, GjsArgumentCache* self,
@@ -1292,7 +1292,7 @@ bool gjs_arg_cache_build_return(JSContext*, GjsArgumentCache* self,
 
     // marshal_in is ignored for the return value, but skip_in is not (it is
     // used in the failure release path)
-    self->skip_in = true;
+    self->flags = (self->flags | GjsArgumentFlags::SKIP_IN);
     self->marshallers = &return_value_marshallers;
 
     return true;
@@ -1538,7 +1538,7 @@ static bool gjs_arg_cache_build_normal_in_arg(JSContext* cx,
                 self->marshallers = &string_in_transfer_none_marshallers;
             else
                 self->marshallers = &string_in_marshallers;
-            self->contents.string_is_filename = true;
+            self->flags = (self->flags | GjsArgumentFlags::FILENAME);
             break;
 
         case GI_TYPE_TAG_UTF8:
@@ -1546,7 +1546,7 @@ static bool gjs_arg_cache_build_normal_in_arg(JSContext* cx,
                 self->marshallers = &string_in_transfer_none_marshallers;
             else
                 self->marshallers = &string_in_marshallers;
-            self->contents.string_is_filename = false;
+            self->flags = (self->flags & ~GjsArgumentFlags::FILENAME);
             break;
 
         case GI_TYPE_TAG_INTERFACE: {
@@ -1618,14 +1618,15 @@ bool gjs_arg_cache_build_arg(JSContext* cx, GjsArgumentCache* self,
         flags |= GjsArgumentFlags::MAY_BE_NULL;
     if (g_arg_info_is_caller_allocates(arg))
         flags |= GjsArgumentFlags::CALLER_ALLOCATES;
-    self->flags = flags;
 
     if (direction == GI_DIRECTION_IN)
-        self->skip_out = true;
+        flags |= GjsArgumentFlags::SKIP_OUT;
     else if (direction == GI_DIRECTION_OUT)
-        self->skip_in = true;
+        flags |= GjsArgumentFlags::SKIP_IN;
     *inc_counter_out = true;
 
+    self->flags = flags;
+
     GITypeTag type_tag = g_type_info_get_tag(&self->type_info);
     if (direction == GI_DIRECTION_OUT &&
         (flags & GjsArgumentFlags::CALLER_ALLOCATES)) {
diff --git a/gi/arg-cache.h b/gi/arg-cache.h
index 669ff454..b45b6dbc 100644
--- a/gi/arg-cache.h
+++ b/gi/arg-cache.h
@@ -41,10 +41,8 @@ struct GjsArgumentCache {
     GITypeInfo type_info;
 
     uint8_t arg_pos;
-    bool skip_in : 1;
-    bool skip_out : 1;
     GITransfer transfer : 2;
-    GjsArgumentFlags flags : 2;
+    GjsArgumentFlags flags : 5;
     bool is_unsigned : 1;  // number and enum only
 
     union {
@@ -77,9 +75,6 @@ struct GjsArgumentCache {
         } enum_type;
         unsigned flags_mask;
 
-        // string / filename
-        bool string_is_filename : 1;
-
         // out caller allocates (FIXME: should be in object)
         size_t caller_allocates_size;
     } contents;
@@ -123,8 +118,7 @@ struct GjsArgumentCache {
         arg_name = "instance parameter";
         // Some calls accept null for the instance, but generally in an object
         // oriented language it's wrong to call a method on null
-        flags = GjsArgumentFlags::NONE;
-        skip_out = true;
+        flags = GjsArgumentFlags::NONE | GjsArgumentFlags::SKIP_OUT;
     }
 
     void set_return_value() {
@@ -134,6 +128,14 @@ struct GjsArgumentCache {
             GjsArgumentFlags::NONE;  // We don't really care for return values
     }
     [[nodiscard]] bool is_return_value() { return arg_pos == RETURN_VALUE; }
+
+    constexpr bool skip_in() const {
+        return (flags & GjsArgumentFlags::SKIP_IN);
+    }
+
+    constexpr bool skip_out() const {
+        return (flags & GjsArgumentFlags::SKIP_OUT);
+    }
 };
 
 // This is a trick to print out the sizes of the structs at compile time, in
diff --git a/gi/arg.h b/gi/arg.h
index 64e0f345..049da403 100644
--- a/gi/arg.h
+++ b/gi/arg.h
@@ -33,6 +33,10 @@ enum class GjsArgumentFlags : uint8_t {
     NONE = 0,
     MAY_BE_NULL = 1 << 0,
     CALLER_ALLOCATES = 1 << 1,
+    SKIP_IN = 1 << 2,
+    SKIP_OUT = 1 << 3,
+    SKIP_ALL = SKIP_IN | SKIP_OUT,
+    FILENAME = 1 << 4,
 };
 
 [[nodiscard]] char* gjs_argument_display_name(const char* arg_name,
diff --git a/gi/function.cpp b/gi/function.cpp
index 9186d157..8993e64b 100644
--- a/gi/function.cpp
+++ b/gi/function.cpp
@@ -655,7 +655,7 @@ void gjs_function_clear_async_closures() { completed_trampolines.clear(); }
 static void* get_return_ffi_pointer_from_giargument(
     GjsArgumentCache* return_arg, GIFFIReturnValue* return_value) {
     // This should be the inverse of gi_type_info_extract_ffi_return_value().
-    if (return_arg->skip_out)
+    if (return_arg->skip_out())
         return nullptr;
 
     // FIXME: Note that v_long and v_ulong don't have type-safe template
@@ -855,7 +855,7 @@ static bool gjs_invoke_c_function(JSContext* context, Function* function,
             break;
         }
 
-        if (!cache->skip_in)
+        if (!cache->skip_in())
             js_arg_pos++;
 
         processed_c_args++;
@@ -900,7 +900,7 @@ static bool gjs_invoke_c_function(JSContext* context, Function* function,
     if (!r_value)
         args.rval().setUndefined();
 
-    if (!function->arguments[-1].skip_out) {
+    if (!function->arguments[-1].skip_out()) {
         gi_type_info_extract_ffi_return_value(
             &function->arguments[-1].type_info, &return_value,
             &state.out_cvalues[-1]);
@@ -926,7 +926,7 @@ static bool gjs_invoke_c_function(JSContext* context, Function* function,
             }
         }
 
-        if (!cache->skip_out) {
+        if (!cache->skip_out()) {
             if (!r_value) {
                 if (!return_values.append(js_out_arg)) {
                     JS_ReportOutOfMemory(context);
@@ -970,7 +970,7 @@ release:
             processed_c_args);
 
         // Only process in or inout arguments if we failed, the rest is garbage
-        if (failed && cache->skip_in)
+        if (failed && cache->skip_in())
             continue;
 
         // Save the return GIArgument if it was requested
@@ -1124,7 +1124,7 @@ function_to_string (JSContext *context,
     n_jsargs = 0;
     arg_names_str = g_string_new("");
     for (i = 0; i < n_args; i++) {
-        if (priv->arguments[i].skip_in)
+        if (priv->arguments[i].skip_in())
             continue;
 
         if (n_jsargs > 0)
@@ -1256,7 +1256,7 @@ init_cached_function_data (JSContext      *context,
         GIDirection direction;
         GIArgInfo arg_info;
 
-        if (arguments[i].skip_in || arguments[i].skip_out)
+        if (arguments[i].skip_in() || arguments[i].skip_out())
             continue;
 
         g_callable_info_load_arg((GICallableInfo*) info, i, &arg_info);


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